背景:使用ansible完成k8s集群的部署,集群扩缩容管理
使用脚本分发秘钥,实现管理机基于秘钥免密连接被控节点
[root@ansible ~]#cat send_ssh_key.sh
#!/bin/bash
# 配置
USER="root"
PORT=22
PASS="1"
SERVERS=(
"10.0.0.221"
"10.0.0.222"
"10.0.0.223"
)
# 安装sshpass(如果没有)
if ! command -v sshpass &> /dev/null; then
echo "安装sshpass..."
if command -v apt-get &> /dev/null; then
sudo apt-get install -y sshpass > /dev/null 2>&1
else
sudo yum install -y sshpass > /dev/null 2>&1
fi
fi
# 生成密钥(如果没有)
if [ ! -f ~/.ssh/id_rsa ]; then
echo "生成SSH密钥..."
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" -q
fi
echo "=== 开始分发公钥 ==="
# 分发到各服务器
for SERVER in "${SERVERS[@]}"; do
echo -n "分发到 $SERVER ... "
sshpass -p "$PASS" ssh-copy-id -o StrictHostKeyChecking=no -p $PORT ${USER}@${SERVER} &> /dev/null
if [ $? -eq 0 ]; then
echo "成功"
else
echo "失败"
fi
done
echo "=== 测试免密登录 ==="
# 测试连接
for SERVER in "${SERVERS[@]}"; do
echo -n "测试 $SERVER ... "
ssh -o ConnectTimeout=3 -o BatchMode=yes ${USER}@${SERVER} "echo OK" &> /dev/null
[ $? -eq 0 ] && echo "成功" || echo "失败"
done
echo "=== 完成 ==="
使用:
chmod +x send_ssh_key.sh
sh send_ssh_key.sh
编写ansible的主机清单
[root@ansible ~]#cat /etc/ansible/hosts
#==========================================================
# K8s 集群
#==========================================================
[k8s_master]
10.0.0.221 hostname=master221
[k8s_worker]
10.0.0.222 hostname=worker222
10.0.0.223 hostname=worker223
[k8s:children]
k8s_master
k8s_worker
[k8s:vars]
ansible_user=root
ansible_ssh_port=22
准备部署k8s集群需要的文件
【我这里是离线部署,也可以在线部署,如果服务器环境不能上网,可以提前下载安装包以及镜像到本地】
[root@ansible k8s-deploy]#pwd
/root/k8s-deploy
[root@ansible k8s-deploy]#tree .
.
├── join.sh # 自动生成的文件 master节点上kubeadm生成的bootstrap-token认证信息,用于节点加入集群
├── k8s_deploy.yml # 部署k8s集群的剧本
├── k8s_scale_down.yml # 集群缩容的剧本
├── k8s_scale_up.yml # 集群扩容的剧本
├── kube-flannel-v0.27.0.yml
├── autoinstall-docker-docker-compose.tar.gz
├── flannel-v0.27.0.tar.gz
├── kubeadm-kubectl-kubelet-1.23.17.tar.gz
├── master-1.23.17.tar.gz
├── slave-1.23.17.tar.gz
└── system_init.sh # k8s环境优化脚本
0 directories, 11 files
[root@ansible k8s-deploy]#
- 编写部署 k8s 集群的 playbook
[root@ansible k8s-deploy]#cat k8s_deploy.yml
---
- name: K8s 1.23.17 集群一键部署(Ubuntu 离线版)
hosts: k8s
gather_facts: false
tasks:
# 1. 系统初始化优化
- name: 上传系统优化脚本
copy:
src: ./system_init.sh
dest: /tmp/system_init.sh
mode: 0755
- name: 执行系统优化
shell: /bin/bash /tmp/system_init.sh
# 2. 安装 Docker
- name: 上传 Docker 离线包
copy:
src: ./autoinstall-docker-docker-compose.tar.gz
dest: /tmp/
- name: 解压 Docker
unarchive:
src: /tmp/autoinstall-docker-docker-compose.tar.gz
dest: /tmp/
remote_src: yes
- name: 执行安装脚本
shell: cd /tmp && chmod +x install-docker.sh && ./install-docker.sh i
- name: 启动并开机自启 Docker
systemd:
name: docker
state: started
enabled: yes
# 3. 离线安装 K8s 1.23.17
- name: 上传 K8s 离线包
copy:
src: ./kubeadm-kubectl-kubelet-1.23.17.tar.gz
dest: /tmp/
- name: 解压 K8s 包
shell: cd /tmp && tar xf kubeadm-kubectl-kubelet-1.23.17.tar.gz
- name: 安装 K8s 组件
shell: cd /tmp && dpkg -i *.deb
- name: 锁定版本
shell: apt-mark hold kubelet kubeadm kubectl
# ======================= Master 节点初始化 =======================
- name: Master 节点初始化
hosts: k8s_master
gather_facts: false
tasks:
- name: 上传 K8s 镜像包
copy:
src: ./master-1.23.17.tar.gz
dest: /tmp/
- name: 导入 K8s 镜像
shell: docker load -i /tmp/master-1.23.17.tar.gz
- name: kubeadm init 初始化 Master
shell: |
kubeadm init --kubernetes-version=v1.23.17 \
--image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.100.0.0/16 \
--service-cidr=10.200.0.0/16 \
--service-dns-domain=luzhiwei.com
- name: 创建 .kube 目录
shell: mkdir -p $HOME/.kube
- name: 拷贝 admin.conf
shell: cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
- name: 修改权限
shell: chown $(id -u):$(id -g) $HOME/.kube/config
- name: 生成节点加入命令
shell: kubeadm token create --print-join-command
register: join_command
- name: 输出 join 命令到本地文件【管理机】
local_action:
module: copy
content: "{{ join_command.stdout_lines[0] }}"
dest: ./join.sh
# ======================= 部署 Flannel CNI 网络 =======================
- name: 所有节点上传并导入 Flannel 镜像
hosts: k8s
gather_facts: false
tasks:
- name: 上传 Flannel 镜像
copy:
src: ./flannel-v0.27.0.tar.gz
dest: /tmp/
- name: docker load 导入镜像
shell: docker load -i /tmp/flannel-v0.27.0.tar.gz
- name: Master 节点部署 Flannel 网络
hosts: k8s_master
gather_facts: false
tasks:
- name: 上传 Flannel YAML 文件
copy:
src: ./kube-flannel-v0.27.0.yml
dest: /root/
- name: 修改 Pod 网络网段
shell: sed -i '/16/s#244#100#' /root/kube-flannel-v0.27.0.yml
- name: kubectl apply 部署 Flannel
shell: kubectl apply -f /root/kube-flannel-v0.27.0.yml
# ======================= kubectl 自动补全 =======================
- name: 配置 kubectl 自动补全
hosts: k8s_master
gather_facts: false
tasks:
- name: 生成 kubectl 补全脚本
shell: kubectl completion bash > ~/.kube/completion.bash.inc
- name: 将补全脚本加入 .bashrc
lineinfile:
path: ~/.bashrc
line: 'source $HOME/.kube/completion.bash.inc'
state: present
- name: 生效 bashrc
shell: source ~/.bashrc
args:
executable: /bin/bash
# ======================= Worker 节点加入集群(最后执行) =======================
- name: Worker 节点部署(镜像导入 + 加入集群)
hosts: k8s_worker
gather_facts: false
tasks:
- name: 上传 slave-1.23.17.tar.gz 镜像包
copy:
src: ./slave-1.23.17.tar.gz
dest: /tmp/
- name: docker load -i 导入节点镜像
shell: docker load -i /tmp/oldboyedu-slave-1.23.17.tar.gz
- name: 执行 kubeadm join 加入master
# 从管理机本地拉取文件
shell: "{{ lookup('file', './join.sh') }}"
[root@ansible k8s-deploy]#ansible-playbook k8s_deploy.yml


k8s 集群缩容
修改主机清单,添加要下线的节点
[root@ansible ~]#cat /etc/ansible/hosts
...
# 要驱逐的节点IP
[deleted_worker]
10.0.0.223 hostname=worker223
# 10.0.0.224 hostname=worker224
# 10.0.0.225 hostname=worker225
...
k8s 集群缩容的 Playbook
[root@ansible k8s-deploy]#cat k8s_scale_down.yml
---
# ==============================================
# K8s 集群批量缩容
# 步骤:驱逐Pod → 删除节点 → 停止服务 → 重置清理
# 只需修改变量:remove_nodes 列表
# ==============================================
- name: 1. Master 节点:批量驱逐并删除节点
hosts: k8s_master
gather_facts: false
vars:
# ====================== 只需修改这里,但注意这里要和主机清单对应 ======================
remove_nodes:
- worker223
# - worker224
# - worker225
# ==========================================================
tasks:
- name: 安全驱逐节点上所有 Pod
shell: |
kubectl drain {{ item }} \
--ignore-daemonsets \
--delete-emptydir-data \
--force
loop: "{{ remove_nodes }}"
- name: 从 K8s 集群中删除节点
shell: kubectl delete node {{ item }}
loop: "{{ remove_nodes }}"
- name: 2. 被缩容节点:清理环境
hosts: deleted_worker
gather_facts: false
tasks:
- name: 停止 kubelet 服务
systemd:
name: kubelet
state: stopped
- name: kubeadm 重置节点环境
shell: kubeadm reset -f
- name: 清除 IPVS 转发规则
shell: ipvsadm --clear
- name: 清理残留 CNI 网络配置
shell: rm -rf /etc/cni /var/lib/cni /var/lib/kubelet /etc/kubernetes
[root@ansible k8s-deploy]#ansible-playbook k8s_scale_down.yml


k8s 集群节点的扩容
【注意:下线节点之后,正常来说要重新安装操作系统,避免数据泄露,然后这个服务器就可以做其他业务了。我这里是把刚才删除的节点重新加入集群,也可以把全新的节点加入集群,只需要在主机清单中配置节点信息即可】
修改主机清单,添加扩容的节点
[root@ansible ~]#cat /etc/ansible/hosts
...
# 重新扩容的节点
[new_workers]
10.0.0.223 hostname=worker223
...
k8s 集群节点扩容的 Playbook
[root@ansible k8s-deploy]#cat k8s_scale_up.yml
---
# ==============================================
# K8s 集群批量扩容
# 步骤:生成token → 清理残留 → 加入集群 → 设置主机名
# 只需修改主机清单 [new_workers]
# ==============================================
- name: 【前置】Master 生成最新 join 命令
hosts: k8s_master
gather_facts: false
tasks:
- name: 创建新的加入令牌
shell: kubeadm token create --print-join-command
register: join_command
- name: 保存到本地 join.sh
local_action:
module: copy
content: "{{ join_command.stdout_lines[0] }}"
dest: ./join.sh
# ========================================================================
- name: K8s 集群批量扩容节点
hosts: new_workers
gather_facts: false
tasks:
- name: 清理旧集群残留环境
shell: |
kubeadm reset -f
ipvsadm --clear
rm -rf /etc/kubernetes /var/lib/kubelet /etc/cni /var/lib/cni
# 以下为首次安装用,已安装过的节点无需执行,保持注释即可
# # 1. 系统优化
# - name: 上传系统优化脚本
# copy:
# src: ./system_init.sh
# dest: /tmp/
# mode: 0755
# - name: 执行系统优化
# shell: /bin/bash /tmp/system_init.sh
# # 2. 安装Docker
# - name: 上传Docker离线包
# copy:
# src: ./autoinstall-docker-docker-compose.tar.gz
# dest: /tmp/
# - name: 解压
# unarchive:
# src: /tmp/autoinstall-docker-docker-compose.tar.gz
# dest: /tmp/
# remote_src: yes
# - name: 安装Docker
# shell: cd /tmp && chmod +x install-docker.sh && ./install-docker.sh i
# - name: 启动Docker
# systemd:
# name: docker
# state: started
# enabled: yes
# # 3. 安装K8s组件
# - name: 上传K8s安装包
# copy:
# src: ./kubeadm-kubectl-kubelet-1.23.17.tar.gz
# dest: /tmp/
# - name: 解压
# shell: cd /tmp && tar xf kubeadm-kubectl-kubelet-1.23.17.tar.gz
# - name: 安装
# shell: cd /tmp && dpkg -i *.deb
# - name: 锁定版本
# shell: apt-mark hold kubelet kubeadm kubectl
# # 4. 启动 kubelet
# - name: 启动 kubelet 服务
# systemd:
# name: kubelet
# state: started
# enabled: yes
# # 5. 导入镜像
# - name: 导入worker镜像
# copy:
# src: ./slave-1.23.17.tar.gz
# dest: /tmp/
# - name: docker load
# shell: docker load -i /tmp/slave-1.23.17.tar.gz
- name: kubeadm join 加入集群
shell: "{{ lookup('file', './join.sh') }}"
# 从主机清单获取 hostname【保持和集群名称一致】
- name: 设置节点hostname(名称与kubectl get nodes 一致)
shell: hostnamectl set-hostname {{ hostname }}
[root@ansible k8s-deploy]#ansible-playbook k8s_scale_up.yml


正文完
wjojxwhtwsuikqhnirjuoeeuoiezre