mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Merge pull request #40316 from luxas/kubeadm_fix_apiserver_certs
Automatic merge from submit-queue (batch tested with PRs 40303, 40316) kubeadm: Fix up the apiserver kubelet client cert **What this PR does / why we need it**: I didn't notice that the apiserver serving cert was _only_ a server cert, not both a server and client cert in https://github.com/kubernetes/kubernetes/pull/40292. This PR fixes that misconception and generates a dedicated client cert for apiserver -> kubelet communication and harmonizes the `ca.crt` path to `/etc/kubernetes/pki/ca.crt` on both master and node. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes # **Special notes for your reviewer**: ```console $ systemctl cat kubelet # /lib/systemd/system/kubelet.service [Unit] Description=kubelet: The Kubernetes Node Agent Documentation=http://kubernetes.io/docs/ [Service] ExecStart=/usr/bin/kubelet Restart=always StartLimitInterval=0 RestartSec=10 [Install] WantedBy=multi-user.target # /etc/systemd/system/kubelet.service.d/10-kubeadm.conf [Service] Environment="KUBELET_KUBECONFIG_ARGS=--kubeconfig=/etc/kubernetes/kubelet.conf **--authorization-mode=Webhook --client-ca-file=/etc/kubernetes/pki/ca.crt** --require-kubeconfig=true" Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true" Environment="KUBELET_NETWORK_ARGS=--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin" Environment="KUBELET_DNS_ARGS=--cluster-dns=10.96.0.10 --cluster-domain=cluster.local" ExecStart= ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_NETWORK_ARGS $KUBELET_DNS_ARGS $KUBELET_EXTRA_ARGS $ curl -k https://localhost:10250/containerLogs/kube-system/weave-net-arm64-4t2xv/weave Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) $ curl --cert /etc/kubernetes/pki/apiserver-kubelet-client.crt --key /etc/kubernetes/pki/apiserver-kubelet-client.key -k https://localhost:10250/containerLogs/kube-system/weave-net-arm64-4t2xv/weave [Works!!] ``` **Release note**: ```release-note NONE ``` @liggitt @deads2k
This commit is contained in:
commit
0fac54e65e
@ -146,7 +146,7 @@ func (j *Join) Run(out io.Writer) error {
|
||||
|
||||
// Write the ca certificate to disk so kubelet can use it for authentication
|
||||
cluster := cfg.Contexts[cfg.CurrentContext].Cluster
|
||||
caCertFile := filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeadmconstants.CACertName)
|
||||
caCertFile := filepath.Join(kubeadmapi.GlobalEnvParams.HostPKIPath, kubeadmconstants.CACertName)
|
||||
err = certutil.WriteCert(caCertFile, cfg.Clusters[cluster].CertificateAuthorityData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't save the CA certificate to disk: %v", err)
|
||||
|
@ -24,4 +24,8 @@ const (
|
||||
APIServerCertAndKeyBaseName = "apiserver"
|
||||
APIServerCertName = "apiserver.crt"
|
||||
APIServerKeyName = "apiserver.key"
|
||||
|
||||
APIServerKubeletClientCertAndKeyBaseName = "apiserver-kubelet-client"
|
||||
APIServerKubeletClientCertName = "apiserver-kubelet-client.crt"
|
||||
APIServerKubeletClientKeyName = "apiserver-kubelet-client.key"
|
||||
)
|
||||
|
@ -322,8 +322,8 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) [
|
||||
"--client-ca-file="+getCertFilePath(kubeadmconstants.CACertName),
|
||||
"--tls-cert-file="+getCertFilePath(kubeadmconstants.APIServerCertName),
|
||||
"--tls-private-key-file="+getCertFilePath(kubeadmconstants.APIServerKeyName),
|
||||
"--kubelet-client-certificate="+getCertFilePath(kubeadmconstants.APIServerCertName),
|
||||
"--kubelet-client-key="+getCertFilePath(kubeadmconstants.APIServerKeyName),
|
||||
"--kubelet-client-certificate="+getCertFilePath(kubeadmconstants.APIServerKubeletClientCertName),
|
||||
"--kubelet-client-key="+getCertFilePath(kubeadmconstants.APIServerKubeletClientKeyName),
|
||||
"--token-auth-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/tokens.csv",
|
||||
fmt.Sprintf("--secure-port=%d", cfg.API.Port),
|
||||
"--allow-privileged",
|
||||
|
@ -376,8 +376,8 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||
"--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
|
||||
"--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
|
||||
"--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
||||
"--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
|
||||
"--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
||||
"--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.crt",
|
||||
"--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.key",
|
||||
"--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv",
|
||||
fmt.Sprintf("--secure-port=%d", 123),
|
||||
"--allow-privileged",
|
||||
@ -399,8 +399,8 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||
"--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
|
||||
"--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
|
||||
"--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
||||
"--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
|
||||
"--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
||||
"--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.crt",
|
||||
"--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.key",
|
||||
"--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv",
|
||||
fmt.Sprintf("--secure-port=%d", 123),
|
||||
"--allow-privileged",
|
||||
@ -424,8 +424,8 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||
"--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
|
||||
"--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
|
||||
"--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
||||
"--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
|
||||
"--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
||||
"--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.crt",
|
||||
"--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.key",
|
||||
"--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv",
|
||||
fmt.Sprintf("--secure-port=%d", 123),
|
||||
"--allow-privileged",
|
||||
@ -451,8 +451,8 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||
"--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
|
||||
"--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
|
||||
"--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
||||
"--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
|
||||
"--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
||||
"--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.crt",
|
||||
"--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.key",
|
||||
"--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv",
|
||||
fmt.Sprintf("--secure-port=%d", 123),
|
||||
"--allow-privileged",
|
||||
|
@ -110,7 +110,7 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiDir string) error {
|
||||
// If at least one of them exists, we should try to load them
|
||||
// In the case that only one exists, there will most likely be an error anyway
|
||||
if pkiutil.CertOrKeyExist(pkiDir, kubeadmconstants.APIServerCertAndKeyBaseName) {
|
||||
// Try to load ca.crt and ca.key from the PKI directory
|
||||
// Try to load apiserver.crt and apiserver.key from the PKI directory
|
||||
apiCert, apiKey, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, kubeadmconstants.APIServerCertAndKeyBaseName)
|
||||
if err != nil || apiCert == nil || apiKey == nil {
|
||||
return fmt.Errorf("certificate and/or key existed but they could not be loaded properly")
|
||||
@ -123,9 +123,7 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiDir string) error {
|
||||
config := certutil.Config{
|
||||
CommonName: "kube-apiserver",
|
||||
AltNames: altNames,
|
||||
// This makes the apiserver allowed to talk to the kubelets in the cluster
|
||||
Organization: []string{"system:masters"},
|
||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
apiCert, apiKey, err := pkiutil.NewCertAndKey(caCert, caKey, config)
|
||||
if err != nil {
|
||||
@ -138,6 +136,35 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiDir string) error {
|
||||
fmt.Println("[certificates] Generated API server certificate and key.")
|
||||
}
|
||||
|
||||
// If at least one of them exists, we should try to load them
|
||||
// In the case that only one exists, there will most likely be an error anyway
|
||||
if pkiutil.CertOrKeyExist(pkiDir, kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName) {
|
||||
// Try to load apiserver-kubelet-client.crt and apiserver-kubelet-client.key from the PKI directory
|
||||
apiCert, apiKey, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName)
|
||||
if err != nil || apiCert == nil || apiKey == nil {
|
||||
return fmt.Errorf("certificate and/or key existed but they could not be loaded properly")
|
||||
}
|
||||
|
||||
fmt.Println("[certificates] Using the existing API Server kubelet client certificate and key.")
|
||||
} else {
|
||||
// The certificate and the key did NOT exist, let's generate them now
|
||||
// TODO: Add a test case to verify that this cert has the x509.ExtKeyUsageClientAuth flag
|
||||
config := certutil.Config{
|
||||
CommonName: "kube-apiserver-kubelet-client",
|
||||
Organization: []string{"system:masters"},
|
||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
}
|
||||
apiClientCert, apiClientKey, err := pkiutil.NewCertAndKey(caCert, caKey, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failure while creating API server kubelet client key and certificate [%v]", err)
|
||||
}
|
||||
|
||||
if err = pkiutil.WriteCertAndKey(pkiDir, kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName, apiClientCert, apiClientKey); err != nil {
|
||||
return fmt.Errorf("failure while saving API server kubelet client certificate and key [%v]", err)
|
||||
}
|
||||
fmt.Println("[certificates] Generated API server kubelet client certificate and key.")
|
||||
}
|
||||
|
||||
fmt.Printf("[certificates] Valid certificates and keys now exist in %q\n", pkiDir)
|
||||
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user