容器编排Docker Swarm
创建一个三个节点的swarm集群
案例在Swarm集群里通过service部署wordpress
问题:由于每个service可能分配到不同的节点,如我们现在要部署的wordpress需要用到mysql,若两个应用在不同的节点应如何通信呢?
方案:
1.创建overlay网络,让处于不同节点的service加入进去:
docker network create -d overlay demo
查看是否创建成功:docker network ls
2.创建mysql service:docker service create --name mysql --env MYSQL_ROOT_PASSWORD=root --env MYSQL_DATABASE=wordpress --mout type=volume,source=mysql-data,destination=/var/lib/mysql --network demo mysql
查看mysql是否创建成功:docker service ls | docker service ps mysql(service名)
3.创建wordpress service:docker service create --name wordpress -p 80:80 --env WORDPRESS_DB_PASSWORD=root --env WORDPRESS_DB_HOST=mysql --network demo wordpress
4.验证我们将wordpress启动起来之后:发现用3个节点的的ip地址都能访问wordpress,为什么呢?为什么不是仅有部署有wordpress的那个节点可以访问呢?
5.见下一个标题
集群服务间通信之Routing Mesh
Routing Mesh有两种体现:
-
Internal----Container和Container之间的访问通过overlay网络(通过VIP —虚拟IP ,VIP还有一个负载均衡的功能) DNS服务发现?通过一个虚拟ip实现,虚拟ip和实际ip有个映射关系
验证
1.创建一个overlay网络:docker network create -d overlay demo
2.创建一个service:docker service create --name whoami -p 8000:8000 --network demo -d jwilder/whoami
3.再创建一个service:docker service create --name client -d --network demo busybox sh -c "whiel true;do sleep 3600;done"
4.我们进入其中一个service:ping 另一个服务,发现ping的ip地址不是实际的地址,而是DNS的地址
5.查看某个服务的DNS地址:nslookup 服务名
6.查询某个service的实际ip地址:nslookup tasks.(service名)
如:补充启动三个whoami服务:docker service scale whoami=3
然后查询实际ip地址:
/app
nslookup: can't resolve '(null)': Name does not resolve
Name: tasks.whoami
Address 1: 10.0.1.9 0e8a9a10858c
Address 2: 10.0.1.234 whoami.3.ya31xac4by6n54hv3i7n14qn5.demo
Address 3: 10.0.1.233 whoami.2.svf7xlgygajofwthsfq4ipyrr.demo
查询DNSip:
/app # nslookup whoami
nslookup: can't resolve '(null)': Name does not resolve
Name: whoami
Address 1: 10.0.1.8
Docker Stack部署wordpress
1.准备docker-compose.yml
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
2.以dockerSwarm的方式执行docker-compose.yml应该用docker stack命令
将整个应用部署为一个stack(wordpress):
docker stack deploy wordpress --compose-file=docker-compose.yml
3.查看当前存在的stack:docker stack ls
4.查看指定的stack的详细信息:docker stack ps [stack名]
5.查看stack里的service信息:docker stack services [stack名]
Docker Secrets Management
**问题:**我们再定义一些docker-compose.yml的文件时会有一些密码设置的一些东西,例如mysql的密码,如果我们用明文不安全,因此考虑用Docker secrets来管理密码
什么是Secret?
- 用户名密码
- SSH Key
- TLS认证
- 任何不想让别人看到的数据
Secret Management
- 存在Swarm Manager节点Raft database里
- Secret可以assign给一个service,这个service就能看到这个secret
- 在container内部Secret看起来像文件,但是实际是在内存中
**案例:**secret的创建
1.从文件里来创建:mkdir secret-example & vim password 内容为:admin123
创建:docker secret create my-pw password
2.为了安全我们要删除文件:rm -rf password
3.查看我们已经创建的secret:docker secret ls
从输出流中创建:
1.通过管道符创建:echo "admin123" | docker secret create my-pw2 -
service如何用secret:
1.创建service并指定要使用的secret:docker service create --name client1 --secret my-pw busybox sh -c "while true;do sleep 3600;done"
2.查看service:docker service ls
3.查看service的详细信息:docker service ps client1
4.进入启动的service里的secret:
[root@localhost secret-example]
/
/run/secrets
my-pw
/run/secrets
例子:创建一个mysql service并使用secret
1.docker service create --name db --secret my-pw -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/my-pw mysql
2.进入容器查看:docker exec -it mysql sh
3.查看密码: cat /run/secrets/my-pw
4.验证是否可以进入mysql:mysql -uroot -p(admin123查看的密码)
docker secret如何在docker-compose文件中使用
1.准备docker-compose.yml
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 //密码路径
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
secrets:
- my-pw
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my-pw //密码路径
MYSQL_DATABASE: wordpress
volumes:
- mysql-data:/var/lib/mysql
networks:
- my-network
deploy:
mode: global //不能做横向扩展,
placement:
constraints:
- node.role == manager //将该service部署到manager
volumes:
mysql-data:
networks:
my-network:
driver: overlay
Service更新
**问题:**我们在实际的生产环境中肯定会对我们已经部署好的service进行更新,那么我们应该如何做到,不让服务挂掉同时更新呢?
案例:
1.创建一个network:docker network create -d overlay demo
2.执行:docker service create --name web --publish 8070:5000 --network demo xiaopeng163/python-flask-demo:1.0
3.为了不让服务挂掉我们要做横向的扩展:docker service scale web=2
4.运行一个shell脚本让它一直去curl:sh -c "while true; do curl 127.0.0.1:8070&&sleep 1; done"
5.通过命令更新image: docker service update --image xiaopeng163/pathon-flask-demo:2.0 web
对端口的更新:docker service update --publish-rm 8070:5000 --publish-add 8088:500 web
docker service update 还有很多选项,可根据自己需求进行选择
|