赞
踩
Ansible 是一种IT自动化工具。它可以配置系统,部署软件以及协调更高级的IT任务,例如持续部署,滚动更新。Ansible 适用于管理企业IT基础设施,从具有少数主机的小规模到数千个实例的企业环境。Ansible 也是一种简单的自动化语言,可以完美地描述IT应用程序基础结构。
具备以下三个特点:
使用文档:https://releases.ansible.com/ansible/
安装 Ansible:
yum -y install ansible
- [master]
- 192.168.56.11 node_name=k8s-master1
- 192.168.56.12 node_name=k8s-master2
- 192.168.56.13 node_name=k8s-master3
-
- [node]
- 192.168.56.11 node_name=k8s-master1
- 192.168.56.12 node_name=k8s-master2
- 192.168.56.13 node_name=k8s-master3
-
- [k8s:children]
- master
- node
SSH密码认证:
- [webservers]
- 192.168.56.11:22 ansible_ssh_user=root ansible_ssh_pass=centos
- 192.168.56.12:22 ansible_ssh_user=root ansible_ssh_pass=centos
- 192.168.56.13
-
- [dbservers]
- 192.168.56.13
SSH密钥对认证:
- [webservers]
- 192.168.56.11:22 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa
- 192.168.56.12:22 ansible_ssh_user=root
-
- 也可以在配置文件中指定:
- [defaults]
- private_key_file = /root/.ssh/id_rsa # 默认路径
选项 | 描述 |
---|---|
-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 | 提权密码 |
- ansible all -m ping
- ansible all -m shell -a "ls /root" -u root -k
在目标主机执行shell命令。
ansible master -m shell -a "date" -k
将文件复制到远程主机。
ansible master -m copy -a "src=./test.txt dest=/root" -k
管理文件和文件属性。
- // 创建目录
- ansible master -m file -a "path=/tmp/test state=directory" -k
-
- // 删除文件
- ansible master -m file -a "path=/root/test.txt state=absent" -k
-
- //删除目录
- ansible master -m file -a "path=/tmp/test state=absent" -k
软件包管理
present,latest:表示安装
absent:表示卸载
- ansible master -m yum -a "name=wget state=present" -k
- ansible master -m yum -a "name=wget state=absent" -k
管理服务
- ansible master -m systemd -a "name=NetworkManager state=restarted enabled=no daemon_reload=yes" -k
- #state: started
- #state: stopped
- #state: restarted
- #state: reloaded
- ansible master -m file -a "path=/tmp/python state=directory" -k
- ansible master -m unarchive -a "src=/opt/software/Python-3.7.10.tgz dest=/tmp/python" -k
- ansible master -m file -a "path=/tmp/python state=absent" -k
执行过程中打印语句。
- ansible localhost -m debug -a "msg={{ hostvars }}" -k
- ansible master -m debug -a "msg={% for host in master %}ip={{ host.host.ip }}{% if not loop.last %},{% endif %}{% endfor %}" -k
- ansible localhost -m debug -a "msg={{ name }}" -k
变量是应用于多个主机的便捷方式; 实际在主机执行之前,变量会对每个主机添加,然后在执行中引用。
- [master]
- 192.168.56.11 ansible_ssh_user=root hostname=master1
- 192.168.56.12 ansible_ssh_user=root hostname=master2
-
- [master:vars]
- ansible_ssh_user=root hostname=master1
- - shell: date
- register: result
- - debug:
- var: result
Playbooks是Ansible的配置,部署和编排语言。他们可以描述您希望在远程机器做哪些事或者描述IT流程中一系列步骤。使用易读的YAML格式组织Playbook文件。
如果Ansible模块是您工作中的工具,那么Playbook就是您的使用说明书,而您的主机资产文件就是您的原材料。
与命令行执行模式相比,Playbooks使用ansible是一种完全不同的方式,并且功能特别强大。
https://docs.ansible.com/ansible/latest/user_guide/playbooks.html
- ---
- - hosts: master
- vars:
- http_port: 80
- remote_user: root
- gather_facts: false
- tasks:
- - name: 安装wget最新版
- yum: name=wget state=latest
- - name: 打印变量
- debug:
- msg: http_port
- - hosts: webservers
- remote_user: root
Ansible中的首选做法是不将变量存储在Inventory中。
除了将变量直接存储在Inventory文件之外,主机和组变量还可以存储在相对于Inventory文件的单个文件中。
- - hosts: webservers
- vars:
- http_port: 80
每个play包含一系列任务。这些任务按照顺序执行,在play中,所有主机都会执行相同的任务指令。play目的是将选择的主机映射到任务。
- tasks:
- - name: 安装wget最新版
- yum: name=nginx state=latest
语法检查:ansible-playbook --check $path/playbook.yaml
测试运行,不实际操作:ansible-playbook -C $path/playbook.yaml
debug模块在执行期间打印语句,对于调试变量或表达式,而不必停止play。与'when:'指令一起调试更佳。
- - hosts: master
- remote_user: root
- gather_facts: false
- tasks:
- - debug:
- msg: "{{group_names}}"
- - debug:
- msg: "{{inventory_hostname}}"
如果你有一个大的剧本,那么能够在不运行整个剧本的情况下运行特定部分可能会很有用。
- tasks:
- - name: 查看文件
- shell: cat /etc/passwd
- tags: cat
- - name: 查看服务器时间
- shell: date
- tags: date
使用:
- ansible-playbook test.yml --tags "cat"
- ansible-playbook test.yml --tags "date"
- ansible-playbook test.yml --skip-tags "cat"
条件:
- - hosts: master
- remote_user: root
- gather_facts: false
- tasks:
- - name: 只在192.168.56.11运行任务
- debug: msg={{ inventory_hostname }}
- when: inventory_hostname == '192.168.56.11'
循环:
- - hosts: master
- remote_user: root
- gather_facts: false
- tasks:
- - name: 批量复制文件
- copy: src=/etc/ansible/{{ item }} dest=/tmp
- with_items:
- - test1
- - test2
- - test3
常用循环语句:
语句 | 描述 |
---|---|
with_items | 标准循环 |
with_fileglob | 遍历目录文件 |
with_dict | 遍历字典 |
- - hosts: localhost
- remote_user: root
- gather_facts: false
- tasks:
- - name: template
- template: src=/etc/ansible/test.conf.j2 dest=/etc/ansible/test.conf
定义变量:
{% 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的变量。
Roles是基于已知文件结构自动加载某些变量文件,任务和处理程序的方法。按角色对内容进行分组,适合构建复杂的部署环境。
Roles目录结构:
- site.yml
- webservers.yml
- fooservers.yml
- roles/
- common/
- tasks/
- handlers/
- files/
- templates/
- vars/
- defaults/
- meta/
- webservers/
- tasks/files
- files/
- templates/
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
- # 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
- - name: 0.系统初始化
- gather_facts: false
- hosts: all
- roles:
- - common
- tags: common
组变量:
group_vars 存放的是组变量
group_vars/all.yml 表示所有主机有效,等同于[all:vars]
grous_vars/etcd.yml 表示etcd组主机有效,等同于[etcd:vars]
服务器规划
IP | 角色 | 虚拟机配置 | 组件 |
---|---|---|---|
192.168.56.11 | master、node | 2C 4G | kube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy、keepalived、haproxy |
192.168.56.12 | master、node | 2C 3G | kube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy、keepalived、haproxy |
192.168.56.13 | master、node | 2C 3G | kube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy、keepalived、haproxy |
系统初始化
主要包括:关闭防火墙、关闭NetworkManager、关闭selinux、关闭swap分区、时间同步、优化参数等
生成自签证书
k8s推荐的通信方式是双认证通信,也就是客户端与服务端双向认证
需要生成的证书有:etcd证书、k8s证书、以及kube-controller-manager和kube-scheduler与kube-apiserver通信的配置文件等
部署docker
docker建议采用离线包安装
Etcd集群部署
创建目录 --> 分发二进制文件 --> 分发证书 --> 分发配置文件 --> 启动etcd --> 查看状态
部署高可用
keepalived + haproxy
部署Master
部署kube-apiserver、kube-controller-manager、kube-scheduler组件
部署bootstrap
bootstrap主要是用来自动给node颁发证书用的,之前用的都是手动颁发证书,每加入一台node节点需要颁发一次证书
部署Node
部署kubelet和kube-proxy
部署addons
部署Calico、CoreDNS、Dashboard、Metrics
编写建议:
下载Ansible部署文件:
etcd版本:3.4
kubernetes组件版本:1.20.2
- cfssl
- cfssljson
- etcd
- etcdctl
- kube-apiserver
- kube-controller-manager
- kubectl
- kubelet
- kube-proxy
- kube-scheduler
修改hosts文件,根据规划修改对应IP和名称。
- # vim hosts
-
- [master]
- 192.168.56.11 node_name=k8s-master1
- 192.168.56.12 node_name=k8s-master2
- 192.168.56.13 node_name=k8s-master3
-
- [node]
- 192.168.56.11 node_name=k8s-master1
- 192.168.56.12 node_name=k8s-master2
- 192.168.56.13 node_name=k8s-master3
-
- [etcd]
- 192.168.56.11 etcd_name=etcd-1
- 192.168.56.12 etcd_name=etcd-2
- 192.168.56.13 etcd_name=etcd-3
-
- [lb]
- 192.168.56.11 lb_name=lb-master
- 192.168.56.12 lb_name=lb-backup
- 192.168.56.13 lb_name=lb-backup
-
- [k8s:children]
- master
- node
修改group_vars/all.yml文件,修改软件包目录和证书可信任IP。
- # vim group_vars/all.yml
-
- # 相关目录
- tools_dir: '/root/binary_tools' # 二进制文件存放目录
- etcd_work_dir: '/opt/etcd' # ETCD工作目录
- k8s_work_dir: '/opt/k8s' # K8S master节点工作目录
- k8s_node_dir: '/opt/k8s_node' # K8S node节点工作目录
- home_dir: '/root' # 用户home目录
- tmp_dir: '/tmp/k8s' # 临时目录
-
- # 时间同步服务器
- time_server: '192.168.56.118'
-
- # crontab文件
- cron: /var/spool/cron/root
-
- # 安装docker
- docker: docker
-
- # 集群网络
- service_cidr: '10.96.0.0/16' # service网段
- cluster_first_ip: '10.96.0.1' # service网段第一个IP
- cluster_dns: '10.96.0.10' # dns IP
- pod_cidr: '172.16.0.0/16' # pod网段
- service_nodeport_range: '30000-32767' # 端口范围
- cluster_domain: 'cluster.local' # 集群域名
-
- # bootstrap信息
- token_id: c8ad9c
- token_secret: 2e4d610cf3e7426e
架构图
部署命令
ansible-playbook -i hosts deploy.yml -uroot -k
集群清理命令clean
ansible-playbook -i hosts clean.yml -uroot -k
如果安装某个阶段失败,可针对性测试.
例如:只运行部署插件
ansible-playbook -i hosts deploy.yml -uroot -k --tags addons
1 验证集群
安装集群之后,第一时间先验证集群是否正常
创建一个pod
- cat<<EOF | kubectl apply -f -
- apiVersion: v1
- kind: Pod
- metadata:
- name: busybox
- namespace: default
- spec:
- containers:
- - name: busybox
- image: busybox:1.28
- command:
- - sleep
- - "3600"
- imagePullPolicy: IfNotPresent
- restartPolicy: Always
- EOF
验证
- # kubectl exec busybox -n default -- nslookup kubernetes
- Server: 10.96.0.10
- Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
-
- Name: kubernetes
- Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
- # kubectl exec busybox -n default -- nslookup kube-dns.kube-system
- Server: 10.96.0.10
- Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
-
- Name: kube-dns.kube-system
- Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
2 kubelet报错
如果之前有部署过k8s集群,再次部署有可能部署不成功的情况,报错信息一般是kubelet报错,需要删除节点的/var/lib/kubelet目录,然后再删除的时候报错,无法删除,则可以通过以下方法删除:
无法删除/var/lib/kubelet目录
- [root@k8s-node2 k8s_node]# rm -rf /var/lib/kubelet
- rm: cannot remove ‘/var/lib/kubelet/pods/0552a913-ea4a-4b91-84a7-87ca6d9f8611/volumes/kubernetes.io~secret/etcd-certs’: Device or resource busy
- rm: cannot remove ‘/var/lib/kubelet/pods/0552a913-ea4a-4b91-84a7-87ca6d9f8611/volumes/kubernetes.io~secret/calico-node-token-7jrks’: Device or resource busy
- rm: cannot remove ‘/var/lib/kubelet/pods/ea2b55a3-0891-4965-a64d-2f27b7d29bf6/volumes/kubernetes.io~secret/etcd-certs’: Device or resource busy
- rm: cannot remove ‘/var/lib/kubelet/pods/ea2b55a3-0891-4965-a64d-2f27b7d29bf6/volumes/kubernetes.io~secret/calico-kube-controllers-token-sgpr9’: Device or resource busy
- rm: cannot remove ‘/var/lib/kubelet/pods/cc699261-f1a5-4c8d-913f-9af943bc4117/volumes/kubernetes.io~secret/coredns-token-rnb5t’: Device or resource busy
- rm: cannot remove ‘/var/lib/kubelet/pods/4533016b-95bf-4376-a3a0-57d8c2b37fc8/volumes/kubernetes.io~secret/kubernetes-dashboard-token-nzqr8’: Device or resource busy
- rm: cannot remove ‘/var/lib/kubelet/pods/2b1e0ff1-23e7-412a-a1f3-a6b6d8c5c991/volumes/kubernetes.io~secret/kubernetes-dashboard-certs’: Device or resource busy
- rm: cannot remove ‘/var/lib/kubelet/pods/2b1e0ff1-23e7-412a-a1f3-a6b6d8c5c991/volumes/kubernetes.io~secret/kubernetes-dashboard-token-nzqr8’: Device or resource busy
查看挂载信息
- [root@k8s-node2 k8s_node]# df -HT | grep '/var/lib/kubelet/pods'
- tmpfs tmpfs 1.5G 0 1.5G 0% /var/lib/kubelet/pods/0552a913-ea4a-4b91-84a7-87ca6d9f8611/volumes/kubernetes.io~secret/etcd-certs
- tmpfs tmpfs 1.5G 13k 1.5G 1% /var/lib/kubelet/pods/0552a913-ea4a-4b91-84a7-87ca6d9f8611/volumes/kubernetes.io~secret/calico-node-token-7jrks
- tmpfs tmpfs 1.5G 13k 1.5G 1% /var/lib/kubelet/pods/cc699261-f1a5-4c8d-913f-9af943bc4117/volumes/kubernetes.io~secret/coredns-token-rnb5t
- tmpfs tmpfs 1.5G 13k 1.5G 1% /var/lib/kubelet/pods/ea2b55a3-0891-4965-a64d-2f27b7d29bf6/volumes/kubernetes.io~secret/etcd-certs
- tmpfs tmpfs 1.5G 13k 1.5G 1% /var/lib/kubelet/pods/ea2b55a3-0891-4965-a64d-2f27b7d29bf6/volumes/kubernetes.io~secret/calico-kube-controllers-token-sgpr9
- tmpfs tmpfs 1.5G 0 1.5G 0% /var/lib/kubelet/pods/2b1e0ff1-23e7-412a-a1f3-a6b6d8c5c991/volumes/kubernetes.io~secret/kubernetes-dashboard-certs
- tmpfs tmpfs 1.5G 13k 1.5G 1% /var/lib/kubelet/pods/2b1e0ff1-23e7-412a-a1f3-a6b6d8c5c991/volumes/kubernetes.io~secret/kubernetes-dashboard-token-nzqr8
- tmpfs tmpfs 1.5G 13k 1.5G 1% /var/lib/kubelet/pods/4533016b-95bf-4376-a3a0-57d8c2b37fc8/volumes/kubernetes.io~secret/kubernetes-dashboard-token-nzqr8
umount这些挂在,然后再删除
- [root@k8s-node2 k8s_node]# umount $(df -HT | grep '/var/lib/kubelet/pods' | awk '{print $7}')
-
- # 已查不到挂载信息,再次删除目录则不再报错
- [root@k8s-node2 k8s_node]# df -HT | grep '/var/lib/kubelet/pods'
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。