Skip to content

Kubespray 部署

kubeadm 适合理解组件关系、手工搭建小规模集群。当需要在 30 台机器上反复交付和升级 K8s 集群时,逐台 SSH 和执行命令的方式会出很多操作一致性上的问题。

Kubespray 用 Ansible 把集群安装变成可重复执行的 playbook——一样的动作在 30 台机器上自动重复,inventory 和 group_vars 作为集群配置的唯一真实来源。

场景说明
多节点裸机 / 虚拟机统一初始化系统、安装运行时和 K8s 组件
多控制平面inventory 里声明 kube_control_plane、etcd、kube_node 三种角色
离线或半离线环境可以提前准备镜像和二进制包
后续扩容升级通过 Ansible playbook 重复执行,参数在 group_vars 里管理

学习组件关系还是 kubeadm 清楚;真正要在一批机器上反复交付集群时,Kubespray 的可重复性更好。

目录和 inventory

bash
git clone https://github.com/kubernetes-sigs/kubespray.git
cd kubespray

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

cp -rfp inventory/sample inventory/mycluster

inventory 写成 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_planeetcdkube_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.yml
yaml
# k8s-cluster.yml
kube_version: v1.36.0
container_manager: containerd
kube_network_plugin: calico

kube_service_addresses: 10.96.0.0/12
kube_pods_subnet: 10.244.0.0/16

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 或云负载均衡时,把 address 填成 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

cluster.yml 实际执行的分阶段:系统初始化→安装 containerd→安装 kubelet/kubeadm→初始化第一台控制平面→安装 CNI→加入其他控制平面→加入工作节点→安装附加组件(CoreDNS、metrics-server 等)。

参数说明
--become / -b提权执行系统级操作
--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 等系统镜像。离线环境先在一台联网机器上生成镜像清单再同步到 Harbor,比安装现场临时拉外网镜像可靠。

扩容节点

新增工作节点时,在 inventory 加主机并加入 kube_node,然后执行:

bash
ansible-playbook -i inventory/mycluster/hosts.yaml \
  --become --become-user=root \
  scale.yml \
  --limit k8s-node02

扩容前确认新节点的内核、系统源、DNS、镜像仓库、时间同步和已有节点一致。节点差异太多,后面排查会很难判断是 K8s 问题还是系统问题。

升级

升级先改 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

升级不是只升 K8s 版本,还要看 containerd、CNI、CSI、Gateway Controller、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,最后会失去自动化的意义。