1、安装配置操作系统,使用CentOS stream 8镜像
之前:RHEL 8.4 发布了,CentOS紧随其后,发布CentOS 8.4
之后:CentOS 走在前面,成为RHEL上游,再去发布RHEL
制作模板,模板配置要求,cpu至少2个,内存建议4G,硬盘100G,网卡使用NAT模式。
1.编辑网卡
[root@temp network-scripts]# vi ifcfg-ens160
[root@temp network-scripts]# cat ifcfg-ens160
TYPE=Ethernet
BOOTPROTO=dhcp
NAME=ens160
DEVICE=ens160
ONBOOT=yes2.清除密钥文件
[root@temp ~]# cd /etc/ssh/
[root@temp ssh]# ls
moduli ssh_config.d ssh_host_ecdsa_key ssh_host_ed25519_key ssh_host_rsa_key
ssh_config sshd_config ssh_host_ecdsa_key.pub ssh_host_ed25519_key.pub ssh_host_rsa_key.pub
[root@temp ssh]# rm -rf ssh_host_*
[root@temp ssh]# ls
moduli ssh_config ssh_config.d sshd_config3.清除machine-id
清除,不是删除
[root@temp ssh]# cat /etc/machine-id
5f9da25a629841b8bdba92d307182c0d
[root@temp ssh]# cat /dev/null > /etc/machine-id
[root@temp ssh]# cat /etc/machine-id 4.关机
init 05.完整克隆(以后用到的虚拟机,都可以进行完整克隆)6.手工配置静态ip
[root@temp network-scripts]# cat ifcfg-ens160
TYPE=Ethernet
BOOTPROTO=none
NAME=ens160
DEVICE=ens160
ONBOOT=yes
IPADDR=192.168.100.177
NETMASK=255.255.255.0
GATEWAY=192.168.100.2
DNS1=192.168.100.2
[root@temp network-scripts]# nmcli conn down ens160
[root@temp network-scripts]# nmcli conn up ens1607.修改主机名
[root@temp network-scripts]# hostnamectl set-hostname docker
[root@temp network-scripts]# exit
logout
Docker 一家公司的名字,产品叫 Docker,容器技术,除了 docker,podman,lxd/lxc,containerd,runc等。
kubernetes(k之间8个字母简称k8s)k8s 容器编排工具。
虚拟机和容器之间的区别::虚拟机目的是为了隔离用户;容器目的是为了隔离应用(namespace cgroup)。
2、安装docker
1、安装基础软件包,用自带的yum在线源(/etc/yum.repos.d),安装bash-completion软件包能用tab键补全命令
yum install -y vim net-tools bash-completion yum-utils
2、下载docker-ce.repo文件
[root@docker yum.repos.d]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@docker yum.repos.d]# ls 查看会多个docker-ce.repo
3、安装docker
查看docker版本,yum list docker-ce --showduplicates | sort -r
默认安装最新版,yum install -y docker-ce
安装指定版本,yum install -y docker-ce-20.10.22 docker-ce-cli-20.10.22
查看已安装的docker版本,# docker -v
Docker version 24.0.6, build ed223bc
4、开启docker服务
[root@docker ~]# systemctl status docker.service
[root@docker ~]# systemctl start docker.service
[root@docker ~]# systemctl enable docker.service
docker架构
3、镜像操作
求帮助,docker --help
搜索镜像,docker search mysql
下载镜像,拉取镜像后面如果没有带版本,那么默认是latest,docker pull centos
默认从Docker Hub获取下载镜像,国外网站网络会有点卡。
查询镜像,docker images
修改镜像名称,会复制一个镜像并重命名,docker tag mysql:latest mysql:v918
删除镜像,用镜像id也行,docker rmi centos
查看镜像历史信息,docker history centos
推送镜像,因为是往自己的仓库里面推送的,所以推送之前必须要登录和tag修改名称。
不管你的仓库是公开的,还是私有的,只要是push推送都要登录。如果仓库是公开的,拉取pull,所有人都可以拉取;如果仓库是私有的,拉取pull,只能自己拉取使用。
推送镜像,阿里云
1、登入仓库,docker login --username=clisdodo@126.com registry.cn-hangzhou.aliyuncs.com
2、改镜像名称,docker tag centos:latest registry.cn-hangzhou.aliyuncs.com/cloudcs/centos:v917
3、推送镜像到仓库,docker push registry.cn-hangzhou.aliyuncs.com/cloudcs/centos:v917
镜像标准的完整名称
服务器 仓库/分类 镜像 版本
registry.cn-hangzhou.aliyuncs.com/cloudcs/centos:latest
推送镜像,华为云,登录华为云生成临时登录链接
[root@docker ~]# docker login -u cn-north-4@xxxxxxx -p xxxxxx swr.cn-north-4.myhuaweicloud.com
[root@docker ~]# docker tag busybox:latest swr.cn-north-4.myhuaweicloud.com/cloudcs/busybox:v917
[root@docker ~]# docker push swr.cn-north-4.myhuaweicloud.com/cloudcs/busybox:v917
镜像保存与导入,保存镜像到本地:docker save centos:latest -o all.tar,从本地导入镜像:docker load -i all.tar
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest a416a98b71e2 2 months ago 4.26MB
centos latest 5d0da3dc9764 2 years ago 231MB
[root@docker ~]# docker save busybox:latest centos:latest -o all.tar 保存镜像到本地
保存镜像到本地方式二,[root@docker ~]# docker save 镜像id -o a.tar
[root@docker ~]# ls
all.tar anaconda-ks.cfg
[root@docker ~]# docker rmi busybox:latest
[root@docker ~]# docker rmi centos:latest
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@docker ~]# docker load -i all.tar 从本地导入镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest a416a98b71e2 2 months ago 4.26MB
centos latest 5d0da3dc9764 2 years ago 231MB
镜像加速器,配置阿里云。默认情况下,下载镜像是从dockerhub上拉取的,国外网站网络会有点卡,这时候可以选择代理(加速器)。
[root@docker ~]# vim /etc/docker/daemon.json
[root@docker ~]# cat /etc/docker/daemon.json
{"registry-mirrors": ["https://cc2d8woc.mirror.aliyuncs.com"]
}
[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl restart docker
现在下载镜像就很快了,[root@docker ~]# docker pull mysql
镜像加速器,配置华为云,和阿里云操作一致。
4、容器操作
查询正在运行的容器,docker ps
查询所有的容器(运行的/非运行的),docker ps -a
运行一个容器run,利用centos镜像运行容器,docker run centos
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6b965c5a9486 centos "/bin/bash" 5 seconds ago Exited (0) 3 seconds ago distracted_proskuriakova
正常情况下容器的status应该是run,原因是因为容器默认运行的进程/bin/bash,因为bash shell 它是一瞬间完成的。
删除一个容器rm,docker rm -f 容器ID(只写容器ID首位就行)
删除所有容器,docker rm -f $(docker ps -qa)
为容器添加一个伪终端-t,[root@docker ~]# docker run -t centos
[root@c4ce30080051 /]# ls
添加终端之后,直接进入到了容器里面,但是执行命令的时候,发现卡死了,原因是因为虽然有了终端来承载shell命令,但是不存在交互。
为容器添加交互-i,[root@docker ~]# docker run -t -i centos
[root@ee0f71706575 /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
但是,一旦退出该容器,容器就会关闭,如果下次使用,需要提前把容器start
为容器添加持续运行--restart always,[root@docker ~]# docker run -t -i --restart always centos
[root@5aa5e29cd42b /]# exit
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5aa5e29cd42b centos "/bin/bash" 12 seconds ago Up 7 seconds elegant_hugle
添加了--restart always参数后,一旦退出容器,容器会再次重启。
这个持续运行,它主要是针对attach命令来进行重启的,但是通过exec进入并退出是不会重启的。
如果没有带--restart always参数,而且使用的attach命令进入容器,那么退出的时候,有两种选择:
要么直接exit退出,这时候容器关闭;要么使用暂停 ctrl + p+q 进行退出,容器不会关闭。
当创建容器的时候,默认会直接进入到容器里面,有时仅想把容器创建出来,而不直接登录。
为容器添加后端分离-d,[root@docker ~]# docker run -t -i -d --restart always centos
6ce63da32b22cfaa5d37fa3858c1b3476f27a24582822dd455501c37b507e17c
这时候想什么时候进入容器,可以由自己管理。
容器创建好之后,名字都是随机生成的,可以自定义容器名称。
为容器自定义名字--name,[root@docker ~]# docker run -t -i -d --name os1 --restart always centos
d98a402f2deddbace28ba19288702ff7a29a6a57a95136039bcfa0e489ed7a2c
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d98a402f2ded centos "/bin/bash" 5 seconds ago Up 4 seconds os1
也可以进行参数简写,[root@docker ~]# docker run -tid --name os1 --restart always centos
如何进入容器,推荐使用exec,docker exec -ti os1 /bin/bash
1.attach这个命令只能用于默认进程为 /bin/bash 或 /bin/sh
2.exec命令可以用于所有的进程
3.K8s对pod的进入操作都是exec
1、[root@docker ~]# docker attach os1
[root@d98a402f2ded /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@d98a402f2ded /]# exit
2、[root@docker ~]# docker exec -ti os1 /bin/bash
[root@d98a402f2ded /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@d98a402f2ded /]# exit举例:比如nginx
[root@docker ~]# docker pull nginx
[root@docker ~]# docker history nginx:latest
IMAGE CREATED CREATED BY S IZE COMMENT
605c77e624dd 20 months ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0
发现nginx默认运行的进程不是/bin/bash 或 /bin/sh
比如创建一个nginx容器,[root@docker ~]# docker run -tid --name web --restart always nginx
e095a5b2852cf49a3af1ac0ac83c3838f1ed3dffd24db000642b7c93c95c0e82
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e095a5b2852c nginx "/docker-entrypoint.…" 7 seconds ago Up 3 seconds 80/tcp web
通过exec可以进入,[root@docker ~]# docker exec -ti web /bin/bash
root@e095a5b2852c:/# exit
但是通过attach无法进入,原因是因为nginx默认运行的进程不是/bin/bash 或/bin/sh
[root@docker ~]# docker attach web
2023/09/19 06:11:14 [notice] 34#34: signal 28 (SIGWINCH) received
2023/09/19 06:11:14 [notice] 33#33: signal 28 (SIGWINCH) received
2023/09/19 06:11:14 [notice] 31#31: signal 28 (SIGWINCH) received
创建一个临时容器(用完即删)--rm,[root@docker ~]# docker run -ti --rm centos
[root@aae612a0b558 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@aae612a0b558 /]# exit
用完退出容器后会自动删除该容器,用完退出删除,就没必要带上-d参数了,也没必要带上--restart always持续运行。
指定容器生命周期sleep(秒),[root@docker ~]# docker run -tid --name os2 centos sleep 10
24a18821bc6ab964619d5646d483377447dc57baf6bbc38e33718277f98f5a97
手工指定容器生命周期,意味着不用反复重启,命令执行完,就直接关闭即可。
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
24a18821bc6a centos "sleep 30" 7 seconds ago Up 6 seconds os2
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
容器启动关闭重启start/stop/restart
[root@docker ~]# docker stop os1
os1
[root@docker ~]# docker start os1
os1
[root@docker ~]# docker restart os1
os1
容器指定环境变量-e,[root@docker ~]# docker run -tid --name os1 --restart always -e aaa=111 centos
f2640347662a563ab05c4aaa6c7c891a25165ba99aa627fec757ddb0ff78fe7f
[root@docker ~]# docker exec -ti os1 /bin/bash
[root@f2640347662a /]# echo $aaa
111举例:比如创建一个mysql容器
[root@docker ~]# docker run -tid --name db --restart always mysql
2de0cf9b29ff84f57115d3a08d6c78ae26296672c1bf532ddd86090166237bbe
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2de0cf9b29ff mysql "docker-entrypoint.s…" 10 seconds ago Restarting (1 ) 1 second ago db
这里状态不正常,可以去查询下该容器的日志
容器日志查询logs,[root@docker ~]# docker logs db
2023-09-19 06:38:18+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.27-1debian10 started.
2023-09-19 06:38:18+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2023-09-19 06:38:18+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.27-1debian10 started.
2023-09-19 06:38:18+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specifiedYou need to specify one of the following:- MYSQL_ROOT_PASSWORD- MYSQL_ALLOW_EMPTY_PASSWORD- MYSQL_RANDOM_ROOT_PASSWORD
通过日志查询,发现错误信息。知道了创建mysql的时候必须要带上设置root密码的参数。
删除db容器后再创建[root@docker ~]# docker rm -f db
[root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat mysql
b0365d36832c8b969cee20feb01a41f27fe7f5d3dee71532c980725ea5a752d2
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b0365d36832c mysql "docker-entrypoint.s…" 10 seconds ago Up 9 seconds 3306/tcp, 33060/tcp db
查询容器的详细信息inspect,[root@docker ~]# docker inspect db |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "172.17.0.3","IPAddress": "172.17.0.3",
尝试登录mysql,[root@docker ~]# mysql
bash: mysql: command not found
现在没有mysql客户端。直接安装mariadb就可以了。
[root@docker ~]# yum install -y mariadb
[root@docker ~]# mysql -uroot -predhat -h 172.17.0.3
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.27 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.003 sec)
MySQL [(none)]>
如果centos是7版本,比如7.9.那么按照上面的流程是无法直接登录的。
[root@thr ~]# mysql -uroot -predhat -h 172.17.0.3
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be
loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared
object file: No such file or directory[root@thr ~]# docker exec -ti os1 /bin/bash
bash-4.4# mysql -uroot -predhat
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.1.0 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
mysql> desc user;
mysql> select user,host,plugin from user;
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| root | % | caching_sha2_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+
mysql> alter user 'root'@'%' identified with mysql_native_password by 'redhat';
Query OK, 0 rows affected (0.00 sec)
mysql> alter user 'root'@'localhost' identified with mysql_native_password by 'redhat';
Query OK, 0 rows affected (0.01 sec)
mysql> select host,user,plugin from user;
+-----------+------------------+-----------------------+
| host | user | plugin |
+-----------+------------------+-----------------------+
| % | root | mysql_native_password |
| localhost | mysql.infoschema | caching_sha2_password |
| localhost | mysql.session | caching_sha2_password |
| localhost | mysql.sys | caching_sha2_password |
| localhost | root | mysql_native_password |
+-----------+------------------+-----------------------+
5 rows in set (0.00 sec)
[root@thr ~]# mysql -uroot -predhat -h 172.17.0.3
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.1.0 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
MySQL [(none)]>
为容器进行端口映射-p,比如创建一个nginx,如何在宿主机上进行访问呢?(nginx和http默认端口都是80)
[root@docker ~]# docker run -tid --name web --restart always -p 5000:80 nginx
1aa2b86303342ad5868e016aba73fa55502475b2be295c2f83ca818c13ad321b
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1aa2b8630334 nginx "/docker-entrypoint.…" 11 seconds ago Up 9 seconds 0.0.0.0:5000->80/tcp, :::5000->80/tcp web
容器和主机之间的拷贝cp
主机拷贝文件到容器
[root@docker ~]# docker run -tid --name web1 --restart always nginx
59e77d1c4229f57b48c20038f1d195289159b065ab6753c716d6203681cf98d4
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
59e77d1c4229 nginx "/docker-entrypoint.…" 6 seconds ago Up 5 seconds 80/tcp web1
1aa2b8630334 nginx "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 0.0.0.0:5000->80/tcp, :::5000->80/tcp web
[root@docker ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@docker ~]# docker cp /etc/hosts web1:/tmp/
Successfully copied 2.05kB to web1:/tmp/
[root@docker ~]# docker exec -ti web1 /bin/bash
root@59e77d1c4229:/# ls /tmp/
hosts容器拷贝文件到主机
root@59e77d1c4229:/# cd /tmp
root@59e77d1c4229:/tmp# touch a.txt
root@59e77d1c4229:/tmp# ls
a.txt hosts
root@59e77d1c4229:/tmp# exit
exit
[root@docker ~]# docker cp web1:/tmp/a.txt /root/
Successfully copied 1.54kB to /root/
[root@docker ~]# ls
anaconda-ks.cfg a.txt
容器常用命令
docker search 搜索镜像
docker pull 拉取镜像
docker run 运行容器
docker attach/exec 进入容器
docker logs 查看容器日志
docker inspect 查看容器底层信息(IP)
docker history 查看镜像历史信息(对外暴露端口号,进程等等)
docker start 启动容器
docker stop 关闭容器
docker restart 重启容器
docker rm 删除容器
docker rmi 删除镜像
docker ps 查看正在运行的容器
docker ps -a 查看所有容器
docker port 查看容器映射端口
docker cp 容器和主机之间进行文件拷贝
docker push 推送镜像
docker tag 对镜像进行设置别名(标签)
docker --help 求帮助
容器网络
当安装docker之后,在宿主机上(Linux)会多出一块虚拟网桥docker0(虚拟网卡/虚拟交换机)
[root@docker ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255inet6 fe80::42:41ff:fe39:80cd prefixlen 64 scopeid 0x20<link>ether 02:42:41:39:80:cd txqueuelen 0 (Ethernet)RX packets 27 bytes 3642 (3.5 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 42 bytes 4225 (4.1 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
5d9d6632dac4 bridge bridge local
d91318448989 host host local
8a522a475a44 none null local
通过查看得知,docker network一共有3种网络,主要关注bridge网络(桥接)。
当创建一个容器的时候,该容器默认是可以连通外网。
[root@docker ~]# docker run -tid --name os1 --restart always centos
2fb0348d746f057d1f2bc2a2390795c4770a6fd1bac2ae49c459016de17c077d
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2fb0348d746f centos "/bin/bash" 10 seconds ago Up 9 seconds os1
[root@docker ~]# docker exec -ti os1 /bin/bash
[root@2fb0348d746f /]# ping www.baidu.com
PING www.a.shifen.com (153.3.238.102) 56(84) bytes of data.
64 bytes from 153.3.238.102 (153.3.238.102): icmp_seq=1 ttl=127 time=18.8 ms
64 bytes from 153.3.238.102 (153.3.238.102): icmp_seq=2 ttl=127 time=18.5 ms
容器是如何连通外网的?查询网络类型,其中有一个叫做bridge类型的网络连接,这个网络所使用的虚拟交换机(虚拟网桥)就是docker0,容器创建后,相当于容器插了一根网线连接到了docker0虚拟交换机上(linux bridge类型),所以容器的ip地址为172.17.0网段。
[root@docker ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255inet6 fe80::42:41ff:fe39:80cd prefixlen 64 scopeid 0x20<link>ether 02:42:41:39:80:cd txqueuelen 0 (Ethernet)RX packets 39 bytes 4464 (4.3 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 54 bytes 5358 (5.2 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[root@2fb0348d746f /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defaultlink/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
如何查看虚拟机交换机?
查询linux bridge 虚拟交换机用 brctl show
查询ovs虚拟交换机使用 ovs-vsctl show
[root@docker ~]# brctl show
-bash: brctl: command not found
命令没有,直接联网安装即可。
[root@docker ~]# yum install -y https://mirrors.aliyun.com/centos/7/os/x86_64/Packages/bridge-utils-1.5-9.el7.x86_64.rpm
[root@docker ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242abfc06e8 no vethe7bbcbe
看到docker0上多了一个接口,这个接口就是连接容器使用的接口。
创建容器的时候,没有特别指定用哪个网络,默认使用bridge(docker0/172.17.0.1),
不想用它默认的这个bridge,可以自己创建一个自己的网络,而且可以上外网。
自定义网络
[root@docker ~]# docker network create -d bridge --subnet 192.168.88.0/24 net88
0356d17e5c4a1a772597a323d82bb90f8d0ec7536568e1d642436ccfc6301533
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
5d9d6632dac4 bridge bridge local
d91318448989 host host local
0356d17e5c4a net88 bridge local
8a522a475a44 none null local
自定义网络创建好之后,在宿主机上会显示多一个虚拟交换机。
[root@docker ~]# ifconfig
br-0356d17e5c4a: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500inet 192.168.88.1 netmask 255.255.255.0 broadcast 192.168.88.255ether 02:42:ea:e4:b5:81 txqueuelen 0 (Ethernet)RX packets 12 bytes 990 (990.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 27 bytes 2279 (2.2 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
默认的name为bridge对应的虚拟交换机为 docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255inet6 fe80::42:41ff:fe39:80cd prefixlen 64 scopeid 0x20<link>ether 02:42:41:39:80:cd txqueuelen 0 (Ethernet)RX packets 39 bytes 4464 (4.3 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 54 bytes 5358 (5.2 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
如何通过自定义网络创建容器呢?
[root@docker ~]# docker run -tid --name os1 --restart always --network net88 centos
ab51cefce1dae6004baa01c1493f6261f7f1dfb844c2674f235bfb8a450ec712
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab51cefce1da centos "/bin/bash" 4 seconds ago Up 3 seconds os1
[root@docker ~]# docker inspect os1 |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "","IPAddress": "192.168.88.2",
验证容器能否上外网
[root@docker ~]# docker exec -ti os1 /bin/bash
[root@ab51cefce1da /]# ping www.baidu.com -c 3
PING www.a.shifen.com (153.3.238.110) 56(84) bytes of data.
64 bytes from 153.3.238.110 (153.3.238.110): icmp_seq=1 ttl=127 time=18.6 ms
64 bytes from 153.3.238.110 (153.3.238.110): icmp_seq=2 ttl=127 time=19.4 ms
64 bytes from 153.3.238.110 (153.3.238.110): icmp_seq=3 ttl=127 time=19.7 ms
--- www.a.shifen.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 18.643/19.247/19.671/0.438 ms
默认情况下,一台主机上,使用同一个网络,创建多个容器,默认多个容器间网络是互通的;一台主机上,使用不同网络,创建的容器,它们之间是不能直接互通的,可以通过配置路由;
容器跨主机如何互通?docker提供了一个集群管理软件(容器编排工具)swarm,谷歌提供一个容器编排工具 kubernetes=k8s,这些编排工具都可以实现容器跨节点互通,它们是通过三方网络插件(calico/flannal等)来实现。
5、容器互联(搭建博客)
通过本地docker,快速部署一个wordpress博客系统。
1、创建一个mysql,在mysql里面单独创建一个数据库,名叫 wordpress,专门给wordpress博客使用。
[root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat -e MYSQL_DATABASE=wordpress mysql
8d8c3d4acd663ca9469987a8b15a47567a45453fbefc558d96655d046abab6ca
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d8c3d4acd66 mysql "docker-entrypoint.s…" 10 seconds ago Up 8 seconds 3306/tcp, 33060/tcp db
[root@docker ~]# docker inspect db |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "172.17.0.2","IPAddress": "172.17.0.2",
[root@docker ~]# mysql -uroot -predhat -h 172.17.0.2
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.27 MySQL Community Server - GPLCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| wordpress |
+--------------------+
5 rows in set (0.002 sec)MySQL [(none)]> use wordpress;
Database changed
MySQL [wordpress]> show tables;
Empty set (0.001 sec)MySQL [wordpress]>
2、创建一个wordpress
[root@docker ~]# docker pull wordpress
[root@docker ~]# docker run -tid --name blog --restart always -e WORDPRESS_DB_HOST=172.17.0.2 -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=redhat -e WORDPRESS_DB_NAME=wordpress -p 80:80 wordpress
fff5f14fa73c3def1c572a1839784a9469b6b03b0eaffe6a6795934e87d35ec8
前面宿主机端口,后面容器端口
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fff5f14fa73c wordpress "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp blog
之后打开浏览器,输入主机ip地址回车即可,10.1.1.77:80。
安装后查看wordpress数据库发现多了些数据表。
[root@docker ~]# mysql -uroot -predhat -h 172.17.0.2
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 38
Server version: 8.0.27 MySQL Community Server - GPLCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]> use wordpress;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
MySQL [wordpress]> show tables;
+-----------------------+
| Tables_in_wordpress |
+-----------------------+
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
12 rows in set (0.002 sec)
把数据库关闭掉,之后刷新页面,发现系统异常显示数据库未连接。
[root@docker ~]# docker inspect db |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "172.17.0.2","IPAddress": "172.17.0.2",
[root@docker ~]# docker inspect blog |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "172.17.0.3","IPAddress": "172.17.0.3",
[root@docker ~]# docker stop db
db
临时创建一个其他容器,比如centos
[root@docker ~]# docker run -tid --name os1 --restart always centos
6c6eb41daaf4c7c51d6188852529565150d02f49d7b06e23db16c804dd25a56e
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6c6eb41daaf4 centos "/bin/bash" 3 seconds ago Up 2 seconds os1
fff5f14fa73c wordpress "docker-entrypoint.s…" 11 minutes ago Up 11 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp blog
[root@docker ~]# docker inspect os1 |grep -i ipadd"SecondaryIPAddresses": null,"IPAddress": "172.17.0.2","IPAddress": "172.17.0.2",
会发现,之前db用的ip为0.2,关闭之后,创建的新的容器,它把0.2占用了。这时在启动db,看下db的ip地址。
[root@docker ~]# docker start db
db
[root@docker ~]# docker inspect db |grep -i ipadd"SecondaryIPAddresses": null,"IPAddress": "172.17.0.4","IPAddress": "172.17.0.4",
现在博客系统不正常,因为在创建wordpress的时候,指定的WORDPRESS_DB_HOST=172.17.0.2 已经写死了。ip地址发生变化了,所以导致无法访问。
如何避免这种问题呢?在数据库停止期间,不管有多少容器被创建,也不管未来数据库启动时会获取什么ip,上层的应用系统(博客)都是正常的。
容器互联(Link)
为了避免底层数据库ip地址发生变化而导致上层应用无法访问,可以使用link的方式指定一个别名。
[root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat -e MYSQL_DATABASE=wordpress mysql
95cadcd677e0a671710ae1758986602344925aec7af50d281ad2a4aa6ae67395
[root@docker ~]# docker inspect db |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "172.17.0.2","IPAddress": "172.17.0.2",
[root@docker ~]# docker run -tid --name blog --restart always --link db:memeda -e WORDPRESS_DB_HOST=memeda -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=redhat -e WORDPRESS_DB_NAME=wordpress -p 80:80 wordpress
30f861fe93637f7685f510bc4e84f051f61daeba189d2a0f3a1193b810fa79d0
[root@docker ~]# docker inspect blog |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "172.17.0.3","IPAddress": "172.17.0.3",
测试博客,一切正常。
接下来,关闭数据库
[root@docker ~]# docker stop db
db
创建一个临时容器占用 0.2 ip地址
[root@docker ~]# docker run -tid --name os1 --restart always centos
4fcad085b3470ef467255561201e5a9249716e063cc726fbc1986445ae6480e4
[root@docker ~]# docker inspect os1 |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "172.17.0.2","IPAddress": "172.17.0.2",
启动数据库
[root@docker ~]# docker start db
db
[root@docker ~]# docker inspect db |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "172.17.0.4","IPAddress": "172.17.0.4",
确认db的ip地址发生变化,刷新博客正常。
数据卷管理
默认卷,容器不能持久化保存数据,当把容器删除后,物理主机上的数据也会随之删除。
[root@docker ~]# docker exec -ti os1 /bin/bash
容器里面新增了一个文件
[root@186445e7abb5 /]# cd /tmp
[root@186445e7abb5 tmp]# touch 1.txt
这个文件是在容器里面新增的,它会映射到物理主机上。
[root@docker ~]# find / -name 1.txt 差分卷(差分数据)
/var/lib/docker/overlay2/29ae59551f8e77b175d5c518802499910f3f1bdcc825076475906850489753c1/diff/tmp/1.txt
/var/lib/docker/overlay2/29ae59551f8e77b175d5c518802499910f3f1bdcc825076475906850489753c1/merged/tmp/1.txt
overlay2保存着容器虚拟文件系统的相关信息。overlay2中有diff目录和merged目录,diff中保存的就是差分信息,merged是在容器运行时才会出现的存储情况集合,我们可以直接对差分信息进行修改,也可以在merged中进行修改,修改后的结果也会出现在diff中,同时容器内部也会直观的看到我们的修改内容。
当把容器删除后,物理主机上的数据也会随之删除。
[root@docker ~]# docker rm -f os1
os1
[root@docker ~]# find / -name 1.txt
指定永久卷,
有两种方式
1)-v /data
2)-v /data:/data2
如果-v参数后面只带了一个目录,那么该目录表示的是容器目录。
[root@docker ~]# docker run -tid --name os1 --restart always -v /abc centos
9c5e4ff5de827814bd0f713d91eb48d5905b2662968e4d0eedcbdf95e0439262
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9c5e4ff5de82 centos "/bin/bash" 1 second ago Up 1 second os1
[root@docker ~]# docker exec -ti os1 /bin/bash
[root@9c5e4ff5de82 /]# ls /abc/
接下来,往容器里面写数据
[root@9c5e4ff5de82 /]# cd /abc/
[root@9c5e4ff5de82 abc]# touch abc.txt
[root@9c5e4ff5de82 abc]# ls
abc.txt
这个文件在容器里面,它会映射到物理主机哪个目录呢?
[root@docker ~]# find / -name abc.txt
/var/lib/docker/volumes/78194401333e91063f4260f2fa45a12ea984a889a19ebf80101e4617fc4cf3d3/_dat a/abc.txt
查询容器的详细信息inspect
[root@docker ~]# docker inspect os1
"Mounts": [{"Type": "volume","Name": "78194401333e91063f4260f2fa45a12ea984a889a19ebf80101e4617fc4cf3d3","Source": "/var/lib/docker/volumes/78194401333e91063f4260f2fa45a12ea984a889a19ebf80101e4617fc4cf3d3/_data","Destination": "/abc","Driver": "local","Mode": "","RW": true,"Propagation": ""}
指定了-v参数后,如果只有一个目录,代表容器目录,它会在宿主机上随机生成一个目录,但是随机生成的这个目录是永久的。比如:删除容器
[root@docker ~]# docker rm -f os1
os1
[root@docker ~]# find / -name abc.txt
/var/lib/docker/volumes/78194401333e91063f4260f2fa45a12ea984a889a19ebf80101e4617fc4cf3d3/_data/abc.txt
删除容器后会发现,容器里面之前的数据,依然在宿主机上保存在。
但是这个目录随机生成,不怎么好记忆,怎么办?通过-v参数带上两个目录即可。
[root@docker ~]# docker run -tid --name os1 --restart always -v /host_dir:/docker_dir centos
bf41a5d2118e3af3393659d3401786b46908577488b90172ff67522c36da4049
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bf41a5d2118e centos "/bin/bash" 4 seconds ago Up 2 seconds os1
[root@docker ~]# docker exec -ti os1 /bin/bash
[root@bf41a5d2118e /]# cd /docker_dir
[root@bf41a5d2118e docker_dir]# touch 1.txt
[root@bf41a5d2118e docker_dir]# ls
1.txt
[root@bf41a5d2118e docker_dir]# exit
exit
[root@docker ~]# ls /host_dir
1.txt
接下来删除容器
[root@docker ~]# docker rm -f os1
os1
[root@docker ~]# ls /host_dir
1.txt
后面创建容器的时候,目录也可以进行复用
[root@docker ~]# docker run -tid --name os1 --restart always -v /host_dir:/docker_dir centos
daf3dcdabab0593afff5ced8e75b74c57e62b35df7070d672da869a73ebd4142
[root@docker ~]# docker exec -ti os1 /bin/bash
[root@daf3dcdabab0 /]# ls /docker_dir
1.txt
数据复用,创建mysql数据库
[root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat -v /host_data/:/var/lib/mysql mysql
68ba945c42da1fb109c60e21b597c39b04ef626bfa7851448deba31c5b51fe61
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
68ba945c42da mysql "docker-entrypoint.s…" 6 seconds ago Up 4 seconds 3306/tcp, 33060/tcp db
[root@docker ~]# ls /host_data68ba945c42da.err ca.pem ibdata1 mysql.ibd sysauto.cnf client-cert.pem ib_logfile0 performance_schema undo_001binlog.000001 client-key.pem ib_logfile1 private_key.pem undo_002binlog.000002 '#ib_16384_0.dblwr' ibtmp1 public_key.pembinlog.index '#ib_16384_1.dblwr' '#innodb_temp' server-cert.pemca-key.pem ib_buffer_pool mysql server-key.pem因为mysql数据目录映射到了宿主机上,所以mysql的所有数据文件日志文件等都保存在了宿主机上。登录数据库并操作
[root@docker ~]# docker inspect db |grep -i ipaddr"SecondaryIPAddresses": null,"IPAddress": "172.17.0.2","IPAddress": "172.17.0.2",
[root@docker ~]# mysql -uroot -predhat -h172.17.0.2
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.27 MySQL Community Server - GPLCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]> create database abc;
Query OK, 1 row affected (0.002 sec)MySQL [(none)]> use abc;
Database changed
MySQL [abc]> show tables;
Empty set (0.001 sec)MySQL [abc]> create table memeda(id int);
Query OK, 0 rows affected (0.007 sec)MySQL [abc]> insert into memeda values(1);
Query OK, 1 row affected (0.004 sec)MySQL [abc]> insert into memeda values(2);
Query OK, 1 row affected (0.001 sec)MySQL [abc]> insert into memeda values(3);
Query OK, 1 row affected (0.001 sec)MySQL [abc]> select * from memeda;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.000 sec)MySQL [abc]> exit;
Bye[root@docker ~]# ls /host_data/ 有刚才创建的abc数据库目录了68ba945c42da.err ca.pem ib_logfile1 server-cert.pemabc client-cert.pem ibtmp1 server-key.pemauto.cnf client-key.pem '#innodb_temp' sysbinlog.000001 '#ib_16384_0.dblwr' mysql undo_001binlog.000002 '#ib_16384_1.dblwr' mysql.ibd undo_002binlog.000003 ib_buffer_pool performance_schemabinlog.index ibdata1 private_key.pemca-key.pem ib_logfile0 public_key.pem
删除容器
[root@docker ~]# docker rm -f db
db
删除容器后,不会影响指定永久数据,依然存在
[root@docker ~]# ls /host_data/68ba945c42da.err ca.pem ib_logfile1 server-cert.pemabc client-cert.pem ibtmp1 server-key.pemauto.cnf client-key.pem '#innodb_temp' sysbinlog.000001 '#ib_16384_0.dblwr' mysql undo_001binlog.000002 '#ib_16384_1.dblwr' mysql.ibd undo_002binlog.000003 ib_buffer_pool performance_schemabinlog.index ibdata1 private_key.pemca-key.pem ib_logfile0 public_key.pem
下次可以直接通过映射关系,把数据映射到数据库里面
[root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat -v /host_data/:/var/lib/mysql mysql
4c62e5e6dda99a1aebadc3d707a3de40da2c499c70019382e309eb66e270df5c
[root@docker ~]# mysql -uroot -predhat -h172.17.0.2
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.27 MySQL Community Server - GPLCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| abc |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.002 sec)MySQL [(none)]> use abc;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
MySQL [abc]> select * from memeda;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.000 sec)
Compose编排
Compose适合针对小场景的容器进行编排操作。把所需要管理的所有的容器,都以yaml文件的格式,写到对应的文件中,之后通过docker compose 命令,去加载这个yaml文件,从而批量化管理所有容器。
yaml文件格式要求:
1.yaml是以空格缩进来控制层级关系,不能使用Tab键,而且大小写敏感的;(参数遵循小驼峰写法imagePullPolicy)
2.yaml缩进的空格数量不重要的,重要的是相同层级要左对齐。相同级别的元素,必须有相同的缩进,子元素的缩进距离一定大于父元素。
3.一组任务列表,列表前要加横线。遇到横线-和冒号:,其后面就空一格(只能用空格缩进不能用tab键来缩进)
需要注意的是,docker compose的语法格式。
在linux 7 版本里面:docker-compose
在linux 8 版本里面:docker compose
以8版本为例,当使用docker compose去执行yaml文件的时候,如果不指定,那么默认加载当前路径下的文件名称为:docker-compose.yaml(标准名称),如果不是这个标准名称,需要带上 -f 参数指定文件名。
比如上面创建的两个容器,一个mysql,一个wordpress,之前都是通过手工单独管理的,那么现在可以通过compose统一管理。
编写yaml文件
[root@docker ~]# vim docker-compose.yaml
[root@docker ~]# cat docker-compose.yaml
services:blog:image: wordpress:latestrestart: alwayslinks:- db:memedaports:- "80:80"environment:- WORDPRESS_DB_HOST=memeda- WORDPRESS_DB_USER=root- WORDPRESS_DB_PASSWORD=redhat- WORDPRESS_DB_NAME=wordpressdb:image: mysql:latestrestart: alwaysenvironment:- MYSQL_ROOT_PASSWORD=redhat- MYSQL_DATABASE=wordpress执行yaml文件
[root@docker ~]# docker compose up -d
[+] Running 3/3✔ Network root_default Created 0.3s ✔ Container root-db-1 Started 0.0s ✔ Container root-blog-1 Started 0.0s
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9569ac4043f1 wordpress:latest "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp root-blog-1
3435539d848d mysql:latest "docker-entrypoint.s…" 6 seconds ago Up 6 seconds 3306/tcp, 33060/tcp root-db-1停止
[root@docker ~]# docker compose stop
[+] Stopping 2/2✔ Container root-blog-1 Stopped 3.2s ✔ Container root-db-1 Stopped 0.9s启动
[root@docker ~]# docker compose start
[+] Running 2/2✔ Container root-db-1 Started 0.5s ✔ Container root-blog-1 Started 1.0s删除
[root@docker ~]# docker compose rm -s -f
[+] Stopping 2/2✔ Container root-blog-1 Stopped 1.2s ✔ Container root-db-1 Stopped 1.5s
Going to remove root-blog-1, root-db-1
[+] Removing 2/0✔ Container root-db-1 Removed 0.0s ✔ Container root-blog-1 Removed 0.0s