一、Docker-Compose使用
当项目涉及容器较多时,需要一个管理容器的工具
1、docker-compose安装
1.1、curl方式安装
命令:curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
1.2、增加可执行权限
命令:chmod +x /usr/local/bin/docker-compose
1.3、查看版本
docker-compose version
2、docker-compose.yaml命令
docker-compose的命令与docker命令极为相似,用法上没有区别,下面列出它特有的几种命令:
- up:创建并启动容器:docker-compose up -d --scale 服务名=数字。
- d:表示后台运行,scale是表示对应的服务同时启动几个容器。
- down:停止并删除容器: docker-compose down。
会停掉容器,并删除掉容器。如果不希望删除容器,请使用stop
3、docker-compose实战
配置参数说明:
version: '2': 表示使用第二代语法
services: 表示 compose需要启动的服务
container_name: 容器名称
environment: 容器环境变量
ports: 对外开放的端口
restart: always 如果服务启动不成功一直尝试。
volumes: 加载本地目录到容器目标路径
depends_on:依赖服务,先启动 depends_on 服务
command: mvn clean spring-boot:run : 表示以这个命令来启动项目。
编写一个项目整体服务,一个网关nginx + springboot的集群,如上图
其中nginx服务,将配置文件挂载在主机当前项目目录的路径下:nginx/conf.d/
命令:docker-compose up -d
docker-compose up -d --scale member-1=2
把member-1服务启动两个容器:
4、docker compose常用命令
#查看帮助
docker-compose -h
# -f 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定。
docker-compose -f docker-compose.yml up -d
#启动所有容器,-d 将会在后台启动并运行所有的容器
docker-compose up -d
#停用移除所有容器以及网络相关
docker-compose down
#查看服务容器的输出
docker-compose logs
#列出项目中目前的所有容器
docker-compose ps
#构建(重新构建)项目中的服务容器。服务容器一旦构建后,将会带上一个标记名,例如对于web项目中的一个db容器,可能是web_db。可以随时在项目目录下运行docker-compose build来重新构建服务
docker-compose build
#拉取服务依赖的镜像
docker-compose pull
#重启项目中的服务
docker-compose restart
#删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop 命令来停止容器。
docker-compose rm
#在指定服务上执行一个命令。
docker-compose run ubuntu ping docker.com
#设置指定服务运行的容器个数。通过 service=num 的参数来设置数量
docker-compose scale web=3 db=2
#启动已经存在的服务容器。
docker-compose start
#停止已经处于运行状态的容器,但不删除它。通过 docker-compose start 可以再次启动这些容器。
docker-compose stop
二、Docker网络路由
1、docker的跨主机网络路由
假设我们现在有两台docker主机,各启动了自己的容器在运行
2、问题由来
1)在网桥模式下,同一个主机下的容器,使用同一个网桥docker0,它们组成一个局域网,如上图主机1的172.17.6.0网段下的三个容器。
2)同一个主机下的容器,相互之间网络是通的。
3)但不同主机下,是不同的局域网,它们之间网络不能互通。
如:172.17.6.2的容器,想要访问172.17.8.2的容器。
3、方案
a机192.168.244.7,容器网段172.17.6.1/16,a机起了容器ip是172.17.6.2
b机192.168.244.8,容器网段172.17.8.1/16,b机起了容器ip是172.17.8.2
3.1、两台机分别配置路由表
a机,route add -net 172.17.8.0 netmask 255.255.255.0 gw 192.168.244.8
b机,route add -net 172.17.6.0 netmask 255.255.255.0 gw 192.168.244.7
添加好后,路由表类似下图
然后a机ping b机容器,发现仍是ping不通,卡住ping不通,就是数据包被drop掉了
3.2、ip_forward配置
我们在b机上使用以下命令查看网络包转发情况,发现有掉包
iptables -t filter -nvL FORWARD
我们需要b机上配置,寻找172.17段ip的网络包不要丢掉,要转发
a机:iptables -I DOCKER --dst 172.17.0.0/16 -j ACCEPT
b机:iptables -I DOCKER --dst 172.17.0.0/16 -j ACCEPT
网络ok,整个网络包的流程,完整如下:
三、Swarm集群管理
到目前为止,我们使用docker容器化部署服务,都是局限在一台宿主机上操作。但是在现实工作中,我们部署的服务都是集群模式的,分布式模式的,没有一台强大的物理机,能支撑整个分布式集群,而且这样也无法防范物理机的单点故障问题。
但是如果在多台宿主机上部署服务,跨宿主机的容器间将无法通讯,这要求你必须是个网络高手才能解决问题。Docker针对这种情况,尝试给出了一个解决方案,就是docker swarm。
1、Swarm简介
Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。
除了前面所说的打通的网络问题外,它主要为我们提供以下服务:
1)与Docker Engine集成
2)使用分散设计:去中心化设计,可大规模部署
3)声明式服务模式
4)弹性服务:通过schedule(调度器)Constraint(约束条件)affinity(共同关系)弹性服务
5)期望状态协调:管理节点收集集群中所有的信息,进行感知和调度
6)多主机联网:指定overlay网络,swarm管理器自动将地址分配给覆盖网络上的容器。
7)服务发现:service
8)负载均衡:使用内建DNS Round-Robin实现集群内的负载均衡,也支持外部负载均衡。
9)滚动更新:高可用和故障恢复机制意味着用户可以创建超过一个master的Swarm。
2、Swarm概念
Swarm集群是由多个运行swarm模式的Docker主机组成,关键的是Docker默认集成了swarm mode。swarm集群中有manager(管理成员关系和选举)、worker(运行swarm service)。当你创建一个service时,你定义了它的理想状态(副本数、网络、存储资源、对外暴露的端口等)。Docker会维持它的状态,例如,如果一个worker node不可用了,Docker会调度不可用node的task到其他nodes上。
运行在容器中的一个task,是swarm service的一部分,且通过swarm manager进行管理和调度,和独立的容器是截然不同的。swarm service相比单容器的一个最大优势就是,你能够修改一个服务的配置:包括网络、数据卷,不需要手工重启服务。Docker将会更新配置,把过期配置的task停掉,重新创建一个新配置的容器。
1)warm:是一组docker引擎的集群。
2)node:是单个docker引擎的实例,可以在一个物理机上也可以在多个。
3)manager node:部署应用的时候会有一个manager node节点。
4)Worker nodes:对应的就是Worker nodes。
5)service:然后service是一堆被workder执行的任务。
6)task:一个task就是一个docker的容器,是Swarm的工作单元。
3、环境准备与初始化创建
规划两台网络互通的机器:
Swarm1 : 192.168.30.161
Swarm2 : 192.168.30.162
3.1、修改docker监听端口(TCP端口2375)
命令:vi /lib/systemd/system/docker.service
修改ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
为:ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
重启docker服务:
systemctl daemon-reload
systemctl restart docker
3.2、创建管理节点
命令:docker swarm init --advertise-addr 192.168.30.161
token:SWMTKN-1-66uehuu4nxy5nzomc67yfs6qzf36etpab9sdhkt81amgqsxamh-6lnpvoxbzv0ca3hf1jt9muz7y 192.168.30.161:2377
查看节点:docker node list
3.3、添加工作节点到集群
在工作机上,执行前面管理节点提示的命令
docker swarm join --token SWMTKN-1-66uehuu4nxy5nzomc67yfs6qzf36etpab9sdhkt81amgqsxamh-6lnpvoxbzv0ca3hf1jt9muz7y 192.168.30.161:2377
节点加入成功,控制节点机上查看(192.168.30.161),已经管理了两台机器了
节点退出:docker swarm leave
3.4、添加管理节点
可以再引入一个管理节点到集群来,先用命令:docker swarm join-token manager在manager(192.168.30.161)机器上得到加入指令如下所示:
在经引入机器上执行提示命令串:
docker swarm join --token SWMTKN-1-66uehuu4nxy5nzomc67yfs6qzf36etpab9sdhkt81amgqsxamh-89vk72aqu5ln1ew8qrzewunkq 192.168.30.161:2377
4、服务管理
swarm环境ok之后,整个工作节点集群,都可以当作一个宿主机来操作了。可以在manager上进行各种服务的部署管理。
4.1、创建服务
创建一个nginx集群,3台机器
docker service create --name nginx --replicas 3 -p 80:80 nginx:1.7.9
查看服务列表:docker service ls
查看服务详情:docker service ps nginx
启动了三个副本 ,在工作节点上查看服务,可以看到有了一个nginx容器
访问服务,任意一台节点机 ip,都可访问:
http://192.168.30.161/
http://192.168.30.162/
4.2、服务维护
服务集群运行后,会以期望的状态方式管理整个集群。如刚刚创建的3中nginx组成的集群。如果其中一台宕机,swarm会自动新建一台,来补足task数量在一个节点机器上。
删除一个容器:docker rm -fv images id
在管理节点上查询:docker service ps nginx
可以看到,又新启了一台服务。
4.3、滚动升级
更新原来的nginx版本为 1.9.7:
docker service update --image nginx:1.9.7 nginx
查看服务,可看到 nginx 已经升级为 1.9.7
4.4、动态扩容
服务还可以动态在节点集群上进行扩容
docker service scale nginx=4
再次查看,发现服务已经扩为四个服务
4.5、网络通讯
swarm管理的集群,内部建立一个统一的网络层,你绑定的端口,并非是直接绑定到宿主机,而是绑在这个overlay网络。对于集群来说,相当于都绑在网络的一个端口上,启用负载策略来转发请求,如下图: