十二、docker三剑客(docker-swarm)

一、简介

为什么使用docker-swarm?

通过前面的介绍,我们已经可以管理docker了,但是如果把docker用于生产,一两个机器还好,如果是多台,甚至是一个集群环境,我们不可能一台机器一台机器的部署,就算可以也没办做到“高可用”,这时docker-swarm就诞生了,他可以把多个docker engin做成一个集群环境来管理。

docker-swarm在docker1.12之前是一个独立的项目,需要单独下载,在1.12之后就和docker合并做为docker的一个子命令。同时docker-swarm也是唯一的docker原生支持集群的管理工具。

我们看一下下面的图

十二、docker三剑客(docker-swarm)_第1张图片

二、docker-swarm的架构

 filter和Strategy都是调度模块(过滤选择最优的模块来部署)

    filter一共五种过滤模式:

            1、Constraints(约束过滤器):根据当前系统版本、内容版本,进行一些指标上的过滤。当然也可以自定义,在deamon启动的时候可以通过lab来制定当前机器所具有的特性,然后通过Constraints把他们过滤出来。

            比如我们创建了一个registry,重新部署的时候我不希望这个镜像让swarm随机分配,还要安装在以前的节点上,可是这么使用:

docker service create --name registry --publish 5000:5000 --constraint 'node.hostname==node01' registry

除了 hostname 也可以使用其他节点属性来创建约束表达式写法参见下表:

节点属性 匹配 示例
node.id 节点 ID node.id == 2ivku8v2gvtg4
node.hostname 节点 hostname node.hostname != node02
node.role 节点 role: manager node.role == manager
node.labels 用户自定义 node labels node.labels.security == high
engine.labels Docker Engine labels engine.labels.operatingsystem == ubuntu 14.04

用户自定义labels可以使用 docker node update 命令添加, 例如:

# docker node update --label-add security=high node01

查看自定义labels

# docker node inspect node01

[

{

"ID": "0nhjsflo3tbd0b7hv2cyrjpin",

...

"Spec": {

"Labels": {

"security": "high"

},

"Role": "manager",

"Availability": "active"

},

"Description": {

"Hostname": "node01",

"Platform": {

"Architecture": "x86_64",

"OS": "linux"

},

...

}

]

对于已有service, 可以通过 docker service update ,添加 constraint配置, 例如:

docker service update registry --constraint-add 'node.labels.security==high'

            2、affinity(亲和过滤器):比如说一个web服务我想把它和数据库放在一起,就可以使用这个。

            3、dependency(依赖过滤器):比如说,容器有link、from这些依赖关系,dependency就会把他们放在一个节点上

            4、Health filter:根据健康状态来过滤,会过滤掉一些有问题的节点

            5、Ports filter:根据端口的使用来选用,比如说8080端口已经被一个机器使用,他会分配到没有使用的节点。

Strategy一共三种过滤模式

            Binpack:同等条件下他会选择资源使用最多的做为选择

            Spread:同等条件下他会选择资源使用最少的做为选择

            Random:随机选择一个节点

三、服务发现

docker内置overlay网络,overlay是什么呢?我们要做到跨主机的网络通信,其思路无非分为两种: 二层VLAN网络和Overlay网络 

VLAN就不介绍了,我们主要说overlay

 

容器在两个跨主机进行通信的时候,是使用overlay network这个网络模式进行通信;如果使用host也可以实现跨主机进行通信,直接使用这个物理的ip地址就可以进行通信。overlay它会虚拟出一个网络比如10.0.2.3这个ip地址。在这个overlay网络模式里面,有一个类似于服务网关的地址,然后把这个包转发到物理服务器这个地址,最终通过路由和交换,到达另一个服务器的ip地址。
 



要实现overlay网络,我们会有一个服务发现。比如说consul,会定义一个ip地址池,比如10.0.2.0/24之类的。上面会有容器,容器的ip地址会从上面去获取。获取完了后,会通过ens33来进行通信,这样就实现跨主机的通信。
 

下面是慕课网的解释:

Docker 使用了 Linux 内核 iptables 和 IPVS 的功能来实现服务发现和负载均衡。

  • iptables 是 Linux 内核中可用的包过滤技术,它可用于根据数据包的内容进行分类、修改和转发决策。

  • IPVS 是 Linux 内核中可用的传输级负载均衡器。


作者:www说
链接:https://www.imooc.com/article/49017
来源:慕课网 

 

我们先看一下docker默认的网络环境:

十二、docker三剑客(docker-swarm)_第2张图片

然后我们使用swarm创建一个集群环境

docker swarm init --advertise-addr 192.168.1.120

如果我们机器上有多个网卡要使用--advertise-addr传入本地的ip

在看一下环境:

十二、docker三剑客(docker-swarm)_第3张图片

可以看到我们多出来一个name为ingress的网络,我们知道overlay是做什么的,那igress是什么意思呢?

 我们在用两个node来加入到这个集群中

docker swarm join --token SWMTKN-1-2khwrs5e07m54r83644qbdmmn38q7cvo591k0u016jfb3t9yrs-emnr9fi6eiokpmozoa623qkvh 192.168.1.120:2377

在看一下现在的node

docker node ls

在运行nginx服务

docker service create --name mynginx --publish 8080:80 --detach=false nginx
docker service scale mynginx=4
docker service ls

启动了四个副本

看一下是否负载,我们别分把这些副本的nginx欢迎页面改了

docker service ps vhufcpae3jid

我到node1、node3、master三台宿主机分别修改页面

我们到node3上修改这个容器里的页面,命令如下:

 修改就按编号修改就可以了

echo 'mynginx.4' > /usr/share/nginx/html/index.html

剩下的同理

十二、docker三剑客(docker-swarm)_第4张图片

可以看到负载成功了,那么每个容器之间是否能ping通呢?

因为nginx镜像中是没有ping的,我们在创建一个服务

docker service create --name myalpine --detach=false alpine ping 192.168.1.1

一定要带着ping 192.168.1.1要不这个容器没有前台进程是起不来的!

我们看一下这个容器在哪使用

docker service ls

docker service ps t2smto1g7uma

这个容器是在docker3上,我们在docker3中进入这个容器

看看wget能不能下载到这个页面

 看到页面是可以下载的,那么我们能不能平通这个服务呢?

可以看到内层网络我们是ping不通的,那我们如何能在内容使用服务名来互相通信呢?

下面介绍两种方法

1、自定义网络

因为在自定义的网络上,swarm mode会分配给每个容器一个dns engin,这个网络必须是自定义overlay的,当访问的时候就会经过节点的dns server然后rourt 到每个容器上

下面我们创建一个网络

docker network create -d overlay overlaytest

查看 

十二、docker三剑客(docker-swarm)_第5张图片

然后我们把刚才的实现步骤重新来一遍,先停下现在所有的服务,然后启动服务到overlaytest网络上

停止服务

创建服务

 进入alpine

ping外部网络

十二、docker三剑客(docker-swarm)_第6张图片

ping服务名

十二、docker三剑客(docker-swarm)_第7张图片

ping内部网络

十二、docker三剑客(docker-swarm)_第8张图片

 下面在介绍第二种方法

2、DNSRR模式

我们先看一下上面的容器

十二、docker三剑客(docker-swarm)_第9张图片

十二、docker三剑客(docker-swarm)_第10张图片

可以看到有一个Endpoint-Mode,他们都是vip,那这个VIP是什么意思呢?

他的作用指定swarm服务发现的模式

  • endpoint_mode: vip - Docker为swarm集群服务分配一个虚拟IP(VIP),作为客户端到达集群服务的“前端”。Docker 在客户端和可用工作节点之间对服务的请求进行路由。而客户端不用知道有多少节点参与服务或者是这些节点的IP/端口。(这是默认模式)
  • endpoint_mode: dnsrr - 
    DNS轮询(DNSRR)服务发现不使用单个虚拟IP。 Docker为服务设置DNS条目,使得服务名称的DNS查询返回一个IP地址列表,并且客户端直接连接到其中的一个。如果您想使用自己的负载平衡器,或者混合Windows和Linux应用程序,则DNS轮询功能非常有用。

上面红字不就是我们需要的模式么?下面配置一下,这次试用docker stack

docker stack是什么?如果你知道docker 和docker compose的关系就知道了,他就好像是docker service的打包版,他和compose都一样需要一个yml文件,下面我们去编写这个文件

version: "3.4"            #版本号用最新就可以
services:                 
  alpine:                 #服务的名字
    image: alpine         #下载的镜像
    command:              #执行命令
      - "ping"
      - "192.168.1.1"
    networks:             #采用哪个网络,不写则是默认
      - "overlaytest"
    deploy:
      endpoint_mode: dnsrr       #mode的模式
      replicas: 2                 #创建的副本数
      restart_policy:             #重启的机制
        condition: on-failure     #失败就重启
      resources:                  #资源
        limits:                  
          cpus: "0.1"             #cpu
          memory: 50M             #内存
    depends_on:
      - nginx                     #依赖关系
  nginx:
    image: nginx
    networks:
      - "overlaytest"
    ports:
      - "8080:80"
networks:
  overlaytest:
    external: true              #他是一个外部定义好的

我们停止当前所有服务

docker service rm `docker service ls -q`

执行创建服务

docker stack deploy -c service.yml test

我们可以看到他会在所有服务前加上“test_”

我们测试一下

ping 服务名

十二、docker三剑客(docker-swarm)_第11张图片

内部网络

十二、docker三剑客(docker-swarm)_第12张图片

但是这里要注意:

dnsrr模式是不开放端口的,因为dnsrr是只是供内部间使用名字调用的

我们总结一下这三种形式

一、ingress默认网络(VIP模式):我们可以通过外端ip+端口进行通信,不能通过服务名进行通信。

二、ingress自定义网络(VIP模式):这个比较宽泛可以使用服务名,可以使用内部网路,也可以使用宿主的网络。

三、dnsrr模式:这个我们最好应用在一些只使用内部服务名的容器通信间进行使用。

到底决定使用哪个网路应该还是要看具体的环境和业务需求吧。

四、swarm命令

https://blog.csdn.net/wanglei_storage/article/details/77508620

这里写的比较全

五、stack命令

https://www.jianshu.com/p/25c529e3a3e6

你可能感兴趣的:(docker)