CentOS 7.9 使用 Ansible 一键自动化部署 Kubernetes 集群
·
文章目录
前言
在传统的 Kubernetes 部署中,手动执行 kubeadm init、安装网络插件、配置节点等步骤不仅繁琐,还极易出错。为了提升运维效率,我采用 Ansible 编写了一套自动化部署剧本,实现了一条命令完成 K8s 集群搭建。
本文基于 CentOS 7.9 环境,IP 规划为 10.8.0.30(Master)、10.8.0.40 和 10.8.0.70(Worker)。Kubernetes 版本选用 v1.28.2,容器运行时为 containerd,网络插件为 Calico。
一、环境准备
1.1 节点规划
| 角色 | 主机名 | IP 地址 |
|---|---|---|
| Master | master | 10.8.0.30 |
| Worker | node01 | 10.8.0.40 |
| Worker | node02 | 10.8.0.70 |
1.2 修改主机名与 hosts 解析
# Master 节点
hostnamectl set-hostname master
# Worker1
hostnamectl set-hostname node01
# Worker2
hostnamectl set-hostname node02
# 所有节点配置 hosts
cat >> /etc/hosts <<EOF
10.8.0.30 master
10.8.0.40 node01
10.8.0.70 node02
EOF

1.3 关闭防火墙、SELinux、swap
systemctl stop firewalld
setenforce 0
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
二、在 Master 节点上安装 Ansible
2.1 安装Ansible
# 安装 EPEL 源
yum install -y epel-release
# 安装 Ansible
yum install -y ansible
# 验证
ansible --version

2.2 配置 SSH 免密登录
# 生成密钥
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
# 拷贝公钥到自身(用于 localhost 连接,也可直接免密)
ssh-copy-id root@10.8.0.30
# 拷贝到 Worker
ssh-copy-id root@10.8.0.40
ssh-copy-id root@10.8.0.70
# 测试免密
ssh root@10.8.0.30 "hostname" # 应输出 master
ssh root@10.8.0.40 "hostname" # 输出 node01
ssh root@10.8.0.70 "hostname" # 输出 node02


三、配置文件内容
vim /root/ansible-k8s/ansible.cfg
[defaults]
inventory = ./inventory
host_key_checking = False
remote_user = root
timeout = 30
vim /root/ansible-k8s/inventory
[masters]
master ansible_host=127.0.0.1 ansible_connection=local
[workers]
node01 ansible_host=10.8.0.40
node02 ansible_host=10.8.0.70
[all:vars]
master_ip = 10.8.0.30
k8s_version = 1.28.2
pod_network_cidr = 10.244.0.0/16
container_runtime = containerd
network_plugin = calico
image_repository = registry.aliyuncs.com/google_containers
vim /root/ansible-k8s/group_vars/all.yml
---
kube_version: "1.28.2"
pod_network_cidr: "10.244.0.0/16"
service_cidr: "10.96.0.0/12"
container_runtime: "containerd"
network_plugin: "calico"
image_repository: "registry.aliyuncs.com/google_containers"



四、任务编写
4.1 Role: common
vim /root/ansible-k8s/roles/common/tasks/main.yml
---
- name: 关闭 firewalld
systemd:
name: firewalld
state: stopped
enabled: no
- name: 禁用 SELinux
selinux:
state: disabled
- name: 关闭 swap
command: swapoff -a
when: ansible_swaptotal_mb > 0
- name: 永久注释 swap
replace:
path: /etc/fstab
regexp: '^.*swap.*$'
replace: '# \g<0>'
when: ansible_swaptotal_mb > 0
- name: 加载内核模块
modprobe:
name: "{{ item }}"
state: present
loop:
- overlay
- br_netfilter
- name: 配置内核参数
sysctl:
name: "{{ item.name }}"
value: "{{ item.value }}"
state: present
reload: yes
loop:
- { name: net.bridge.bridge-nf-call-iptables, value: 1 }
- { name: net.bridge.bridge-nf-call-ip6tables, value: 1 }
- { name: net.ipv4.ip_forward, value: 1 }
- { name: vm.swappiness, value: 0 }
- name: 安装基础工具
yum:
name:
- yum-utils
- device-mapper-persistent-data
- lvm2
- wget
- vim
state: present
- name: 添加 Kubernetes YUM 源(阿里云)
yum_repository:
name: kubernetes
description: Kubernetes YUM repo
baseurl: https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled: yes
gpgcheck: yes
repo_gpgcheck: yes
gpgkey: https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
- name: 安装 kubeadm、kubelet、kubectl
yum:
name:
- kubeadm-{{ kube_version }}-0
- kubelet-{{ kube_version }}-0
- kubectl-{{ kube_version }}-0
state: present
allow_downgrade: yes
- name: 配置 kubelet 使用 systemd cgroup
lineinfile:
path: /etc/sysconfig/kubelet
line: 'KUBELET_EXTRA_ARGS="--cgroup-driver=systemd --runtime-request-timeout=15m"'
create: yes
regexp: '^KUBELET_EXTRA_ARGS='
# ---------- 安装 containerd ----------
- name: 安装 EPEL 源
yum:
name: epel-release
state: present
- name: 添加 Docker-CE 源(用于 containerd.io)
yum_repository:
name: docker-ce
description: Docker CE Stable
baseurl: https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable
enabled: yes
gpgcheck: yes
gpgkey: https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
- name: 安装 containerd.io
yum:
name: containerd.io
state: present
- name: 创建 containerd 配置目录
file:
path: /etc/containerd
state: directory
- name: 生成默认配置
command: containerd config default > /etc/containerd/config.toml
args:
creates: /etc/containerd/config.toml
- name: 启用 systemd cgroup
replace:
path: /etc/containerd/config.toml
regexp: 'SystemdCgroup = false'
replace: 'SystemdCgroup = true'
- name: 修改 pause 镜像为阿里云
replace:
path: /etc/containerd/config.toml
regexp: 'registry.k8s.io/pause'
replace: 'registry.aliyuncs.com/google_containers/pause'
- name: 启动 containerd
systemd:
name: containerd
state: started
enabled: yes
4.2 Role: master
vim /root/ansible-k8s/roles/master/tasks/main.yml
---
- name: 预拉取镜像
command: >
kubeadm config images pull
--image-repository={{ image_repository }}
--kubernetes-version=v{{ kube_version }}
- name: 初始化集群
command: >
kubeadm init
--apiserver-advertise-address={{ master_ip }}
--pod-network-cidr={{ pod_network_cidr }}
--image-repository={{ image_repository }}
--kubernetes-version=v{{ kube_version }}
--service-cidr={{ service_cidr }}
--cri-socket=/run/containerd/containerd.sock
args:
creates: /etc/kubernetes/admin.conf
- name: 创建 .kube 目录
file:
path: /root/.kube
state: directory
mode: 0755
- name: 复制 admin.conf
copy:
src: /etc/kubernetes/admin.conf
dest: /root/.kube/config
remote_src: yes
mode: 0644
- name: 安装 Calico 网络插件
command: >
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/calico.yaml
- name: 生成 worker 加入命令
command: kubeadm token create --print-join-command
register: join_command
run_once: true
- name: 保存 join 命令
copy:
content: "{{ join_command.stdout }}"
dest: /root/join-command.sh
mode: 0755
4.3 Role: worker
vim /root/ansible-k8s/roles/worker/tasks/main.yml
---
- name: 从 Master 获取 join 命令
slurp:
src: /root/join-command.sh
delegate_to: "{{ master_ip }}"
run_once: true
register: join_cmd
- name: 执行 join
command: "{{ join_cmd.content | b64decode }}"
args:
creates: /etc/kubernetes/kubelet.conf
- name: 打 worker 标签
command: >
kubectl label node {{ ansible_hostname }} node-role.kubernetes.io/worker=worker
delegate_to: "{{ master_ip }}"
ignore_errors: yes
4.4 主 Playbook
vim /root/ansible-k8s/deploy-k8s.yml
---
- name: 1. 配置所有节点基础环境
hosts: all
become: true
roles:
- common
- name: 2. 部署 Master 节点
hosts: masters
become: true
roles:
- master
- name: 3. Worker 节点加入集群
hosts: workers
become: true
roles:
- worker
- name: 4. 验证集群
hosts: masters
become: true
tasks:
- name: 查看节点状态
command: kubectl get nodes
register: node_status
- name: 输出节点信息
debug:
msg: "{{ node_status.stdout_lines }}"
五、执行部署
5.1 测试脚本
cd /root/ansible-k8s
# 测试连通性(master 是 local,worker 应返回 pong)
ansible -i inventory all -m ping
# 执行一键部署
ansible-playbook -i inventory deploy-k8s.yml


5.2 验证集群
kubectl get nodes
kubectl get pods -n kube-system
kubectl get pods -n kube-flannel


六、注意事项
| 现象 | 处理 |
|---|---|
| kubeadm init 提示 cgroup 驱动不匹配 | 检查 /etc/sysconfig/kubelet 和 containerd 配置,确保均为 systemd |
| 节点 NotReady | 一般因 Calico 未正常运行,执行 kubectl logs -n kube-system calico-node-xxx 查看;内核过低是常见原因,务必升级 |
| 镜像拉取失败 | 确认 image_repository 为阿里云,并且节点可访问外网 |
| Worker 无法加入 | 检查 join 命令是否过期,重新生成:kubeadm token create --print-join-command 手动执行 |
总结
本文实现了 在 Master 节点上直接运行 Ansible 来部署 Kubernetes 集群,无需额外部署机,结构紧凑、操作简便。通过本地连接管理 Master 自身,通过 SSH 管理 Worker,整个流程高度自动化,适用于资源有限或希望简化架构的场景。
更多推荐
所有评论(0)