当前位置:   article > 正文

Ansible自动化部署高可用K8S集群_ansible kubectl apply

ansible kubectl apply

1.1 Ansible介绍

Ansible 是一种IT自动化工具。它可以配置系统,部署软件以及协调更高级的IT任务,例如持续部署,滚动更新。Ansible 适用于管理企业IT基础设施,从具有少数主机的小规模到数千个实例的企业环境。Ansible 也是一种简单的自动化语言,可以完美地描述IT应用程序基础结构。

具备以下三个特点:

  • 简单:减少学习成本
  • 强大:协调应用程序生命周期
  • 无代理:可预测,可靠和安全

使用文档:https://releases.ansible.com/ansible/

安装 Ansible:

yum -y install ansible

  • Inventory:Ansible管理的主机信息,包括IP地址、SSH端口、账号、密码等
  • Modules:任务均有模块完成,也可以自定义模块,例如经常用的脚本。
  • Plugins:使用插件增加Ansible核心功能,自身提供了很多插件,也可以自定义插件。例如connection插件,用于连接目标主机。
  • Playbooks:“剧本”,模块化定义一系列任务,供外部统一调用。Ansible核心功能。

1.2 主机清单

  1. [master]
  2. 192.168.56.11 node_name=k8s-master1
  3. 192.168.56.12 node_name=k8s-master2
  4. 192.168.56.13 node_name=k8s-master3
  5. [node]
  6. 192.168.56.11 node_name=k8s-master1
  7. 192.168.56.12 node_name=k8s-master2
  8. 192.168.56.13 node_name=k8s-master3
  9. [k8s:children]
  10. master
  11. node

1.3 命令行使用

1、连接远程主机认证

SSH密码认证:

  1. [webservers]
  2. 192.168.56.11:22 ansible_ssh_user=root ansible_ssh_pass=centos
  3. 192.168.56.12:22 ansible_ssh_user=root ansible_ssh_pass=centos
  4. 192.168.56.13
  5. [dbservers]
  6. 192.168.56.13

SSH密钥对认证:

  1. [webservers]
  2. 192.168.56.11:22 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa
  3. 192.168.56.12:22 ansible_ssh_user=root
  4. 也可以在配置文件中指定:
  5. [defaults]
  6. private_key_file = /root/.ssh/id_rsa # 默认路径

2、常用选项

选项描述
-C, --check运行检查,不执行任何操作
-e EXTRA_VARS,--extra-vars=EXTRA_VARS设置附加变量 key=value
-u REMOTE_USER, --user=REMOTE_USERSSH连接用户,默认None
-k, --ask-passSSH连接用户密码
-b, --become提权,默认root
-K, --ask-become-pass提权密码

3、命令行使用

  1. ansible all -m ping
  2. ansible all -m shell -a "ls /root" -u root -k

1.4 常用模块

1、shell

在目标主机执行shell命令。

ansible master -m shell -a "date" -k

2、copy

将文件复制到远程主机。

ansible master -m copy -a "src=./test.txt dest=/root" -k

3、file

管理文件和文件属性。

  1. // 创建目录
  2. ansible master -m file -a "path=/tmp/test state=directory" -k
  3. // 删除文件
  4. ansible master -m file -a "path=/root/test.txt state=absent" -k
  5. //删除目录
  6. ansible master -m file -a "path=/tmp/test state=absent" -k

4、yum

软件包管理

present,latest:表示安装

absent:表示卸载

  1. ansible master -m yum -a "name=wget state=present" -k
  2. ansible master -m yum -a "name=wget state=absent" -k

5、service/systemd

管理服务

  1. ansible master -m systemd -a "name=NetworkManager state=restarted enabled=no daemon_reload=yes" -k
  2. #state: started
  3. #state: stopped
  4. #state: restarted
  5. #state: reloaded

6、unarchive

  1. ansible master -m file -a "path=/tmp/python state=directory" -k
  2. ansible master -m unarchive -a "src=/opt/software/Python-3.7.10.tgz dest=/tmp/python" -k
  3. ansible master -m file -a "path=/tmp/python state=absent" -k

7、debug

执行过程中打印语句。

  1. ansible localhost -m debug -a "msg={{ hostvars }}" -k
  2. ansible master -m debug -a "msg={% for host in master %}ip={{ host.host.ip }}{% if not loop.last %},{% endif %}{% endfor %}" -k
  3. ansible localhost -m debug -a "msg={{ name }}" -k

1.5 变量

变量是应用于多个主机的便捷方式; 实际在主机执行之前,变量会对每个主机添加,然后在执行中引用。

1、主机变量与组变量

  1. [master]
  2. 192.168.56.11 ansible_ssh_user=root hostname=master1
  3. 192.168.56.12 ansible_ssh_user=root hostname=master2
  4. [master:vars]
  5. ansible_ssh_user=root hostname=master1

2、Register变量

  1. - shell: date
  2. register: result
  3. - debug:
  4. var: result

1.6 Playbook

Playbooks是Ansible的配置,部署和编排语言。他们可以描述您希望在远程机器做哪些事或者描述IT流程中一系列步骤。使用易读的YAML格式组织Playbook文件。

如果Ansible模块是您工作中的工具,那么Playbook就是您的使用说明书,而您的主机资产文件就是您的原材料。

与命令行执行模式相比,Playbooks使用ansible是一种完全不同的方式,并且功能特别强大。

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

  1. ---
  2. - hosts: master
  3. vars:
  4. http_port: 80
  5. remote_user: root
  6. gather_facts: false
  7. tasks:
  8. - name: 安装wget最新版
  9. yum: name=wget state=latest
  10. - name: 打印变量
  11. debug:
  12. msg: http_port

1、主机和用户

  1. - hosts: webservers
  2. remote_user: root

2、定义变量

Ansible中的首选做法是不将变量存储在Inventory中。

除了将变量直接存储在Inventory文件之外,主机和组变量还可以存储在相对于Inventory文件的单个文件中。

  1. - hosts: webservers
  2. vars:
  3. http_port: 80

3、任务列表

每个play包含一系列任务。这些任务按照顺序执行,在play中,所有主机都会执行相同的任务指令。play目的是将选择的主机映射到任务。

  1. tasks:
  2. - name: 安装wget最新版
  3. yum: name=nginx state=latest

4、语法检查与调试

语法检查:ansible-playbook --check $path/playbook.yaml

测试运行,不实际操作:ansible-playbook -C $path/playbook.yaml

debug模块在执行期间打印语句,对于调试变量或表达式,而不必停止play。与'when:'指令一起调试更佳。

  1. - hosts: master
  2. remote_user: root
  3. gather_facts: false
  4. tasks:
  5. - debug:
  6. msg: "{{group_names}}"
  7. - debug:
  8. msg: "{{inventory_hostname}}"

5、任务控制

如果你有一个大的剧本,那么能够在不运行整个剧本的情况下运行特定部分可能会很有用。

  1. tasks:
  2. - name: 查看文件
  3. shell: cat /etc/passwd
  4. tags: cat
  5. - name: 查看服务器时间
  6. shell: date
  7. tags: date

使用:

  1. ansible-playbook test.yml --tags "cat"
  2. ansible-playbook test.yml --tags "date"
  3. ansible-playbook test.yml --skip-tags "cat"

6、流程控制

条件:

  1. - hosts: master
  2. remote_user: root
  3. gather_facts: false
  4. tasks:
  5. - name: 只在192.168.56.11运行任务
  6. debug: msg={{ inventory_hostname }}
  7. when: inventory_hostname == '192.168.56.11'

循环:

  1. - hosts: master
  2. remote_user: root
  3. gather_facts: false
  4. tasks:
  5. - name: 批量复制文件
  6. copy: src=/etc/ansible/{{ item }} dest=/tmp
  7. with_items:
  8. - test1
  9. - test2
  10. - test3

常用循环语句:

语句描述
with_items标准循环
with_fileglob遍历目录文件
with_dict遍历字典

7、模板

  1. - hosts: localhost
  2. remote_user: root
  3. gather_facts: false
  4. tasks:
  5. - name: template
  6. template: src=/etc/ansible/test.conf.j2 dest=/etc/ansible/test.conf

定义变量

{% set local_ip = inventory_hostname %}

条件和循环

  1. {% set list=['one', 'two', 'three'] %}
  2. {% for i in list %}
  3. {% if i == 'two' %}
  4. -> two
  5. {% elif loop.index == 3 %}
  6. -> 3
  7. {% else %}
  8. {{i}}
  9. {% endif %}
  10. {% endfor %}

例如:生成连接etcd字符串

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

里面也可以用ansible的变量。

1.7 Roles

Roles是基于已知文件结构自动加载某些变量文件,任务和处理程序的方法。按角色对内容进行分组,适合构建复杂的部署环境。

1、定义Roles

Roles目录结构:

  1. site.yml
  2. webservers.yml
  3. fooservers.yml
  4. roles/
  5. common/
  6. tasks/
  7. handlers/
  8. files/
  9. templates/
  10. vars/
  11. defaults/
  12. meta/
  13. webservers/
  14. tasks/files
  15. files/
  16. templates/
  • tasks -包含角色要执行的任务的主要列表。
  • handlers -包含处理程序,此角色甚至在此角色之外的任何地方都可以使用这些处理程序。
  • defaults-角色的默认变量
  • vars-角色的其他变量
  • files -包含可以通过此角色部署的文件。
  • templates -包含可以通过此角色部署的模板。
  • meta-为此角色定义一些元数据。请参阅下面的更多细节。

通常的做法是从tasks/main.yml文件中包含特定于平台的任务:

  1. # roles/webservers/tasks/main.yml
  2. - name: added in 2.4, previously you used 'include'
  3. import_tasks: redhat.yml
  4. when: ansible_facts['os_family']|lower == 'redhat'
  5. - import_tasks: debian.yml
  6. when: ansible_facts['os_family']|lower == 'debian'
  7. # roles/webservers/tasks/redhat.yml
  8. - yum:
  9. name: "httpd"
  10. state: present
  11. # roles/webservers/tasks/debian.yml
  12. - apt:
  13. name: "apache2"
  14. state: present

2、使用角色

  1. # site.yml
  2. - hosts: webservers
  3. roles:
  4. - common
  5. - webservers
  6. 定义多个:
  7. - name: 0
  8. gather_facts: false
  9. hosts: all
  10. roles:
  11. - common
  12. - name: 1
  13. gather_facts: false
  14. hosts: all
  15. roles:
  16. - webservers

3、角色控制

  1. - name: 0.系统初始化
  2. gather_facts: false
  3. hosts: all
  4. roles:
  5. - common
  6. tags: common

4、定义变量

组变量:

group_vars 存放的是组变量

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

grous_vars/etcd.yml 表示etcd组主机有效,等同于[etcd:vars]

1.8 自动化部署K8S

1、 熟悉二进制部署K8S步骤

  1. 服务器规划

    IP角色虚拟机配置组件
    192.168.56.11master、node2C 4Gkube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy、keepalived、haproxy
    192.168.56.12master、node2C 3Gkube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy、keepalived、haproxy
    192.168.56.13master、node2C 3Gkube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy、keepalived、haproxy
  2. 系统初始化

    主要包括:关闭防火墙、关闭NetworkManager、关闭selinux、关闭swap分区、时间同步、优化参数等

  3. 生成自签证书

    k8s推荐的通信方式是双认证通信,也就是客户端与服务端双向认证

    需要生成的证书有:etcd证书、k8s证书、以及kube-controller-manager和kube-scheduler与kube-apiserver通信的配置文件等

  4. 部署docker

    docker建议采用离线包安装

  5. Etcd集群部署

    创建目录 --> 分发二进制文件 --> 分发证书 --> 分发配置文件 --> 启动etcd --> 查看状态

  6. 部署高可用

    keepalived + haproxy

  7. 部署Master

    部署kube-apiserver、kube-controller-manager、kube-scheduler组件

  8. 部署bootstrap

    bootstrap主要是用来自动给node颁发证书用的,之前用的都是手动颁发证书,每加入一台node节点需要颁发一次证书

  9. 部署Node

    部署kubelet和kube-proxy

  10. 部署addons

    部署Calico、CoreDNS、Dashboard、Metrics

2、Roles组织K8S各组件部署解析

编写建议:

  1. 梳理流程和Roles结构
  2. 如果配置文件有不固定内容,使用jinja渲染
  3. 人工干预改动的内容应统一写到一个文件中

3、下载所需文件

下载Ansible部署文件:

etcd版本:3.4

kubernetes组件版本:1.20.2

  1. cfssl
  2. cfssljson
  3. etcd
  4. etcdctl
  5. kube-apiserver
  6. kube-controller-manager
  7. kubectl
  8. kubelet
  9. kube-proxy
  10. kube-scheduler

4、修改Ansible文件

修改hosts文件,根据规划修改对应IP和名称。

  1. # vim hosts
  2. [master]
  3. 192.168.56.11 node_name=k8s-master1
  4. 192.168.56.12 node_name=k8s-master2
  5. 192.168.56.13 node_name=k8s-master3
  6. [node]
  7. 192.168.56.11 node_name=k8s-master1
  8. 192.168.56.12 node_name=k8s-master2
  9. 192.168.56.13 node_name=k8s-master3
  10. [etcd]
  11. 192.168.56.11 etcd_name=etcd-1
  12. 192.168.56.12 etcd_name=etcd-2
  13. 192.168.56.13 etcd_name=etcd-3
  14. [lb]
  15. 192.168.56.11 lb_name=lb-master
  16. 192.168.56.12 lb_name=lb-backup
  17. 192.168.56.13 lb_name=lb-backup
  18. [k8s:children]
  19. master
  20. node

修改group_vars/all.yml文件,修改软件包目录和证书可信任IP。

  1. # vim group_vars/all.yml
  2. # 相关目录
  3. tools_dir: '/root/binary_tools' # 二进制文件存放目录
  4. etcd_work_dir: '/opt/etcd' # ETCD工作目录
  5. k8s_work_dir: '/opt/k8s' # K8S master节点工作目录
  6. k8s_node_dir: '/opt/k8s_node' # K8S node节点工作目录
  7. home_dir: '/root' # 用户home目录
  8. tmp_dir: '/tmp/k8s' # 临时目录
  9. # 时间同步服务器
  10. time_server: '192.168.56.118'
  11. # crontab文件
  12. cron: /var/spool/cron/root
  13. # 安装docker
  14. docker: docker
  15. # 集群网络
  16. service_cidr: '10.96.0.0/16' # service网段
  17. cluster_first_ip: '10.96.0.1' # service网段第一个IP
  18. cluster_dns: '10.96.0.10' # dns IP
  19. pod_cidr: '172.16.0.0/16' # pod网段
  20. service_nodeport_range: '30000-32767' # 端口范围
  21. cluster_domain: 'cluster.local' # 集群域名
  22. # bootstrap信息
  23. token_id: c8ad9c
  24. token_secret: 2e4d610cf3e7426e

5、一键部署

架构图

部署命令

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

集群清理命令clean

ansible-playbook -i hosts clean.yml -uroot -k

6、部署控制

如果安装某个阶段失败,可针对性测试.

例如:只运行部署插件

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

7、注意事项

1 验证集群

安装集群之后,第一时间先验证集群是否正常

创建一个pod

  1. cat<<EOF | kubectl apply -f -
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: busybox
  6. namespace: default
  7. spec:
  8. containers:
  9. - name: busybox
  10. image: busybox:1.28
  11. command:
  12. - sleep
  13. - "3600"
  14. imagePullPolicy: IfNotPresent
  15. restartPolicy: Always
  16. EOF

验证

  1. # kubectl exec busybox -n default -- nslookup kubernetes
  2. Server: 10.96.0.10
  3. Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
  4. Name: kubernetes
  5. Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
  6. # kubectl exec busybox -n default -- nslookup kube-dns.kube-system
  7. Server: 10.96.0.10
  8. Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
  9. Name: kube-dns.kube-system
  10. Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

2 kubelet报错

如果之前有部署过k8s集群,再次部署有可能部署不成功的情况,报错信息一般是kubelet报错,需要删除节点的/var/lib/kubelet目录,然后再删除的时候报错,无法删除,则可以通过以下方法删除:

无法删除/var/lib/kubelet目录

  1. [root@k8s-node2 k8s_node]# rm -rf /var/lib/kubelet
  2. rm: cannot remove ‘/var/lib/kubelet/pods/0552a913-ea4a-4b91-84a7-87ca6d9f8611/volumes/kubernetes.io~secret/etcd-certs’: Device or resource busy
  3. rm: cannot remove ‘/var/lib/kubelet/pods/0552a913-ea4a-4b91-84a7-87ca6d9f8611/volumes/kubernetes.io~secret/calico-node-token-7jrks’: Device or resource busy
  4. rm: cannot remove ‘/var/lib/kubelet/pods/ea2b55a3-0891-4965-a64d-2f27b7d29bf6/volumes/kubernetes.io~secret/etcd-certs’: Device or resource busy
  5. 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
  6. rm: cannot remove ‘/var/lib/kubelet/pods/cc699261-f1a5-4c8d-913f-9af943bc4117/volumes/kubernetes.io~secret/coredns-token-rnb5t’: Device or resource busy
  7. rm: cannot remove ‘/var/lib/kubelet/pods/4533016b-95bf-4376-a3a0-57d8c2b37fc8/volumes/kubernetes.io~secret/kubernetes-dashboard-token-nzqr8’: Device or resource busy
  8. rm: cannot remove ‘/var/lib/kubelet/pods/2b1e0ff1-23e7-412a-a1f3-a6b6d8c5c991/volumes/kubernetes.io~secret/kubernetes-dashboard-certs’: Device or resource busy
  9. rm: cannot remove ‘/var/lib/kubelet/pods/2b1e0ff1-23e7-412a-a1f3-a6b6d8c5c991/volumes/kubernetes.io~secret/kubernetes-dashboard-token-nzqr8’: Device or resource busy

查看挂载信息

  1. [root@k8s-node2 k8s_node]# df -HT | grep '/var/lib/kubelet/pods'
  2. tmpfs tmpfs 1.5G 0 1.5G 0% /var/lib/kubelet/pods/0552a913-ea4a-4b91-84a7-87ca6d9f8611/volumes/kubernetes.io~secret/etcd-certs
  3. 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
  4. tmpfs tmpfs 1.5G 13k 1.5G 1% /var/lib/kubelet/pods/cc699261-f1a5-4c8d-913f-9af943bc4117/volumes/kubernetes.io~secret/coredns-token-rnb5t
  5. tmpfs tmpfs 1.5G 13k 1.5G 1% /var/lib/kubelet/pods/ea2b55a3-0891-4965-a64d-2f27b7d29bf6/volumes/kubernetes.io~secret/etcd-certs
  6. 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
  7. tmpfs tmpfs 1.5G 0 1.5G 0% /var/lib/kubelet/pods/2b1e0ff1-23e7-412a-a1f3-a6b6d8c5c991/volumes/kubernetes.io~secret/kubernetes-dashboard-certs
  8. 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
  9. 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这些挂在,然后再删除

  1. [root@k8s-node2 k8s_node]# umount $(df -HT | grep '/var/lib/kubelet/pods' | awk '{print $7}')
  2. # 已查不到挂载信息,再次删除目录则不再报错
  3. [root@k8s-node2 k8s_node]# df -HT | grep '/var/lib/kubelet/pods'
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号