前言

在传统的 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 地址
Mastermaster10.8.0.30
Workernode0110.8.0.40
Workernode0210.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,整个流程高度自动化,适用于资源有限或希望简化架构的场景。

更多推荐