docker swarm学习笔记

vi /etc/sysctl.conf
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-arptables = 1
sysctl -p
需要重启

yum remove -y docker*

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

sudo yum install docker -y

修改/etc/sysconfig/docker文件
# 将--selinux-enabled设置为false,不然可能会由于selinux服务不能用导致docker启动失败
OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false' 改为:
OPTIONS='--selinux-enabled=false --log-driver=json-file --signature-verification=false'

##修改docker存储目录(默认var/lib/docker不合适正式环境#
#通过disable enable 查看docker配置文件
[root@localhost _data]# systemctl disable docker
Removed symlink /etc/systemd/system/multi-user.target.wants/docker.service.
[root@localhost _data]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
sed -i -e "/ExecStart=\/usr\/bin\/dockerd-current /a\ -g \/usr\/local\/data \\\\" /usr/lib/systemd/system/docker.service
##修改/usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd-current \
-g /data/docker \ ##更换路径
--add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \
--default-runtime=docker-runc \

##重载配置
systemctl daemon-reload
##重启服务 ##修改后原有信息不会保留已经跑的业务注意迁移
systemctl restart docker

systemctl enable docker && systemctl start docker


建议先修改独立唯一的主机名

# 在A机器创建集群
docker swarm init --advertise-addr 本机内网IP

#在A机器
docker swarm join-token (manager|worker) 输出 以什么身份的加入集群的token值

#在B机器输入
docker swarm join --token SWMTKN-1-2ftsa277uecm0edb238e9a84h34ifarknitkn9yrqzn1wnafdb-71xjwcjhpzubgqts0ou73h3m9 192.168.0.140:2377
加入A机器的集群

###删除集群
docker swarm leave --force


docker node --help (节点相关
docker service --help(容器相关

docker service rm NAME (此命令删除运行中容器无需确认,谨慎使用

#查看指定节点上运行的service
docker node ps docker123

#把名为nginxtest的nginx容器创建到hostname为docker123的node上。(constraint 参数可以指定多个不同的hostname的节点)
docker service create --replicas 1 --constraint node.hostname==docker123 --name nginxtest nginx

#在集群中创建4个副本 名为test123的 alpine 容器,并执行参数ping docker.com
docker service create --replicas 4 --name test123 alpine ping docker.com

#给node ID为“hbex1b6iw7wfjsushdbot9gfs ” 添加nginx标签 (ID参数也可使用hostname)
docker node update --label-add func=nginx hbex1b6iw7wfjsushdbot9gfs

#把nginx容器创建到带nginx标签的node上。
docker service create --name my_testnginx --constraint 'node.labels.func == nginx' nginx

#查看节点标签
docker node inspect hostname

#删除标签
docker node update --label-rm func hostname

#把docker123节点排除掉 并停用该节点上所有容器,将这些容器移动到别的可用节点上
docker node update --availability drain docker123

#把docker123节点排除掉不再分配任务,但允许已运行的容器继续运行。
docker node update --availability pause

#恢复为可用状态 允许任务被分配到该节点上
docker node update --availability Active docker123

#调度程序不会将新任务分配给节点。调度程序关闭任何现有任务并在可用节点上安排它们
docker node update --availability drain

#将worker节点升级为manager节点
docker node promote nodename
#将manager节点降级为worker
docker node demote nodename

# 减少服务副本,增加服务副本
docker service scale servicename=副本数量

#强制更新,一次更新1个副本,当副本为running状态后等待10秒更新下一个副本 更新服务myweb
docker service update --force --update-parallelism 1 --update-delay 10s myweb


#显示test123服务的全部ID
docker service ps test123 -q
#显示该服务的信息
docker service ps test123
#找到对应副本的对应ID
#再到/var/lib/docker/containers 容器数据目录下搜索
grep -r "kfvwy24gpaq7suryqhsvvfhlj" ./*
#最后就可以找到对应目录 如有需要数据可以CP出
docker ps查看本机docker id,再用 docer cp 本机目录 容器ID:容器目录 的方式把包放到集群的容器里
警告:如果用docker restart 重启该容器,会导致容器转移到集群其他节点,该节点容器会进入死循环。


我们在使用docker的过程中发现基于swarm使用Storage Driver: overlay的方式进行存储.但是发现这个特别占用存储空间.
清理所有停止的容器
docker container prune

清理所有不用数据(停止的容器,不使用的volume,不使用的networks,悬挂的镜像)
docker system prune -a

 


# type=volume,将容器目录映射到卷存储上。docker volume create创建出的卷,可用在此处。
#如果拷贝war文件到该卷后 再重启某节点docker服务 该节点容器恢复后 使用的卷新增的文件不会被删除。
#以下面为例,4个副本,2个副本在A节点,A节点如果进入某个容器的shell环境删除了 该卷下的一个tomcat自带文件,则两个容器里的相应文件都会被删除,且重启docker服务后该文件不会生成。
##换言之 用了挂载卷后,相当于对应容器的副本 共用同一个卷,且数据全部存在本地磁盘上 而非容器里,可以理解为容器里的该目录只是磁盘的一个映像。
docker service create --mount src=tomcatdata,dst=/usr/local/tomcat/ --name myweb --publish 80:8080 --replicas 4 tomcat
tomcatdata卷会自动创建
可以使用docker volume inspect tomcatdata 查看卷信息
###故障测试1
worker节点重启docker服务时,本节点容器重启,不会影响其他节点。
manager节点重启docker服务时,本节点容器重启,也不会影响其他节点。
manager节点(Leader)重启docker服务时,会造成Leader转移到其他manager节点,本节点容器重启,不会影响其他节点。
###故障测试2
##环境
三个节点四个副本的状态下。(manager节点1个,manager领导节点1个,worker节点1个)
##manager节点(非领导)
将两个副本的manager属性(非领导)节点关机,节点上的2个副本并不会迁移,但现实manager节点已不可用,重启后节点上的副本被转移到worker节点上。
(stop docker服务的结果有所区别:重启docker服务后节点上的容器还是在本节点启动)
###目前暂时无法在节点恢复后自动把之前的副本迁移回恢复节点。需要手动更新或者stop掉需要重新分配的容器
docker service update --force --update-parallelism 1 --update-delay 10s myweb
继续将worker节点刚才转移过来的两个节点stop掉,节点又调回manager节点启动。
###worker节点
继续测试将一个副本的worker节点关机,发现副本迁移出来了。
worker节点开机后服务同样无转回,需手动。
worker节点stop docker服务 和关机的结果并无区别。
##(目前测出来的结果只有worker节点关机会被迁移出来,manager节点不会迁移)。
######manager节点(领导)
领导节点关机后,另一个manager节点的管理功能不可用,但是节点容器和worker节点容器都正常工作。
领导节点重启后,领导位置被另一个manger取代,功能也全部恢复,原领导节点的容器还是在本节点启动。
(stop docker服务结果一样)
PS:两个manger节点的实验结果如上,将第三个worker升级为manger节点(三个manager节点)后关机leader后 leader转移成功。
补充:两个manager节点的情况下 关机了leader,管理无法用的情况,可以在剩下的manager节点
docker swarm init --force-new-cluster
执行这条命令重新初始化,重新初始化后,manager节点升级为leader功能恢复。但是当老leader节点恢复时这个老leader节点会丢失manager属性,只能作为worker节点使用且无法重新被leader提升为manager节点,只能在这台上退出集群,然后从新leader上删除该节点,让这台机器重新加入。

###降级leader节点
降级leader会导致5秒钟左右的管理功能失效,之后leader转移成功。

###负载均衡实测

环境1:起了4个副本,分布3个节点,有一个节点是2个副本的,然后请求了4次, 两个副本因为挂载的目录相同 所以日志写入在同一个文件里了。
环境2:3manager,2worker节点,4副本平均分布在两个worker节点上,每个节点两个副本(没做挂载映射)。当访问Aworker节点时,请求会平均分布到A节点的两个副本上,当访问Bworker节点时
同样分布到B节点上。

###扩展测试
环境:3manager,1worker的情况下,drain 掉3个manager的worker属性。
假设我用rsync同步或者把有数据的tomcat目录 cp到 worker节点的挂载卷tomcatdata下,再创建服务时,容器在worker节点会启动失败,当我清空目录时服务启动成功。
经过以上负载均衡测试可以得知,如果新增节点,可以先加入集群,拉取原始tomcat镜像,然后再用rsync排除log目录的方式同步其他数据到新节点上,然后再把节点加入到前端nginx配置upstream中。


以副本模式的方式起容器,则在一个节点上会存有镜像,在我删除myweb服务后,去三个节点执行
docker system prune -a
命令,会发现只有一个节点删除了400多M的数据,其他的数据都只有几M甚至更少,推测是有一个节点存储镜像,其他节点副本都是通过这个镜像起的,之前测过如果存镜像的节点宕机,发生漂移,会在漂移的目标端下拉新的镜像,在最后清理时会有2个节点有400M的数据被清理,而镜像节点宕机时也不会影响在跑节点。

#集群创建的容器默认网络的情况下是无法互相访问的,可以创建独立的overlay网络 在docker service create --network xjj的时候指定网络
docker network create -d overlay xjj
其中service的endpointmode有2种,VIP和DNSRR,前者有一个虚拟IP来做负载均衡到同一个service的不同容器中, 后者则是把虚拟IP去掉,hosts将同一个服务名解析到多个容器ip来实现负载均衡。 后者不支持把容器内部端口映射到物理机上。

#经测试如创建一个mynginx 为名字的nginx容器,2个副本的情况下 总共会有3个容器内部IP,一个是负载均衡mynginx,ping向它后 会均衡的转发到 mynginx.1xxxxx 和myning.2xxxx的容器IP上。
而微服务就可以借助负载均衡的name去进行微服务集群之间的通讯。

posted @ 2018-11-05 15:33  恋恋红尘JJ  阅读(514)  评论(0编辑  收藏  举报