docker进程管理
docker进程
docker-ce-1809后的主要进程:
- dockerd:被docker客户端访问
- docker-proxy:容器间通信
- containerd:被dockerd调用,
- containerd-shim:被containerd调用
- runc:被container-shim调用
- containerd-shim:被containerd调用
容器创建过程
容器创建流程描述:
- dockerd复制接收客户端的命令,如docker的命令行;
- dockerd处理客户端指令,借助libcontainer,通过grpc调用和containerd通信
- containerd结束dockerd来的grpc请求,调用container-shim进程;
- container-shim再调用runc,runc负责提供容器运行环境
- 再层次返回:runc->container-shim->containerd->dockerd-docker客户端输出信息
容器创建流程图:
grpc简介:
google开源的远程过程调用框架,google remote procedure call
docker常用命令
查看帮助
[root@host2 ~]# docker --help
Usage: docker [OPTIONS] COMMAND
Run 'docker COMMAND --help' for more information on a command.
#docker的管理命令可以分为几大类,每类都可以进一步用--help查看更详细的帮助
如:
docker image
docker container
docker network
分别为管理镜像、容器、网络,每类里,都包含基础操作子命令,如查看、删除、创建;
docker run
[root@host2 ~]# docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
# 启动centos镜像,进入交互式窗口,执行bash命令
[root@host2 ~]# docker run -it centos bash
[root@3d7ace123eb6 /]# pwd
/
ctrl p q 退出窗口,但不终止容器
# 利用exec命令指定容器id再次进入
[root@host2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d7ace123eb6 centos "bash" 3 minutes ago Up 3 minutes heuristic_bohr
69aec747f923 nginx "/docker-entrypoint.…" 32 minutes ago Up 32 minutes 80/tcp tender_clarke
[root@host2 ~]# docker exec -it 3d7ace123eb6 bash
[root@3d7ace123eb6 /]# cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)
docker ps
[root@host2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69aec747f923 nginx "/docker-entrypoint.…" 27 minutes ago Up 27 minutes 80/tcp tender_clarke
查看运行中容器,
等同于docker container ls
[root@host2 ~]# docker ps -a
#查看,所有容器,包括已经退出的
docker rm
[root@host2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d7ace123eb6 centos "bash" 34 minutes ago Up 34 minutes heuristic_bohr
69aec747f923 nginx "/docker-entrypoint.…" About an hour ago Up About an hour 80/tcp tender_clarke
[root@host2 ~]# docker rm -f 3d7ace123eb6
3d7ace123eb6
[root@host2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69aec747f923 nginx "/docker-entrypoint.…" About an hour ago Up About an hour 80/tcp tender_clarke
docker端口映射
语法:
-P随机映射
-p手动指定映射端口
[root@host2 ~]# docker run --help |grep publish
-p, --publish list Publish a container's port(s) to the host
-P, --publish-all Publish all exposed ports to random ports
0、随机指定端口
# P选项随机映射一个宿主机端口给容器,从而使得可以通过该映射端口访问容器内服务
[root@host2 ~]# docker run -d -P --name ng2 nginx
5af682a72e9c3db95d6efeefc21535ea7d40915ce52b081adb26e807956e151b
[root@host2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5af682a72e9c nginx "/docker-entrypoint.…" 6 seconds ago Up 5 seconds 0.0.0.0:32772->80/tcp ng2
7f0e166b3b04 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:81->80/tcp ng1
1、手动指定端口
[root@host2 ~]# docker run -d -p 81:80 --name ng1 nginx
7f0e166b3b04cbc9871d245d519508a43e9a77e096350e7976d78f7031044031
[root@host2 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7f0e166b3b04 nginx "/docker-entrypoint.…" 2 seconds ago Up 1 second 0.0.0.0:81->80/tcp ng1
# 指定映射本地ip
[root@host2 ~]# docker run -d -p 192.168.80.101:82:80 --name ng3 nginx
8ac02c1fd17bedc1cde8b8315def27636fbda3feaa3cd7d666cfda77388358d2
# 本地端口随机
[root@host2 ~]# docker run -d -p 192.168.80.101::80 --name ng4 nginx
edcdbe7c747b53bf9e695cdc797c0a8e437d16b0a69909a95dfc24da62df79f1
# 指定协议,默认tcp
[root@host2 ~]# docker run -d -p 192.168.80.101:83:80/udp --name ng5 nginx
b23954c0209317b2b5e857a10e70001a5690080a4dc45110a54414fd50da1a1b
# 同时映射多个端口
[root@host2 ~]# docker run -d -p 443:443 -p 8080:80/udp --name ng8 nginx
6ed9115f3c11ac9f90021d5a28150f6e4f708ca34767493428f2ca871e86dad9
docker port
[root@host2 ~]# docker port ng1
80/tcp -> 0.0.0.0:8080
docker log
[root@host2 ~]# docker run -d -p 8080:80 --name ng1 nginx
74821b97914e4ff7425d558ca63cffc0546a6831eaeabf6ae01cce2bf214b853
[root@host2 ~]# docker logs ng1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
[root@host2 ~]# docker logs -f ng1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
# docker log可以查看容器日志
自定义容器名
[root@host2 ~]# docker run -d -p 8080:80 --name ng1 nginx
--name NAME自定义容器名称
后台启动容器
[root@host2 ~]# docker run -d -p 8080:80 --name ng1 nginx
74821b97914e4ff7425d558ca63cffc0546a6831eaeabf6ae01cce2bf214b853
-d后台运行容器,不占用命令行,返回一个容器长id
进入容器命令行
[root@host2 ~]# docker run -it --name ng2 nginx /bin/bash
root@9ca5172549f8:/# pwd
/
# -it选项,搭配进入后要执行的命令,一般是bash命令行
# exit退出,且容器也退出
# ctrl p q,只退出命令行,容器不退出
单次运行
[root@host2 ~]# docker run -it --rm --name ng1 nginx /bin/bash
root@12aaeebd9eea:/# exit
exit
[root@host2 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@host2 ~]# docker run -it --name ng1 nginx /bin/bash
root@efbc905bd87f:/# exit
exit
[root@host2 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
efbc905bd87f nginx "/docker-entrypoint.…" 5 seconds ago Exited (0) 3 seconds ago ng1
# 加了--rm,退出时,容器会自动删除的干净,ps -a看不到
# 没有--rm,退出时,docker ps -a仍然能看到exited状态的容器
传递运行命令
docker容器能一直运行的前提是,容器内的的执行命令一直在前台执行,占据shell窗口;前台指的是进入容器后的前台,非docker host的前台和shell;
[root@host2 ~]# docker run -d centos --name c1 /usr/bin/tail -f '/etc/hosts'
54965d492d2b9fd9aba780ac63c0d4e7a9ceac2805ceaba17975be91a939b4e0
[root@host2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ae02ad68a6fd centos "/usr/bin/tail -f /e…" 5 seconds ago Up 4 seconds
# tail -f 会一直占据容器内 的 命令行,所以容器放在后台执行,状态也是一直,在运行;
# 这里的容器后台执行,是指相对与docker host的后台;
[root@host2 ~]# docker run -d --name c2 centos /usr/bin/tail '/etc/hosts'
28d5548d63d83c42e8c7a8ec0918f38e360c45be3860b0b0353a932290fe270b
[root@host2 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
28d5548d63d8 centos "/usr/bin/tail /etc/…" 7 seconds ago Exited (0) 7 seconds ago c2
# tail 没有-f只是一个执行后立即退出的命令,不会占据容器内的命令行
# 所以docker放在后台执行时,也会立即转为exited状态;
容器启停
[root@host2 ~]# docker stop c1
[root@host2 ~]# docker start c1
# 直接用容器的名称,或id,即可完成容器的启停;
进入正在运行的容器
attach
[root@host2 ~]# docker run -it --name c3 centos /bin/bash
ctrl p q 退出
[root@host2 ~]# docker attach c3
[root@a7c4a756ce54 /]# pwd
/
exit时,退出,容器会停止
ctrl p q 退出,容器不会停止
exec
[root@host2 ~]# docker run -it --name c4 centos /bin/bash
[root@host2 ~]# docker exec -it c4 /bin/bash
[root@d3322bcf78b8 /]# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 12008 1980 pts/0 Ss+ 10:01 0:00 /bin/bash
root 14 0.7 0.2 12008 2164 pts/1 Ss 10:01 0:00 /bin/bash
root 27 0.0 0.2 47496 2068 pts/1 R+ 10:01 0:00 ps -aux
# exec进入用exit退出时,容器不会停止;
nsenter
推荐方式:
1、下载工具包;
[root@host2 ~]# yum install -y util-linux
[root@host2 ~]# nsenter --help
Usage:
nsenter [options] <program> [<argument>...]
# Run a program with namespaces of other processes.
# 安装包含nsenter命令的rpm包;
# docker inspect 容器名,可以输出容器的详细信息;json格式;
# docker inspect -f 可以过滤特定字段的信息
# 如下,过滤出c4这个容器的pid,然后利用nsenter命令进入容器;
# nsenter各个选项如下:
Options:
-t, --target <pid> target process to get namespaces from
-m, --mount[=<file>] enter mount namespace
-u, --uts[=<file>] enter UTS namespace (hostname etc)
-i, --ipc[=<file>] enter System V IPC namespace
-n, --net[=<file>] enter network namespace
-p, --pid[=<file>] enter pid namespace
2、过滤出目标容器的pid
[root@host2 ~]# docker inspect -f "{{.State.Pid}}" c4
8056
3、用nsenter进入容器
[root@host2 ~]# nsenter -t 8056 -m -u -i -n -p
[root@d3322bcf78b8 /]# pwd
/
[root@d3322bcf78b8 /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
脚本
将nsenter命令封装为shell脚本,通过传入容器的名称,或id,即可进入容器内部;
# 编写脚本如下:
[root@host2 ~]# vim docker-in.sh
[root@host2 ~]# cat docker-in.sh
#!/bin/bash
docker_in ()
{
pid=$(docker inspect -f {{.State.Pid}} $1)
nsenter -t $pid -m -u -i -n -p
}
docker_in $1
# 检查语法,执行权限
[root@host2 ~]# sh -n docker-in.sh
[root@host2 ~]# chmod +x docker-in.sh
# 调用,传入容器名,或容器id都行
[root@host2 ~]# ./docker-in.sh c1
[root@ae02ad68a6fd /]#
查看容器内hosts文件
# 默认会把自己的主机名加入hosts文件;
[root@ae02ad68a6fd /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 ae02ad68a6fd
[root@ae02ad68a6fd /]# hostname
ae02ad68a6fd
[root@ae02ad68a6fd /]# ip a
61: eth0@if62: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
批量关闭运行中容器
[root@host2 ~]# docker stop $(docker ps -a -q)
[root@host2 ~]# docker kill $(docker ps -a -q)
# 批量关闭、强制关闭所有容器;
批量删除已经退出容器
[root@host2 ~]# docker rm -f $(docker ps -a -q -f status=exited)
# 通过status=exited过滤出退出状态的容器,然后删除
批量删除所有容器
[root@host2 ~]# docker rm -f $(docker ps -a -q)
630df903f078
63acaa793dce
bfc10919be02
d1c4b7e8d131
7fc5f49f46ef
0e39ad7cbc87
1cf45dea0499
43118146035a
8d86b6ab5514
7ed2af9cb4c1
[root@host2 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# docker ps -a -q列出所有容器的id,然后利用rm -f删除;
指定容器dns
[root@host2 ~]# docker run -it --name c1 centos /bin/bash
[root@418ae275981a /]# pwd
/
[root@418ae275981a /]# cat /etc/resolv.conf
# Generated by NetworkManager
search b.com
nameserver 192.168.80.2
[root@host2 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search b.com
nameserver 192.168.80.2
# 由上可知,容器会默认继承宿主机的dns配置;
# 给容器配置dns有2种方式:
1、将dns配置在宿主机上,由容器继承;
2、启动容器时,将dns作为参数传递给容器
# 传递dns参数;可以看到,传递的dns参数,覆盖了从宿主机的dns配置;
[root@host2 ~]# docker run -it --name c6 --dns 8.8.8.8 centos /bin/bash
[root@56a7d66d3df5 /]# pwd
/
[root@56a7d66d3df5 /]# cat /etc/resolv.conf
search b.com
nameserver 8.8.8.8