系统学习Docker 践行DevOps理念 笔记(六)|容器编排Docker Swarm
容器编排Docker Swarm,是课程第七章的内容
1.容器编排Swarm介绍
Swarm是Docker自带的,不需要额外安装
Swarm里面有两种节点,一种是Manager节点,还有一种是Worker节点。 一般Container是运行在Worker上的,但是Manager节点上也是可以运行的,只是一般不这么做
2.创建一个三节点的swarm集群
docker swarm init --advertise-addr=192.168.205.10
这个命令要在准备作为manager节点的机器上来运行,运行这个命令的就是manager节点了,ip就是本机的ip,运行完成之后,会返回命令2docker swarm join --token SWMTKN-1-1rbdry31gxzz2u0nsbrqa5xkkd31lw83dpj5jife62xhqclbpr-151fu5csqw3ombtkm19jp9vej 192.168.205.10:2377
这个命令都是命令1里面返回的,我们直接到worker节点的机器上运行就可以了docker node ls
,查看现在的集群情况,这个命令要在manager节点上运行
3.Service的创建维护和水平扩展
相关命令:
docker service create --name demo busybox sh -c "while true; do sleep 3600; done",
这个就是启动一个service,相当于与docker rundocker service ls
,查看所有service的情况docker service ps demo
,查看某个service的情况,可以看到运行在哪个节点上docker service rm demo
,删除service,但是容器被删除会有一点延迟docker service scale demo=3
,横向扩展,也就是demo这个service的replicas会变成3,
NOTICE
- docker service ls命令返回结果里面的REPLICAS,都是"3/3"这样,分母表示总共有总数,分子表示现在有多少已经ready了
- 假设replicas我们设置为了5,那么swarm会自动帮我们去创建5个container,这时候,我们使用docker rm -f强制删除一个容器。我们会看到replicas会变成4/5,但是过一会又会变成5/5,因为swarm会确保我们的replicas个数。4/5的时候,swarm会自动帮我们再创建一个。
4.在swarm集群里通过service部署wordpress
部署过程:
- docker network create demo -d overlay,在集群里面创建overlay的网络,name为demo
- docker service create –name mysql –network demo –env MYSQL_ROOT_PASSWORD=xphone123 –env MYSQL_DATABASE=wordpress –mount type=volume,source=mysql-data,destination=/var/lib/mysql mysql 这个是创建mysql这个service的命令,–mount就是我们的docker run里面使用的-v命令,source=mysql-data指定的就是volume name,要注意docker run和docker service create里面的有些参数是不一样的
- docker service create –name wordpress -p 80:80 –env WORDPRESS_DB_PASSWORD=xphone123 –env WORDPRESS_DB_HOST=mysql –network demo wordpress,这个是创建wordpress的命令,WORDPRESS_DB_HOST的值等于mysql,这个mysql就是service的name,也就是之前ping mysql会得到那个地址的逻辑。
NOTICE
我们在运行了上面命令之后,我们可以通过docker service ps wordpress看到这个service是运行在哪个节点上面的,我们可以访问这个节点的ip,然后就看到了wordpress页面,这个是肯定的。但是这里要注意,我们这时候去访问其他两个节点的ip,也是可以看到wordpress页面的。原理在7-5,7-6里面
5.集群服务间通信之Routing Mesh
命令:
- docker network create demo -d overlay
- 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”
上面的命令都运行好之后,我们现在应该是两个容器。我们进入client这个service的容器里面,我们ping whoami,是会通的,会得到一个地址,这里我们假设是10.0.0.9。
然后我们运行一个命令,docker service scale whoami=2,那么现在whoami这个service下面就有两个容器了。
我们还是在client里面ping whoami,这个时候我们发现,ping的通,但是ip还会是10.0.0.9。
那这里就有个问题了,whoami这个service有两个容器,我们到底ping的是哪个?
其实这个10.0.0.9,这个其实不是哪个容器的ip,这个是vip,也就是一个虚拟ip,容器有另外的ip。我们可以使用nslookup查看tasks.whoami,我们就看到了真实的ip。或者我们在client容器里面运行traceroute tasks.whoami,我们可以看到每次的结果可能是不一样的。因为docker会自动为我们在service里面负载均衡。发送给10.0.0.9的这个vip的流量会被分配到每个容器的真实ip上。
NOTICE
- nslookup whoami,这个可以看到vip是多少
- nslookup tasks.whoami,可以看到vip之后的所有真实ip是多少
- 容器里面的nslookup可能会有问题,也就是找不到这个dns记录,这个时候我们可以使用
traceroute tasks.servicename
来解决 - LVS可以就认为是IPVS,因为现在IPVS是LVS的一部分
6.Routing Mesh之Ingress负载均衡
Routing Mesh两种体现里面的另一个,Ingress Network。这个是可以把服务端口暴露到每个swarm节点上,和7-5里面的不一样。
试验步骤:
试验用swarm集群情况,还是上面的集群,两个whoami,一个client,whoami开放了一个8000端口,并且映射到了本地
- curl 127.0.0.1:8000,本机运行这个命令,发现背后有负载均衡。因为每次的返回会不一样,是从不一样的容器返回的,因为现在有两个whoami容器
- sudo iptables -nL -t nat,查看端口的情况,查看本地的转发规则 可以看到有一行,tcp dpt:8000 to:172.18.0.2:8000,也就是8000端口的流量,会转发到172.18.0.2:8000
- 我们可以在本机ip a,可以看到一个172.18.0.1,docker_gwbridge这个network,和2里面的转发的ip是一个网段里面的
- brctl show
- docker network inspect docker_gwbridge,查看这个network的情况,会看到172.18.0.2这个ip,属于一个ingress-sbox,它其实是一个network的namespace。我们可以用命令6来查看
- sudo ls /var/run/docker/netns,查看namespace
- sudo nsenter –net=/var/run/docker/netns/ingress_sbox,进入这个namespace,然后我们会发现,我们进入了ingress_sbox这个namespace,我们运行ip a,就是172.18.0.2
- iptables -nL -t mangle,查看这个namespace的iptables,会发现有一行 tcp dpt:8000 MARK set 0x102,MARK set 0x102就是表示IPVS会进行负载均衡
- 查看IPVS的具体情况,我们先退出这个namespace,在本机环境里面安装ipvsadm,sudo yum install -y ipvsadm,然后再进入namespace
- 再次进入ingress_box这个netns,运行ipvsadm -l,就可以看到负载均衡的真实地址了。这里面的地址就是两个whoami的容器真实ip
数据包走向:
7.Docker Stack部署Wordpress
简单的说,stack就是通过文件来启动一系列service,而不是我们用命令一个个的去生成。
具体是用docker-compose file里面的deploy可以实现,具体的yml规则可以看下面的连接。
https://docs.docker.com/engine/reference/commandline/stack_deploy/
命令:
- docker stack deploy wordpress –compose-file=docker-compose.yml,创建一个stack,stack的name是wordpress,–compose-file用来指定yml配置文件,也可以是-c
- docker stack ls,查看现在的stack
- docker stack ps wordpress,查看stack的具体情况
- docker stack services wordpress,查看stack里面的service,可以看到绑定的端口
- docker stack rm wordpress,删除stack
docker-compose.yml:
|
|
8.作业解答之部署投票应用
具体docker-compose.yml可以查看docker-labs
8.1stack可视化
dockersamples/visualizer:stable,使用这个镜像,可以可视化整个stack
|
|
9.Docker Secret管理和使用
9.1什么是Secret
这些我们都可以存到docker secret里面
9.2Secret存在哪里
9.3使用方法
相关命令:
- 从文件创建
docker secret create my-pw password,这个password是一个文件,注意,我们创建好了docker secret之后,要把这个文件删掉 - 从输入流创建
echo “adminadmin” | docker secret create my-pw2 -,注意最后的-
- docker secret ls,查看所有的secert
- docker secret rm secret_name,删除secret
- docker service create –name client –secret my-pw busybox sh -c “while true; do sleep 3600; done”,启动一个service,–secret指定这个service可以读取的secret,可以指定多个
- cat /run/secrets/my-pw,我们在容器内部的这个路径,就可以读取到对应的secret了
- 比如我们启动的mysql容器的时候,需要指定数据库密码,我们使用-e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/my-pw,这样就可以读取到我们写在docker secret里面的密码了
10.Docker Secret在Stack中的使用
docker-compose.yml配置文件里面虽然可以写上secret的配置,可以去读取一个文件然后自动生成一个docker secret。但是毕竟这样的方式会存在文件,会不安全。所以开始推荐要用的时候先在命令行里面手动创建docker secret
|
|
11.Service更新
对service可以更新很多内容,比如更新镜像(镜像里面的代码逻辑需要更新比如),容器端口的更新
11.1更新镜像:
- 更新之前,为了使得我们现在的服务不会因为更新而不能访问(因为swarm集群里面的节点,一般都是生产环境,所以最好是不要有服务中断的情况),所以我们应该先对service进行scale,比如web的service,可以scale=2,那样就会有两个容器在服务
- 开始更新镜像,镜像的更新会一个一个来进行,因为我们已经做了scale了,所以服务不会中断,docker service update –image new_image_new web,这里的web是service的name。因为会一个一个更新,所以会出现一个容器是老的镜像,还有一个容器是新的镜像的时刻。
11.2更新端口:
更新端口可以通过先删去老的端口,然后加上新的端口来实现。 docker service update –publish-rm 8080:5000 –publish-add 8088:5000 这样就把原来的8080端口换到了8088端口,更新端口的时候,服务是会中断的,不会像更新镜像的时候一样,因为service都用一个VIP,然后VIP会负载均衡。那么更新端口的时候,VIP的端口会改变,所以服务会中断