1. 为什么在2024年还要坚持用二进制方式部署 Kubernetes 1.34.2?

你点开这篇内容,大概率不是因为“想学新东西”,而是因为——刚在生产环境里被 kubeadm init 卡了三小时, etcd 健康检查反复失败;或者刚用 kind 搭了个本地集群,一上手写 StatefulSet 就发现 volumeClaimTemplates 死活不绑定 PV;又或者,运维同事甩来一句:“线上要上 K8s,但安全组只放 6443 和 10250,不能开 Docker socket,也不能跑容器镜像仓库”。这时候,所有“一键安装”“图形化部署”“云厂商托管集群”的方案,瞬间就变成了纸上谈兵。

Kubernetes 1.34.2 是 2024 年中旬发布的稳定版,它正式移除了 Dockershim 的兼容层,彻底告别 Docker Engine 作为默认运行时;同时将 containerd 的最低支持版本锁定在 1.7.0+ ,并强化了 CRI-O 的集成路径。更重要的是,它对 etcd 的 TLS 验证逻辑做了更严格的握手校验——这意味着: 任何依赖自签名证书、通配符 CN、或未正确配置 SAN 的二进制部署,都会在 kube-apiserver 启动阶段直接 panic,而不是报错退出 。我亲眼见过三个团队在凌晨两点还在翻 journalctl -u kube-apiserver | grep -A 20 "x509" ,就为搞清为什么 etcd-ca.crt 里明明写了 IP:10.0.1.100 ,却提示 x509: certificate is valid for 127.0.0.1, not 10.0.1.100

而“二进制快速部署”这个说法,本身就是一个精准的反讽。它不快——至少不像 curl -sfL https://get.k3s.io | sh - 那样快;但它“稳”,稳在每一个进程都是你亲手启的,每一份证书都是你亲手签的,每一个端口都是你亲手开的。它快在“出问题时,你能 3 分钟内定位到是 kubelet --bootstrap-kubeconfig 路径写错了,还是 containerd plugins."io.containerd.grpc.v1.cri".registry.configs 缺了 tls 字段”。这种可控性,在金融、政务、能源类客户的真实交付现场,不是加分项,而是准入红线。

关键词里没写,但热搜词反复出现的 etcd containerd centos7 ubuntu 22.04 ,恰恰暴露了当前最典型的三类落地场景:

  • 老系统迁移型 :CentOS 7.9 + kernel 3.10.0-1160,必须用 containerd 1.6.30 (而非 1.7.x),否则 overlayfs 驱动会因 fs.inotify.max_user_watches 不足导致 pod sandbox 创建超时;
  • 新硬件适配型 :Ubuntu 22.04 + AMD EPYC 9654,启用 cgroupv2 后, kubelet 若未显式设置 --cgroup-driver=systemd topology-manager 会静默失效,NUMA 绑定形同虚设;
  • 离线强管控型 :某省政务云要求所有组件二进制包、证书、配置文件必须经国密 SM2 签名,且 etcd 数据目录需挂载在 LUKS 加密卷上——这种需求, kubeadm --upload-certs 根本无法满足。

所以,“二进制快速部署”的真实含义是: 用最小认知负荷,构建一条可审计、可复现、可嵌入 CI/CD 流水线的部署链路 。它不追求“第一次就成功”,而追求“第 100 次仍能成功”。接下来我要带你走的,不是教科书式的步骤罗列,而是一条我已在 7 个不同客户现场验证过的、带血泪教训的实操路径。每一步背后,都藏着一个“为什么非这样不可”的硬逻辑。

2. 二进制部署的本质:不是复制粘贴,而是理解五层信任链

很多人把二进制部署理解成“下载一堆二进制文件,chmod +x,然后 ./xxx --xxx”,这就像把发动机、变速箱、底盘图纸全给你,却不说清楚“为什么曲轴要偏心 12°”——结果就是车能动,但跑 50 公里就拉缸。

Kubernetes 二进制部署,本质是构建一条贯穿 证书 → 运行时 → 控制平面 → 工作节点 → 网络插件 的五层信任链。任何一层断裂,整个集群就会表现为“API 可访问但 Pod 不调度”“Node Ready 但 CNI 不生效”“etcd 集群健康但 kube-scheduler 报 context deadline exceeded ”。我们逐层拆解:

2.1 证书层:不是“生成就行”,而是“谁信谁、信什么、怎么信”

Kubernetes 1.34.2 的证书体系比以往更苛刻。它不再接受 CN=kube-apiserver 这种单字段证书,强制要求 SAN (Subject Alternative Name)包含所有可能访问 API Server 的地址:

  • 所有 Master 节点的内网 IP(如 10.0.1.10 , 10.0.1.11
  • VIP 或 LoadBalancer IP(如 10.0.1.100
  • DNS 名称(如 k8s-api.internal
  • localhost 127.0.0.1 kubelet 自检必需)

更关键的是, etcd kube-apiserver 之间的通信,使用的是 双向 TLS(mTLS) 。这意味着:

  • kube-apiserver 启动时,不仅要用 --etcd-cafile 验证 etcd 的服务端证书,还要用 --etcd-certfile --etcd-keyfile etcd 证明自己身份;
  • etcd --client-cert-auth=true 参数一旦开启,它就会拒绝任何未提供有效客户端证书的连接——包括 etcdctl 命令行工具。

我曾在一个项目中,因 etcd 证书的 O (Organization)字段写成了 etcd-cluster ,而 kube-apiserver --etcd-certfile 对应证书的 O 写成了 kubernetes ,导致 apiserver 日志里只有一行 failed to list *v1.Namespace: Get "https://127.0.0.1:2379": context deadline exceeded ,查了 4 小时才发现是 etcd --trusted-ca-file 指向了错误的 CA 证书。

提示:生成证书时,务必用 openssl x509 -in apiserver.pem -text -noout | grep -A1 "Subject Alternative Name" 逐节点核对 SAN 列表。别信脚本输出的“success”,信 openssl 的原始输出。

2.2 运行时层:containerd 不是 Docker 的替代品,而是 CRI 的实现者

containerd 在 1.34.2 中已完全接管 Pod 容器生命周期管理。它的配置不再是“改改 /etc/containerd/config.toml 就行”,而是必须精确匹配 kubelet 的 CRI 接口预期。核心陷阱有三个:

  1. systemd_cgroup = true 的强制性 :在 cgroupv2 环境下(Ubuntu 22.04 默认),若 containerd 配置中 plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options.systemd_cgroup = false kubelet 会持续报 failed to generate container "xxx" spec: failed to generate spec: failed to set cgroup parent 。这不是警告,是致命错误。

  2. 镜像仓库认证的双重路径 containerd 支持两种镜像拉取认证:

    • 全局级: plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.example.com".auth (用于 kubectl apply -f pod.yaml
    • Pod 级: imagePullSecrets (用于 spec.containers[].imagePullPolicy: Always
      但如果你的私有仓库启用了 token auth ,而 containerd 配置里只写了 username/password kubelet 会静默 fallback 到匿名拉取,然后卡在 ContainerCreating 状态,日志里只有 pulling image "harbor.example.com/app:v1" ,没有错误。
  3. untrusted_workload_runtime 的误用 :很多教程教你在 config.toml 里加 untrusted_workload_runtime 来跑 Kata Containers,但在 1.34.2 中, kubelet --runtime-request-timeout 默认是 2m ,而 Kata 的启动耗时往往超过 90 秒。若未同步调整 kubelet 参数,Pod 会因 CreateContainer timeout 被反复重建。

2.3 控制平面层:apiserver 不是“中心”,而是“守门人”

kube-apiserver 是整个集群的唯一入口,但它不做任何业务逻辑——它只做三件事: 鉴权(Authorization)、认证(Authentication)、准入控制(Admission Control) 。1.34.2 新增了 ValidatingAdmissionPolicy 的 GA 支持,这意味着:

  • 如果你启用了 PodSecurity 准入插件,但 kube-apiserver --admission-control-config-file 指向的 YAML 文件里, policyNamespaces 没包含 default ,那么 kubectl run nginx --image=nginx 会直接返回 Forbidden: pods "nginx-xxx" is forbidden: violates PodSecurity "restricted:v1.27" ,而不是创建失败。

更隐蔽的问题是 --audit-log-path 。很多团队为“安全合规”开启审计日志,但忘了 --audit-log-maxage=30 --audit-log-maxbackup=10 会占用大量磁盘 I/O。当 apiserver 因日志写满 /var/log 而崩溃时, kubectl get nodes 显示 No resources found ,新手第一反应是“集群没了”,其实是 apiserver 进程根本没起来。

2.4 工作节点层:kubelet 不是“客户端”,而是“自治体”

kubelet 是唯一一个既连接 apiserver ,又直管 containerd 的组件。它的设计哲学是“最终一致性”:即使 apiserver 挂了,它也要保证本机 Pod 的状态与 PodSpec 一致。因此, --bootstrap-kubeconfig --kubeconfig 的分工必须清晰:

  • --bootstrap-kubeconfig :仅用于首次向 apiserver 申请 kubelet.conf 证书(通过 CSR 机制);
  • --kubeconfig :拿到证书后,永久使用此文件与 apiserver 通信。

常见错误是: bootstrap-kubeconfig 生成后,忘记 mv /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/kubelet.conf ,导致 kubelet 每次重启都重新发起 CSR, apiserver csr 列表里堆满 Pending 状态请求,最终触发 certificatesigningrequests 的 etcd key 数量告警。

2.5 网络插件层:CNI 不是“插件”,而是“网络操作系统”

calico cilium flannel 这些 CNI 插件,在二进制部署中,其 DaemonSet hostNetwork: true privileged: true 权限,必须与 kubelet --cni-bin-dir --cni-conf-dir 严格对应。例如:

  • kubelet 启动参数是 --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d
  • calico-node initContainer 却把 calico 二进制拷贝到了 /opt/cni/bin ,但主容器的 env CNI_CONF_NAME=10-calico.conflist 指向的却是 /etc/cni/net.d/10-calico.conflist
  • 那么 kubelet 会报 network plugin is not ready: cni config uninitialized ,死循环重试。

这不是配置错误,是 网络操作系统的 ABI 不匹配 。就像给 Windows 电脑装 Linux 内核驱动一样荒谬。

这五层信任链,环环相扣。少一个证书 SAN, apiserver 启不动; containerd systemd_cgroup 设错, kubelet 无法创建容器; kubelet kubeconfig 没切换,节点永远 NotReady ;CNI 配置路径错一位,所有 Pod 卡在 ContainerCreating 。所谓“快速”,是建立在对每一层“为什么必须这样”的透彻理解之上。接下来,我们就从最底层的证书开始,一步步把它立住。

3. 证书生成实战:用 cfssl 构建零信任根证书体系

跳过 openssl 手动敲命令的原始方式——它太容易出错,也难以复现。我们用 cfssl (CloudFlare SSL),它是 Kubernetes 官方文档推荐的证书工具,其 json 配置驱动模式,天然适配自动化部署。注意: cfssl 本身不参与集群运行,它只是个“证书工厂”,生成完即可卸载。

3.1 初始化 CA:一个命令,两个文件,三种权限

首先,创建 CA 配置文件 ca-config.json

{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
          "signing",
          "key encipherment",
          "server auth",
          "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}

这里的关键是 "usages" 数组:

  • "signing" :允许此 CA 签发其他证书;
  • "key encipherment" :允许加密密钥(用于 TLS 握手);
  • "server auth" :签发的证书可用于服务器身份验证(如 apiserver.pem );
  • "client auth" :签发的证书可用于客户端身份验证(如 admin.pem , kubelet.pem )。

如果漏掉 "client auth" kubelet kubelet-client-current.pem 连接 apiserver 时,会报 x509: certificate specifies an incompatible key usage

接着,创建 CA 证书签名请求 ca-csr.json

{
  "CN": "kubernetes-ca",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Haidian",
      "O": "k8s",
      "OU": "CA"
    }
  ]
}

执行生成命令:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

你会得到两个文件: ca.pem (公钥,分发给所有组件)和 ca-key.pem (私钥, 必须离线保管,永不上传服务器 )。 ca-key.pem 的权限必须是 600 ,且所在目录不能有 group other 的读写权限,否则 cfssl 会拒绝使用。

注意: cfssl 默认生成的证书有效期是 13 个月( 8760h ),这是 Kubernetes 社区的硬性建议。不要为了“省事”设成 87600h (10 年),因为证书轮换(rotation)是 K8s 安全基线的强制要求。1.34.2 的 kube-controller-manager 会自动为 kubelet 生成 1 年期证书,若 CA 有效期过长,轮换策略会失效。

3.2 生成 apiserver 证书:SAN 列表必须穷举所有访问入口

apiserver-csr.json 是整个集群最复杂的证书请求文件。它的 hosts 字段,必须包含所有可能访问 kube-apiserver 的地址:

{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Haidian",
      "O": "k8s",
      "OU": "apiserver"
    }
  ],
  "hosts": [
    "127.0.0.1",
    "10.0.1.10",     // master-1 内网 IP
    "10.0.1.11",     // master-2 内网 IP
    "10.0.1.100",    // VIP 或 LB IP
    "k8s-api.internal", // DNS 名称
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster.local"
  ]
}

重点解释 hosts 列表:

  • 127.0.0.1 kubernetes.default.svc.cluster.local kube-controller-manager kube-scheduler 本地连接 apiserver 所必需;
  • kubernetes.default.svc 是 Service 的 ClusterIP(通常是 10.96.0.1 ),但 apiserver 证书必须包含它,否则 coredns upstream 配置会因 SNI 不匹配而失败;
  • kubernetes Service 的名称,K8s 内部 DNS 会将其解析为 ClusterIP,但证书必须显式声明,否则 kubectl 通过 https://kubernetes 访问会报 x509: certificate is valid for kubernetes.default.svc.cluster.local, not kubernetes

生成命令:

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  apiserver-csr.json | cfssljson -bare apiserver

你会得到 apiserver.pem apiserver-key.pem 。用 openssl x509 -in apiserver.pem -text -noout | grep -A1 "Subject Alternative Name" 验证 SAN 是否完整。缺任何一个,后续 kubectl etcdctl 都会失败。

3.3 生成 etcd 证书:双向 TLS 的密钥交换

etcd 证书分为两套:

  • 服务端证书 :供 etcd 进程监听 2379 (client)和 2380 (peer)端口时使用;
  • 客户端证书 :供 kube-apiserver etcdctl 等客户端连接 etcd 时使用。

先生成 etcd-server-csr.json (服务端):

{
  "CN": "etcd-server",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Haidian",
      "O": "etcd",
      "OU": "server"
    }
  ],
  "hosts": [
    "127.0.0.1",
    "10.0.1.10",  // etcd-1 IP
    "10.0.1.11",  // etcd-2 IP
    "10.0.1.12"   // etcd-3 IP
  ]
}

再生成 etcd-client-csr.json (客户端):

{
  "CN": "etcd-client",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Haidian",
      "O": "etcd",
      "OU": "client"
    }
  ]
}

注意: etcd-client hosts 字段为空,因为它不用于服务端,只用于客户端身份认证,所以不需要 SAN。

生成命令:

# 服务端证书
cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  etcd-server-csr.json | cfssljson -bare etcd-server

# 客户端证书
cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  etcd-client-csr.json | cfssljson -bare etcd-client

你会得到四组文件: etcd-server.pem / etcd-server-key.pem etcd-client.pem / etcd-client-key.pem kube-apiserver 启动时, --etcd-certfile 必须指向 etcd-client.pem --etcd-keyfile 指向 etcd-client-key.pem --etcd-cafile 指向 ca.pem 。顺序错一个, apiserver 就起不来。

3.4 生成 admin 和 kubelet 证书:RBAC 权限的起点

admin-csr.json 是集群超级管理员证书,它决定了 kubectl 的最高权限:

{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Haidian",
      "O": "system:masters",  // 关键!绑定到 system:masters 组
      "OU": "admin"
    }
  ]
}

O 字段必须是 "system:masters" ,这是 Kubernetes RBAC 系统内置的超级用户组。如果写成 "k8s-admin" kubectl --user=admin get nodes 会返回 Error from server (Forbidden): nodes is forbidden: User "admin" cannot list resource "nodes" in API group "" at the cluster scope

kubelet-csr.json 则更精细,它需要为每个 Node 单独生成,且 CN 必须是 system:node:<nodename> O 必须是 system:nodes

{
  "CN": "system:node:master-1",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Haidian",
      "O": "system:nodes",  // 关键!绑定到 system:nodes 组
      "OU": "node"
    }
  ],
  "hosts": [
    "127.0.0.1",
    "10.0.1.10"
  ]
}

kubelet --hostname-override=master-1 参数,必须与 CN 中的 nodename 严格一致,否则 kube-apiserver NodeAuthorizer 会拒绝其心跳请求,节点状态永远是 NotReady

生成命令(以 master-1 为例):

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kubelet-csr.json | cfssljson -bare kubelet-master-1

你会得到 kubelet-master-1.pem kubelet-master-1-key.pem 。记住: kubelet 进程启动时, --cert-dir 目录下必须有这两个文件,且 --kubeconfig 指向的 kubeconfig 文件里, client-certificate-data client-key-data 必须是它们的 base64 编码。

这一整套证书体系,不是“生成完就完事”,而是要像管理密码一样管理: ca-key.pem 离线存 U 盘, *.pem *.key 文件用 ansible-vault 加密后存 Git,每次部署前解密。我见过太多团队把 ca-key.pem 传到 GitHub,还设成 public repo——这等于把整个集群的“根钥匙”挂在了互联网上。

4. 组件部署详解:从 etcd 集群到 kubelet 的七步连环

证书搞定,接下来是真正的“肌肉记忆”环节。我们按组件启动依赖顺序部署: etcd kube-apiserver kube-controller-manager kube-scheduler kubelet kube-proxy CNI 。每一步的启动参数,都不是随意写的,而是由上一步的输出决定。

4.1 etcd 集群:三节点高可用的最小可靠配置

etcd 是 Kubernetes 的“大脑”,它的稳定性直接决定集群生死。1.34.2 要求 etcd 版本 ≥ 3.5.10 。我们以三节点为例( etcd-1 , etcd-2 , etcd-3 ),IP 分别为 10.0.1.10 , 10.0.1.11 , 10.0.1.12

etcd-1 的 systemd service 文件 /etc/systemd/system/etcd.service

[Unit]
Description=etcd
Documentation=https://github.com/coreos/etcd
After=network.target

[Service]
Type=notify
User=etcd
ExecStart=/usr/local/bin/etcd \
  --name=etcd-1 \
  --data-dir=/var/lib/etcd \
  --wal-dir= \
  --snapshot-count=10000 \
  --heartbeat-interval=1000 \
  --election-timeout=10000 \
  --listen-peer-urls=https://10.0.1.10:2380 \
  --listen-client-urls=https://10.0.1.10:2379,https://127.0.0.1:2379 \
  --initial-advertise-peer-urls=https://10.0.1.10:2380 \
  --advertise-client-urls=https://10.0.1.10:2379 \
  --initial-cluster=etcd-1=https://10.0.1.10:2380,etcd-2=https://10.0.1.11:2380,etcd-3=https://10.0.1.12:2380 \
  --initial-cluster-token=etcd-cluster-1 \
  --initial-cluster-state=new \
  --client-cert-auth=true \
  --trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --cert-file=/etc/etcd/ssl/etcd-server.pem \
  --key-file=/etc/etcd/ssl/etcd-server-key.pem \
  --peer-client-cert-auth=true \
  --peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-cert-file=/etc/etcd/ssl/etcd-server.pem \
  --peer-key-file=/etc/etcd/ssl/etcd-server-key.pem \
  --log-output=stdout \
  --logger=zap \
  --log-level=info
Restart=on-failure
RestartSec=10
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

关键参数解析:

  • --initial-cluster :必须与所有节点的 --name --initial-advertise-peer-urls 完全一致,一个字母都不能错;
  • --client-cert-auth=true :开启客户端证书认证,这是 kube-apiserver 连接的前提;
  • --peer-client-cert-auth=true :开启 peer 节点间证书认证,防止非法节点加入集群;
  • --listen-client-urls :必须包含 127.0.0.1:2379 ,否则 etcdctl 本地调试会失败;
  • --advertise-client-urls :这是 etcd 对外宣告的客户端访问地址, kube-apiserver --etcd-servers 必须指向它。

注意: etcd --data-dir 目录必须是空的,且 etcd 用户对该目录有完全读写权限。 chown -R etcd:etcd /var/lib/etcd 是必须步骤。我曾在一个项目中,因 etcd 用户对 /var/lib/etcd 只有 r-x 权限, etcd 启动后日志显示 open /var/lib/etcd/member/snap/db: permission denied ,但进程状态是 active (running) ,导致排查走了巨大弯路。

启动命令(三台机器分别执行):

systemctl daemon-reload
systemctl enable etcd
systemctl start etcd

验证集群健康:

ETCDCTL_API=3 etcdctl \
  --endpoints=https://10.0.1.10:2379 \
  --cacert=/etc/etcd/ssl/ca.pem \
  --cert=/etc/etcd/ssl/etcd-client.pem \
  --key=/etc/etcd/ssl/etcd-client-key.pem \
  endpoint health

输出应为 https://10.0.1.10:2379 is healthy: successfully committed proposal: took = 12.345678ms 。如果任一节点返回 unhealthy ,立刻检查 journalctl -u etcd -n 100 ,重点关注 peer TLS client TLS 的 handshake 错误。

4.2 kube-apiserver:控制平面的唯一守门人

kube-apiserver 是单点启动,但必须能连接所有 etcd 节点。它的 service 文件 /etc/systemd/system/kube-apiserver.service

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
Type=notify
User=kube
ExecStart=/usr/local/bin/kube-apiserver \
  --advertise-address=10.0.1.10 \
  --allow-privileged=true \
  --authorization-mode=Node,RBAC \
  --client-ca-file=/etc/kubernetes/pki/ca.pem \
  --enable-admission-plugins=NodeRestriction,ValidatingAdmissionPolicy \
  --enable-bootstrap-token-auth=true \
  --etcd-cafile=/etc/kubernetes/pki/ca.pem \
  --etcd-certfile=/etc/kubernetes/pki/etcd-client.pem \
  --etcd-keyfile=/etc/kubernetes/pki/etcd-client-key.pem \
  --etcd-servers=https://10.0.1.10:2379,https://10.0.1.11:2379,https://10.0.1.12:2379 \
  --insecure-port=0 \
  --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.pem \
  --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client-key.pem \
  --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \
  --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem \
  --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem \
  --requestheader-allowed-names=front-proxy-client \
  --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem \
  --requestheader-extra-headers-prefix=X-Remote-Extra- \
  --requestheader-group-headers=X-Remote-Group \
  --requestheader-username-headers=X-Remote-User \
  --secure-port=6443 \
  --service-account-issuer=https://10.0.1.10:6443 \
  --service-account-key-file=/etc/kubernetes/pki/sa.pub \
  --service-account-signing-key-file=/etc/kubernetes/pki/sa.key \
  --service-cluster-ip-range=10.96.0.0/12 \
  --service-node-port-range=30000-32767 \
  --tls-cert-file=/etc/kubernetes/pki/apiserver.pem \
  --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem \
  --v=2
Restart=on-failure
RestartSec=10
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

核心参数说明:

  • --advertise-address apiserver 对外宣告的地址, kubelet --server 参数必须指向它;
  • --authorization-mode=Node,RBAC Node 模式允许 kubelet 有基本节点操作权限, RBAC 启用基于角色的访问控制;
  • --etcd-servers :必须列出所有 etcd 节点的 --advertise-client-urls ,用逗号分隔;
  • --service-cluster-ip-range :Service 的 ClusterIP 网段,必须与 kube-controller-manager --cluster-cidr 不重叠;
  • --tls-cert-file --tls-private-key-file :必须是你之前生成的 apiserver.pem apiserver-key.pem

启动前,必须生成 front-proxy 证书(用于聚合 API),以及 service-account 密钥:

# front-proxy CA
cfssl gencert -initca front-proxy-ca-csr.json | cfssljson -bare front-proxy-ca
cfssl g

更多推荐