Docker容器自动启动、网络类型、容器互联、容器跨宿主机通信、docker-compose使用-Day03
1. 重启docker服务,容器全部退出解决办法
1.1 方法1,运行容器时添加参数(推荐使用)
--restart=always
docker run --restart=always
# 例子
[root@docker01 ~]# docker run -d --restart=always nginx-1.16.1:ubuntu
be32abfee0ff311aafc4fe8366b720b7aee0cb36a2f71c65f38d25fcb49e73d2
[root@docker01 ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be32abfee0ff nginx-1.16.1:ubuntu "/bin/bash /nginx.sh" 4 seconds ago Up 3 seconds dreamy_carson
[root@docker01 ~]# systemctl restart docker
[root@docker01 ~]# docker ps -l # 这里注意CREATED和STATUS的时间,使用--restart=always重启后,CREATED时间不会清零
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be32abfee0ff nginx-1.16.1:ubuntu "/bin/bash /nginx.sh" 37 seconds ago Up 5 seconds dreamy_carso
1.2 方法2,在配置文件添加参数
[root@docker01 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.11:5000"],
"live-restore": true # 加在这里
[root@docker01 ~]# systemctl restart docker
# 例子
[root@docker01 ~]# docker run -d nginx-1.16.1:alpine
82b8143418db23ee034624bb7cea7da1b0811b71b1a94e499f6fcb913adf1e17
[root@docker01 ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
82b8143418db nginx-1.16.1:alpine "nginx -g 'daemon of…" 3 seconds ago Up 3 seconds relaxed_lovelace
[root@docker01 ~]# systemctl restart docker
[root@docker01 ~]# docker ps -l # 这里容器docker后,CREATED和STATUS时间是不会改变的
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
82b8143418db nginx-1.16.1:alpine "nginx -g 'daemon of…" 2 minutes ago Up 2 minutes relaxed_lovelace
2. Docker网络类型
2.1 四种网络类型
(1)None:不为容器配置任何网络功能,--net=none
(2)Container:与另一个运行中的容器共享Network Namespace,--net=container:containerID(K8S)
(3)Host:与宿主机共享Network Namespace,--network=host 性能最高,不用使用-p端口映射,直接使用宿主机端口
(4)Bridge:Docker设计的NAT网络模型(默认类型),container:容器id
2.2 查看docker网络类型
[root@docker01 ~]# docker inspect 82b8143418db|grep -wi -A 1 networks
"Networks": {
"bridge": { # 这就是容器默认使用的网络类型
3. 容器互联
# 默认情况下,容器启动后,容器内部可以与其他容器进行通讯,但是必须要知道对方的IP地址,而容器每次启动时,分配的IP地址都不一样。那么启动容器时可以添加--link参数,而且可以--link多个不同的容器,但是--link是单方向的。
[root@docker01 ~]# docker run -d -p 80:80 nginx-1.16.1:ubuntu
591749f9d440b9c8703e414b9a17dae2572b73ad56d8eddfd56b635cef6b49d1
[root@docker01 ~]# docker run -d -p 81:80 nginx-1.16.1:ubuntu
0adf57bb18343986c972b6ab23abacd23f07b1c4897a6fc4c51b7fb0599e425f
[root@docker01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0adf57bb1834 nginx-1.16.1:ubuntu "/bin/bash /nginx.sh" 5 seconds ago Up 5 seconds 0.0.0.0:81->80/tcp amazing_brattain
591749f9d440 nginx-1.16.1:ubuntu "/bin/bash /nginx.sh" 8 seconds ago Up 8 seconds 0.0.0.0:80->80/tcp vigorous_brown
[root@docker01 ~]# docker inspect 0adf57bb1834|grep -i ipadd
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
[root@docker01 /opt/dockerfile/web/nginx-ubuntu]# docker exec -it 591749f9d440 /bin/bash
root@591749f9d440:/# curl -I 172.17.0.3 # 这样虽然可以访问,但是很麻烦
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Wed, 09 Dec 2020 09:04:34 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 09 Dec 2020 06:20:56 GMT
Connection: keep-alive
ETag: "5fd06cc8-264"
Accept-Ranges: bytes
root@591749f9d440:/#
# 使用--link参数
[root@docker01 ~]# docker rm -f `docker ps -a -q`
0adf57bb1834
591749f9d440
[root@docker01 ~]# docker run --name web01 -d -p 80:80 nginx-1.16.1:ubuntu
9abc121fa093292d26c2989ee43de72ef3776e6f49059fd7ad18a54edd5e846d
[root@docker01 ~]# docker run --link web01:web02 -d -p 81:80 nginx-1.16.1:ubuntu # --link 其他容器的名称:自己的名称
0a0a3665c7f08a79b107fb235be28186a25d6d28e71239dbab155af5094e48ac
[root@docker01 ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a0a3665c7f0 nginx-1.16.1:ubuntu "/bin/bash /nginx.sh" 3 seconds ago Up 2 seconds 0.0.0.0:81->80/tcp naughty_elbakyan
[root@docker01 ~]# docker exec -it 0a0a3665c7f0 /bin/bash
root@0a0a3665c7f0:/# curl -I web01 # 这样就可以直接访问另一个容器的名称即可,不在需要IP地址
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Wed, 09 Dec 2020 09:10:50 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 09 Dec 2020 06:20:56 GMT
Connection: keep-alive
ETag: "5fd06cc8-264"
Accept-Ranges: bytes
# 原理如下
root@0a0a3665c7f0:/# 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 web02 9abc121fa093 web01 # 每次使用--link时,都会做一个解析到hosts文件中
172.17.0.3 0a0a3665c7f0
4. Docker跨主机容器之间的通信(macvlan)
这个演示至少要需要两台虚拟机,这里使用docker01和docker02
4.1 macvlan作用
默认情况下,一个物理网卡,只有一个物理mac地址。而macvlan的作用就是虚拟出多个mac地址。
4.2 创建macvlan网络
# 查看网络类型,默认只有三种网络类型
[root@docker01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
14868a693063 bridge bridge local
303047fe0d1b host host local
f58b20c0ab84 none null local
6333170d6b1a wordpress_default bridge local
# 两台机器都创建macvlan网络
# create 创建网络
# --driver 创建新的网络类型macvlan
# --subnet 10.0.0.0/24 指定子网范围
# --gateway 10.0.0.254 指定网关
# -o parent=eth0 指定基于eth0网卡,来创建桥接网卡。
# macvlan_1,网络名称
[root@docker01 ~]# docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=eth0 macvlan_1
776d26b3f647f8b0e5a4a02da94e1e8be35ee4ea25d1cbe6cbbdeea83eee3f27
[root@docker02 ~]# docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=eth0 macvlan_1
7df61ea3061e103eb60334fb54ec1a9dc4dcaf38da10d528575ef6e4153c7a01
4.3 测试
# docker01和docker02进行相同镜像导入操作
[root@docker01 ~]# ll
total 1496
-rw-------. 1 root root 1502 Oct 7 23:37 anaconda-ks.cfg
-rw-r--r-- 1 root root 1424896 Nov 24 19:38 docker_busybox.tar.gz
-rw-r--r-- 1 root root 98997 Dec 9 10:22 nginx-1.16.1.tar.gz
[root@docker01 ~]# docker load -i docker_busybox.tar.gz
adab5d09ba79: Loading layer 1.416MB/1.416MB
Loaded image: busybox:latest
[root@docker01 ~]# docker run -it --net macvlan_1 --ip=10.0.0.201 busybox:latest
/ #
[root@docker02 ~]# docker run -it --net macvlan_1 --ip=10.0.0.202 busybox:latest
/ #
# ping测试
/ # ping 10.0.0.202 -c 3
PING 10.0.0.202 (10.0.0.202): 56 data bytes
64 bytes from 10.0.0.202: seq=0 ttl=64 time=0.435 ms
64 bytes from 10.0.0.202: seq=1 ttl=64 time=1.197 ms
64 bytes from 10.0.0.202: seq=2 ttl=64 time=1.341 ms
--- 10.0.0.202 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.435/0.991/1.341 ms
/ # ping 10.0.0.201 -c 3
PING 10.0.0.201 (10.0.0.201): 56 data bytes
64 bytes from 10.0.0.201: seq=0 ttl=64 time=0.479 ms
64 bytes from 10.0.0.201: seq=1 ttl=64 time=4.287 ms
64 bytes from 10.0.0.201: seq=2 ttl=64 time=1.245 ms
--- 10.0.0.201 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.479/2.003/4.287 ms
5. Docker跨宿主机容器通信之overlay
该模式需要三台机器,两台docker,一台consul
该模式不用手动指定ip地址,使用时会自动分配IP。
该模式会有一个专门的数据库来集中存储管理IP地址。
5.1 启动consul容器
consul操作
[root@consol ~]# docker pull consul
[root@consul ~]# docker run -d -h consul --name=consul -p 8500:8500 -e CONSUL_BIND_INTERFACE=eth0 consul # -h,设置容器主机名,--name,设置容器名
9924d1a5ec4c35c2935947cec73f4863f1153b6e8643b2ce3e8e3c9b877cac01
[root@consul ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9924d1a5ec4c consul "docker-entrypoint.s…" 3 seconds ago Up 3 seconds 8300-8302/tcp, 8301-8302/udp, 8600/tcp, 8600/udp, 0.0.0.0:8500->8500/tcp consul
浏览器访问
5.2 更新docker01、docker02配置文件
[root@docker01 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.11:5000"],
"hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"], # 添加的配置
"cluster-store": "consul://10.0.0.13:8500", # 添加的配置
"cluster-advertise": "10.0.0.11:2376" # 添加的配置
}
# 这里直接重启docker会报错,需要更改docker启动文件,把/usr/lib/systemd/system/docker.service文件中的ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock,改成ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
# 然后再重启docker
[root@docker01 ~]# systemctl daemon-reload
[root@docker01 ~]# systemctl restart docker
# docker02配置
[root@docker02 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://hub-mirror.c.163.com"],
"insecure-registries": ["10.0.0.11:5000"],
"hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
"cluster-store": "consul://10.0.0.13:8500",
"cluster-advertise": "10.0.0.12:2376"
}
# 这里直接重启docker会报错,需要更改docker启动文件,把/usr/lib/systemd/system/docker.service文件中的ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock,改成ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
[root@docker02 ~]# vim /usr/lib/systemd/system/docker.service
# 然后再重启docker
[root@docker02 ~]# systemctl daemon-reload
[root@docker02 ~]# systemctl restart docker
浏览器查看
5.3 创建overlay网络
任意一个node节点操作
[root@docker02 ~]# docker network create -d overlay --subnet 172.16.1.0/24 --gateway 172.16.1.254 ol1 # 跟宿主机不同网段,ol1为网络名称,该命令执行后,会自动同步到其他节点
bc485f18c541c9fb8e7d2127e55ffc6e7eb480a50e85f053cd1ce6d2593bc168
[root@docker01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
3e20c61cde5d bridge bridge local
e679a51fa5c5 host host local
7df61ea3061e macvlan_1 macvlan local
6a766fea9687 none null local
bc485f18c541 ol1 overlay global # 新创建的overlay
5.4 创建容器测试
[root@docker01 ~]# docker run -it --network ol1 --name oldboy01 busybox /bin/sh
/ #
[root@docker02 ~]# docker run -it --network ol1 --name oldboy02 busybox /bin/sh
/ # ping oldboy01 -c 3
PING oldboy01 (172.16.1.2): 56 data bytes
64 bytes from 172.16.1.2: seq=0 ttl=64 time=0.444 ms
64 bytes from 172.16.1.2: seq=1 ttl=64 time=0.457 ms
64 bytes from 172.16.1.2: seq=2 ttl=64 time=0.325 ms
--- oldboy01 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.325/0.408/0.457 ms
/ #
6. docker-compose(单机版的容器编排工具)
通过docker-compose,可以一次性启动多个容器。
6.1 docker-compose结构介绍
version: '3' # api版本,官方有3个版本,1、2、3,不同版本的语法不一致
services: # 声明服务,也就是要启动多少个容器
db: # 服务 1
image: mysql:5.7 # 使用的镜像
volumes: # 持久化
- db_data:/var/lib/mysql # 挂载的目录
restart: always # 容器停止后自动启动
environment: # 启动后的环境变量
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress: # 服务 2
depends_on:
- db
image: wordpress:latest
volumes:
- web_data:/var/www/html
ports: # 端口映射
- "80" # 随机端口映射到容器的80
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes: # 全局声明持久化,把上面的两个数据库再次全局声明一次
db_data:
web_data:
6.2 安装docker-compose(需要epel源)
[root@docker01 ~]# yum install -y docker-compose
[root@docker01 ~]# mkdir /data/docker-compose -p
[root@docker01 ~]# cd /data/docker-compose/
[root@docker01 /data/docker-compose]#
[root@docker01 /data/docker-compose]# mkdir wordpress
[root@docker01 /data/docker-compose]# cd wordpress
6.3 编辑并使用
[root@docker01 /data/docker-compose/wordpress]# vim docker-compose.yaml # 这个名称跟dockerfile一样都是固定的,yaml也可以写成yml。
version: '3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- web_data:/var/www/html
ports:
- "80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:
web_data:
# 前台运行
[root@docker01 /data/docker-compose/wordpress]# docker-compose up # 后台运行在up 后面加上-d即可
## ………………省略部分输出
wordpress_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message
wordpress_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message
wordpress_1 | [Thu Dec 10 06:59:08.702632 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) PHP/7.4.13 configured -- resuming normal operations
wordpress_1 | [Thu Dec 10 06:59:08.702822 2020] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
[root@docker01 /data/docker-compose/wordpress]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c10b4b501be wordpress:latest "docker-entrypoint.s…" 3 minutes ago Up 52 seconds 0.0.0.0:32770->80/tcp wordpress_wordpress_1
98f0a3cf8604 mysql:5.7 "docker-entrypoint.s…" 3 minutes ago Up 52 seconds 3306/tcp, 33060/tcp wordpress_db_1
[root@docker01 /data/docker-compose/wordpress]# docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------
wordpress_db_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
wordpress_wordpress_1 docker-entrypoint.sh apach ... Up 0.0.0.0:32770->80/tcp # 这里做的是随机端口映射。访问的时候要带上端口
浏览器访问
6.4 docker-compose 基本操作
前台启动:docker-compose up
后台启动:docker-compose up -d
启动单个容器:docker-compose start 容器名
查看启动的容器:docker-compose ps
停止所有容器:docker-compose stop
停止单个:docker-compose stop 容器名
停止并删除所有容器:docker-compose down
查看帮助:docker-compose -h