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步驟
- 服務器規划
- 系統初始化
- 關閉selinux,firewalld
- 關閉swap
- 時間同步
- 寫hosts
- Etcd集群部署
- 生成etcd證書
- 部署三個etcd集群
- 查看集群狀態
- 部署Master
- 生成apiserver證書
- 部署apiserver、controller-manager和scheduler組件
- 啟動TLS Bootstrapping
- 部署Node
- 安裝Docker
- 部署kubelet和kube-proxy
- 在Master上允許為新Node頒發證書
- 授權apiserver訪問kubelet
- 部署插件(准備好鏡像)
- Flannel
- Web UI
- CoreDNS
- Ingress Controller
- Master高可用
- 增加Master節點(與Master1一致)
- 部署Nginx負載均衡器
- Nginx+Keepalived高可用
- 修改Node連接VIP
2、Roles組織K8S各組件部署解析
編寫建議:
- 梳理流程和Roles結構
- 如果配置文件有不固定內容,使用jinja渲染
- 人工干預改動的內容應統一寫到一個文件中
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