眼见这双爪便要抓在牛魔王左肋上,这时,一只牛蹄鬼魅般现了出来,正蹬在大鹏利爪之上。这一下又是硬碰硬,大鹏猝不及防,又在空中折了一个跟斗,牛魔王也借势在空中打了个滚,心中大为惊讶。

然而就在这时,王小民忽然出现在门口,幽幽的道:“洪大少,你说送谁上西天啊?”

2018年生意门路

爱伦尼忽然放慢了缰绳,笑道:“对了,我忘记告诉了,父亲已经把阿蒂尔城封给了我,我正是这里的女主人。”
还没等这个鬼子军官掏出来短刀剖肚子,一排硕大的炮弹呼啸着纷纷砸入了开阔地之中,顿时一道道升腾而起的烟雾将整个阵地给笼罩住了,强大的似海啸一般的冲击波滚滚而来,将躲在战壕防炮洞里的独立师刘团长他们给震得耳膜出血来。

注意到了一个脸上保持着亲切的笑容让人难以对其产生厌恶感的男人加入了争斗当中,这个男人的修为明显比所有人都强大,他显然是观察过周围,发现没有人比自己强大,并且在得到了灵物之后也不怕被人群而攻之之后才出手的。

Docker 小记 — Compose & Swarm


前言

任何相对完整的应用服务都不可能是由单一的程序来完成支持,计划使用 Docker 来部署的服务更是如此。大型服务需要进行拆分,形成微服务集群方能增强其稳定性和可维护性。本篇随笔将对 Docker Compose 和 Docker Swarm 的原理和配置做整理归纳,并分享其使用经验。

1. YAML 简介

Docker Compose 的配置文件采用 YAML 格式,因此有必要在正文之前简要说明下。YAML 是一门专门用来写配置文件的语言,设计目标就是方便读写,其实质上是一种通用的数据串行化格式,基本语法规则如下:

  • 大小写敏感。
  • # 表示注释。
  • 使用缩进表示层级关系。
  • 缩进时不允许使用 Tab 键,只允许使用空格。
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可。

YAML 支持的数据结构有三种:

  • 对象:animal:cat
  • 数组:一组中划线开头的行,例如:
# ex1
  - cat
  - dog
  - bird
  
# ex2
  -
    - cat
    - dog
    - bird
    
# ex3
  animal: [cat, dog, bird]
  • 值类型和字符串。

2. Docker Compose

2.1 安装与简介

Docker 可以极为方便地部署单个服务,但这时候我们需要一个工具来整合 Docker 的功能,使之能够更便捷地去管理整个微服务集群的部署和迁移,Docker Compose 正是应此而生。他是由 Python 编写的程序,能够根据指令结合配置文件转换成对应的 Docker API 的操作,并直接体现到 Docker Daemon 中,这就代替我们完成了重复输入复杂指令的过程,主要功能可分为以下两点:

  • Service:代表的是运行同种应用程序的一个或多个相同容器的抽象定义,也是我们在Docker Compose 中配置的主要对象。在每个 Docker Compose 的配置文件中,我们可以定义多个服务,并定义服务的配置,以及服务于服务之间的以来关系。
  • Project:代表的是由多个服务所组成的一个相对完整的业务单元。

安装命令:

curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose

2.2 配置参数

Docker Compose 的核心就是其配置文件,采用 YAML 格式,默认为 docker-compose.yml ,参数详解可查阅“官方文档”,以下只做一个常规摘要。

services

所有服务的根节点。

image

指定服务的镜像名,若本地不存在,则 Compose 会去仓库拉取这个镜像:

services:
  web:
    image: nginx

ports

端口映射,例:

ports:
  - "80:80"
  - "81:81"

volumes

挂载主机目录,其中 ro 表示只读,例:

volumes:
  - "/etc/nginx/www:/www"
  - "/var/run/docker.sock:/tmp/docker.sock:ro"

大多数情况下集群中部署的应该都是无状态服务,服务可复制且不固定在某一台宿主机,所以挂载的数据卷最好应当与宿主机脱离关系,例:

  web:
  services:
    image: nginx
    volumes:
      - type: volume
        source: logs
        target: /mnt
        volume:
          nocopy: true
          
volumes:
  logs:
    driver_opts:
      type: nfs
      o: addr=***.cn-hangzhou.nas.aliyuncs.com,rw
      device: ":/"

当然,这种情况下最好是优先创建数据卷,后在配置文件中引用,例:

docker volume create --driver local 
    --opt type=nfs 
    --opt o=addr=***.cn-hangzhou.nas.aliyuncs.com,rw 
    --opt device=:/ 
    logs
volumes:
  logs:
    external: true

若必须挂载集群中一台宿主机的目录作为数据卷,则要安装一个 docker 插件:

docker plugin install vieux/sshfs

# 若配置了密钥对则可省略 password 参数
docker volume create 
  -d vieux/sshfs 
  --name sshvolume 
  -o "sshcmd=user@1.2.3.4:/remote" 
  -o "password=$(cat file_containing_password_for_remote_host) 
sshvolume

networks

配置服务间的网路互通与隔离,例:

services:
  web:
    image: nginx
    networks:
      - proxy
      - youclk
networks:
  youclk:
    external: true
  proxy:
    external: true

secrets

配置服务密码访问,例:

services:
  redis:
    image: redis:latest
    deploy:
      replicas: 1
    secrets:
      - my_secret
      - my_other_secret
secrets:
  my_secret:
    file: "./my_secret.txt"
  my_other_secret:
    external: true
docker secret create [OPTIONS] SECRET [file|-]
echo "admin:password" | docker secret create my_secret -
docker secret create my_secret ./secret.json

healthcheck

健康检查,这个非常有必要,等服务准备好以后再上线,避免更新过程中出现短暂的无法访问。

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost/alive"]
  interval: 5s
  timeout: 3s

其实大多数情况下健康检查的规则都会写在 Dockerfile 中:

FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s CMD curl -f http://localhost/alive || exit 1

depends_on

依赖的服务,优先启动,例:

depends_on:
  - redis

environment & env_file

设置环境变量和指定环境变量的文件,例:

environment:
  - VIRTUAL_HOST=test.youclk.com
env_file:
  - ./common.env

deploy

部署相关的配置都在这个节点下,例:

deploy:
  mode: replicated
  replicas: 2
  restart_policy:
    condition: on-failure
    max_attempts: 3
  update_config:
    delay: 5s
    order: start-first # 默认为 stop-first,推荐设置先启动新服务再终止旧的
  resources:
    limits:
      cpus: "0.50"
      memory: 1g
deploy:
  mode: global # 不推荐全局模式(仅个人意见)。
  placement:
    constraints: [node.role == manager]

若非特殊服务,以上各节点的配置能够满足大部分部署场景了。

3. Swarm

Docker 默认包含了 Swarm,因此可以直接使用,初始化命令:docker swarm init,此时将会默认当前节点为 Leader,以下命令为查看 token:docker swarm join-token (worker|manager),其他节点可以用 manager 或者 worker 的身份加入到当前集群,例:

docker swarm join --token SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx 172.17.0.2:2377

执行 docker swarm leave 脱离集群。

以下各节点常规操作命令,比较简单,就不解释了:

  • docker node demote [NODE]
  • docker node inspect [NODE]
  • docker node ls
  • docker node promote [NODE]
  • docker node ps [NODE]
  • docker node rm [NODE]
  • docker node update [OPTIONS] NODE

4. 应用案例

集群最擅长的就是解决多服务问题,只要在同一 network 之下,服务之间默认可以直接通过 service_name 互通有无。但为了避免混乱,各服务与外部的通信最好统一交给一个反向代理服务转发。因对 nginx 比较熟悉,所以我最初选择的代理是“jwilder/nginx-proxy”:

server
{
    listen 80;
    server_name localhost;
    location /alive {
        return 200;
    }
}

server {
    listen  81;
    return  301 https://$host$request_uri;
}
FROM jwilder/nginx-proxy
ADD ./src /etc/nginx/conf.d
ADD https://gitee.com/youclk/entry/raw/master/debian/sources-vpc.list /etc/apt/sources.list
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s CMD curl -f http://localhost/alive || exit 1
version: "3.5"

services:

  proxy:
    image: $REGISTRY/proxy
    ports:
      - "80:80"
      - "81:81"
    volumes:
      - "/var/run/docker.sock:/tmp/docker.sock:ro"
    deploy:
      placement:
        constraints: [node.role == manager]
      restart_policy:
        condition: on-failure
        max_attempts: 3
      update_config:
        delay: 5s
        order: start-first 
      resources:
        limits:
          cpus: "0.50"
          memory: 1g

负载均衡使用的是阿里云的 SLB,监听 80 -> 81, 443 -> 80,这样一个服务就实现了节点检查、代理和 https 重定向为一身。拖 nginx 的福,反正用起来就是爽,点击“Nginx 原理解析和配置摘要”进一步了解。

正所谓乐极生悲,某一次我在扩展 Swarm 集群的时候提升了部分 work 节点为 manager, 并且扩展了代理的数量,这让很多服务频繁出现 503,找来找去我发现问题出在 nginx-proxy 代理上。当服务在各节点分布不均的时候,非 leader 节点上的那个代理无法找到服务,废了老大的劲儿也没找到合理的解决方案。

最后我决定选择“Docker Flow Proxy”作为新的代理(好家伙,这一看文档吓我一跳,我还是第一次看到私人的开源项目能把参考文档写得这么详细,作者的细腻程度“令人发指”,小弟顶礼膜拜之),以下是我的案例:

version: "3.5"

services:

  proxy:
    image: vfarcic/docker-flow-proxy
    ports:
      - "80:80"
    networks:
      - proxy
    environment:
      - LISTENER_ADDRESS=swarm-listener
      - MODE=swarm
    secrets:
      - dfp_users_admin
    deploy:
      replicas: 2
      labels:
        - com.df.notify=true
        - com.df.port=8080
        - com.df.serviceDomain=localhost
        - com.df.reqPathSearchReplace=/alive,/v1/docker-flow-proxy/ping

  swarm-listener:
    image: vfarcic/docker-flow-swarm-listener
    networks:
      - proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DF_NOTIFY_CREATE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/reconfigure
      - DF_NOTIFY_REMOVE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/remove
    deploy:
      placement:
        constraints: [node.role == manager]

networks:
  proxy:
    external: true
secrets:
  dfp_users_admin:
    external: true

更换代理的过程也并非一帆风顺,我在 https 重定向这个问题浪费了好多时间,最后也没在代理中解决。作者当然是考虑到了这个问题,经典的解决方案应如下:

services:
  proxy:
    image: vfarcic/docker-flow-proxy
    ports:
      - "80:80"
      - "443:443"
    networks:
      - proxy
    environment:
      - LISTENER_ADDRESS=swarm-listener
      - MODE=swarm
    deploy:
      replicas: 2
      labels:
        - com.df.notify=true
        - com.df.httpsOnly=true
        - com.df.httpsRedirectCode=301

但奈何哥哥“非经典”呀,我的 https 证书和负载均衡都委托给阿里云的 SLB 了,SLB 代理的后端请求只能限定 http。我的想法还是监听所有请求 443 端口的域名并返回 301,但以下方案并没有成功:

labels:
  - com.df.notify=true
  - com.df.httpsRedirectCode=301
  - com.df.serviceDomainAlgo=hdr_dom(host)
    
  - com.df.srcPort.1=80
  - com.df.port.1=8080
  - com.df.serviceDomain.1=localhost
  - com.df.reqPathSearchReplace.1=/alive,/v1/docker-flow-proxy/ping
    
  - com.df.srcPort.2=443
  - com.df.port.2=8080
  - com.df.serviceDomain.2=youclk.com,localhost
  - com.df.httpsOnly.2=true

当然重定向可以在各服务内部实现,但我不认为这是个好的解决方案。最后的最后,我想反正迟早都要上 CND,于是就在 CND 中加了 https 重定向(哎,就是带宽的费用要 double 咯...):

除了代理,最好再加一个监控服务,我选择了官方案例中的 visualizer ,配合 proxy 示例:

services:
  visualizer:
    image: dockersamples/visualizer
    networks:
      - proxy
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
      labels:
        - com.df.notify=true
        - com.df.serviceDomain=visualizer.youclk.com
        - com.df.port=8080
        - com.df.usersSecret=admin

visualizer 算是敏感服务了,一般需要用密码保护,这里通过 com.df.usersSecret 指定了密码文件,密码已写入 secrets dfp_users_admin 中。注意,com.df.usersSecret 的值与 dfp_users_* 必须相同,示例已在上文。部署后显示如下:

docker-flow-proxy 还有一个默认的监控服务,显示如下:

不过数据没有统一收集,因此意义不大,看看就好。除此之外就是真正需要部署的应用了,只要服务器性能足够,随便想来几个来几个。

5. 部署与维护

docker stack

部署命令:docker stack deploy -c docker-compose.yml --with-registry-auth youclk,私有仓库必须加 --with-registry-auth 才能下载镜像。除此之外常用的如下:

# network volume service secret 用法都类似,同出一系嘛...
docker stack ls
docker stack ps youclk
docker stack rm youclk

docker service

我使用 Compose 的场景一般都结合 Swarm,因此很少去记手动创建或者更改配置的命令了,意义也不大。除了查看移除等与上文相似以外,此处还应记两个:

docker service logs --tail 10  youclk_proxy
docker service update --force youclk_proxy

分别是查看日志和服务异常后强制重启。

结语

到此为止写了蛮多了,其余还有一些比较重要内容的后续有空再整理一篇。总结一下,开头我放的那张图其实很形象:Docker 可以看做集装箱把杂乱的货物一个个整理归类, Compose 则是用于编排这些集装箱,最后 Swarm 就是多提供几条船,挂掉一两条还能继续走,提高稳定性。

不知为何此刻我会突然想到一句诗:“天苍苍野茫茫风吹草低见牛羊”,有关联吗?没关联,想到就写了,晚安:)

当前文章:http://hnhdqp.com/news/2018102034542/index.html

发布时间:2018-11-15 14:19:33

怎么来钱快 创富吧网赚chuangfuba 一天不做能赚20 梦幻西游五开赚钱2018 适合在家做的手工活 什么是微商投资 投资理财风险防范 长沙商铺投资

编辑:陵密秉

相关新闻

路由器特色服务势在必行 西默路由器成广告时代终结者

2018-11-15 09:52:33

苏州贤偃梅广告传媒有限公司

信用卡管理APP大比拼,谁最好用?

2018-11-15 11:02:31

诸城链液经贸有限公司

前列康杯环青海湖嘉年华开赛在即 全民骑行助力环湖赛

2018-11-15 12:04:01

宜春蔚俣电子科技有限公司

热门推荐

  • UWP Popup 弹出提示框
  • Facebook:消息流界面将消亡,图集是未来
  • 走着走着手机突然没信号了,是怎么回事?
  • 诺基亚Lumia 830成功运行Windows 10 ARM版系统
  • 谷歌Duo将可联系未安装应用程序的联系人
  • 如何将外部的obj模型导入OpenGL
  • 1片补充21种维生素和矿物质,善存佳维片60片×3瓶79元(40元券)
  • 欧盟公布“避税天堂”黑名单 共17个国家和地区澳门上榜
  • 饿了么员工购43张黑证助商家上线,获刑三年半
  • 《干物妹小埋》二期动画第4话预告视频 小萝莉乖巧激萌
  • 河北新闻网版权所有 本站点信息未经允许不得复制或镜像 法律顾问:不用本钱赚钱 能打字赚钱的网站
  • 怎么赚学生的钱 copyright ? 2000 - 2016
  • 新闻热线:0311-67563366 广告热线:0311-67562966 新闻投诉:0311-67562994
  • 冀ICP备 09047539号-1 | 互联网新闻信息服务许可证编号:1312006002
  • 广播电视节目制作经营许可证(冀)字第101号|信息网络传播视听节目许可证0311618号
  • 官方网站兼职 做任务赚钱的软件 境界哥网赚博客 紫阳网赚论坛