2022-06-10

2022-06-10  本文已影响0人  brightranger

Ansible playbook 自动化部署方案

1. 方案背景

当前Jlite非标部署比较复杂,需要部署的服务比较多,每个服务又有很多配置。一是部署时间比较长、二是部署不够标准(基础软件版本、日志文件配置等不统计)。为了使部署更加简单、方便、快捷,特提供本部署方案。

ansible playbook自动化部署技术目前比较成熟、文档齐全,固本次选择ansible playbook为自动化部署技术方案。

2. Ansible 简介

Ansible是一种常用的自动运维化工具,基于python开发,分布式,无需客户端,轻量级,配置语言采用YAML。

2.1. Ansible的特性:

  1. 模块化:调用特定的模块,完成特殊的任务。
  2. Paramiko(python对ssh的实现),PyYaml,jinja2(模块语言)三个关键模块。
  3. 支持自定义模块,可使用任何编程语言写模块。
  4. 基于python语言实现。
  5. 部署简单,基于python和SSH(默认已安装),agentless,无需代理不依赖KPI(无需SSL)。
  6. 安全,基于OpenSSH
  7. 幂等性:一个任务执行一次和执行n遍效果一样,不因重复执行带来意外情况。
  8. 支持playbook编排任务,YAML格式,编排任务,支持丰富的数据结构。
  9. 较强大的多层解决方案role。

2.2 Ansible的作用目标:

  1. 自动化部署APP
  2. 自动化管理配置项
  3. 自动化的持续交付
  4. 自动化的云服务管理

3. Playbook简介

playbook是ansible用于配置,部署和管理托管主机剧本,通过playbook的详细描述,执行其中一系列tasks,可以让远程主机达到预期状态。playbook是由一个或多个"play"组成的列表。

也可以说,playbook字面意思及剧本,现实中由演员按剧本表演,在ansible中由计算机进行安装,部署应用,提供对外服务,以及组织计算机处理各种各样的事情

3.1. Playbook 核心元素

4. 部署组件图

结合Ansible Playbook、Docker、Docker Compose、Docker Swarm集群、Nacos功能特点。可以使用如下组件图方案对Jlite实施自动化部署。

1654850242(1).png

4.1. 本地nacos配置信息说明

因为Ansible Playbook并没有提供一个界面配置,所以我们使用Nacos作为所有部署时参数的配置中心。

4.1.1 远程服务器资源
4.1.2 服务部署信息
4.1.3 每个服务依赖的配置

每个服务自已依赖的nacos配置不变,只需要要本地配置就好,自动化脚本自动下载后上传到远程部署服务器的nacos上。

5. 服务的 docker-compose.yaml

每个服务的docker-compose.yaml文件由研发提供,可以在里面可以使用参数占位符。参数由前面的service-docker-compose-parameter.yaml定义。

version: '3'

services:
  jlite:
    image: {{ services.jlite.image }}
    container_name: jlite_node_noe
    dns_search: .
    volumes: 
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - /home/jht/logs/jlite:/home/jht/logs
    environment:
      - TZ=Asia/Shanghai
    ports: {{ services.jlite.ports }}
    networks:
      - swarm_net
    deploy:
      mode: replicated
      replicas: {{ services.jlite.deploy.replicas }}
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 5s
    depends_on:
      - redis
      - lucene
      - emqx
      - nginx
  redis:
    image: redis_docker_images_name
    container_name: redis_container
    environment:
      - TZ=Asia/Shanghai
    ports: {{ services.redis.ports }}
    networks:
      - swarm_net
    deploy:
      mode: replicated
      replicas: {{ services.redis.deploy.replicas }}
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 5s

6. 安装包

安装包由OA流程走完后,运维工具跑定时任务,定时打镜像到仓库中。

7. 日志文件

可以在docker swarm的集群服务器上共享挂载磁盘的方式,集中在一起。如下

services:
  jlite:
    volumes:
      - /home/docker/logs/jlite:/home/jht/logs

8. 自动化部署流程图

image.png

9. ansible playbook 环境安装配置

9.1 获取读取nacos配置文件 playbook脚本

---
- hosts: localhost
  remote_user: jht
  vars:
    - workspace: 93549ceb-522d-4137-b02d-7aa05ab10852
  tasks:
    - name: login nacos
      uri:
        url: http://10.10.204.114:8848/nacos/v1/auth/users/login?username=nacos&password=nacos
        method: post
        return_content: yes
        status_code: 200
      register: login
    - debug:
        var: login.json.accessToken
    - name: download config
      uri:
        url: http://10.10.204.114:8848/nacos/v1/cs/configs?show=all&dataId=serviceConfiguration&group=ansible&tenant={{ workspace }}&accessToken={{ login.json.accessToken }}&namespaceId={{ workspace }}
        method: get
        return_content: yes
        status_code: 200
      register: config
    - debug:
        var: config.json.content
    - name: write file
      file:
        path: /home/jht/playbook/templates
        state: directory
    - name: create file
      file:
        path: /home/jht/playbook/templates/serviceConfiguration.yaml
        state: touch
    - name: write file content
      blockinfile:
        path: /home/jht/playbook/templates/serviceConfiguration.yaml
        block: "{{ config.json.content }}"

9.2 安装docker

- name: install required packages
  yum:
    name: "{{ item }}"
    state: present
  with_items:
    - yum-utils
    - device-mapper-persistent-data
    - lvm2
- name: add docker repo to /etc/yum.repos.d
  shell: yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  register: result
- name: debug
  debug:
    var: not result.failed
- name: install docker-ce
  yum:
    name: docker-ce
    state: present
  when: not result.failed
- name: install docker-ce-cli
  yum:
    name: docker-ce-cli
    state: present
  when: not result.failed
- name: install containerd.io
  yum:
    name: containerd.io
    state: present
  when: not result.failed
- name: create /etc/docker
  file:
    path: "{{ docker_config_dir }}"
    state: directory
- name: start docker service
  systemd:
    name: docker
    state: started
    enabled: true
- name: provide docker-ce configfile
  template:
    src: daemon.json.j2
    dest: /etc/docker/daemon.json
  notify: restart docker

9.3 安装docker compose

- name: copy docker-compose-Linux-x86_64 to /usr/local/bin
  copy:
    src: ../files/docker-compose-linux-x86_64
    dest: "{{ docker_compose_dir }}/docker-compose-Linux-x86_64"

- name: install docker-compose
  shell: cd "{{ docker_compose_dir }}" && mv docker-compose-Linux-x86_64 docker-compose && chmod +x docker-compose

9.4 安装docker swarm leader

---
- name: Create leader node of docker swarm cluster
  hosts: leader
  remote_user: jht
  gather_facts: yes
  become: yes
  become_method: sudo
  become_user: root
  vars:
    ip_addr: "{{ ansible_default_ipv4['address'] }}"
  tasks:
    - name: show ip_add
      debug:
        var: ip_addr

    - name: Ensure docker is running
      become: yes
      service:
        name: docker
        state: started

    - name: Get docker info
      shell: docker info
      register: docker_info

    - name: show docker_info
      debug:
        var: docker_info

    - name: Create docker swarm leader node
      shell: docker swarm init --advertise-addr {{ ip_addr }}
      when: "docker_info.stdout.find('Swarm: inactive') != -1"

    - name: Get docker swarm manager token
      shell: docker swarm join-token -q manager
      register: manager_token

    - name: Get docker swarm worker token
      shell: docker swarm join-token -q worker
      register: worker_token

    - name: Output tokens
      debug:
        msg: "{{ manager_token.stdout }} ----------------- {{ worker_token.stdout }}"

    - name: Add tokens to dummy host, to be shared between multiple hosts
      add_host:
        name: swarm_tokens_host
        worker_token: "{{ worker_token.stdout }}"
        manager_token: "{{ manager_token.stdout }}"
        leader_ip_addr: "{{ ip_addr }}"

    - name: Show nodes of docker swarm
      shell: docker node ls

9.5 设置 docker swarm manager

---
- name: Create manager nodes of docker swarm cluster
  hosts: managers
  remote_user: jht
  become: true
  become_method: sudo
  become_user: root
  vars:
    manager_token: "SWMTKN-1-0xwaprlwrnc1ep0839lpuwgl2muq10vxu09forqgh7ojo4hx89-2fx5aapfq3uwq65slca5ph99r"
    leader_ip_addr: "10.10.205.115"
  tasks:
    - name: Ensure docker is running
      service:
        name: docker
        state: started

    - name: Get docker info
      shell: docker info
      register: docker_info

    - name: Join as manager node
      shell: docker swarm join --token {{ manager_token }} {{ leader_ip_addr }}:2377
      when: "docker_info.stdout.find('Swarm: inactive') != -1"
      retries: 3
      delay: 20
...

9.6 设置 docker swarm workers

---
- name: Create docker swarm worker nodes
  gather_facts: yes
  hosts: workers
  remote_user: jht
  become: yes
  become_method: sudo
  become_user: root
  vars:
    worker_token: "SWMTKN-1-0xwaprlwrnc1ep0839lpuwgl2muq10vxu09forqgh7ojo4hx89-5yps35hmuo6eda9cncl2vra39"
    leader_ip_addr: "10.10.205.115"
  tasks:
    - name: Ensure docker is running
      become: yes
      service:
        name: docker
        state: started

    - name: Get docker info
      shell: docker info
      register: docker_info

    - name: Join as worker node
      shell: docker swarm join --token {{ worker_token }} {{ leader_ip_addr }}:2377
      when: "docker_info.stdout.find('Swarm: inactive') != -1"
      retries: 3
      delay: 20
...

10. 部署实例

10.1 部署 nginx

---
- name: Deploy services to docker swarm cluster
  gather_facts: no
  hosts: leader
  remote_user: jht
  become: true
  become_method: sudo
  become_user: root
  vars:
    src_docker_compose: ./docker-compose.yml
    dest_docker_compose: ~/docker-compose.yml
    stack_name: first_stack
  tasks:
    - name: Upload docker compose file
      template:
        src: "{{ src_docker_compose }}"
        dest: "{{ dest_docker_compose }}"

    - name: Deploy services
      shell: docker stack deploy --with-registry-auth --prune --compose-file {{ dest_docker_compose }} {{ stack_name }}

    - name: Pause for 10 seconds to wait for services being running
      pause:
        seconds: 10

    - name: Ensure services deployed
      shell: docker service ls
      register: service_output

    - name: Output service list
      debug:
        msg: "{{ service_output.stdout_lines }}"

    - name: Show stacks
      shell: docker stack ls
...
上一篇下一篇

猜你喜欢

热点阅读