docker学习-容器中的进程

进入容器nginx:docker exec -it nginx-demo /bin/bash

[root@192 docker]# docker exec -it nginx-demo /bin/bash
root@9afab2acfaa4:/#

执行上述命令,命令提示符会从host主机的提示符变成容器的提示符(host主机就是容器所在的主机),容器的提示符是root@9afab2acfaa4:/#,9afab2acfaa4正是容器的id,也就是docker ps命令时看到的nginx-demo的容器id

可以查看目录下的容器:

root@9afab2acfaa4:/# cd /etc/nginx
root@9afab2acfaa4:/etc/nginx# ls
conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params
在容器中使用vi/vim指令去修改配置文件,则会报错,因为镜像中不包含vi/vim(原因是创建镜像是为了减少镜像的体积,编辑器并不是以来的程序,所以未打包到镜像),所以如果要改变配置文件,可以将配置文件拷贝到宿主机中,修改之后再拷回去

#将文件拷贝到当前目录中 ./表示当前目录,nginx-demo表示当前容器名称
[root@192 docker]# docker cp nginx-demo:/etc/nginx/nginx.conf ./
[root@192 /]# cd /root/root/setup/docker
[root@192 docker]# ls
docker-20.10.8.tgz  docker.bash  hello-world.tar.gz  install.sh  nginx.conf

此时就可以使用vim命令,修改之后重新拷贝回去

#将当前目录下的文件拷贝到指定容器的目录下
[root@192 docker]# docker cp ./nginx.conf nginx-demo:/etc/nginx/nginx.conf

在容器中的shell中执行exit命令会结束当前shell,如不想结束当前shell,可以是哦那个组合键ctrl+p+q 

docker启动容器中的it是什么意思:-i表示interactive,即交互模式 -t参数表示一个伪终端,这两个参数在在一起终端中以交互模式运行指定的程序

由于容器中年没有v/vim等指令包,可以使用apt-get的软件源安装需要的软件,此处在nginx-demo容器中安装procps包,以便在容器中执行ps命令,方便之后的测试,同理,也可以安装vim,方便再容器中直接编辑文件:

root@9afab2acfaa4:/# apt-get update
Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
Get:2 http://deb.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Get:3 http://deb.debian.org/debian bullseye-updates InRelease [44.1 kB]
Get:4 http://deb.debian.org/debian bullseye/main amd64 Packages [8184 kB]
Ign:4 http://deb.debian.org/debian bullseye/main amd64 Packages
Get:5 http://deb.debian.org/debian-security bullseye-security/main amd64 Packages [189 kB]
Get:6 http://deb.debian.org/debian bullseye-updates/main amd64 Packages [6344 B]
Get:4 http://deb.debian.org/debian bullseye/main amd64 Packages [8184 kB]
Fetched 4655 kB in 3min 50s (20.2 kB/s)
Reading package lists... Done
root@9afab2acfaa4:/# apt-get install procps
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libgpm2 libncurses6 libncursesw6 libprocps8 psmisc
Suggested packages:
  gpm
The following NEW packages will be installed:
  libgpm2 libncurses6 libncursesw6 libprocps8 procps psmisc
0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
Need to get 1034 kB of archives.
After this operation, 3474 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://deb.debian.org/debian bullseye/main amd64 libncurses6 amd64 6.2+20201114-2 [102 kB]
Get:2 http://deb.debian.org/debian bullseye/main amd64 libncursesw6 amd64 6.2+20201114-2 [132 kB]
Get:3 http://deb.debian.org/debian bullseye/main amd64 libprocps8 amd64 2:3.3.17-5 [63.9 kB]
Get:4 http://deb.debian.org/debian bullseye/main amd64 procps amd64 2:3.3.17-5 [502 kB]
Get:5 http://deb.debian.org/debian bullseye/main amd64 libgpm2 amd64 1.20.7-8 [35.6 kB]
Get:6 http://deb.debian.org/debian bullseye/main amd64 psmisc amd64 23.4-2 [198 kB]
Fetched 1034 kB in 35s (29.8 kB/s)

两条命令也可以和在一起:

apt-get update && apt-get install procps

 安装procps包后,就可以在容器中使用ps指令了

root@9afab2acfaa4:/# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 15:00 pts/0    00:00:00 nginx: master process nginx -g daemon off;
nginx        31      1  0 15:00 pts/0    00:00:00 nginx: worker process
root         41      0  0 15:40 pts/1    00:00:00 /bin/bash
root        385     41  0 15:52 pts/1    00:00:00 ps -ef

可以看到shell的pid是385,如果此时在容器内执行exit命令,则结束当前pid为385的进程,并退出容器,如果使用ctrl+p+q,则不会结束pid未385的bash进程,而是直接从容器中剥离出来

如上:nginx的master进程的pid为1,其他的nginx worker进程的子进程,如果此时将pid为1的进程kill掉:

#kill -9没杀死,yongkill-15杀死
root@9afab2acfaa4:/# kill -9 1
root@9afab2acfaa4:/# kill -15 1
root@9afab2acfaa4:/# [root@192 docker]#

可以看到用kill杀死之后,跳到宿主机目录中了,查看正在运行的容器

[root@192 docker]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@192 docker]# docker ps -a
CONTAINER ID   IMAGE        COMMAND                  CREATED             STATUS                           PORTS                                                            NAMES
9afab2acfaa4   nginx:1.22   "/docker-entrypoint.…"   About an hour ago   Exited (0) 4 minutes ago                                                                          nginx-demo

可以看到,使用kill杀死之后是字节退出容器,并停止运行容器,退出码是0,说明是正常退出的。其实,当我们通过docker stop命令去停止容器时,也是类似的原理,docker stop命令会向容器内部的主进程(PID为1的进程)发送SIGTERM信号,主进程收到信号后,开始停止,主进程停止后,容器也会随之停止,如果超过默认时间(10秒)主进程还是没有停止,则发送SIGKILL信号强制

除了docker stop命令,docker kill命令也可以用来停止容器,只不过docker kill命令默认更加激进,docker kill命令默认直接向容器主进程发送SIGKILL信号。

docker kill命令也可以根据用户的需求,向容器的主进程发送指定的信号,使用--signal参数即可,示例如下

[root@192 docker[# docker kill --signal=HUP nginx-demo

nginx-demo

上述命令表示向nginx-demo容器内的主进程(PID为1的进程)发送HUP信号,由于nginx-demo容器中的主进程就是nginx master进程,所以上例命令相当于向容器内的nginx master进程发送HUP信号。
我们知道,当执行nginx -s reload命令时,其实就是在向nginx的master进程发送HUP信号(具体可以参考博客中的这篇文章:nginx信号),所以,上例命令相当于在nginx-demo容器中执行nginx -s reload命令,即重载配置,如果我们修改了nginx配置文件,借助上例命令,即使不进入nginx-demo容器,也可以实现重载配置的目的。

重新启动容器,ps -ef查询进程,以及使用docker top 容器名 查询在host中查看指定容器的进程

[root@192 docker]# docker start nginx-demo
nginx-demo
[root@192 docker]# docker exec -it nginx-demo /bin/bash
root@9afab2acfaa4:/# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  2 16:16 pts/0    00:00:00 nginx: master process nginx -g daemon off;
nginx        24      1  0 16:16 pts/0    00:00:00 nginx: worker process
root         25      0  3 16:16 pts/1    00:00:00 /bin/bash
root         31     25  0 16:16 pts/1    00:00:00 ps -ef

[root@192 docker]# docker top nginx-demo
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                8598                8578                0                   00:16               pts/0               00:00:00            nginx: master process nginx -g daemon off;
101                 8640                8598                0                   00:16               pts/0               00:00:00            nginx: worker process

重点:结论:在host主机中通过docker top 命令查询出的id,和在容器中通过ps命令查询出的pid不同,docker本质是一种进程隔离技术,docker是通过linux内核的namespace功能实现PID的隔离的,pid namespace将host上的PID映射为容器的PID,这样可以让不同的PID namespace中存在相同的进程号,并控制进程间的关系,直白讲:两个容器,一个nginx容器,一个redis容器,在nginx容器中,nginx的master进程的pid为1,在redis容器中,redis-server进程的pid为1,对于nginx-master进程或者redis-server进程来说,它们都以为自己是这个世界上的王者,因为它们只能看到自己的世界,而且在自己看到的世界中,自己是主进程(PID为1),其实,它们都只不过是host主机中的一个普通进程罢了,nginx容器的master进程在host主机中的PID可能是1234,redis容器中的server进程在host主机中的PID可能是5678,即使在各自的容器中,它们的PID都是1,也许这就是pid namespace进程隔离最直观的感受吧。所以,docker top命令查看的是容器进程在host中的pid,在容器内执行ps命令查看的是容器进程在容器内的pid。

删除nginx-demo容器,然后使用docker  rmi删除镜像

[root@192 docker]# docker rm nginx-demo
nginx-demo
[root@192 docker]# docker rmi nginx:1.22
Untagged: nginx:1.22
Untagged: nginx@sha256:f0d28f2047853cbc10732d6eaa1b57f1f4db9b017679b9fd7966b6a2f9ccc2d1
Deleted: sha256:08a1cbf9c69edd2ab8e5250ae97703f60b9393fc5a4827cedda4b7387a5cfc6a
Deleted: sha256:4c0c7f5702a72dace2fb8b7324b2897eef47b28061e96a5fa071fec4d288e794
Deleted: sha256:ed42c9f350f17dc213acbbb3567e9cbb5fd20c10a636bc8facdebd81ca9c3ad3
Deleted: sha256:b1a85589cff385910b8aa0c15ea5ef47615d341a18b7cf45ac7156caf7022163
Deleted: sha256:bf761ad2d7d661b32945bb398d8de5fd8e51a8671039b6c40b2ce89f5b726853
Deleted: sha256:6bc3d8552fbe9f8b03d63f8805bb3586901ecf61d0f75dbaf4af644b2600eaf0

你可能感兴趣的:(Linux,docker,学习,linux)