草庐IT

Ansible自动化部署K8S集群

赵承胜博客 2023-03-28 原文

一、Ansible自动化部署K8S集群

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 主机清单

[webservers]
192.168.20.232
192.168.20.233
192.168.20.234
192.168.20.235
192.168.20.236

[dbservers]
db01.intranet.mydomain.net
db02.intranet.mydomain.net
10.25.1.232
10.25.1.233
ssh-keygen -t rsa
ssh-copy-id -i /root/.ssh/id_rsa.pub -p '20100' 'root@192.168.20.231'
ssh-copy-id -i /root/.ssh/id_rsa.pub -p '20100' 'root@192.168.20.232'
ssh-copy-id -i /root/.ssh/id_rsa.pub -p '20100' 'root@192.168.20.23
chown 0700 -R /root/.ssh/
cat /root/.ssh/id_rsa.pub > /root/.ssh/authorized_keys
chown root.root -R /root/.ssh/
cd /root/.ssh/
sed -i "s/#host_key_checking = .*/host_key_checking = False/g" /etc/ansible/ansible.cfg

1.3 命令行使用

1、连接远程主机认证

SSH密码认证:

[webservers]
192.168.20.232:20100 ansible_ssh_user=root ansible_ssh_pass=’200271200’
192.168.20.233:20100 ansible_ssh_user=root ansible_ssh_pass=’200271200’
192.168.20.234:20100 ansible_ssh_user=root ansible_ssh_port=’200271200’

[dbservers]
db01.intranet.mydomain.net
db02.intranet.mydomain.net
10.25.1.56
10.25.1.57
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

也可以在配置文件中指定:
[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

1.4 常用模块

ansible-doc –l 查看所有模块

ansible-doc –s copy 查看模块文档

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

软件包管理。

ansible webservers -m yum -a "name=http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.1-1.el7.ngx.x86_64.rpm state=present"


ansible webservers -m systemd -a "name=http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.1-1.el7.ngx.x86_64.rpm state=restarted enabled=yes"






- 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/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
# name: /usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm
state: present

5、service/systemd

管理服务。

- name: 服务管理
service:
name: httpd
state: started
#state: stopped
#state: restarted
#state: reloaded
- name: 设置开机启动
service:
name: httpd
enabled: 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 变量

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

1、主机变量与组变量

[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

2、Register变量

- shell: /usr/bin/uptime
register: result
- debug:
var: result
verbosity: 2

1.6 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: root
become: yes
become_user: lizhenliang

2、定义变量

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

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

- hosts: webservers
vars:
http_port: 80
server_name: www.ctnrs.com

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:'指令一起调试更佳。

- hosts: webserver
tasks:
- debug:
msg: {{group_names}}
- debug:
msg: {{inventory_hostname}}
- debug:
msg: {{ansible_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、模板

tasks:
- name: 写入nginx配置文件
template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.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的变量。

1.7 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

4、定义变量

组变量:

group_vars 存放的是组变量

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

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

1.8 自动化部署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. 系统初始化
  2. Etcd集群部署
  1. 生成etcd证书
  2. 部署三个Etc集群
  3. 查看集群状态
  1. 部署Master
  1. 生成apiserver证书
  2. 部署apiserver、controller-manager和scheduler组件
  3. 启动TLS Bootstrapping
  1. 部署Node
  1. 安装Docker
  2. 部署kubelet和kube-proxy
  3. 在Master上允许为新Node颁发证书
  4. 授权apiserver访问kubelet
  1. 部署插件(准备好镜像)
  1. Flannel
  2. Web UI
  3. CoreDNS
  4. Ingress Controller
  1. 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

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​


有关Ansible自动化部署K8S集群的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  4. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  5. ruby - 在 ruby​​ 中使用自动创建插入数组 - 2

    我想知道是否可以通过自动创建数组来插入数组,如果数组不存在的话,就像在PHP中一样:$toto[]='titi';如果尚未定义$toto,它将创建数组并将“titi”压入。如果已经存在,它只会推送。在Ruby中我必须这样做:toto||=[]toto.push('titi')可以一行完成吗?因为如果我有一个循环,它会测试“||=”,除了第一次:Person.all.eachdo|person|toto||=[]#with1billionofperson,thislineisuseless999999999times...toto.push(person.name)你有更好的解决方案吗?

  6. 【自动驾驶环境感知项目】——基于Paddle3D的点云障碍物检测 - 2

    文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3

  7. ruby-on-rails - 自动完成搜索的 Rails 实现 - 2

    我不确定如何为我的搜索功能添加自动完成表单。"get"do%>nil%>我有一个具有自定义操作的Controllerdefquery@users=Search.user(params[:query])@article=Search.article(params[:query])end模型如下:defself.user(search)ifsearchUser.find(:all,:conditions=>['first_nameLIKE?',"%#{search}%"])elseUser.find(:all)endenddefself.article(search)ifsearchArt

  8. ruby - 如何设置自动测试以仅重新运行失败的 rspec 示例 - 2

    我对自动测试的工作方式的印象(基于cucumbergithubwiki和其他在线内容)是它应该重新运行红色示例,直到它们通过。我的问题是它会重新运行规范文件中找到失败示例的所有示例,包括通过的示例。我不想浪费时间在修复失败示例的同时重新运行通过的示例。是否可以配置自动测试以便仅运行失败的示例? 最佳答案 您需要rspec-retrygem。以下是文档中有关如何实现它的一些示例:将它应用到覆盖整个测试套件的configureblock中...RSpec.configuredo|config|config.verbose_retry=t

  9. ruby - 在多个线程中引用类方法会导致自动加载循环依赖崩溃 - 2

    代码:threads=[]Thread.abort_on_exception=truebegin#throwexceptionsinthreadssowecanseethemthreadseputs"EXCEPTION:#{e.inspect}"puts"MESSAGE:#{e.message}"end崩溃:.rvm/gems/ruby-2.1.3@req/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:478:inload_missing_constant':自动加载常量MyClass时检测到循环依赖稍加研究后,

  10. ruby - 自动将院子文档框架添加到现有的 Rails 遗留代码中 - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭4年前。Improvethisquestion我希望能够将模板化的YARD文档样式注释插入到我现有的Rails遗留应用程序中。目前它的评论很少。我想要具有指定参数的类header和方法header(通过从我假定的方法签名中提取)和返回值的占位符。在PHP代码中,我有一些工具可以检查代码并在适当的位置创建插入到代码中的文档header注释。在带有Ducktyping等的Ruby中,我确信诸如@params等类型之类

随机推荐