跳转至

04-Docker容器管理

常用命令

启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。

因为Docker的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。

命令功能``````` 命令使用格式
启动容器 docker run --name -h hostname
停止容器 docker stop CONTAINER ID
查看容器 docker ps -a -l
进入容器 docker exec | docker attach方法1:docker attach mydocker #进入docker容器的方法方法2:docker exec mydocker whoami #不进入docker,查看docker内容方法3:使用nsenter命令进入,生产常用
删除容器 docker rm

创建容器

简单创建

所需要的命令主要为docker run

例如,下面的命令输出一个hehe,之后终止容器。

[root@linux-node1 ~]# docker run centos /bin/echo 'hello word'
#启动docker容器本地直接执行 /bin/echo "hello word!"
centos      #表示镜像名称
[root@linux-node1 ~]# docker run --name mydocker -it centos /bin/bash 
#启动一个bash终端,允许用户进行交互。
[root@4ef888578321 /]# cat /etc/redhat-release 
CentOS Linux release 8.4.2105
提示:只要进程一结束,容器就会结束

删除测试容器:
docker rm mydocker

参数解释

--name: 给容器定义一个名称
-i: 则让容器的标准输入保持打开。
-t: 让Docker分配一个伪终端,并绑定到容器的标准输入上
/bin/bash:  执行一个命令

当利用docker run来创建容器时,Docker在后台运行的标准操作包括:

1.检查本地是否存在指定的镜像,不存在就从公有仓库下载
2.利用镜像创建并启动一个容器
3.分配一个文件系统,并在只读的镜像层外面挂在一层可读写层
4.从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
5.从地址池配置一个ip地址给容器
6.执行用户指定的应用程序
7.执行完毕后容器被终止

创建容器(创建完毕后自动进入容器)

docker run --name centos01 -it centos:7.9.2009 /bin/bash 
docker rm centos01

创建容器(创建完毕后自动进入容器,退出自动删除容器)

docker run --name centos01 --rm -it centos:7.9.2009 /bin/bash 

创建容器(执行命令完毕后自动删除容器)

docker run --name centos01 --rm -it centos:7.9.2009 /bin/bash -c "cat /etc/redhat-release ; hostname"

创建容器(映射端口,退出后容器会关闭)

docker run --name nginx01 -it -p 8080:80 nginx
docker rm nginx01

创建容器(映射端口,后台运行容器)-d 参数:后台运行

docker run --name nginx01 -it -d -p 8080:80 nginx
docker rm -f nginx01

查看容器

创建容器:

docker run --name centos01 -d -it centos:7.9.2009 /bin/bash 
docker run --name centos02 -it centos:7.9.2009 /bin/bash 

查看已经启动的容器

docker ps

查看已经所有容器(包含未启动的)

docker ps -a

启动容器

可以利用docker start命令,直接将一个已经终止的容器启动运行。

容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其他的资源。可以在伪终端中利用ps和top来查看进程信息。

[root@docker ~]# docker start centos02

启动一个终止的容器

[root@docker ~]# docker ps -a #查看是否启动
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c6c3f38ea07 centos “/bin/bash” 8 minutes ago Up 1 seconds mycentos

停止容器

可以使用docker stop来终止一个运行中的容器。

此外,当Docker容器中指定的应用终结时,容器也自动终止。例如启动一个终端的容器,用户通过exit命令或者ctrl+d来退出终端时,所创建的容器立刻终止。

终止状态的容器可以用docker ps -a命令看到,也可以通过docker start ID 命令来启动容器。

[root@docker ~]# docker ps -a #查看所有容器的情况
[root@docker ~]# docker stop centos02 #停止容器
961fd1162c2f
[root@docker ~]# docker ps -a

极端方式停止容器(不推荐)

[root@867e6627a194 ~]# docker ps -a -q 
#列出所有启动容器的ID
867e6627a194
[root@867e6627a194 ~]# docker kill $(docker ps -a -q) 

删除容器

查看所有容器当前状态

[root@867e6627a194 ~]# docker ps -a #查看所有容器当前状态

docker rm +容器ID或者名称,删除运行的容器,-f即可

[root@867e6627a194 ~]# docker rm centos02       #删除已经停止的容器
c599b569f387
[root@867e6627a194 ~]# docker rm -f centos01    #删除正在运行的容器
302f39c202c9

在容器启动时,使用--rm参数,在容器退出时,会自动删除,在自己实验的时候很好用

[root@docker ~]# docker run --rm centos echo "hello world"
hello world

杀掉所有正在运行的容器(危险)

[root@docker ~]# docker kill $(docker ps -a -q)
80c583f13d27

删除所有正在运行的容器(危险)

[root@linux-node1 ~]# docker rm $(docker ps -a -q)

进入容器

docker attach是Docker自带的命令。下面示例如何使用该命令。

[root@docker ~]# docker run --name centos01 -d -it centos:7.9.2009 /bin/bash 
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
867e6627a194 centos “/bin/bash” 10 minutes ago Exited (127) 47 seconds ago mydocker

但是使用attach命令有时候并不方便。当多个窗口同时attach到同一个容器的时候,所有的窗口都会同步显示,当某个窗口因命令阻塞时,其他窗口也无法执行操作了。

使用attach进入,使用此方法进入的话,只要一退出容器,容器就会自动停止

[root@docker ~]# docker attach centos01

当然我们也可以使用exec来进入容器,这样就算退出,容器也不会自动停止

docker start centos01
docker exec -it centos01 bash

nsenter

nsenter命令是一个可以在指定进程的命令空间下运行指定程序的命令。它位于util-linux包中。

一个最典型的用途就是进入容器的网络命令空间。相当多的容器为了轻量级,是不包含较为基础的命令的,比如说 ip address,ping,telnet,ss,tcpdump ``等等命令,这就给调试容器网络带来相当大的困扰:只能通过 docker inspect ContainerID 命令获取到容器IP,以及无法测试和其他网络的连通性。这时就可以使用nsenter命令仅进入该容器的网络命名空间,使用宿主机的命令调试容器网络。此外,nsenter也可以进入 mnt, uts, ipc, pid, user 命令空间,以及指定根目录和工作目录。

nsenter可以访问另一个进程的名字空间。nsenter需要有root权限

[root@docker ~]# yum install -y util-linux
#安装包中有需要用到的nsenter
[root@linux-node1 ~]# docker inspect --format "{{.State.Pid}}" 21498d811e31
18433
#找到容器的第一个进程PID
[root@linux-node1 ~]# nsenter -t 18433 -u -i -n -p -m
#通过这个PID连接到容器

编写成脚本快速进入容器空间(共享宿主机的文件系统)

[root@docker ~]# vi in01.sh #编写成脚本快速进入容器空间
#!/bin/sh
if [ ! -n "$1" ];then
    docker ps
    exit 0
fi
PID=$(docker inspect --format "{{.State.Pid}}" $1) 
nsenter -t $PID -u -i -n -p 

编写成脚本快速进入容器空间(挂载命名空间,使进程有一个独立的挂载文件系统)

[root@docker ~]# vi in02.sh
#!/bin/sh
if [ ! -n "$1" ];then
    docker ps
    exit 0
fi
PID=$(docker inspect --format "{{.State.Pid}}" $1) 
nsenter --target $PID  --mount --uts --ipc --net --pid

这样我们就可以重复的进入docker的方法,生产环境用的比较多

[root@linux-bkce-node21 ~]# sh in01.sh centos01
[root@0b8e01915d3f ~]# ip addr
[root@linux-bkce-node21 ~]# sh in02.sh centos01
[root@0b8e01915d3f /]# ip addr
-bash: ip: command not found

容器自启动

Docker容器开机自动启动

https://www.cnblogs.com/royfans/p/11393791.html

部署项目服务器时,为了应对停电等情况影响正常web项目的访问,会把Docker容器设置为开机自动启动。

创建容器(映射端口,后台运行,容器自动启动)--restart=always 设置容器自动启动

docker run --name nginx01 -it --restart=always -d -p 8080:80 nginx
docker rm -f nginx01

--restart具体参数值详细信息:

​ no - 容器退出时,不重启容器;

​ on-failure - 只有在非0状态退出时才从新启动容器;

​ always - 无论退出状态是如何,都重启容器;

还可以在使用on - failure策略时,指定Docker将尝试重新启动容器的最大次数。默认情况下,Docker将尝试永远重新启动容器。

sudo docker run --restart=on-failure:10 redis

如果创建时未指定 --restart=always ,可通过update 命令

docker update --restart=always xxx
  1. Docker stop命令可以关闭容器
  2. 服务器重启reboot以后容器会自动启动
  3. 服务器强制下电后,启动后容器正常自动启动

容器转换镜像

Docker容器转换成镜像

https://www.cnblogs.com/byzy/articles/12541229.html

制作nginx容器

docker run --name centos01 -it --restart=always -d centos:7.9.2009

docker exec -it centos01 /bin/bash
rm -f /etc/yum.repos.d/*.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum repolist
yum -y install nginx
rpm -qa|grep nginx

将容器转换为镜像

docker commit centos01 centos:2022-04-06-v1

容器转换成镜像,只用复制id前几位就可以了

查看镜像

docker images

创建新容器

docker run --name centos02 -it -d centos:2022-04-06-v1

进入容器

docker exec -it centos02 /bin/bash

验证镜像

docker exec -it centos02 /bin/bash
rpm -qa|grep nginx

清理环境

docker rm -f centos01
docker rm -f centos02
docker rmi centos:2022-04-06-v1

特权模式容器

最近在使用docker 构建centos7 容器时,发现无法使用systemctl 命令。后来万能的百度解决了问题,随记之以备后用。

解决办法:

docker run --privileged -it -d centos:7.9.2009 /usr/sbin/init

#注意2点:1. --privileged 参数必须加,2. /usr/sbin/init作为容器的启动命令

验证方法:

docker exec -it $containerID bash #进入容器的bash命令行
systemctl #验证systemctl 命令是否可用

清理容器:

docker rm -f 1c4283c02547

其他

创建容器(映射端口,后台运行生产使用)

  1. 生成密钥对
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa 
  1. 准备生成工作
cat >/root/.ssh/config<<EOF
Host *
    StrictHostKeyChecking no
    UserKnownHostsFile=/dev/null

EOF
chmod 644 /root/.ssh/config
cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
mkdir -p /root/devops 
  1. 初始化容器(特权模式进入,支持systemctl)sshd服务启动慢
docker rm -f centos
docker run --privileged -v /root/.ssh:/root/.ssh -v /root/devops:/root/devops --name centos -it --restart=always -d -p 1000:22 centos/centos76:2021-11-10 /usr/sbin/init

docker exec -it centos bash
  1. 初始化容器(常规进入,不支持systemctl)sshd服务启动快
docker rm -f centos
docker run -v /root/.ssh:/root/.ssh -v /root/devops:/root/devops --name centos -it --restart=always -d -p 1000:22 centos/centos76:2021-11-10

alias j="ssh -p1000 root@localhost"
sleep 3
ssh -p1000 root@localhost