docker-compose使用
docker官方学习地址 (opens new window)
docker-compose 是一个单机的容器编排工具
Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持Docker API,就可以在其上利用Compose来进行编排管理。
github-docker-compose二进制包下载地址 (opens new window)
# docker-compose工具安装
Centos: yum install -y docker-compose
Ubuntu: apt install python-pip
也可以把已经安装过的机器,把docker-compose的二进制执行文件拷贝到对应机器(添加执行权限)
sudo curl -L https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
#sudo curl -L https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
2
3
4
查看版本:docker-compose -v
# docker-compose.yml属性
Docker-Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。
- 先给出一个常用的 docker-compose.yml 参考
目录结构
[root@yfk application]# tree ./
./
├── docker-compose.yml
├── nginx_test
│ └── dist
│ └── index.html
├── nginx_test2
│ └── Dockerfile
└── redis
└── data
└── dump.rdb
5 directories, 4 files
[root@yfk application]# cat nginx_test2/Dockerfile
FROM nginx:latest
RUN echo yfk_test_nginx_2 > /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
docker-compose.yml文件示例
[root@yfk application]# cat docker-compose.yml
version: '3'
#宿主机IP: 192.168.5.64
services:
test_nginx:
restart: always
image: nginx:latest
container_name: test_nginx
working_dir: /usr/share/nginx/html
user: "30000"
volumes:
- /etc/localtime:/etc/localtime
- ./nginx_test/dist:/usr/share/nginx/html
extra_hosts:
- "www.baidu.com:127.0.0.1"
- "www.google.com:127.0.0.1"
links:
- "test_nginx2:nginx2"
ports:
- "192.168.5.64:81:80"
networks:
yfk_test_net:
ipv4_address: 172.16.0.15
test_nginx2:
restart: always
container_name: test_nginx2
build:
context: ./nginx_test2
dockerfile: Dockerfile
working_dir: /usr/share/nginx/html
volumes:
- /etc/localtime:/etc/localtime
depends_on:
- test_redis
ports:
- "82:80"
networks:
yfk_test_net:
ipv4_address: 172.16.0.16
test_redis:
restart: always
image: redis:6
container_name: test_redis
volumes:
- ./redis/data:/data
- /etc/localtime:/etc/localtime
ports:
- "6379:6379"
environment:
- TZ=Asia/Shanghai
entrypoint: ["docker-entrypoint.sh","redis-server"]
networks:
yfk_test_net:
ipv4_address: 172.16.0.100
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 1G
networks:
yfk_test_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.16.0.0/24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
- 后台启动
docker-compos -f docker-compose.yaml up -d
在上面的docker-compose.yml里我创建了3 service服务【test_nginx,test_nginx2,test_redis】,按照上面的yml,来说明每个属性
1.version
docker-compose 的yml 文件版本
2.restart
开机自启动
3.image
容器镜像名
4.container_name
docker ps |awk '{print $NF}'
容器启动显示的名称
5.build
context Dockerfile构建目录 dockerfile 指定dockerfile 文件名
6.volumes
把宿主机的目录挂载到容器里面,不存在会自动创建空的文件夹 比如把 /etc/timezone 挂载到容器里面,当宿主机没有就会在宿主机创建一个 /etc/timezone 的目录
7.working_dir
容器内部的工作目录,比如如是java程序,启动jar包的时候,某些情况需要进入到对应的目录启动,有了这个workdir指定就不需要进入对应的目录
8.depends_on
依赖某个服务启动,比如这个test_nginx2 里面的服务需要连redis,而程序的启动顺序是先启动redis再启动test_nginx2服务,就可以用这个
9.links
容器别名,用于容器内部使用,在这里当执行“docker exec -it” 进入到test_nginx2容器,ping nginx2 发现网络是通的,IP解析到 172.16.0.16
10.build
context:dockerfile存放路径 dockerfile: dockerfile名称
如果没有镜像就会执行打包,并运行服务
docker-compose -f docker-compose up -d
构建镜像,镜像名以当前目录为前缀,版本latest,重复构建,之前的镜像TAG为空
docker-compose -f docker-compose.yml build test_nginx2
- 11.ports
"宿主机IP:宿主机端口:容器端口"
"82:80"
a.容器端口映射,监听**ipv6**
"192.168.5.64:81:80"
b.容器端口映射,监听**ipv4**,用于一个服务器存在多个IP,但多个IP想要使用同一个端口
12.environment
容器内部环境变量
13.entrypoint和command
容器启动初始命令
14.networks
设置容器网络IP地址
15.deploy
limits:限制容器启动的资源,如果超过limits的限制,容器将被强制kill之后,重新启动一个容器 reservations:容器启动初始资源
16.networks
设置docker网卡名,连接方式,容器的网段
17.extra_hosts
设置内部 hosts (和docker的参数--add-host= 功能一样)
18.user
指定启动用户id
# docker-compose 网络
查看docker网卡: docker network ls
- 创建以当前目录名前缀的网络
在docker-compose中,未显示声明,会生成默认的网络名(以当前目录名为前缀,比如当前目录是./app ,网卡名app_default)
配置yml文件
version: '3'
services:
test:
image: nginx:latest
container_name: test
2
3
4
5
6
- 使用已存在的网络
创建网络: docker network create test_bridge --driver bridge
配置yml文件
version: '3'
services:
test:
image: nginx:latest
container_name: test
networks:
default:
external:
name: test_bridge
2
3
4
5
6
7
8
9
10
- 自定义容器子网
配置yml文件
version: '3'
services:
test:
image: nginx:latest
container_name: test
networks:
app_yfk_test_net:
ipv4_address: 172.16.0.100
networks:
app_yfk_test_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.16.0.0/24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 不创建网络,使用默认的bridge网络,network_mode,
注意,使用该类型,不能自定义容器IP
配置yml文件
version: '3'
services:
test:
image: nginx:latest
container_name: test
network_mode: bridge
2
3
4
5
6
7
查看,会发现刚刚启动的容器,用的是这个网络
docker network inspect bridge
# docker-compose多机网络互联(flanneld)
部署过程需要重启docker,关闭防火墙
主机 | 部署应用 |
---|---|
192.168.5.201 | etcd,flanneld,docker |
192.168.5.202 | flanneld,docker |
# 安装Etcd和Flannel
# 安装配置Etcd
- 安装etcd
yum install etcd -y
- 配置etcd
[root@emq-test2 ~]# grep -Ev "^$|#" /etc/etcd/etcd.conf
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" #修改监听地址
ETCD_NAME="default"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.5.201:2379" #修改连接IP
2
3
4
5
- 启动
systemctl start etcd
systemctl enable etcd
2
- 添加网络
mkdir -p /opt/flannel/bin /opt/flannel/cfg
cp -a /usr/bin/etcdctl /usr/bin/etcd /opt/flannel/bin/
/opt/flannel/bin/etcdctl --no-sync -C http://192.168.5.201:2379 \
mk /flannel/network/config '{ "Network": "10.2.0.0/16", "Backend": { "Type": "vxlan", "VNI": 1 }}'
2
3
4
# 安装配置Flannel
- 安装配置flanneld
test -d /opt/soft ||mkdir -p /opt/soft && cd /opt/soft
mkdir -p /opt/flannel/bin /opt/flannel/cfg && chmod +x /opt/flannel/bin/*
wget https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz
tar zxf flannel-v0.10.0-linux-amd64.tar.gz
cp -a flanneld mk-docker-opts.sh remove-docker0.sh /opt/flannel/bin/
2
3
4
5
不知道为啥,这个脚本没有了
#cat remove-docker0.sh
#!/bin/bash
set -e
rc=0
ip link show docker0 >/dev/null 2>&1 || rc="$?"
if [[ "$rc" -eq "0" ]]; then
ip link set dev docker0 down
ip link delete docker0
fi
2
3
4
5
6
7
8
9
- 修改flannel.service
#cat /usr/lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
Before=docker.service
[Service]
EnvironmentFile=-/opt/flannel/cfg/flannel
ExecStartPre=/opt/flannel/bin/remove-docker0.sh
ExecStart=/opt/flannel/bin/flanneld ${FLANNEL_ETCD} ${FLANNEL_ETCD_KEY} ${FLANNEL_ETCD_CAFILE} ${FLANNEL_ETCD_CERTFILE} ${FLANNEL_ETCD_KEYFILE}
ExecStartPost=/opt/flannel/bin/mk-docker-opts.sh -d /run/flannel/docker
Type=notify
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 安装cni
wget https://github.com/containernetworking/plugins/releases/download/v0.7.1/cni-plugins-amd64-v0.7.1.tgz
gunzip cni-plugins-amd64-v0.7.1.tgz
mkdir -p /opt/flannel/bin/cni
tar xf cni-plugins-amd64-v0.7.1.tar -C /opt/flannel/bin/cni
chmod +x /opt/flannel/bin/*
2
3
4
5
- 修改docker.service
修改三个参数:vi /usr/lib/systemd/system/docker.service
Requires=docker.socket flanneld.service
EnvironmentFile=-/run/flannel/docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock $DOCKER_OPTS
2
3
3.重启服务
systemctl daemon-reload
systemctl enable flanneld
systemctl start flanneld
systemctl restart docker
2
3
4
# 配置新机器:192.168.5.202
1.拷贝/opt/flannel 到 192.168.5.202:/opt/flannel
2.修改:docker.service,flanneld.service
3.重启服务
systemctl daemon-reload
systemctl enable flanneld
systemctl start flanneld
systemctl restart docker
2
3
4
- 查看IP信息
# 个人存储下载地址。。。
x86_64_docker-compose-v2.16.0 (opens new window)
flannel-v0.10.0-linux-amd64.tar.gz
cni-plugins-amd64-v0.7.1.tgz
docker.service
flanneld.service
remove-docker0.sh
2
3
4
5
6
7