Appearance
Kubespray 部署
Kubespray 用 Ansible 部署 Kubernetes,适合多节点、参数较多、需要批量扩容升级的自建集群。kubeadm 更适合理解组件关系和手工搭建,Kubespray 更像一套自动化交付方案——把集群安装变成可重复执行的 playbook。
Kubespray 适合什么
| 场景 | 说明 |
|---|---|
| 多节点裸机 / 虚拟机 | 统一初始化系统、安装运行时和 K8s 组件 |
| 多控制平面 | inventory 里声明 control plane、etcd、worker 三种角色 |
| 离线或半离线环境 | 可以提前准备镜像和二进制包 |
| 后续扩容升级 | 通过 Ansible playbook 重复执行,参数在 group_vars 里管理 |
学习组件关系还是 kubeadm 清楚;真正要在一批机器上反复交付集群时,Kubespray 的可重复性更好。
目录和 inventory
bash
git clone https://github.com/kubernetes-sigs/kubespray.git
cd kubespray
# 用虚拟环境安装依赖,不污染系统 Python
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp -rfp inventory/sample inventory/myclusterinventory 主机文件写成 YAML,角色清晰:
yaml
# inventory/mycluster/hosts.yaml
all:
hosts:
k8s-master01:
ansible_host: 192.168.10.11
ip: 192.168.10.11
access_ip: 192.168.10.11
k8s-master02:
ansible_host: 192.168.10.12
ip: 192.168.10.12
access_ip: 192.168.10.12
k8s-master03:
ansible_host: 192.168.10.13
ip: 192.168.10.13
access_ip: 192.168.10.13
k8s-node01:
ansible_host: 192.168.10.21
ip: 192.168.10.21
access_ip: 192.168.10.21
children:
kube_control_plane:
hosts:
k8s-master01:
k8s-master02:
k8s-master03:
etcd:
hosts:
k8s-master01:
k8s-master02:
k8s-master03:
kube_node:
hosts:
k8s-node01:
k8s_cluster:
children:
kube_control_plane:
kube_node:
calico_rr:
hosts: {}kube_control_plane 表示控制平面节点,etcd 表示 etcd 成员,kube_node 表示工作节点。三种角色可以重叠(stacked etcd),也可以拆开(external etcd)。
关键 group_vars
集群级配置在:
text
inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
inventory/mycluster/group_vars/k8s_cluster/k8s-net-calico.yml
inventory/mycluster/group_vars/all/containerd.ymlyaml
# k8s-cluster.yml
kube_version: v1.36.0
container_manager: containerd
kube_network_plugin: calico
kube_service_addresses: 10.96.0.0/12 # Service CIDR
kube_pods_subnet: 10.244.0.0/16 # Pod CIDR
dns_mode: coredns
helm_enabled: true
metrics_server_enabled: true控制平面入口:
yaml
# all.yml
apiserver_loadbalancer_domain_name: "k8s-api.example.local"
loadbalancer_apiserver:
address: 192.168.10.100
port: 6443如果外部已经有 HAProxy/Keepalived 或云负载均衡,就把地址写成 VIP。
安装前检查
安装前最容易漏的是:节点时间不同步、DNS 解析不一致、系统源不可用、镜像仓库不可达、机器里残留旧 kubelet/containerd 配置。
bash
ansible -i inventory/mycluster/hosts.yaml all -m ping
ansible -i inventory/mycluster/hosts.yaml all -m shell -a 'hostname; date; df -h /'
ansible -i inventory/mycluster/hosts.yaml all -m shell -a 'ip route; ping -c 2 192.168.10.11'执行安装
bash
ansible-playbook -i inventory/mycluster/hosts.yaml \
--become --become-user=root \
cluster.yml| 参数 | 说明 |
|---|---|
--become | 提权执行系统级操作 |
-b | --become 简写 |
--limit | 限制执行主机,扩容或修复时常用 |
-vvv | 输出更详细日志 |
安装完成后取 kubeconfig:
bash
scp root@192.168.10.11:/etc/kubernetes/admin.conf ./kubeconfig
export KUBECONFIG=$PWD/kubeconfig
kubectl get nodes -o wide
kubectl get pods -A -o wide离线环境和镜像
国内或内网环境要重点处理镜像。思路是把默认镜像仓库改成内部 registry:
yaml
# k8s-cluster.yml
registry_host: "registry.example.local"实际项目中还需要同步 kube-apiserver、etcd、pause、CoreDNS、Calico、metrics-server、Helm 组件的镜像。离线环境先在一台联网机器上生成镜像清单,再同步到 Harbor,比安装现场临时拉外网镜像可靠得多。
扩容节点
新增工作节点时,先在 inventory 加主机并加入 kube_node,然后执行:
bash
ansible-playbook -i inventory/mycluster/hosts.yaml \
--become --become-user=root \
scale.yml \
--limit k8s-node02扩容前要确认新节点的内核、系统源、DNS、镜像仓库、时间同步和已有节点一致。节点差异太多,后面排查会很难判断是 Kubernetes 问题还是系统问题。
升级
升级一般先改 kube_version,再执行:
bash
ansible-playbook -i inventory/mycluster/hosts.yaml \
--become --become-user=root \
upgrade-cluster.yml升级前固定检查:
bash
kubectl get nodes
kubectl get pods -A
kubectl -n kube-system get pods升级不是只升 Kubernetes 版本,还要看 containerd、CNI、CSI、Ingress/Gateway、Prometheus Operator、metrics-server 和业务组件兼容性。Kubespray 能执行升级动作,不能替代版本兼容性判断。
常见问题
| 现象 | 常见原因 | 处理方向 |
|---|---|---|
| Ansible ping 失败 | SSH、sudo、Python 环境 | 先跑 ansible all -m ping |
| 任务卡在拉镜像 | 外网慢、仓库认证失败 | 配内部 registry,提前同步镜像 |
| 节点 Join 失败 | Token、证书、API 入口不可达 | 看 kubelet 日志和 API Server 入口 |
| CNI Pod 不正常 | Pod CIDR、镜像、内核模块 | 看 Calico/Cilium 日志 |
| 重跑失败 | 节点残留旧配置 | 按 Kubespray reset 流程清理 |
Kubespray 的优势是可重复,但前提是 inventory 和 group_vars 也被当成代码管理。手工改一堆节点再跑 playbook,最后会失去自动化的意义。