• Docker容器管理


    Docker容器管理
    # 启动容器
    启动镜像有两种方式:
        一种是将已经存在,但是是stopped状态的镜像启动,
        一种就是基于一个镜像新建一个新的容器并启动。
    
    新建并启动容器
    让我们先老生常谈,输出一个Hello World吧。
    [root@linux-node1 ~]# docker run centos /bin/echo 'Hello World'
    Hello World
    
    很神奇,可以在精通各种语言的Hello World计数器+1了,这个和你在本地系统运行/bin/echo 'Hello world' 几乎没有任何区别,但是它是Docker容器输出的,而且输出后,它就完成使命,自动退出了。
    注意:这里就是我们学习Docker要面临的第一个疑惑,就是容器只会在前台运行一个任务,任务结束,容器就终止了。
    
    查看当前启动的容器
    [root@linux-node1 ~]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                          PORTS               NAMES
    31228cec880c        centos              "/bin/echo 'Hello Wo…"   About a minute ago   Exited (0) About a minute ago                       musing_proskuriakova
    
    刚接触Docker到这里还会有第二个疑惑:
    Docker自动帮你生成了一个名字,比如本例中是pedantic_kare。
    
    很困惑?好吧,让我们来启动一个我们自定义名称,同时可以有终端的容器,就像启动一个虚拟机一样,不过只是像而已,它们本质上完全不同。
    [root@linux-node1 ~]# docker run --name mydocker -t -i centos /bin/bash
    [root@1b0cae722fa0 /]#
    [root@1b0cae722fa0 /]# ls /
    anaconda-post.log bin dev etc home lib lib64 lost+found media mnt opt proc root
    run sbin srv sys tmp usr var
    
    上面我们使用了两个选项,-t 选项让Docker分配一个伪终端并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。
    
    [root@1b0cae722fa0 /]# ps aux
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root         1  0.0  0.1  12012  2156 pts/0    Ss   15:27   0:00 /bin/bash
    root        18  0.0  0.0  43948  1728 pts/0    R+   15:27   0:00 ps aux
    
    当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
    检查本地是否存在指定的镜像,不存在就从公共仓库下载;
    利用镜像创建并启动一个容器;
    分配一个文件系统,并在只读的镜像层外面挂载一层可读写层;
    从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去;
    从地址池配置一个ip地址给容器;
    执行用户指定的应用程序;
    执行完毕后容器被终止。
    
    
    让我们输入exit来退出这个容器,退出后,容器会自动终止运行。
    Docker容器在前台运行一个单任务,任务结束,容器就终止。这就是Docker容器的特性!同时你有没有注意到一个小细节,默认docker容器的主机名就是CONTAINER ID。
    
    让容器容器后台运行
    在使用docker run运行容器更多时候,我们是需要容器在后台运行的,也就是以守护态形式运行。可以通过-d参数来实现。
    [root@linux-node1 ~]# docker run -d --name mydocker2 centos /bin/bash
    38e42accfa2226bb6c7da2e28e12dc95f6b6d6717326442131887a24bb321cdd
    
    容器启动后就会在后台运行,然后返回一个容器ID到控制台,而且上面这个容器也终止了,带着问题继续前进。
    
    
    # 终止容器
    在前面的输出Hello World的操作中我们看到了,当Docker容器中指定的应用程序运行完毕,容器也就自动终止了。
    同时我们可以使用exit命令退出运行/bin/bash的终端,同时我们也可以使用Ctrl+d来实现同样的效果。
    
    使用docker stop来停止一个容器,默认是先给容器发送SIGTERM信号,然后10秒后发生SIGKILL信号终止容器,可以使用-t或者—time来设置等待的时间,单位是秒
    
    docker stop 容器名称、容器ID
    
    对于终止的容器,可以使用docker start来启动,或者使用docker restart来重启。
    
    [root@bc419cd0b8fa /]# exit
    Exit
    
    可以使用docker ps –a来查看容器的状态,发现已经是停止模式。
    [root@linux-node1 ~]# docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    38e42accfa22 centos "/bin/bash" 17 seconds ago Exited (0) 16 seconds ago
    mydocker2
    a5ef57e8783f centos "/bin/bash" 3 minutes ago Exited (0) About a minute ago
    mydocker
    d132d6e645ad centos "/bin/echo 'Hello wo…" 3 minutes ago Exited (0) 3 minutes
    ago serene_dijkstra
    
    启动已终止容器
    可以使用docker start来开启已经终止的容器,可以通过输入容器的CONTAINER ID,或者NAMES来进行启动。
    [root@linux-node1 ~]# docker start mydocker
    mydocker
    
    好的,我们又一次启动了运行/bin/bash的容器,那么问题来了,我们怎么进去呢。
    
    
    # 进入容器
    [root@linux-node1 ~]# docker attach mydocker
    [root@a5ef57e8783f /]#
    注意,在我们使用 attach 进入容器的时候,如果同时有多个窗口 attach 到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。这可怎么办,如果我们是团队作战,可能多个同事需要同时进入容器操作呢?还有一个最关键的问题。你输入exit以后呢?之前运行的容器退出了。
    
    nsenter进入容器
    nsenter命令被包含在util-linux软件包里面。
    [root@docker ~]# yum install -y util-linux
    
    为了连接到容器,你还需要找到容器的第一个进程的 PID,可以通过下面的命令获取。
    # docker inspect --format "{{ .State.Pid }}" <container ID or NAMES>
    
    通过这个 PID,就可以连接到这个容器:
    # nsenter --target $PID --mount --uts --ipc --net –pid
    
    [root@linux-node1 ~]# PID=$(docker inspect --format "{{ .State.Pid }}" mydocker)
    [root@linux-node1 ~]# echo $PID
    8029
    
    注意如果你的PID变量为0,说明mydocker容器没有启动。
    [root@linux-node1 ~]# nsenter --target $PID --mount --uts --ipc --net --pid
    [root@94bb1c151fbc /]# ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 15:35 pts/0    00:00:00 /bin/bash
    root        14     0  0 15:37 pts/0    00:00:00 -bash
    root        29    14  0 15:38 pts/0    00:00:00 ps -ef
    
    编写一个脚本用户进入容器
    [root@linux-node1 ~]# vim docker_in.sh
    #!/bin/bash
    # Use nsenter to access docker
    docker_in(){
    NAME_ID=$1
    PID=$(docker inspect --format "{{ .State.Pid }}" $NAME_ID)
    nsenter --target $PID --mount --uts --ipc --net --pid
    }
    docker_in $1
    
    [root@linux-node1 ~]# chmod +x docker_in.sh
    [root@linux-node1 ~]# ./docker_in.sh mydocker
    [root@94bb1c151fbc /]# exit
    logout
    [root@linux-node1 ~]#
    
    # 不进入容器执行命令
    [root@linux-node1 ~]# docker exec mydocker whoami
    root
    
    使用exec进入容器
    [root@linux-node1 ~]# docker exec -it mydocker /bin/bash
    
    注意,现在你进入容器和其它方法都是不一样的,其实是你执行了一个/bin/bash的命令,所以你现在拥有了一个shell,你现在所在的shell应该是下图中PID为33的进程。
    [root@1b0cae722fa0 /]# ps -ef
    UID PID PPID C STIME TTY TIME CMD
    root 1 0 0 15:37 ? 00:00:00 /bin/bash
    root 33 0 0 15:41 ? 00:00:00 /bin/bash
    root 46 33 0 15:41 ? 00:00:00 ps -ef
    
    或许你也发现使用docker exec、nsenter进入容器后,执行exit退出容器,容器并不会关闭。
    但是使用docker attach进入容器,输入exit退出容器后,容器也会自动终止。
    你可以想想为什么???
    
    因为除了attach,nsenter和exec实际中都是开了一个新的shell在执行。
    而attach是使用容器本身启动的/bin/bash,这个shell环境退出了,那么容器就自动退出了。
    所以Docker的魔咒来了:docker容器只能而且必须在前台运行一个进程,如果进程退出,容器就关闭。
    当然如果你想在Docker容器中启动多进程也是有办法的,我们后面会讲到。
    
    
    # 删除容器
    可以使用 docker rm 来删除一个处于终止状态的容器。
    如果要删除一个运行中的容器,可以添加-f参数。Docker会发送 SIGKILL信号给容器。
    [root@docker ~]# docker rm mydocker
    
    
    # 学习中的小技巧
    如果你在学习和测试的过程中,经常因为启动非常多的容易想删除也很难,下面列举了几个小技巧,可以快速的帮我们进行容器的清理。
    
    容器停止后就自动删除:
    docker run --rm centos /bin/echo "One"
    
    --------------------------------------------------------------------------------------
    # 杀死所有正在运行的容器.
    alias docker_kill='docker kill $(docker ps -a -q)'
    
    # 删除所有已经停止的容器.
    alias docker_clean_rm='docker rm $(docker ps -a -q)'
    
    # 删除所有未打dangling标签的镜像.
    alias docker_clean_rmi='docker rmi $(docker images -q -f dangling=true)'
    
    # 删除所有已经停止的容器和未打标签的镜像.
    alias dockerclean='dockercleanc || true && dockercleani'
    
    # 删除所有镜像.
    alias docker_rmi_images='docker rmi $(docker images -q)'
    
    注意:生产环境一定要慎用!!!
  • 相关阅读:
    Android · SQLite
    Android · 获取网络图片
    Android · 广告走灯
    Android · 动画
    Android常用资源
    Android · Fragment
    JSP 自动刷新
    JSP 点击量统计
    JSP 页面重定向
    JSP 日期处理
  • 原文地址:https://www.cnblogs.com/zhouwanchun/p/12560344.html
Copyright © 2020-2023  润新知