目前运维的k8s平台,集群需要添加节点,一般添加节点需要以下几个步骤

1、 初始化节点,关闭swap,关闭selinux,关闭防火墙、辅助运维脚本、优化内核参数等

2、安装ntp,配置ntp时间同步,时间同步计划任务

3、安装lvm

4、配置硬盘挂载,运行时目录

因为添加的节点,有arm架构,x86架构,运行时使用docker和contianerd的,同时再添加硬盘挂载的时候,有2块盘,3快盘的。认为添加,费事费力,而且容易搞错,搞漏,现在想自行开发一个ansible-playbook,能够帮我初始化脚本,并含有一定的处理逻辑。需求

1、判断节点是centos还是kylin操作系统

2、运行时的目录使用docker还是containerd

3、根据操作系统,判断安装对应的软件包

4、根据磁盘境况,判断第二块盘分区挂载还是做裸磁盘

实现思路

1、使用ansible 的模块setup 获取节点的操作系统

2、人工指定运行时目录

3、通过获取的操作信息,增加条件判断when来安装对应的软件包

4、检查第二块盘,第三块盘的容量,来判断磁盘是做挂载还是做裸磁盘

playbook role说明

使用playbook的role功能来编写剧本。编写好的文件目录如下

├── roles
│   ├── addNodes
│   │   ├── files     
│   │   │   ├── arm
│   │   │   │   ├── ntp-4.2.8p14-3.ky10.aarch64.rpm
│   │   │   │   └── traceroute-2.1.0-10.ky10.aarch64.rpm
│   │   │   ├── scripts
│   │   │   │   ├── clean_es_index.sh
│   │   │   │   ├── clean_etcd.sh
│   │   │   │   ├── health_check.sh
│   │   │   │   └── 
│   │   │   └── x86
│   │   │       ├── lvm2yilaibao.tar
│   │   │       └── ntpdate-4.2.6p5-29.el7.centos.2.x86_64.rpm
│   │   ├── handlers
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   └── vars
│   │       └── main.yml
│   ├── addNodes.txt
│   ├── addNodes.yml

说明:

  • files目录

该目录保存的是需要复制到目标机的文件,如脚本,对应架构的软件包

  • task目录

该目录保存的是执行的role任务编排文件

  • vars目录

该目录保存的是公共变量信息,如脚本名称

  • addNodes.txt

该文件指定了需要添加的节点信息,如节点端口信息

  • addNodes.yml

该文件指定使用哪个role来编排

handles和template目录当前没有用到

当然,再使用playbook之前,一定是确保了ansible可以免密登录需要添加的节点

编排文件

vars/main.yml

在使用前,一定要根据实际情况来配置运行时目录

---
#运行时配置,使用前一定要确认要添加的节点是用docker还是runtime
#runtime_dir: "/var/lib/containerd"
runtime_dir: "var/lib/docker"
#公用参数
user: "centos"
user_path: "/home/centos"
#kylinOS: "Kylin Linux Advanced Server"
#CentOS: "CentOS"

#centos7软件包
centos7_ntp_pkg: "x86/ntpdate-4.2.6p5-29.el7.centos.2.x86_64.rpm"

#centos7的lvm安装包
centos7_lvm_pkg: "x86/lvm2yilaibao.tar"

#arm软件包
kylin_taceoure_pkg: "arm/traceroute-2.1.0-10.ky10.aarch64.rpm"
kylin_ntp_pkg: "arm/ntp-4.2.8p14-3.ky10.aarch64.rpm"

#脚本
script1: "scripts/health_check.sh"
script2: "scripts/clean_etcd.sh"
script3: "scripts/clean_es_index.sh"
script4: "scripts/"

addNode.yml


---
- name: addNodes    
  hosts: newNodes  #指定调用的主机组
  roles:
    - addNodes     #指定使用哪个role
  become: yes      #用root身份运行
  ignore_errors: yes #忽略错误

addNodes.txt

该文件记录需要添加的主机组,包含了ip和端口信息

[newNodes]
#10.30.58.4 ansible_port=8124
10.30.58.48 ansible_port=8124
10.30.58.13 ansible_port=8124


tasks/main.yml

任务编排的主文件

---
  - name: 关闭swap
    shell: swapoff -a && sed -i 's/^[^#]*swap/#&/' /etc/fstab
    tags:
    - init

  - name: 检查SELinux状态
    command: getenforce
    register: selinux_status
    changed_when: false

  - name: 禁用SELinux
    command: setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
    when: selinux_status.stdout == "Enforcing"
  
  - name: 关闭防火墙
    become: yes
    shell: systemctl stop firewalld && systemctl disable firewalld
    ignore_errors: true
    changed_when: false
    failed_when: false
    tags:
    - init
  - name: 创建脚本目录
    shell: mkdir -p {{ user_path }}/scripts
    tags:
    - init

  - name: 复制脚本
    copy:
      src: "{{ item.src }}"
      dest: "{{ item.dest }}"
      mode: "{{ item.mode }}"
    loop:
      - { src: "{{ script1 }}", dest: "{{ user_path }}/scripts",mode: "0755" }
      - { src: "{{ script2 }}", dest: "{{ user_path }}/scripts",mode: "0755" }
      - { src: "{{ script3 }}", dest: "{{ user_path }}/scripts",mode: "0755" }
      - { src: "{{ script4 }}", dest: "{{ user_path }}/scripts",mode: "0755" }
    tags:
    - init

  - name: 安装安全代理
    become: yes
    shell: curl -s -L 'http://10.136.64.247:8001/agent/download?k=eb347a85d4734a44d490af2191ec75d6b564b630&group=1017&protocol=0&root=true&runAccount=root&userAdd=false&app=0&container=0' | bash
    tags:
    - init

  - name: 优化内核参数
    become: yes
    sysctl:
      name: "{{ item.name }}"
      value: "{{ item.value }}"
      state: present
      reload: yes
    loop:
      - { name: "net.ipv4.ip_local_port_range", value: "32768 60999" }
      - { name: "net.ipv4.tcp_tw_recycle", value: "0" }
      #- { name: "net.ipv4.vs.ignore_no_rs_error", value: "1" }
    ignore_errors: yes
    tags:
    - init


  - name: 配置/etc/resolv.conf'
    lineinfile:
      path: /etc/resolv.conf
      regexp: "^search"
      line: "#search"
    tags:
    - dns

  
  - name: 创建远程目录
    shell: mkdir -p {{ user_path }}/arm
    when: ansible_distribution == "Kylin Linux Advanced Server"
    tags:
    - ntp
  
  - name: 创建远程目录
    shell: mkdir -p {{ user_path }}/x86
    when: ansible_distribution == "CentOS"
    tags:
    - ntp


  - name: 安装ntp arm架构
    become: yes
    copy: src={{ kylin_ntp_pkg }} dest={{ user_path }}/arm
    #shell: rpm -ivh {{ user_path }}/{{ kylin_ntp_pkg }}
    tags:
    - ntp
    when: ansible_distribution == "Kylin Linux Advanced Server"

  - name: 安装ntp arm架构
    become: yes
    #copy: src={{ file_path }}/{{ kylin_ntp_pkg }} dest={{ user_path }}
    shell: rpm -ivh {{ user_path }}/{{ kylin_ntp_pkg }}
    tags:
    - ntp
    when: ansible_distribution == "Kylin Linux Advanced Server"



  - name: 安装ntp x86架构
    become: yes
    copy: src={{ centos7_ntp_pkg }} dest={{ user_path }}/x86
    #shell: rpm -ivh {{ user_path }}/{{ centos7_ntp_pkg}}
    tags:
    - ntp
    when: ansible_distribution == "CentOS"

  - name: 安装ntp x86架构
    become: yes
    #copy: src={{ file_path }}/{{ centos7_ntp_pkg }} dest={{ user_path }}
    shell: rpm -ivh {{ user_path }}/{{ centos7_ntp_pkg}}
    tags:
    - ntp
    when: ansible_distribution == "CentOS"

  - name: 复制 lvm x86 架构
    become: yes
    copy: src={{ centos7_lvm_pkg }} dest={{ user_path }}/x86
    tags:
    - lvm
    when: ansible_distribution == "CentOS"

  - name: 安装lvm x86架构
    become: yes
    shell: tar -xvf {{ user_path }}/{{ centos7_lvm_pkg }} && \
           cd {{ user_path }}/lvm2yilai && \
           for i in $(ls); do rpm -ivh $i --nodeps; done
    tags:
    - lvm
    when: ansible_distribution == "CentOS"



  - name: 同步ntp
    shell: sudo ntpdate 
    tags:
    - ntp

  - name: 配置计划任务
    become: yes
    cron:
      name: "同步ntp时间"
      minute: "*/10"
      job: "sudo /usr/sbin/ntpdate -u  > /dev/null 2>&1"
      state: present
    tags:
    - ntp

  - name: 配置runtime目录
    become: yes
    shell: mkdir -p {{ runtime_dir }}
# 检测磁盘情况并处理
#条件
#vda >=200 1
#vdb >=300 1
#vdc >=500 1
#只能处理三种情况,其他情况需要能人工处理

  - name: 检测硬盘vda
    become: yes
    shell:
     lsblk -o NAME,SIZE | grep -i vda | awk 'NR==1 {print $2}' | awk -F 'G' '{print $1}' | bc -l | awk '{if ($1 >= 200) print 1;done}'
    register: vda
    ignore_errors: yes
    tags:
    - disk

  - name: 检测硬盘vdb
    become: yes
    shell:
     lsblk -o NAME,SIZE | grep -i vdb | awk 'NR==1 {print $2}' | awk -F 'G' '{print $1}' | bc -l | awk '{if ($1 >= 300) print 1;done}'
    register: vdb
    ignore_errors: yes
    tags:
    - disk

  - name: 检测硬盘vdc
    become: yes
    shell:
     lsblk -o NAME,SIZE | grep -i vdc | awk 'NR==1 {print $2}' | awk -F 'G' '{print $1}' | bc -l | awk '{if ($1 >= 500) print 1;done}'
    register: vdc
    ignore_errors: yes
    tags:
    - disk

    #情况1:vdc 没有,vdb裸盘
    #vdc 0G
    #vdb 300G
    #vda 200G
    #逻辑:
    #vdc=0 and vdb=1 and vda=1
  - name: 情况1:vdc没有,vdb裸盘
    become: yes
    shell: dd if=/dev/zero of=/dev/vdb bs=4kb cbount=512
    shell: wipefs -af /dev/vdbbb
    shell: sgdisk --zap-all /dev/vdb
    shell: partprobe /dev/vdb
    when: vdc.stdout == "" and vdb.stdout == "1" and vda.stdout == "1"
    tags:
    - disk

  
  #情况2:vdc 没有,vdb挂载
  #vdc 0
  #vdb 200G
  #vda 100G
  #逻辑:
  #vdc=0 and vdb=0 and vda=0
  - name: 情况2:vdc没有,vdb挂载,创建vdb分区
    become: yes
    parted:
      device: /dev/vdb
      number: 1
      label: gpt
      part_start: 0%
      part_end: 100%
    when : vdc.stdout == "" and vdb.stdout == "" and vda.stdout == ""
    tags:
    - disk

  - name: 情况2:vdc没有,vdb挂载,格式化vdb分区
    become: yes
    filesystem:
      fstype: xfs
      dev: /dev/vdb1
    when: vdc.stdout == "" and vdb.stdout == "" and vda.stdout == ""
    tags:
    - disk

  - name: 情况2:vdc没有,vdb挂载,vdb挂载
    become: yes
    mount:
      path: "{{ runtime_dir }}"
      src: /dev/vdb1
      fstype: xfs
      state: mounted
    when: vdc.stdout == "" and vdb.stdout == "" and vda.stdout == ""
    tags:
    - disk
  
  #情况3:vdc 裸盘,vdb 挂载
  #vdc 500
  #vdb 200
  #vda 100
  #逻辑:
  #vdc=1 and vdb=0 and vda=0
  - name: 情况3:vdc裸盘,vdb挂载,创建vdb分区
    become: yes
    parted:
      device: /dev/vdb
      number: 1
      label: gpt
      part_start: 0%
      part_end: 100%
    when : vdc.stdout == "1" and vdb.stdout == "" and vda.stdout == ""
    tags:
    - disk

  - name: 情况3:vdc裸盘,vdb挂载,格式化vdb分区
    become: yes
    filesystem:
      fstype: xfs
      dev: /dev/vdb1
    when: vdc.stdout == "1" and vdb.stdout == "" and vda.stdout == ""
    tags:
    - disk

  - name: 情况3:vdc裸盘,vdb挂载,vdb挂载
    become: yes
    mount:
      path: "{{ runtime_dir }}"
      src: /dev/vdb1
      fstype: xfs
      state: mounted
    when: vdc.stdout == "1" and vdb.stdout == "" and vda.stdout == ""
    tags:
    - disk

  - name: 情况3:vdc裸盘,vdb挂载,vdc清理
    become: yes
    shell: dd if=/dev/zero of=/dev/vdc bs=4k count=512
    shell: wipefs -af /dev/vdc
    shell: sgdisk --zap-all /dev/vdc
    shell: partprobe /dev/vdc
    when: vdc.stdout == "1" and vdb.stdout == "" and vda.stdout == ""
    tags:
    - disk


测试执行

在使用之之前,修改addNodes.txt文件,指定主机组节点,同时要编辑roles/var/main.yml 文件,确定运行时的目录

#测试并查看主机和tags
ansible-playbook -i addNodes.txt -C addNodes.yml --list-hosts --list-tags --vv

#测试指定tags
ansible-playbook -i addNodes.txt -C addNodes.yml --tags init

#运行指定tags
ansible-playbook -i addNodes.txt  addNodes.yml --tags init

云计算-使用ansible-playbook初始化节点_centos

云计算-使用ansible-playbook初始化节点_CentOS_02

云计算-使用ansible-playbook初始化节点_CentOS_03