Docker Swarm
提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案。使用它,用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。
到处都使用容器=麻烦来了
- 怎么去管理这么多容器?
- 怎么能方便的横向扩展?
- 如果容器down了,怎么能自动恢复?
- 如何去更新容器而不影响业务?
- 如何去监控追踪这些容器?
- 怎么去调度容器的创建?保护隐私数据?
1、swam的架构和概念
Swarm 是使用 SwarmKit 构建的 Docker 引擎内置(原生)的集群管理和编排工具。
(1)节点(node)
- 运行 Docker 的主机可以主动初始化一个 Swarm 集群或者加入一个已存在的 Swarm 集群,这样这个运行 Docker 的主机就成为一个 Swarm 集群的节点 (node) 。
- 节点分为管理 (manager) 节点和工作 (worker) 节点。
-
- 管理节点用于 Swarm 集群的管理:manager至少要有两个,manager节点之间要进行同步。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。
manager 一般要有两个
- 管理节点用于 Swarm 集群的管理:manager至少要有两个,manager节点之间要进行同步。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。
-
- 工作节点是任务执行节点。管理节点将服务 (service) 下发至工作节点执行。通过 gossip network 网络实现信息的同步
(2)服务(service)和任务(task)
swrvice
swrvice和docker-compose里面的service意思基本一样,一个service就是一个容器
服务有两种模式:
replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
global services 每个工作节点上运行一个任务
2、创建3个节点的 swarm
docker swarm --help
docker swarm init --help
ip a
先运行的节点将会成为manager节点
docker swarm init --advertise-addr=192.168.204.10
在其他节点中添加下面的命令,就会变成这个节点的工作节点
docker swarm join --token SWMTKN-1-0ghkjmz4c59pbu2nixs29ykm679jft9b9y37ngb46sxnyxgvvw-a2xgo5i2hskcgjx7jfi4wtnuh 192.168.204.10:2377
查看节点
docker node ls
3、Service的创建维护和水平扩展
docker service create --help
相当于 docker run
docker service create --name demo busybox sh -c "while true;do sleep 3600;done"
docker service ls
REPLICAS 表示当前水平扩张的节点数量
docker service ps demo
docker ps
docker service scale demo=5
docker service ls
REPLICAS 就有5个
docker service ps demo
进入work节点
docker ps
查看 docker service 横向扩张后的结果
docker rm -f loxllbj93nnu
删除work节点中的一个容器
docker service ls
但是,因为设置了docker service scale demo=5 ,所以节点依旧会变成5个
docker service rm demo
删除 service
4、在 swarm 集群里通过serivce部署 wordpress
swarm 会进行网络的创建与维护
创建一个网络 overlay 类的网络,名字为demo
docker network create -d overlay demo
docker network ls
docker service create --name mysql --env MYSQL_ROOT_PASSWORD=root --env MYSQL_DATABASE=workpress --network demo --mount type=volume,source=mysql-data,destination=/var/lib/mysql mysql:5.7
--mount 相当 -v
docker service rm mysql
docker service ls
docker service ps mysql
docker service create --name wordpress -p 80:80 --env WORDPRESS_DB_PASSWORD=root --env WORDPRESS_DB_HOST=mysql --network demo wordpress
http://192.168.204.10/ 访问
虽然在不同的节点上,但是用3个节点的地址,都可以访问 wordpress
5、集群服务间通信之RoutingMesh
两种方式:Internal 与 Ingress
- Internal-Container和Container之间的访问通过overlay网络(通过VIP虚拟IP)
- Ingress-如果服务有绑定接口,则此服务可以通过任意swarm节点的相应接口访问
内置的DNS服务发现功能
Internal-Container和Container之间的访问通过overlay网络(通过VIP虚拟IP) 方式:
docker network create -d overlay demo
docker service create --name whoami -p 8000:8000 --network demo -d jwilder/whoami
docker service create --name client -d --network demo busybox sh -c "while true;do sleep 3600;done"
docker exec -it 59531e3efd79 sh 进入 busybox 的容器中
ping whoami
docker service scale whoami=2
docker service ps whoami
ping whoami
得到的结果都是一样的,是因为ping的ip是虚拟的ip
nslookup whoami
查询DNS
nslookup task.whoami
看到容器的ip地址
Ingress
外部访问负载均衡
服务端口被暴露到各个swarm节点
内部通过IPVS进行负载均衡
yum install ipvsadm
iptables -nL -t nat
查看本地网络的转化规则
brctl show
ls /var/run/docker/netns
nsenter --net=/var/run/docker/netns/ingress_sbox
iptables -nL -t mangle
ipvsadm -l
6、DockerStack部署wordpress
endpoint_mode vip/dnsrr
vip:虚拟对外就一个地址,默认值
dnsrr:扩展一个就是一个地址,通过dns实现循环访问
mode: global/replicated
global:不能做横向的扩展,只有一个
replicated:默认值,可以横向扩展
placement:限制条件
constraints:
- node.role == manager
就会部署到 manager上
replicas: 3 一开始就部署了3个容器
resources:设置系统资源
limits:
cpus:'0.5'
memory:50M
reservations: # 优先保留
cpus:'0.5'
memory:50M
restart_policy:容器因意外退出,是否需要重启
condition: on-failure
delay: 5s
max_attempts: 3
update_config:#容器更新时,做的设置
parallelism: 1#同时更新一个容器
delay: 10s #容器与容器更新的间隔时间
version: '3'
services:
web:
image: wordpress
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_PASSWORD: root
networks:
- my-network
depends_on:
- mysql
deploy:
mode: replicated
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1
delay: 10s
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
volumes:
- mysql-data:/var/lib/mysql
networks:
- my-network
deploy:
mode: global
placement:
constraints:
- node.role == manager
volumes:
mysql-data:
networks:
my-network:
driver: overlay
cd /home/vagrant/labs/wordpress
more docker-compose.yml
docker stack deploy wordpress --compose-file=docker-compose.yml
docker stack ls
docker stack ps wordpress
docker stack services wordpress
docker stack rm wordpress
7、DockerSecret管理和使用
Secret 就是任何不想让别人看到的数据
Secret Management
- 存在Swarm Manager节点Raft database里。
- Secret可以assign给一个service ,这个service就能看到这个secret
- 在container内部Secret看起来像文件,但是实际是在内存
Secret 创建
1、从文件中创建
vim password
admin123
docker secret create my-pw password
docker secret ls
2、命令输入创建
echo "adminadmin" | docker secret create my-pw2 -
docker service create --name client --secret my-pw busybox sh -c "while true;do sleep 3600;done"
docker service ls
docker service ps client
docker ps
docker exec -it 473d1f1f03cc sh
cd /run/secrets
ls
cat my-pw
docker service create --name db --secret my-pw -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/my-pw mysql:5.7
docker service ps db
docker exec -it 61f1b95d93f4 sh
cat /run/secrets/my-pw
mysql -u root -p
admin123
在docker-compose中使用 secret
version: '3'
services:
web:
image: wordpress
ports:
- 8080:80
secrets:
- my-pw
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_PASSWORD_FILE: /run/secrets/my-pw
mysql:
image: mysql
secrets:
- my-pw
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my-pw
MYSQL_DATABASE: wordpress
部署的过程
docker stack deploy wordpress -c=docker-compose.yml
docker stack services wordpress
8、Service更新
尽量不中断更新,将一个节点变成两个,更新后再变成一个
docker network ls
docker service create --name web --publish 8080:5000 --network demo xiaopeng163/python-flask-demo:1.0
docker service ps web
docker service scale web=2
docker service ps web
curl 127.0.0.1:8080
sh -c "while true; do curl 127.0.0.1:8080&&sleep 1;done"
在另外一台机器上运行
docker service update --image xiaopeng163/python-flask-demo:2.0 web
docker service ps web
端口的更新:
docker service update --publish-rm 8080:5000 --publish-add 8088:5000 web