Kubernetes 二进制部署实战指南(v1.28.0):从零开始构建高可用集群


Kubernetes 二进制部署实战指南(v1.28.0):从零开始构建高可用集群

前言

为什么选择二进制部署?

当我们使用 kubeadm 部署 Kubernetes 时,就像使用“一键安装包”,简单快捷但隐藏了大量细节。而二进制部署则像是“手动组装乐高”,你需要亲手下载每一个组件、配置每一张证书、编写每一个启动文件。

虽然过程繁琐,但这是彻底理解 Kubernetes 架构的最佳途径。通过本文,你将清晰地理解:

  • Kubernetes 的核心组件(ApiServer, Scheduler, Controller-Manager, Etcd)是如何协作的。
  • TLS 认证体系是如何构建信任链的。
  • Node 节点是如何通过 Kubelet 与 Master 通信的。

本文适合想深入理解 K8s 内部机制的开发者或运维人员。


第一阶段:环境准备

假设我们有两台 CentOS 7 虚拟机:

角色 主机名 IP 地址
Master master2 192.168.88.134
Node node2 192.168.88.132

前置条件

  • 所有节点网络互通。
  • 宿主机提供代理服务:192.168.88.1:10808(K8s 的很多资源在国外,代理是必须的)。

1. 配置主机名与解析

在每台机器上设置唯一的主机名,并配置 /etc/hosts 解析,这样节点之间可以通过名字互相认识。

1
2
3
4
5
6
7
8
9
10
11
# 在 Master 上执行
hostnamectl set-hostname master2

# 在 Node 上执行
hostnamectl set-hostname node2

# 在所有节点 /etc/hosts 添加
cat >> /etc/hosts << EOF
192.168.88.134 master2
192.168.88.132 node2
EOF

2. 系统优化(必须)

Kubernetes 对系统环境有严格要求,请务必执行以下“三板斧”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 关闭防火墙 (K8s 端口极其复杂,建议直接关闭,通过云厂商安全组控制)
systemctl stop firewalld && systemctl disable firewalld

# 2. 关闭 Selinux (它会阻止 K8s 修改系统文件权限)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

# 3. 关闭 Swap (K8s 为了性能考量,强制要求关闭交换分区)
swapoff -a
sed -i '/swap/d' /etc/fstab

# 4. 时间同步 (保证集群内证书验证的时间一致性)
yum install -y ntpdate
ntpdate time.windows.com

第二阶段:安装 Containerd(容器运行时)

Kubernetes 1.24 版本后,Docker 被移除,官方推荐使用 Containerd

1. 安装 Containerd

1
2
3
4
5
6
# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加 Docker 阿里云源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装
yum install -y containerd.io

2. 配置 Containerd

生成默认配置并开启 SystemdCgroup(K8s 使用 Systemd 管理进程,Containerd 必须与之匹配)。

1
2
3
4
5
6
7
8
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

# 修改 SystemdCgroup 为 true
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

# 启动服务
systemctl enable --now containerd

第三阶段:下载二进制文件(Master 节点)

我们需要下载 Kubernetes、Etcd、CNI 插件和网络插件。

1. 配置代理

在终端设置代理,确保能从 Google 和 GitHub 下载文件。

1
2
export http_proxy=http://192.168.88.1:10808
export https_proxy=http://192.168.88.1:10808

2. 下载核心文件

1
2
3
4
5
6
7
8
9
10
mkdir -p /data/k8s-work && cd /data/k8s-work

# 下载 Kubernetes (约 360MB)
wget https://dl.k8s.io/v1.28.0/kubernetes-server-linux-amd64.tar.gz

# 下载 Etcd (K8s 数据库)
wget https://github.com/etcd-io/etcd/releases/download/v3.5.9/etcd-v3.5.9-linux-amd64.tar.gz

# 下载 CNI 插件 (容器网络接口)
wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz

3. 解压与分发

解压:

1
2
tar -zxvf kubernetes-server-linux-amd64.tar.gz
tar -zxvf etcd-v3.5.9-linux-amd64.tar.gz

安装 Master 组件:

1
2
3
4
cd kubernetes/server/bin/
cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
cd ../../etcd-v3.5.9-linux-amd64/
cp etcd etcdctl /usr/local/bin/

分发 Node 组件:
将 Node 需要的程序远程拷贝到 node2。

1
2
scp /data/k8s-work/kubernetes/server/bin/kubelet [email protected]:/usr/local/bin/
scp /data/k8s-work/kubernetes/server/bin/kube-proxy [email protected]:/usr/local/bin/

第四阶段:制作 SSL 证书(最关键的一步)

Kubernetes 的安全性基于 TLS 加密。每一个组件(如 ApiServer、Kubelet)都需要证书来证明身份。我们使用 cfssl 工具来生成。

1. 安装 CFSSL

1
2
3
4
5
cd /data/k8s-work
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64 -O cfssl
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64 -O cfssljson
chmod +x cfssl cfssljson
mv cfssl cfssljson /usr/local/bin/

2. 生成 CA 根证书

就像身份证签发机关,CA 是信任链的源头。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
mkdir -p /data/k8s-work/etcd-cert && cd /data/k8s-work/etcd-cert

# CA 配置文件
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"www": {
"expiry": "87600h",
"usages": ["signing", "key encipherment", "server auth", "client auth"]
}
}
}
}
EOF

# CA 证书请求文件
cat > ca-csr.json << EOF
{
"CN": "kubernetes",
"key": { "algo": "rsa", "size": 2048 },
"names": [{ "C": "CN", "L": "Beijing", "ST": "Beijing" }]
}
EOF

# 生成 CA 证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca

3. 生成 Etcd 证书

Etcd 是 K8s 的数据库,必须严格加密。

1
2
3
4
5
6
7
8
9
10
11
# 注意:hosts 必须包含本机 IP 和 127.0.0.1
cat > etcd-csr.json << EOF
{
"CN": "etcd",
"hosts": ["127.0.0.1", "192.168.88.134", "master2"],
"key": { "algo": "rsa", "size": 2048 },
"names": [{ "C": "CN", "L": "Beijing", "ST": "Beijing" }]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www etcd-csr.json | cfssljson -bare etcd

4. 生成 ApiServer 证书

这是最复杂的证书,因为它需要包含 Cluster IP(通常是 10.96.0.1)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat > server-csr.json << EOF
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"192.168.88.134",
"master2",
"10.96.0.1",
"kubernetes",
"kubernetes.default"
],
"key": { "algo": "rsa", "size": 2048 },
"names": [{ "C": "CN", "L": "Beijing", "ST": "Beijing" }]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server

5. 生成 Service Account (SA) 证书

用于给 Pod 里的 ServiceAccount 签发 Token。

1
2
openssl genrsa -out sa.key 2048
openssl rsa -in sa.key -pubout -out sa.pub

第五阶段:部署 Etcd 和 Master 组件

1. 部署 Etcd

先将证书移动到标准目录:

1
2
3
4
5
mkdir -p /etc/etcd/ssl /etc/kubernetes/pki /var/lib/etcd
cp ca.pem ca-key.pem /etc/kubernetes/pki/
cp etcd.pem etcd-key.pem /etc/etcd/ssl/
cp server.pem server-key.pem /etc/kubernetes/pki/
cp sa.key sa.pub /etc/kubernetes/pki/

创建 Systemd 服务文件 /usr/lib/systemd/system/etcd.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[Unit]
Description=Etcd Server
After=network.target

[Service]
Type=notify
ExecStart=/usr/local/bin/etcd \
--name master2 \
--data-dir=/var/lib/etcd \
--listen-client-urls https://192.168.88.134:2379,http://127.0.0.1:2379 \
--advertise-client-urls https://192.168.88.134:2379 \
--listen-peer-urls https://192.168.88.134:2380 \
--initial-advertise-peer-urls https://192.168.88.134:2380 \
--initial-cluster master2=https://192.168.88.134:2380 \
--initial-cluster-token etcd-cluster-0 \
--initial-cluster-state new \
--client-cert-auth \
--trusted-ca-file=/etc/kubernetes/pki/ca.pem \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-client-cert-auth \
--peer-trusted-ca-file=/etc/kubernetes/pki/ca.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem
Restart=on-failure

[Install]
WantedBy=multi-user.target

启动:systemctl daemon-reload && systemctl enable --now etcd

2. 部署 Kube-apiserver

创建 /usr/lib/systemd/system/kube-apiserver.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[Unit]
Description=Kubernetes API Server

[Service]
ExecStart=/usr/local/bin/kube-apiserver \
--advertise-address=192.168.88.134 \
--allow-privileged=true \
--authorization-mode=Node,RBAC \
--client-ca-file=/etc/kubernetes/pki/ca.pem \
--enable-bootstrap-token-auth=true \
--etcd-servers=https://192.168.88.134:2379 \
--etcd-cafile=/etc/kubernetes/pki/ca.pem \
--etcd-certfile=/etc/etcd/ssl/etcd.pem \
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \
--service-cluster-ip-range=10.96.0.0/12 \
--service-node-port-range=30000-32767 \
--tls-cert-file=/etc/kubernetes/pki/server.pem \
--tls-private-key-file=/etc/kubernetes/pki/server-key.pem \
--service-account-issuer=https://kubernetes.default.svc.cluster.local \
--service-account-signing-key-file=/etc/kubernetes/pki/sa.key \
--service-account-key-file=/etc/kubernetes/pki/sa.pub
Restart=on-failure

[Install]
WantedBy=multi-user.target

启动:systemctl daemon-reload && systemctl enable --now kube-apiserver

3. 配置 Kubectl 与 RBAC

生成管理员配置文件:

1
2
3
4
5
6
7
kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.pem --embed-certs=true --server=https://192.168.88.134:6443 --kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config set-credentials kubernetes-admin --client-certificate=/etc/kubernetes/pki/server.pem --client-key=/etc/kubernetes/pki/server-key.pem --embed-certs=true --kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config set-context default --cluster=kubernetes --user=kubernetes-admin --kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config use-context default --kubeconfig=/etc/kubernetes/admin.kubeconfig

mkdir -p ~/.kube
cp /etc/kubernetes/admin.kubeconfig ~/.kube/config

授权:

1
2
# 给予用户 'kubernetes' 超级管理员权限
kubectl create clusterrolebinding kubernetes-admin --clusterrole=cluster-admin --user=kubernetes

4. 部署 Controller-Manager 和 Scheduler

这两个组件需要通过 kubeconfig 文件访问 ApiServer。生成 kubeconfig 的步骤类似于 admin.kubeconfig,生成后创建对应的 systemd 服务即可(详细命令见上文实战部分,此处略写)。

启动后,检查状态:

1
2
kubectl get cs
# 应该看到 scheduler 和 controller-manager 都是 Healthy

第六阶段:部署 Node 节点

切换到 Node2 终端操作。

1. 安装 Containerd

同 Master 步骤,安装并启动 Containerd。

2. 部署 Kubelet

我们需要在 Master 上为 Node 生成证书和 kubeconfig 文件,然后分发过来。

在 Master 上生成 Node 证书:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 生成 Node2 的证书 (CN 必须是 system:node:<节点名>)
cd /data/k8s-work/etcd-cert
cat > node2-csr.json << EOF
{
"CN": "system:node:node2",
"hosts": ["192.168.88.132"],
"key": { "algo": "rsa", "size": 2048 },
"names": [{ "C": "CN", "O": "system:nodes" }]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www node2-csr.json | cfssljson -bare node2

# 生成 kubeconfig 并传输
# ... (参考上文生成 node2.kubeconfig)
scp node2.kubeconfig [email protected]:/etc/kubernetes/kubelet.kubeconfig

在 Node2 上配置 Kubelet 服务:
创建 /usr/lib/systemd/system/kubelet.service,配置文件略(见上文)。

3. 部署 Kube-Proxy

类似 Kubelet,生成 kube-proxy.kubeconfig 并分发,然后创建 systemd 服务。


第七阶段:网络插件与验证

1. 安装 Flannel

在 Master 上执行:

1
2
3
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 如果镜像拉不下来,请修改 yml 中的镜像地址为阿里云镜像
kubectl apply -f kube-flannel.yml

2. 解决镜像拉取问题(避坑指南)

这是新手最容易卡住的地方。

如果 Node 节点没有代理,kubelet 启动 Pod 时无法拉取镜像。
解决方案:配置 Containerd 镜像加速。

在 Node 节点上执行:

1
2
3
4
5
6
7
8
mkdir -p /etc/containerd/certs.d/docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "https://registry-1.docker.io"

[host."https://registry.cn-hangzhou.aliyuncs.com"]
capabilities = ["pull", "resolve"]
EOF
systemctl restart containerd

3. 最终验证

1
2
3
4
5
6
7
8
9
10
# 查看节点
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# node2 Ready <none> 10m v1.28.0

# 部署 Nginx 测试
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort

# 访问 http://<Node_IP>:<NodePort>

总结

通过这次二进制部署,我们虽然敲了很多命令,但也彻底厘清了 Kubernetes 的骨架:

  1. Etcd 存储数据。
  2. ApiServer 提供入口。
  3. Controller-Manager 维持状态。
  4. Scheduler 调度 Pod。
  5. Kubelet 执行命令。

希望这份指南能帮助您在 Kubernetes 的学习之路上更进一步!