如何使 kubeadm init 与外部 CA 一起工作?

如何使 kubeadm init 与外部 CA 一起工作?

我正在尝试使用自己的证书颁发机构 (CA) 来引导 Kubernetes 集群。我正在遵循Kubernetes 强化指南,建议为 etcd 和其余控制平面设置单独的 CA。除此之外,我还为前端代理证书设置了一个外部 CA,这样就一共有三个 CA。我使用 Vault 生成这些 CA,利用了离线根 CA。

此外,我的集群设计为与已经运行的外部 etcd 集群协同工作。

我关注了外部 CA 文档PKI 要求PKI requirements生成证书并将其放在我的控制平面节点上后,我拥有以下目录结构:

tree /etc/kubernetes/
/etc/kubernetes/
├── manifests
└── pki
    ├── apiserver.crt
    ├── apiserver-etcd-client.crt
    ├── apiserver-etcd-client.key
    ├── apiserver.key
    ├── apiserver-kubelet-client.crt
    ├── apiserver-kubelet-client.key
    ├── ca.crt
    ├── etcd
    │   ├── ca.crt
    │   ├── healthcheck-client.crt
    │   └── healthcheck-client.key
    ├── front-proxy-ca.crt
    ├── front-proxy-client.crt
    └── front-proxy-client.key

4 directories, 13 files

高可用性,我设立了我的kubeadm-config.yaml如下:

apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: stable
controlPlaneEndpoint: "load_balencer_dns_name:6443"
networking:
  podSubnet: "192.168.0.0/16"
etcd:
  external:
    endpoints:
      - "https://ip_node_1:2379"
      - "https://ip_node_2:2379"
      - "https://ip_node_3:2379"
    caFile: "/etc/kubernetes/pki/etcd/ca.crt"
    certFile: "/etc/kubernetes/pki/apiserver-etcd-client.crt"
    keyFile: "/etc/kubernetes/pki/apiserver-etcd-client.key"

然而,在运行时

kubeadm init --config kubeadm-config.yaml --upload-certs --v=6

我遇到了以下错误:

I0315 16:38:30.120235   39470 initconfiguration.go:260] loading configuration from "kubeadm-config.yaml"
I0315 16:38:30.121084   39470 initconfiguration.go:122] detected and using CRI socket: unix:///var/run/crio/crio.sock
I0315 16:38:30.121228   39470 interface.go:432] Looking for default routes with IPv4 addresses
I0315 16:38:30.121243   39470 interface.go:437] Default route transits interface "ens18"
I0315 16:38:30.121333   39470 interface.go:209] Interface ens18 is up
I0315 16:38:30.121378   39470 interface.go:257] Interface "ens18" has 2 addresses :[ip].
I0315 16:38:30.121396   39470 interface.go:224] Checking addr  ip/cidr.
I0315 16:38:30.121409   39470 interface.go:231] IP found ip
I0315 16:38:30.121428   39470 interface.go:263] Found valid IPv4 address ip for interface "ens18".
I0315 16:38:30.121437   39470 interface.go:443] Found active IP ip 
I0315 16:38:30.121457   39470 kubelet.go:196] the value of KubeletConfiguration.cgroupDriver is empty; setting it to "systemd"
I0315 16:38:30.127682   39470 version.go:187] fetching Kubernetes version from URL: https://dl.k8s.io/release/stable.txt
I0315 16:38:30.713146   39470 certs.go:519] validating certificate period for CA certificate
I0315 16:38:30.713239   39470 certs.go:519] validating certificate period for API server certificate
I0315 16:38:30.713859   39470 certs.go:519] validating certificate period for API server kubelet client certificate
I0315 16:38:30.714411   39470 certs.go:519] validating certificate period for ca certificate
stat /etc/kubernetes/controller-manager.conf: no such file or directory
the controller-manager.conf file does not exists or it is not valid
k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig.ValidateKubeconfigsForExternalCA
    cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go:406
k8s.io/kubernetes/cmd/kubeadm/app/cmd.newInitData
    cmd/kubeadm/app/cmd/init.go:368
k8s.io/kubernetes/cmd/kubeadm/app/cmd.newCmdInit.func3
    cmd/kubeadm/app/cmd/init.go:170
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).InitData
    cmd/kubeadm/app/cmd/phases/workflow/runner.go:183
k8s.io/kubernetes/cmd/kubeadm/app/cmd.newCmdInit.func1
    cmd/kubeadm/app/cmd/init.go:116
github.com/spf13/cobra.(*Command).execute
    vendor/github.com/spf13/cobra/command.go:940
github.com/spf13/cobra.(*Command).ExecuteC
    vendor/github.com/spf13/cobra/command.go:1068
github.com/spf13/cobra.(*Command).Execute
    vendor/github.com/spf13/cobra/command.go:992
k8s.io/kubernetes/cmd/kubeadm/app.Run
    cmd/kubeadm/app/kubeadm.go:50
main.main
    cmd/kubeadm/kubeadm.go:25
runtime.main
    /usr/local/go/src/runtime/proc.go:267
runtime.goexit
    /usr/local/go/src/runtime/asm_amd64.s:1650

经过研究,我发现ServerFault 上的这个问题这表明,在外部 CA 模式下,需要先配置其他文件。但是,我无法确认这一点。

我还尝试通过运行来拆分 kubeadm init

kubeadm init phase kubeconfig controller-manager --config kubeadm-config.yaml

但最终我遇到了和以前一样的错误。

我的kubeadm、kubelet、kubectl都是版本1.29.2。我甚至尝试修改我的 kubeadm-config 文件,指定

kubernetesVersion: "1.29.2"

但仍然遇到同样的错误。

我现在正在寻求社区的帮助!

编辑:

我也遇到了这个--ignore-preflight-errors参数并尝试将其传递给我的 kubeadm init 命令:

kubeadm init --ignore-preflight-errors=All --config kubeadm-config.yaml

但仍然有同样的错误

答案1

参考此处的解决方法昏睡,他们所做的是让 kubeadm 为集群本身创建内部证书,而 etcd 的证书将由 vault 颁发。他们将 etcd 证书注入到控制平面节点的 cloudinit 配置文件中,而无需先从 etcd 节点中提取该信息。

您可以尝试一种解决方法,即创建缺少的配置文件,/etc/kubernetes/controller-manager.conf并使用引用控制器管理器的预生成证书的必要参数来创建手动配置。然后指定选项并引用 API 服务器证书。以下是参考文档

您可以尝试kubeadm init使用 分离阶段kubeadm init phases control-plane --config.yaml来初始化控制平面,而无需通过 kubeadm 生成证书。这将在 中创建必要的静态 Pod 清单/etc/kubernetes/manifests,但不会生成证书或配置文件。之后,手动将预生成的证书放在适当的位置(/etc/kubernetes/pki)并创建配置文件,例如controller-manager.conf。然后运行kubeadm init phase kubeconfig --config kubeadm-config.yaml以根据现有证书生成 kubeconfig 文件。

相关内容