Docker Compose来轻松高效的管理编排容器,定义运行多个容器
步骤:
Dockerfile
docker-compose.yml
docker-compose up
启动,run docker-compose down
停止# 1.
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 2.
sudo chmod +x /usr/local/bin/docker-compose
# 3.
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 4.
docker-compose --version
1. docker-compose
-f --file docker-compose.yml # FILE指定Compose模板文件,默认为docker-compose.yml
2. docker-compose up # 启动所有服务
-d # 在后台运行服务器
-f docker-compose.yml # 指定compose.yml文件
3. docker-compose ps # 列出向项目中目前所有容器
4. docker-compose stop # 停止正在运行的容器
5. docker-compose down # 停止和删除容器,网络,
6. docker-compose logs # 查看服务容器的输出默认情况下,docker-compose将对不同的服务输出使用不同的颜色来区分。可以通过–no-color来关闭颜色
7. docker-compose build # 构建(重新构建)项目中的服务容器
8. docker-compose restart # 重启项目中的服务
9. docker-compose start # 启动已经存在的服务容器
10. docker-compose version # 打印version版本
1.
mkdir composetest
cd composetest
2. app.py
"""
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host=‘redis‘, port=6379) # redis为域名,对应hosts
def get_hit_count():
retries = 5
while True:
try:
return cache.incr(‘hits‘)
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route(‘/‘)
def hello():
count = get_hit_count()
return ‘Hello World! I have been seen {} times.\n‘.format(count)
"""
3. 编写docker-compose.yml
4. 启动docker-compose up
5. 启动后 默认服务名为 文件名_服务名_num
例如:code_web_1 # code目录下的web服务,num副本数量
集群状态,副本数量不只有一个运行实例
1. 网络规则
docke-compose 启动后,自动维护了一个网络 composetest_default (当前目录名称),服务间访问,不会使用ip,直接使用redis:6379
2. 如果在同一个网络下,可以直接使用域名访问
cache = redis.Redis(host=‘redis‘, port=6379)
# 只有三层
version: "3" # 版本
services: # 服务
web: # 服务1
image: redis # 镜像
build: /root/my_app # Dockerfile所在目录
command: pipenv run python app.py # 执行命令
container_name: my_web # 容器名
depends_on: # 启动顺序在redis和mysql之后
- redis
- mysql
ports: # 端口映射,暴露容器端口到主机的任意端口或指定端口(类似docker run -p)
- "3000"
- "8000:8000"
- "127.0.0.1:8001:7801"
expose: # 端口映射,暴露容器端口到其他容器,不暴露给主机(类似docker run --link)
- "6379"
volumes: # 挂载一个存在的数据卷容器
- /var/lib/mysql # Docker 会自动在创建一个数据卷,匿名挂载
- /opt/data:/var/lib/mysql # 绝对路径挂载
- datavolume:/var/lib/mysql # 具名挂载
volumes_from: # 从另一个服务或容器挂载其数据卷
- redis
entrypoint: /entrypoint.sh
environments:
- "MYSQL_ROOT_PASSWORD=123"
links: # 不推荐吧,在web的/etc/hosts里配置db的ip, 例如: 192.168.10.1 db
- db
- myserver:db # 在容器web中,容器myserver的名字就是db, 可以连接数据库 http://db:6379
redis: # 服务2
mysql: # 服务3
volumes: # 全局配置
networks:
configs:
实例:
version: "3.9"
services:
web:
container_name: my_web
build: .
ports: # 暴露端口
- "5000:5000"
depends_on: # web依赖于db和redis, 启动顺序先启动db和redis最后启动web
- db
- redis
command: pipenv run flask run
environment:
- a=b
volumes:
- ./data:/var/xxx
redis:
image: "redis:alpine"
db:
image: mysql
集群方式的部署,四台服务器,我自己用virtualbox + centos7 * 4
节点:
搭建集群:
docker swarm --help
私网和公网
对node1 机器执行 docker swarm init --advertise-addr 私网地址 --listen-addr 私网地址
例如:
$ docker swarm init --advertise-addr # 初始化节点 添加--advertise-addr参数的原因是大多数情况下我们的主机都不只有一张网卡。而一个swarm集群需要辨明集群所在的子网络是哪张网卡的 --listen-addr指出的是这个集群暴露给外界调用的HTTPAPI的socket地址
"""
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-56f5ccl2kyls04d5uxx1wwva9rv9ijtt4zs8jwcvxroxstf0s6-d5k6pk82emis2rpla7qevqe60 192.168.0.115:2377 # 复制到其他机器执行,可以加入为worker节点
To add a manager to this swarm, run ‘docker swarm join-token manager‘ and follow the instructions.
"""
# 初始化节点
docker swarm init
# 生成一个加入manager或worker的token
docker swarm join-token manager
docker swarm join-token worker
"""
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c 192.168.99.100:2377
"""
# 查看节点(只有manger节点可以使用, 比如我现在四台虚拟机,则node ls为四个)
docker node ls
"""
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ruyjls193xrvtdvt4h9b8020l * master Ready Active Leader 20.10.6
mg6qegsok9i19spfo8el7ec9j node2 Ready Active 20.10.6
48fstkzfi627kze80eqd60tbc node3 Ready Active Reachable 20.10.6
aikez4xzcvy9602hjxhynxnaa node4 Ready Active 20.10.6
"""
# 然后node1和node3位manger, node2 和node4位worker
# 在manager node 中创建服务,
docker service create --replicas 1 --name helloworld alpine ping docker.com
# 查看服务
docker service ls
# 查看服务详细信息
docker service inspect --pretty helloworld
# 查看那些node正在运行这个service
docker service ps helloworld
# 对service扩缩容
docker service scale 服务名(或id)=个数
例如: docker service scale helloworld=3
# 对删除service
docker service rm helloworld # docker ps 中对应的容器一会也会删除
# 更新服务(例如redis:3.0.6,现在你想升级为redis3.0.7)
docker service update --image redis:3.0.7 redis
# 修改一个node的Availability可用性drain。DRAIN availability prevents a node from receiving new tasks from the swarm manager. 则这个node不会接收来自manager的tasks,manager会结束之前drain node的tasks,会重新在active的node上创建tasks
docker node update --availability drain <NODE-ID>
例如:docker node update --availability drain master
[root@localhost ~]# docker swarm join --token SWMTKN-1-0hv0so8y1bl4hp9ahzand12rp82c8afrea6m7n22ae9gktx8bf-2oh0ty4vecnfm3tbin515hz30 192.168.0.115:2377
"""
Error response from daemon: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 192.168.0.115:2377: connect: no route to host"
"""
# manager机器的防火墙导致
systemctl status firewalld.service # 查看防火墙状态
systemctl stop firewalld.service # 停止防火墙
systemctl disable firewalld.service # 永久停止
双主双从:假设一个节点挂了,其他节点是否可用?
实验:
将docker1的机器docker服务停止,宕机,双主,另外一个主节点也不能使用
可以将其他节点离开,则显示Down
的状态
当三个机器为管理节点时候,有一个宕机,其余两个仍然可用。如果有两个为管理节点,一个宕机,另一个不能用了。
总结:
实战: 动态扩缩容
# 1. 创建服务
docker service create -p 8888:80 --name my_nginx nginx
# 2. 调整为3个副本,动态扩缩容
docker service update --replicas 3 my_nginx
docker service scale my_nginx=3 # 法二
# 3. 访问服务
curl 192.168.0.116:8888
swarm: 集群的管理和编号,docker可以初始化一个swarm集群,其他节点可以加入(管理者,工人)。
**Node: ** 对应的docker节点,多个节点组成一个网络集群(管理,工作者)
Service: 任务,可以在管理节点或者工作节点来运行,核心。
**Task: ** 容器内的命令,细节任务
其他命令:
--mode string # 创建的服务,以什么模式运行 Service mode (replicated, global, replicated-job, or global-job)
docker service create --mode replicated --name my_nginx nginx
docker service create --mode gobal --name my_nginx nginx # 每个node都有nginx
网络
overlay
ingress
原文:https://www.cnblogs.com/xuexishiguang/p/14772594.html