Deploy

Deploy是一个高效的、面向配置的部署工具,可以快速地构建、发布服务到Docker集群中。

功能

  • 快速的搭建部署环境
  • 多环境隔离部署
  • 基于git仓库或标准包的镜像和服务发布

安装

环境依赖

验证环境是否满足要求

  1. # 查看python是否为2.x版本
  2. python --version
  3. # 查看是否安装git
  4. git --version
  5. # 查看是否安装ansible,同时也会输出当前使用的python版本
  6. ansible --version
  7. # 查看是否安装make
  8. make --version

获取最新的部署工程

  1. git clone --recursive ssh://git@git.ascs.tech/tool/deploy.git deploy
  2. cd deploy
  3. # 目前工具还没走发布流程,新的功能都在develop分支,还没并入master分支
  4. git checkout develop

工程结构介绍

  1. deploy
  2. ├── config
  3. ├── environment # 存放部署配置的目录,以目录来区分多不同环境
  4. ├── wushan # 乌山环境的部署配置
  5. ├── group_vars # 组变量
  6. ├── service_conf # 服务配置目录
  7. ├── ssh # 环境的公私钥,隔离各环境对git仓库的访问
  8. ├── hosts # 主机列表
  9. └── images.json # 环境的镜像仓库配置
  10. ├── baoan # 宝安环境的部署配置
  11. ├── ...
  12. ├── id_rsa & id_rsa.pub # 通用的deploy公私钥,用于访问通用的仓库
  13. └── images.json # 各个环境通用的镜像仓库配置
  14. ├── files # 存放离线包
  15. ├── filter_plugins # ansible中的过滤器插件
  16. ├── inventories # ansible框架使用的配置目录,以目录来区分多不同环境
  17. ├── full
  18. └── wushan
  19. ├── library # ansible的自定义插件
  20. ├── roles # ansible角色
  21. ├── auth
  22. ├── ...
  23. ├── scripts
  24. ├── tasks
  25. ├── Makefile # make指令的集合
  26. ├── auth.yml # ansible的剧本
  27. └── xxx.yml # 其他xxx剧本

不同环境的配置可以存放在对应的Bitbucket project里,进行版本控制

原理阐述

流程说明

deploy工程 - 图1

上图为简易的一个部署架构和流程,包含了两个命令:
make images-publish为触发镜像发布的命令
make service为触发服务发布的命令

部署场景的角色主要分以下几种:

  • 部署工具:就是运行deploy工程make命令的主机,一般就是自己的机器
  • ansible(build-server):被控制机中会有一台被选为构建服务器,构建服务器主要负责从git仓库中拉取代码进行构建(因此需要给这台机器额外安装jdk、node、go等)、将标准包解压进行构建等工作
  • 其他被控制机器:无特殊角色,按照Docker Swarm集群内的角色进行服务,承载容器

make images-publish service_name=monitor-history后发生了什么

images-publish依赖于service_conf下的配置和environment下的images.json的配置

执行命令的具体流程如下:

deploy工程 - 图2

  1. 根据service_name在service_conf下寻找服务的配置文件monitor-history.json
  2. 读取配置文件的image节点的内容”upm/monitor-history:develop”,在images.json中寻找upm节点下的monitor-history节点。
  3. 找到该节点后,判断是否有source节点,如果有,执行第4步,如果没有,执行第5步
  4. 判断是git仓库还是dockerhub,如果是dockerhub,则直接docker pull即可,如果是git仓库,就克隆仓库的develop分支做构建工作
  5. 在ansible主机上的/root/.cityworks/packages/upm节点下寻找monitor-history-develop.tar.gz包,找到后开始构建工作

make service service_name=monitor-history后发生了什么

  1. 根据service_name在service_conf下寻找服务的配置文件monitor-history.json
  2. 读取配置文件的内容,组装启动容器的所有参数
  3. 启动容器

服务配置文件书写规则

均遵守Docker for Python SDK的参数格式

对主要的几种属性说明如下:

属性名称 说明 备注
args 对应上面的ARG…
env 标识环境变量 此处为针对不同部署环境可以特定设置,达到镜像复用的效果
mounts 数据持久化挂载 /开头的绝对路径标识bind的模式,纯字母标识数据卷
mode 部署模式 replicated 副本模式需要设置副本数replicas,global代表全局模式
networks 挂载网络 挂载同一个网络的服务,可以通过dns做服务发现
endpoint_spec 标识端口的设置
constraints 约束条件 约束容器只能运行在特定节点上

images.json的覆盖规则

  • 环境内部的私有images.json会覆盖通用的images.json
  • 以深度为1的节点为单位进行覆盖,比如两个json文件中都有public节点,环境私有的images.json里的pubic节点会覆盖通用的images.json里的public节点。

服务配置文件中image的书写规则和images.json的映射关系

基于git仓库或标准包进行发布时

[category]/[image-name]:[branch | tag]

基于公网镜像进行发布时

[category]/[image-name]:[tag] 其中category一般为public

image和images.json的映射关系

  • category对应images.json中的深度为1的节点
  • image-name对应images.json中category节点下的一个子节点
  • image-name内会配置source节点,代表镜像在git或docker仓库的位置,如果基于标准包进行部署,则没有source节点
  • branch | tag 是针对git仓库或标准包而言的,公网镜像里的tag则就是针对docker image的

使用场景

实际搭建一个Docker Swarm的部署环境

  1. 首先在environment目录下,新建一个文件夹代表环境,环境名即为目录名。

    1. # 这里假设环境名为demo
    2. cd environment
    3. mkdir demo
  2. 从full中复制一份完整的环境配置文件到demo环境,并进行修改

    1. 如果使用docker-register的话,需要修改group_vars/base中的registry字段
    2. 如果使用ntp同步时间的话,需要修改group_vars/ntpd.yml中的restricts字段
    3. service_conf目录下存放服务的配置文件
    4. 在ssh目录下执行ssh-keygen -t rsa -C 'demo' -f 'id_rsa' -P '',-C后为环境名,此处为demo
    5. 修改images.json,加入环境相关服务的仓库配置
    6. 修改hosts文件,配置主机列表 ```shell [ansible] 192.168.56.201 ansible_ssh_user=root

[base:children] docker

[docker] 192.168.56.201 ansible_ssh_user=root hostname=docker-1-manager host_type=leader 192.168.56.202 ansible_ssh_user=root hostname=docker-2-manager host_type=manager 192.168.56.203 ansible_ssh_user=root hostname=docker-3-manager host_type=manager 192.168.56.204 ansible_ssh_user=root hostname=docker-4-worker host_type=worker 192.168.56.205 ansible_ssh_user=root hostname=docker-5-worker host_type=worker [docker:vars] leader_host=192.168.56.201

[ntpd:children] docker [ntpd:vars] server_host=192.168.56.201

  1. 3. 开始从零构建环境,后续步骤的命令默认都是在deploy工程的根目录执行
  2. 4. 执行`export ENVIRONMENT_NAME=demo`,设置当前的部署环境,其中demo为你配置的环境名
  3. 5. 执行`make auth`,根据提示输入被控制机器的密码,免密登录被控制机器,避免每次都需要输入密码
  4. 6. 执行`make infra`,修改公用的基础环境配置
  5. 7. 执行`make hostname`,根据主机列表中的配置的hostname,修改被控机器的hostname
  6. 8. 执行`make base-vm`,为base组安装基础软件,包括docker及一些常用命令,可以在`group_vars/software.yml`中进行配置
  7. 9. 执行`make manager-vm`,为ansible组安装构建需要的环境,包括jdknodego等,这些包需要提前放置在 files 目录下
  8. 10. 执行`make build-server`,初始化ansible组的主机的ssh公司钥
  9. 11. 执行`make ntpd`,同步ntpd组内主机的时间,`server_host`向公网同步,其他机器向`server_host`同步
  10. 12. 执行`make docker-daemon`,修改dockerregister
  11. 13. 执行`make docker-cluster`,按照主机列表中的配置组建docker集群
  12. 14. 至此,一个基本的部署环境就已经有了
  13. <a name="d8d13d07"></a>
  14. ### 实际部署一个k8s环境
  15. 基础host文件如下

[docker] 192.168.100.68 ansible_ssh_user=root hostname=k8s-node-1 host_type=leader keepalived_role=MASTER keepalived_priority=100 192.168.100.69 ansible_ssh_user=root hostname=k8s-node-2 host_type=master keepalived_role=BACKUP keepalived_priority=80 192.168.100.70 ansible_ssh_user=root hostname=k8s-node-3 host_type=master keepalived_role=BACKUP keepalived_priority=80 192.168.100.71 ansible_ssh_user=root hostname=k8s-node-4 host_type=worker [docker:vars] leader_host=192.168.100.68

  1. 变量描述:
  2. - leader_host: 会作为集群初始化的节点, 该节点keepalived_priority需要最大, 初始化集群会通过vip请求kube api
  3. - host_type: host_typemaster的会作为contro plane 加入集群, 此时配合keepalived_rolekeepalived_priority, worker会作为工作节点加入, 其他值会被忽略
  4. <a name="91010747"></a>
  5. #### 变量配置说明
  6. base的文件配置

cluster_mode: k8s #部署模式为k8s集群方式 k8s: pod_network_cidr: 10.244.0.0/16 #pod 的网络划分, 需要和cni的网络池对应 control_plane_endpoint: 192.168.100.72:6443 #pod ha部署的时候的上层入口 clean_taints: false # 是否清理master的污点 mode: ha # 待定,暂时无用 ha_model: keepalived # 暂时只有通过keepalived的方式部署 nodePortRange: 30000-32767 # 开放的端口

  1. addon.yml文件
  2. 用于插件的变量配置, 目前支持的插件有`helm`

helm: repo: #用于添加安装插件的时候,默认添加的repo

开始部署

新建虚拟机在可以联网的情况下, 直接执行make k8s-auto-cluster hosts=docker 执行一键安装

如果基础环境已经配置好, 可以使用make k8s-cluster hosts=docker直接进行集群组建

扩展集群, 目前可以按顺序执行make base-vm hosts=docker, make keepalived hosts=docker, make firewalld hosts=docker进行基础配置

然后根据需要执行make k8s-control-plane-join hosts=docker来添加控制平面, 或者make k8s-worker-join hosts=docker 来添加worker节点

部署一个符合标准的微服务

基于公网镜像的部署

需求:以demo环境为例,在集群中部署一个postgres数据库

操作:

  1. service_conf下创建pg.json文件,内容如下

    1. {
    2. "image": "public/postgres:9.6.1",
    3. "networks": [
    4. "cw"
    5. ],
    6. "mode": {
    7. "replicated": {
    8. "replicas": 1
    9. }
    10. },
    11. "mounts": [
    12. "pg-dev:/var/lib/postgresql/data"
    13. ],
    14. "env": {
    15. "POSTGRES_USER" : "ascs",
    16. "POSTGRES_PASSWORD" : "ascs.tech"
    17. },
    18. "endpoint_spec": {
    19. "ports":{
    20. "5432":5432
    21. }
    22. }
    23. }
  2. 修改environment目录下的images.json文件,在public节点下添加如下记录,修改后的文件如下所示

    1. {
    2. "public": {
    3. "postgres": {
    4. "sources": "postgres"
    5. }
    6. }
    7. }
  3. 在deploy工程的根目录,执行make images-publish service_name=pg发布镜像,其中,service_name就是service_conf下postgres配置文件pg.json的文件名pg。如果没有部署docker-register的话,最后可能会有一个被忽略的错误,是没有影响的

  4. 在deploy工程的根目录,执行make service service_name=pg发布服务,这条命令会基于刚才发布的镜像启动容器

基于git仓库的部署

需求:以demo环境为例,发布upm中的monitor-history服务,git仓库地址为ssh://git@git.ascs.tech/man/monitor-history.git
操作:

  1. service_conf下创建monitor-history.json文件,内容如下

    1. {
    2. "image": "upm/monitor-history:develop",
    3. "env": {
    4. "SWAGGER.HOST": "192.168.2.30:10202",
    5. "SPRING.DATA.MONGODB.HOST": "mongo-dev",
    6. "SPRING.DATA.MONGODB.PORT": "27017",
    7. "SPRING.DATA.MONGODB.DATABASE": "docker_monitor"
    8. },
    9. "mode": {
    10. "replicated": {
    11. "replicas": 1
    12. }
    13. },
    14. "networks": [
    15. "cw"
    16. ],
    17. "endpoint_spec": {
    18. "ports": {
    19. "10202": 8080
    20. }
    21. }
    22. }
  2. 修改环境内的images.json文件,在upm节点下添加如下记录,修改后的文件如下所示

    1. {
    2. "upm": {
    3. "monitor-history": {
    4. "sources": "ssh://git@git.ascs.tech/man/monitor-history.git"
    5. }
    6. }
    7. }
  3. 需要将demo环境中的公钥添加到monitor-history仓库的access_keys,保证可以拉取代码

  4. 在deploy工程的根目录,执行make images-publish service_name=monitor-history发布镜像,其中,service_name就是service_conf下monitor-history配置文件monitor-history.json的文件名monitor-history。如果没有部署docker-register的话,最后可能会有一个被忽略的错误,是没有影响的
  5. 在deploy工程的根目录,执行make service service_name=monitor-history发布服务,这条命令会基于刚才发布的镜像启动容器

基于标准包的部署

需求:以demo环境为例,基于标准包发布upm中的monitor-histor服务(以develop分支为例),git仓库地址为ssh://git@git.ascs.tech/man/monitor-history.git
操作:

  1. 克隆代码到本地,并进行打包,最终会得到monitor-history-develop.tar.gz

    1. git clone --recursive ssh://git@git.ascs.tech/man/monitor-history.git monitor-history
    2. cd monitor-history && git checkout develop
    3. make package -m OUT_DIR=.
  2. 复制monitor-history-develop.tar.gz到ansible组的主机文件系统 ```shell

    在root@192.168.56.201上新建文件夹(如果不存在的话)

    mkdir -p /root/.cityworks/package/upm

在本地执行,将monitor-history-develop.tar.gz复制到ansible组的主机文件系统

scp monitor-history-develop.tar.gz root@192.168.56.201:/root/.cityworks/package/upm

  1. 3. `service_conf`下创建`monitor-history.json`文件,内容如下
  2. ```json
  3. {
  4. "image": "upm/monitor-history:develop",
  5. "env": {
  6. "SWAGGER.HOST": "192.168.2.30:10202",
  7. "SPRING.DATA.MONGODB.HOST": "mongo-dev",
  8. "SPRING.DATA.MONGODB.PORT": "27017",
  9. "SPRING.DATA.MONGODB.DATABASE": "docker_monitor"
  10. },
  11. "mode": {
  12. "replicated": {
  13. "replicas": 1
  14. }
  15. },
  16. "networks": [
  17. "cw"
  18. ],
  19. "endpoint_spec": {
  20. "ports": {
  21. "10202": 8080
  22. }
  23. }
  24. }
  1. 修改环境内的images.json文件,在upm节点下添加如下记录,修改后的文件如下所示

    1. {
    2. "upm": {
    3. "monitor-history": {
    4. }
    5. }
    6. }
  2. 在deploy工程的根目录,执行make images-publish service_name=monitor-history发布镜像,其中,service_name就是service_conf下monitor-history配置文件monitor-history.json的文件名monitor-history。如果没有部署docker-register的话,最后可能会有一个被忽略的错误,是没有影响的

  3. 在deploy工程的根目录,执行make service service_name=monitor-history发布服务,这条命令会基于刚才发布的镜像启动容器

三种方式的异同

服务的配置文件

均遵守Docker for Python SDK的参数格式

images.json
  • 公网镜像:在public节点下添加postgres子节点,source写docker hub中的镜像名称即可,一般在environment下的通用images.json中添加
  • git仓库:在upm节点下添加monitor-history子节点,source写git仓库地址即可,一般在环境内的私有images.json中添加
  • 标准包:在upm节点下添加monitor-history子节点,节点内留空(留空的情况会在ansible主机的/root/.cityworks/package/upm/寻找对应规则的tar.gz)

跨网络环境进行部署

deploy工程 - 图3

前提及准备工作

  1. 已经创建好-R及-L的通道,可以通过ssh root@localhost -p xxx的形式连接到跳板机
  2. 执行ssh-copy-id root@localhost -p xxx,使ansible控制机免密登录跳板机
  3. 跳板机可以连通被控制机

全局生效

在根路径下的ansible.cfg文件中添加如下参数,替换root@localhost -p xxx为跳板机的连接信息,所有主机均通过隧道远程部署

  1. [ssh_connection]
  2. ssh_args = -o ProxyCommand="ssh -W %h:%p root@localhost -p xxx"

主机组生效

假设主机组为[tunnel],给主机组添加如下参数,替换root@localhost -p xxx为跳板机的连接信,当前主机组即可通过隧道远程部署

  1. [tunnel:vars]
  2. ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p root@localhost -p xxx"'

命令级别生效

ansibleansible-playbook命令均支持如下参数,执行命令时,添加此参数即可

  1. --ssh-common-args=SSH_COMMON_ARGS specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand)

小技巧

覆盖剧本默认的组

默认每个剧本都是指定了对应的组的,但有时我们可能需要对其他组使用这个剧本,因此可以通过传入hosts来覆盖剧本默认的组,如

make hostname hosts=docker

当前支持覆盖的剧本包括

make指令 默认组
auth all
hostname all
base-vm base
jdk jdk
nifi nifi
zookeeper-cluster zookeeper
firewalld docker
keepalived docker
storage storage

反馈

Bug Report

如果在使用中遇到了问题,请通过邮件的形式进行反馈,我们将尽快处理。
点我反馈缺陷

Feature Request

如果你对deploy工程有什么好的想法或者需求,欢迎通过邮件的形式向我们阐述,我们将对它进行评估,决定是否进行支持。
点我提个需求

FAQ

反馈部分的链接失效

请手动发送邮件到zhaowei@ascs.tech,并抄送renjie@ascs.techyuetongshu@ascs.tech,主题写清楚反馈的类型即可。

Windows用户如何使用部署工程

windows下的配合修改,包括准备make等