Kubernetes 二进制部署:从零搭建单 Master 集群
目录
使用 kubeadm 部署 Kubernetes 集群很方便,但它隐藏了底层细节。通过二进制方式手动部署,可以深入理解每个组件的作用和协作方式。
本文在 etcd 集群 已部署的基础上,搭建单 Master 节点的 Kubernetes 集群。
架构概览
单 Master 架构中,Master 节点运行控制平面组件,Worker 节点运行工作负载:

核心组件
| 组件 | 运行位置 | 作用 |
|---|---|---|
| kube-apiserver | Master | 集群入口,所有操作的统一接口 |
| etcd | Master | 分布式键值存储,保存集群状态 |
| kube-controller-manager | Master | 控制循环,确保实际状态匹配期望状态 |
| kube-scheduler | Master | 将 Pod 调度到合适的 Node |
| kubelet | Worker | 管理 Pod 生命周期,汇报节点状态 |
| kube-proxy | Worker | 实现 Service 网络代理和负载均衡 |
组件协作流程
kubectl create deployment nginx --image=nginx
│
▼
kube-apiserver ──→ etcd(存储期望状态)
│
▼
controller-manager(创建 ReplicaSet → 创建 Pod)
│
▼
scheduler(选定 Node,写入 Pod.Spec.NodeName)
│
▼
kubelet(watch 到分配给自己的 Pod,拉起容器)
│
▼
kube-proxy(配置 iptables/IPVS 规则,实现 Service 访问)前置条件
| 条件 | 说明 |
|---|---|
| etcd 集群 | 已部署,参考 etcd 集群部署 |
| 操作系统 | Linux(本文以 Ubuntu 为例) |
| 容器运行时 | containerd 或 Docker 已安装,参考 Docker 入门 |
| 网络 | 节点间互通,关闭 swap |
关闭 swap
Kubernetes 默认要求关闭 swap:
sudo swapoff -a
# 永久关闭:注释 /etc/fstab 中的 swap 行
sudo sed -i '/ swap / s/^/#/' /etc/fstab下载二进制文件
从 Kubernetes GitHub Releases 下载:
# 设置版本
KUBE_VERSION="v1.33.0"
ARCH="amd64"
# 下载 Server 二进制(Master 节点需要)
wget "https://dl.k8s.io/${KUBE_VERSION}/kubernetes-server-linux-${ARCH}.tar.gz"
tar -xf kubernetes-server-linux-${ARCH}.tar.gz
# 复制到系统路径
sudo cp kubernetes/server/bin/kube-apiserver /usr/local/bin/
sudo cp kubernetes/server/bin/kube-controller-manager /usr/local/bin/
sudo cp kubernetes/server/bin/kube-scheduler /usr/local/bin/
sudo cp kubernetes/server/bin/kubectl /usr/local/bin/
# Worker 节点需要的二进制
sudo cp kubernetes/server/bin/kubelet /usr/local/bin/
sudo cp kubernetes/server/bin/kube-proxy /usr/local/bin/也可以单独下载 Node 二进制:
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.33.md#node-binaries部署 Master 组件
生成集群证书
Kubernetes 各组件之间通过 TLS 加密通信,需要生成证书:
# 安装 cfssl 工具
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl_1.6.5_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssljson_1.6.5_linux_amd64
chmod +x cfssl_* && sudo mv cfssl_* /usr/local/bin/
# 创建 CA 证书
mkdir -p /etc/kubernetes/pki && cd /etc/kubernetes/pki
cat > ca-config.json <<EOF
{
"signing": {
"default": { "expiry": "87600h" },
"profiles": {
"kubernetes": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "87600h"
}
}
}
}
EOF
cat > ca-csr.json <<EOF
{
"CN": "kubernetes-ca",
"key": { "algo": "rsa", "size": 2048 },
"names": [{ "C": "CN", "ST": "Beijing", "L": "Beijing", "O": "k8s", "OU": "system" }]
}
EOF
cfssl gencert -initca ca-csr.json | cfssljson -bare ca生成 apiserver 证书:
cat > apiserver-csr.json <<EOF
{
"CN": "kube-apiserver",
"key": { "algo": "rsa", "size": 2048 },
"names": [{ "C": "CN", "ST": "Beijing", "L": "Beijing", "O": "k8s", "OU": "system" }],
"hosts": [
"127.0.0.1",
"10.96.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster.local",
"MASTER_IP",
"MASTER_PUBLIC_IP"
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json \
-profile=kubernetes apiserver-csr.json | cfssljson -bare apiserver将
MASTER_IP和MASTER_PUBLIC_IP替换为实际的内网和公网 IP。
部署 kube-apiserver
创建 systemd 服务文件:
cat > /etc/systemd/system/kube-apiserver.service <<EOF
[Unit]
Description=Kubernetes API Server
After=network.target etcd.service
[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
--advertise-address=MASTER_IP \\
--bind-address=0.0.0.0 \\
--secure-port=6443 \\
--etcd-servers=https://ETCD_IP1:2379,https://ETCD_IP2:2379,https://ETCD_IP3:2379 \\
--etcd-cafile=/etc/kubernetes/pki/ca.pem \\
--etcd-certfile=/etc/kubernetes/pki/apiserver.pem \\
--etcd-keyfile=/etc/kubernetes/pki/apiserver-key.pem \\
--tls-cert-file=/etc/kubernetes/pki/apiserver.pem \\
--tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem \\
--client-ca-file=/etc/kubernetes/pki/ca.pem \\
--service-cluster-ip-range=10.96.0.0/12 \\
--service-node-port-range=30000-32767 \\
--allow-privileged=true \\
--enable-bootstrap-token-auth \\
--authorization-mode=Node,RBAC \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF关键参数说明:
| 参数 | 作用 |
|---|---|
--etcd-servers |
etcd 集群地址 |
--service-cluster-ip-range |
Service ClusterIP 地址范围 |
--authorization-mode |
授权模式,RBAC 是标准选择 |
--enable-bootstrap-token-auth |
启用 Bootstrap Token 认证(用于节点自动注册) |
启动并验证:
sudo systemctl daemon-reload
sudo systemctl enable --now kube-apiserver
# 验证
curl -k https://127.0.0.1:6443/healthz部署 kube-controller-manager
cat > /etc/systemd/system/kube-controller-manager.service <<EOF
[Unit]
Description=Kubernetes Controller Manager
After=kube-apiserver.service
[Service]
ExecStart=/usr/local/bin/kube-controller-manager \\
--master=https://127.0.0.1:6443 \\
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig \\
--cluster-cidr=10.244.0.0/16 \\
--service-cluster-ip-range=10.96.0.0/12 \\
--cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem \\
--cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem \\
--root-ca-file=/etc/kubernetes/pki/ca.pem \\
--service-account-private-key-file=/etc/kubernetes/pki/ca-key.pem \\
--allocate-node-cidrs=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now kube-controller-manager部署 kube-scheduler
cat > /etc/systemd/system/kube-scheduler.service <<EOF
[Unit]
Description=Kubernetes Scheduler
After=kube-apiserver.service
[Service]
ExecStart=/usr/local/bin/kube-scheduler \\
--master=https://127.0.0.1:6443 \\
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now kube-scheduler验证 Master 组件
# 查看组件状态
kubectl --kubeconfig=/etc/kubernetes/admin.kubeconfig get cs
# 预期输出
# NAME STATUS MESSAGE ERROR
# controller-manager Healthy ok
# scheduler Healthy ok
# etcd-0 Healthy ok部署 Worker 组件
以下步骤在每个 Worker 节点上执行。
部署 kubelet
# 创建 kubelet 配置
cat > /etc/kubernetes/kubelet-config.yaml <<EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
mode: Webhook
clusterDomain: cluster.local
clusterDNS:
- 10.96.0.10
resolvConf: /run/systemd/resolve/resolv.conf
runtimeRequestTimeout: "15m"
EOF
# 创建 systemd 服务
cat > /etc/systemd/system/kubelet.service <<EOF
[Unit]
Description=Kubernetes Kubelet
After=containerd.service
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \\
--config=/etc/kubernetes/kubelet-config.yaml \\
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \\
--container-runtime-endpoint=unix:///run/containerd/containerd.sock \\
--pod-infra-container-image=registry.k8s.io/pause:3.10 \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now kubelet部署 kube-proxy
# 创建 kube-proxy 配置
cat > /etc/kubernetes/kube-proxy-config.yaml <<EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
mode: ipvs
clusterCIDR: 10.244.0.0/16
EOF
# 创建 systemd 服务
cat > /etc/systemd/system/kube-proxy.service <<EOF
[Unit]
Description=Kubernetes Kube Proxy
After=network.target
[Service]
ExecStart=/usr/local/bin/kube-proxy \\
--config=/etc/kubernetes/kube-proxy-config.yaml \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now kube-proxy验证集群
检查节点状态
kubectl get nodes
# 预期输出(节点需几分钟变为 Ready)
# NAME STATUS ROLES AGE VERSION
# master-01 Ready control-plane 5m v1.33.0
# worker-01 Ready <none> 3m v1.33.0
# worker-02 Ready <none> 3m v1.33.0部署 CNI 网络插件
节点处于 NotReady 状态通常是因为没有安装 CNI。以 Calico 为例:
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.3/manifests/calico.yaml部署 CoreDNS
CoreDNS 提供集群内 DNS 解析:
# 下载 CoreDNS 部署清单
wget https://raw.githubusercontent.com/kubernetes/kubernetes/v1.33.0/cluster/addons/dns/coredns/coredns.yaml.sed
mv coredns.yaml.sed coredns.yaml
# 替换变量
sed -i 's/__DNS__DOMAIN__/cluster.local/g' coredns.yaml
sed -i 's/__DNS__SERVER__IP__/10.96.0.10/g' coredns.yaml
kubectl apply -f coredns.yaml验证集群功能
# 创建测试 Pod
kubectl run nginx --image=nginx --port=80
# 检查 Pod 状态
kubectl get pods -o wide
# 创建 Service
kubectl expose pod nginx --port=80 --type=NodePort
# 访问测试
curl $(kubectl get svc nginx -o jsonpath='{.spec.ports[0].nodePort}')证书与配置文件汇总
| 文件 | 用途 |
|---|---|
ca.pem / ca-key.pem |
CA 根证书和私钥 |
apiserver.pem / apiserver-key.pem |
API Server TLS 证书 |
admin.kubeconfig |
管理员 kubectl 配置 |
controller-manager.kubeconfig |
Controller Manager 连接 API Server |
scheduler.kubeconfig |
Scheduler 连接 API Server |
kubelet.kubeconfig |
Kubelet 连接 API Server |
kube-proxy.kubeconfig |
Kube Proxy 连接 API Server |
bootstrap.kubeconfig |
节点自动注册 Bootstrap Token |
排错指南
| 现象 | 排查方向 |
|---|---|
kubectl 连接超时 |
检查 apiserver 端口 6443 是否监听,防火墙是否放通 |
节点 NotReady |
journalctl -u kubelet 查看日志,检查 CNI 插件是否安装 |
Pod Pending |
kubectl describe pod <name> 查看调度失败原因 |
| Service 无法访问 | 检查 kube-proxy 是否运行,ipvsadm -Ln 查看规则 |
| 证书错误 | 检查证书 hosts 是否包含实际 IP,证书是否过期 |
生产环境建议
二进制部署适合学习和理解架构,生产环境建议:
- kubeadm:官方推荐的集群部署工具
- 托管服务:阿里云 ACK、腾讯云 TKE、AWS EKS 等
- 高可用:多 Master + 外部 etcd + 负载均衡器