1. 程式人生 > 實用技巧 >Ansible自動化部署Kubernetes

Ansible自動化部署Kubernetes

講師:李振良

官方網站: http://www.ctnrs.com

第一章:《Ansible自動化部署K8S叢集》

說明:

  1. 強烈建議學習課堂視訊,更多細節都在裡面!
  2. 本文件為內部學員資料,請不要隨意轉發。

一、Ansible自動化部署K8S叢集

1.1 Ansible介紹

Ansible是一種IT自動化工具。它可以配置系統,部署軟體以及協調更高階的IT任務,例如持續部署,滾動更新。Ansible適用於管理企業IT基礎設施,從具有少數主機的小規模到數千個例項的企業環境。Ansible也是一種簡單的自動化語言,可以完美地描述IT應用程式基礎結構。

具備以下三個特點:

  • 簡單:減少學習成本
  • 強大:協調應用程式生命週期
  • 無代理:可預測,可靠和安全

使用文件: https://docs.ansible.com/

安裝Ansible:yum install ansible -y

  • Inventory:Ansible管理的主機資訊,包括IP地址、SSH埠、賬號、密碼等
  • Modules:任務均有模組完成,也可以自定義模組,例如經常用的指令碼。
  • Plugins:使用外掛增加Ansible核心功能,自身提供了很多外掛,也可以自定義外掛。例如connection外掛,用於連線目標主機。
  • Playbooks:“劇本”,模組化定義一系列任務,供外部統一呼叫。Ansible核心功能。

1.2 主機清單

[webservers]
alpha.example.org
beta.example.org
192.168.1.100
www[001:006].example.com

[dbservers]
db01.intranet.mydomain.net
db02.intranet.mydomain.net
10.25.1.56
10.25.1.57
db-[99:101]-node.example.com

1.3 命令列使用

ad-hoc命令可以輸入內容,快速執行某個操作,但不希望留存記錄。

ad-hoc命令是理解Ansible和在學習playbooks之前需要掌握的基礎知識。

一般來說,Ansible的真正能力在於劇本。

1、連線遠端主機認證

SSH密碼認證:

[webservers]
192.168.1.100:22 ansible_ssh_user=root ansible_ssh_pass=’123456’
192.168.1.101:22 ansible_ssh_user=root ansible_ssh_pass=’123456’

SSH金鑰對認證:

[webservers]
10.206.240.111:22 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa 
10.206.240.112:22 ansible_ssh_user=root

也可以ansible.cfg在配置檔案中指定:
[defaults]
private_key_file = /root/.ssh/id_rsa  # 預設路徑

2、常用選項

選項 描述
-C, --check 執行檢查,不執行任何操作
-e EXTRA_VARS,--extra-vars=EXTRA_VARS 設定附加變數 key=value
-u REMOTE_USER, --user=REMOTE_USER SSH連線使用者,預設None
-k, --ask-pass SSH連線使用者密碼
-b, --become 提權,預設root
-K, --ask-become-pass 提權密碼

3、命令列使用

ansible all -m ping
ansible all -m shell -a "ls /root" -u root -k 
ansible webservers -m copy –a "src=/etc/hosts dest=/tmp/hosts"

1.4 常用模組

ansible-doc –l 檢視所有模組

ansible-doc –s copy 檢視模組文件

模組文件:https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

1、shell

在目標主機執行shell命令。

- name: 將命令結果輸出到指定檔案
  shell: somescript.sh >> somelog.txt
- name: 切換目錄執行命令
  shell:
    cmd: ls -l | grep log
    chdir: somedir/
- name: 編寫指令碼
  shell: |
      if [ 0 -eq 0 ]; then
         echo yes > /tmp/result
      else
         echo no > /tmp/result
      fi
  args:
    executable: /bin/bash

2、copy

將檔案複製到遠端主機。

- name: 拷貝檔案
  copy:
    src: /srv/myfiles/foo.conf
    dest: /etc/foo.conf
    owner: foo
    group: foo
    mode: u=rw,g=r,o=r
    # mode: u+rw,g-wx,o-rwx
    # mode: '0644'
    backup: yes

3、file

管理檔案和檔案屬性。

- name: 建立目錄
  file:
    path: /etc/some_directory
    state: directory
    mode: '0755'
- name: 刪除檔案
  file:
    path: /etc/foo.txt
    state: absent
- name: 遞迴刪除目錄
  file:
    path: /etc/foo
    state: absent

present,latest:表示安裝

absent:表示解除安裝

4、yum

軟體包管理。

- name: 安裝最新版apache
  yum:
    name: httpd
    state: latest
- name: 安裝列表中所有包
  yum:
    name:
      - nginx
      - postgresql
      - postgresql-server
    state: present
- name: 解除安裝apache包
  yum:
    name: httpd
    state: absent 
- name: 更新所有包
  yum:
    name: '*'
    state: latest
- name: 安裝nginx來自遠端repo
  yum:
    name: http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.14.0-1.el7_4.ngx.x86_64.rpm
    # name: /usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm
    state: present

5、service/systemd

管理服務。

- name: 服務管理
  service:
    name: etcd
    state: started
    #state: stopped
    #state: restarted
    #state: reloaded
- name: 設定開機啟動
  service:
    name: httpd
    enabled: yes
- name: 服務管理  
  systemd: 
	name=etcd 
	state=restarted 
	enabled=yes 
	daemon_reload=yes

6、unarchive

- name: 解壓
  unarchive: 
    src=test.tar.gz 
    dest=/tmp

7、debug

執行過程中列印語句。

- debug:
    msg: System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}

- name: 顯示主機已知的所有變數
  debug:
    var: hostvars[inventory_hostname]
    verbosity: 4

1.5 Playbook

Playbooks是Ansible的配置,部署和編排語言。他們可以描述您希望在遠端機器做哪些事或者描述IT流程中一系列步驟。使用易讀的YAML格式組織Playbook檔案。

如果Ansible模組是您工作中的工具,那麼Playbook就是您的使用說明書,而您的主機資產檔案就是您的原材料。

與adhoc任務執行模式相比,Playbooks使用ansible是一種完全不同的方式,並且功能特別強大。

https://docs.ansible.com/ansible/latest/user_guide/playbooks.html

---
- hosts: webservers
  vars:
    http_port: 80
    server_name: www.ctnrs.com
  remote_user: root
  gather_facts: false
  tasks:
  - name: 安裝nginx最新版
    yum: pkg=nginx state=latest
  - name: 寫入nginx配置檔案
    template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
    notify:
    - restart nginx
  - name: 確保nginx正在執行
    service: name=httpd state=started
  handlers:
    - name: restart nginx
      service: name=nginx state=reloaded

1、主機和使用者

- hosts: webservers
  remote_user: lizhenliang
  become: yes
  become_user: root

ansible-playbook nginx.yaml -u lizhenliang -k -b -K

2、定義變數

變數是應用於多個主機的便捷方式; 實際在主機執行之前,變數會對每個主機新增,然後在執行中引用。

  • 命令列傳遞

    -e VAR=VALUE
    
  • 主機變數與組變數

在Inventory中定義變數。

[webservers]
192.168.1.100 ansible_ssh_user=root hostname=web1
192.168.1.100 ansible_ssh_user=root hostname=web2

[webservers:vars]
ansible_ssh_user=root hostname=web1
  • 單檔案儲存

Ansible中的首選做法是不將變數儲存在Inventory中。

除了將變數直接儲存在Inventory檔案之外,主機和組變數還可以儲存在相對於Inventory檔案的單個檔案中。

組變數:

group_vars 存放的是組變數

group_vars/all.yml 表示所有主機有效,等同於[all:vars]

grous_vars/etcd.yml 表示etcd組主機有效,等同於[etcd:vars]

# vi /etc/ansible/group_vars/all.yml
work_dir: /data
# vi /etc/ansible/host_vars/webservers.yml
nginx_port: 80
  • 在Playbook中定義
- hosts: webservers
  vars:
    http_port: 80
    server_name: www.ctnrs.com
  • Register變數
- shell: /usr/bin/uptime
  register: result
- debug:
    var: result

3、任務列表

每個play包含一系列任務。這些任務按照順序執行,在play中,所有主機都會執行相同的任務指令。play目的是將選擇的主機對映到任務。

  tasks:
  - name: 安裝nginx最新版
    yum: pkg=nginx state=latest

4、語法檢查與除錯

語法檢查:ansible-playbook --check /path/to/playbook.yaml

測試執行,不實際操作:ansible-playbook -C /path/to/playbook.yaml

debug模組在執行期間列印語句,對於除錯變數或表示式,而不必停止play。與'when:'指令一起除錯更佳。

  - debug: msg={{group_names}}
  - name: 主機名
    debug:
      msg: "{{inventory_hostname}}"

5、任務控制

如果你有一個大的劇本,那麼能夠在不執行整個劇本的情況下執行特定部分可能會很有用。

  tasks:
  - name: 安裝nginx最新版
    yum: pkg=nginx state=latest
    tags: install
  - name: 寫入nginx配置檔案
    template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
    tags: config

使用:

ansible-playbook example.yml --tags "install"
ansible-playbook example.yml --tags "install,config"
ansible-playbook example.yml --skip-tags "install"

6、流程控制

條件:

tasks:
- name: 只在192.168.1.100執行任務
  debug: msg="{{ansible_default_ipv4.address}}"
  when: ansible_default_ipv4.address == '192.168.1.100'

迴圈:

tasks:
- name: 批量建立使用者
  user: name={{ item }} state=present groups=wheel
  with_items:
     - testuser1
     - testuser2
- name: 解壓
  copy: src={{ item }} dest=/tmp
  with_fileglob:
    - "*.txt"

常用迴圈語句:

語句 描述
with_items 標準迴圈
with_fileglob 遍歷目錄檔案
with_dict 遍歷字典

7、模板

 vars:
    domain: "www.ctnrs.com"
 tasks:
  - name: 寫入nginx配置檔案
    template: src=/srv/server.j2 dest=/etc/nginx/conf.d/server.conf
# server.j2
{% set domain_name = domain %}
server {
   listen 80;
   server_name {{ domain_name }};
   location / {
        root /usr/share/html;
   }
}

在jinja裡使用ansible變數直接 {{ }}引用。使用ansible變數賦值jinja變數不用{{ }}引用。

定義變數

{% set local_ip = inventory_hostname %}

條件和迴圈

{% set list=['one', 'two', 'three'] %}
{% for i in list %}
	{% if i == 'two' %}
		-> two
	{% elif loop.index == 3 %}
		-> 3
	{% else %}
		{{i}}
	{% endif %}
{% endfor %}

例如:生成連線etcd字串

{% for host in groups['etcd'] %}
	https://{{ hostvars[host].inventory_hostname }}:2379
	{% if not loop.last %},{% endif %}
{% endfor %} 

裡面也可以用ansible的變數。

1.6 Roles

Roles是基於已知檔案結構自動載入某些變數檔案,任務和處理程式的方法。按角色對內容進行分組,適合構建複雜的部署環境。

1、定義Roles

Roles目錄結構:

site.yml
webservers.yml
fooservers.yml
roles/
   common/
     tasks/
     handlers/
     files/
     templates/
     vars/
     defaults/
     meta/
   webservers/
     tasks/
     defaults/
     meta/
  • tasks -包含角色要執行的任務的主要列表。
  • handlers -包含處理程式,此角色甚至在此角色之外的任何地方都可以使用這些處理程式。
  • defaults-角色的預設變數
  • vars-角色的其他變數
  • files -包含可以通過此角色部署的檔案。
  • templates -包含可以通過此角色部署的模板。
  • meta-為此角色定義一些元資料。請參閱下面的更多細節。

通常的做法是從tasks/main.yml檔案中包含特定於平臺的任務:

# roles/webservers/tasks/main.yml
- name: added in 2.4, previously you used 'include'
  import_tasks: redhat.yml
  when: ansible_facts['os_family']|lower == 'redhat'
- import_tasks: debian.yml
  when: ansible_facts['os_family']|lower == 'debian'

# roles/webservers/tasks/redhat.yml
- yum:
    name: "httpd"
    state: present

# roles/webservers/tasks/debian.yml
- apt:
    name: "apache2"
    state: present

2、使用角色

# site.yml
- hosts: webservers
  roles:
    - common
    - webservers


定義多個:
- name: 0
  gather_facts: false
  hosts: all 
  roles:
    - common

- name: 1
  gather_facts: false
  hosts: all 
  roles:
    - webservers

3、角色控制

- name: 0.系統初始化
  gather_facts: false
  hosts: all 
  roles:
    - common
  tags: common 

1.7 自動化部署K8S(離線版)

1、 熟悉二進位制部署K8S步驟

  1. 伺服器規劃
角色 IP 元件
k8s-master1 192.168.31.61 kube-apiserver kube-controller-manager kube-scheduler etcd
k8s-master2 192.168.31.62 kube-apiserver kube-controller-manager kube-scheduler
k8s-node1 192.168.31.63 kubelet kube-proxy docker etcd
k8s-node2 192.168.31.66 kubelet kube-proxy docker etcd
Load Balancer(Master) 192.168.31.61 192.168.31.60 (VIP) nginx keepalived
Load Balancer(Backup) 192.168.31.62 nginx keepalived
  1. 系統初始化
    1. 關閉selinux,firewalld
    2. 關閉swap
    3. 時間同步
    4. 寫hosts
  2. Etcd叢集部署
    1. 生成etcd證書
    2. 部署三個etcd叢集
    3. 檢視叢集狀態
  3. 部署Master
    1. 生成apiserver證書
    2. 部署apiserver、controller-manager和scheduler元件
    3. 啟動TLS Bootstrapping
  4. 部署Node
    1. 安裝Docker
    2. 部署kubelet和kube-proxy
    3. 在Master上允許為新Node頒發證書
    4. 授權apiserver訪問kubelet
  5. 部署外掛(準備好映象)
    1. Flannel
    2. Web UI
    3. CoreDNS
    4. Ingress Controller
  6. Master高可用
    1. 增加Master節點(與Master1一致)
    2. 部署Nginx負載均衡器
    3. Nginx+Keepalived高可用
    4. 修改Node連線VIP

2、Roles組織K8S各元件部署解析

編寫建議:

  1. 梳理流程和Roles結構
  2. 如果配置檔案有不固定內容,使用jinja渲染
  3. 人工干預改動的內容應統一寫到一個檔案中

3、下載所需檔案

確保所有節點系統時間一致

下載Ansible部署檔案:

git clone https://github.com/lizhenliang/ansible-install-k8s
cd ansible-install-k8s

下載軟體包並解壓:

雲盤地址:https://pan.baidu.com/s/1lTXolmlcCJbei9HY2BJRPQ

tar zxf binary_pkg.tar.gz

4、修改Ansible檔案

修改hosts檔案,根據規劃修改對應IP和名稱。

vi hosts

修改group_vars/all.yml檔案,修改軟體包目錄和證書可信任IP。

vim group_vars/all.yml
software_dir: '/root/binary_pkg'
...
cert_hosts:
  k8s:
  etcd:

5、一鍵部署

架構圖

​ 單Master架構

​ 多Master架構

部署命令
單Master版:

ansible-playbook -i hosts single-master-deploy.yml -uroot -k

多Master版:

ansible-playbook -i hosts multi-master-deploy.yml -uroot -k

6、部署控制

如果安裝某個階段失敗,可針對性測試.

例如:只執行部署外掛

ansible-playbook -i hosts single-master-deploy.yml -uroot -k --tags addons

示例參考:https://github.com/ansible/ansible-examples

講師:李振良

官方網站: http://www.ctnrs.com