• Kubeadm证书过期时间调整


    kubeadm 默认证书为一年,一年过期后,会导致api service不可用,使用过程中会出现:x509: certificate has expired or is not yet valid.

    方案一 通过修改kubeadm 调整证书过期时间

    修改代码,调整过期时间

    克隆代码:git clone https://github.com/kubernetes/kubernetes.git, 切换到指定的tag或者版本修改vendor/k8s.io/client-go/util/cert/cert.go文件,git diff 对比如下:

    diff --git a/staging/src/k8s.io/client-go/util/cert/cert.go b/staging/src/k8s.io/client-go/util/cert/cert.go
    index fb7f5fa..e800962 100644
    --- a/staging/src/k8s.io/client-go/util/cert/cert.go
    +++ b/staging/src/k8s.io/client-go/util/cert/cert.go
    @@ -104,7 +104,7 @@ func NewSignedCert(cfg Config, key *rsa.PrivateKey, caCert *x509.Certificate, ca
                    IPAddresses:  cfg.AltNames.IPs,
                    SerialNumber: serial,
                    NotBefore:    caCert.NotBefore,
    -               NotAfter:     time.Now().Add(duration365d).UTC(),
    +               NotAfter:     time.Now().Add(duration365d * 10).UTC(),
                    KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
                    ExtKeyUsage:  cfg.Usages,
            }
    @@ -149,7 +149,7 @@ func GenerateSelfSignedCertKey(host string, alternateIPs []net.IP, alternateDNS
                            CommonName: fmt.Sprintf("%s-ca@%d", host, time.Now().Unix()),
                    },
                    NotBefore: time.Now(),
    -               NotAfter:  time.Now().Add(time.Hour * 24 * 365),
    +               NotAfter:  time.Now().Add(time.Hour * 24 * 3650),
    
                    KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
                    BasicConstraintsValid: true,

    编译代码

    这里我们可以使用官方容器对代码进行编译。

    k8s.gcr.io/kube-cross:v1.12.5-1,如果不能翻墙的用户,可以拉取我个人下的镜像skymyyang/kube-cross:v1.12.5-1

    docker pull skymyyang/kube-cross:v1.12.5-1

    编译

    docker run --rm -v 你修改后的代码目录:/go/src/k8s.io/kubernetes -it skymyyang/kube-cross:v1.12.5-1 bash
    
    cd /go/src/k8s.io/kubernetes
    
    # 编译kubeadm, 这里主要编译kubeadm 即可
    make all WHAT=cmd/kubeadm GOFLAGS=-v
    
    # 编译kubelet
    # make all WHAT=cmd/kubelet GOFLAGS=-v
    
    # 编译kubectl
    # make all WHAT=cmd/kubectl GOFLAGS=-v
    
    #编译完产物在 _output/bin/kubeadm 目录下
    #将kubeadm 文件拷贝出来,替换系统中的kubeadm

    替换证书

    #用新的kubeadm 替换官方的kubeadm
    chmod +x kubeadm && cp -f kubeadm /usr/bin
    
    #备份原有的证书
    mv /etc/kubernetes/pki /etc/kubernetes/pki.old
    
    #生成新的证书,kubeadm.yaml 指定你自己服务器上的
    kubeadm alpha phase certs all --config  ~/kubeadm.yaml
    
    #备份原有的conf文件
    mv /etc/kubernetes/*conf /etc/kubernetes/*conf-old
    
    #根据新证书重新生成新的配置文件
    kubeadm alpha phase kubeconfig all --config ~/kubeadm.yaml
    
    #替换老的config文件
    cp -f /etc/kubernetes/admin.conf ~/.kube/config

    方案二 启用自动轮换kubelet 证书

    kubelet证书分为server和client两种, k8s 1.9默认启用了client证书的自动轮换,但server证书自动轮换需要用户开启

    增加 kubelet 参数

    # 在/etc/systemd/system/kubelet.service.d/10-kubeadm.conf 增加如下参数
    Environment="KUBELET_EXTRA_ARGS=--feature-gates=RotateKubeletServerCertificate=true"

    增加 controller-manager 参数

    # 在/etc/kubernetes/manifests/kube-controller-manager.yaml 添加如下参数
      - command:
        - kube-controller-manager
        - --experimental-cluster-signing-duration=87600h0m0s
        - --feature-gates=RotateKubeletServerCertificate=true
        - ....

    创建 rbac 对象

    创建rbac对象,允许节点轮换kubelet server证书:

    cat > ca-update.yaml << EOF
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      annotations:
        rbac.authorization.kubernetes.io/autoupdate: "true"
      labels:
        kubernetes.io/bootstrapping: rbac-defaults
      name: system:certificates.k8s.io:certificatesigningrequests:selfnodeserver
    rules:
    - apiGroups:
      - certificates.k8s.io
      resources:
      - certificatesigningrequests/selfnodeserver
      verbs:
      - create
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: kubeadm:node-autoapprove-certificate-server
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:certificates.k8s.io:certificatesigningrequests:selfnodeserver
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: Group
      name: system:nodes
    EOF
    
    kubectl create –f ca-update.yaml

    如果证书已经过期,如何进行重新签发证书

    针对kubeadm 1.13.x 及以上处理

    准备kubeadm.conf 配置文件一份
    apiVersion: kubeadm.k8s.io/v1beta1
    kind: ClusterConfiguration
    kubernetesVersion: v1.14.1 #-->这里改成你集群对应的版本
    imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers 
    #这里使用国内的镜像仓库,否则在重新签发的时候会报错:could not fetch a Kubernetes version from the internet: unable to get URL "https://dl.k8s.io/release/stable-1.txt"
    重新签发命令
    kubeadm alpha certs renew all --config=/root/kubeadm.conf
    
    运行如上命令会重新生成以下证书
    #-- /etc/kubernetes/pki/apiserver.key
    #-- /etc/kubernetes/pki/apiserver.crt
    
    #-- /etc/kubernetes/pki/apiserver-etcd-client.key
    #-- /etc/kubernetes/pki/apiserver-etcd-client.crt
    
    #-- /etc/kubernetes/pki/apiserver-kubelet-client.key
    #-- /etc/kubernetes/pki/apiserver-kubelet-client.crt
    
    #-- /etc/kubernetes/pki/front-proxy-client.key
    #-- /etc/kubernetes/pki/front-proxy-client.crt
    
    #-- /etc/kubernetes/pki/etcd/healthcheck-client.key
    #-- /etc/kubernetes/pki/etcd/healthcheck-client.crt
    
    #-- /etc/kubernetes/pki/etcd/peer.key
    #-- /etc/kubernetes/pki/etcd/peer.crt
    
    #-- /etc/kubernetes/pki/etcd/server.key
    #-- /etc/kubernetes/pki/etcd/server.crt
    完成后重启kube-apiserver,kube-controller,kube-scheduler,etcd这4个容器

    针对kubeadm 1.13.0(不包含1.13.0) 以下处理

    移动证书和配置【注意!必须移动,不然会使用现有的证书,不会重新生成】
    cd /etc/kubernetes
    mkdir ./pki_bak
    mkdir ./pki_bak/etcd
    mkdir ./conf_bak
    mv pki/apiserver* ./pki_bak/
    mv pki/front-proxy-client.* ./pki_bak/
    mv pki/etcd/healthcheck-client.* ./pki_bak/etcd/
    mv pki/etcd/peer.* ./pki_bak/etcd/
    mv pki/etcd/server.* ./pki_bak/etcd/
    mv ./admin.conf ./conf_bak/
    mv ./kubelet.conf ./conf_bak/
    mv ./controller-manager.conf ./conf_bak/
    mv ./scheduler.conf ./conf_bak/
    创建证书
    kubeadm alpha phase certs all --apiserver-advertise-address=${MASTER_API_SERVER_IP} --apiserver-cert-extra-sans=主机内网ip,主机公网ip
    
    运行如上命令会重新生成以下证书
    #-- /etc/kubernetes/pki/apiserver.key
    #-- /etc/kubernetes/pki/apiserver.crt
    
    #-- /etc/kubernetes/pki/apiserver-etcd-client.key
    #-- /etc/kubernetes/pki/apiserver-etcd-client.crt
    
    #-- /etc/kubernetes/pki/apiserver-kubelet-client.key
    #-- /etc/kubernetes/pki/apiserver-kubelet-client.crt
    
    #-- /etc/kubernetes/pki/front-proxy-client.key
    #-- /etc/kubernetes/pki/front-proxy-client.crt
    
    #-- /etc/kubernetes/pki/etcd/healthcheck-client.key
    #-- /etc/kubernetes/pki/etcd/healthcheck-client.crt
    
    #-- /etc/kubernetes/pki/etcd/peer.key
    #-- /etc/kubernetes/pki/etcd/peer.crt
    
    #-- /etc/kubernetes/pki/etcd/server.key
    #-- /etc/kubernetes/pki/etcd/server.crt
    
    不移动证书会有如下提示
    #[certificates] Using the existing apiserver certificate and key.
    #[certificates] Using the existing apiserver-kubelet-client certificate and key.
    #[certificates] Using the existing front-proxy-client certificate and key.
    #[certificates] Using the existing etcd/server certificate and key.
    #[certificates] Using the existing etcd/peer certificate and key.
    #[certificates] Using the existing etcd/healthcheck-client certificate and key.
    #[certificates] Using the existing apiserver-etcd-client certificate and key.
    #[certificates] valid certificates and keys now exist in "/etc/kubernetes/pki"
    #[certificates] Using the existing sa key.
    生成新配置文件
    kubeadm alpha phase kubeconfig all --apiserver-advertise-address=${MASTER_API_SERVER_IP}
    将新生成的admin配置文件覆盖掉原本的admin文件
    mv $HOME/.kube/config $HOME/.kube/config.old
    cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    chown $(id -u):$(id -g) $HOME/.kube/config
    sudo chmod 777 $HOME/.kube/config
    完成后重启kube-apiserver,kube-controller,kube-scheduler,etcd这4个容器
    如果有多台master,则将第一台生成的相关证书拷贝到其余master即可。

    kubeadm 1.14 证书调整教程

    kubeadm部署的kubernets证书一直都是个诟病,默认都只有一年有效期,kubeadm 1.14.x安装后有部分证书还是一年有效期,但个别证书已修改为10年有效期,但对我们使用来说,一年有效期还是一个比较的坑,需要进行调整。

    修改kubeadm 1.14.x源码,调整证书过期时间

    kubeadm1.14.x 安装过后crt证书如下所示

    /etc/kubernetes/pki/apiserver.crt
    /etc/kubernetes/pki/front-proxy-ca.crt         #10年有效期
    /etc/kubernetes/pki/ca.crt                     #10年有效期
    /etc/kubernetes/pki/apiserver-etcd-client.crt
    /etc/kubernetes/pki/front-proxy-client.crt     #10年有效期
    /etc/kubernetes/pki/etcd/server.crt
    /etc/kubernetes/pki/etcd/ca.crt                #10年有效期
    /etc/kubernetes/pki/etcd/peer.crt              #10年有效期
    /etc/kubernetes/pki/etcd/healthcheck-client.crt
    /etc/kubernetes/pki/apiserver-kubelet-client.crt

    如上所示,除了标注说明的证书为10年有效期,其余都是1年有效期,我们查看下原先调整证书有效期的源码,克隆kubernetes 源码,切换到1.14.1 tag 查看:
    代码目录: staging/src/k8s.io/client-go/util/cert/cert.go

    const duration365d = time.Hour * 24 * 365
    
    func NewSelfSignedCACert(cfg Config, key crypto.Signer) (*x509.Certificate, error) {
        now := time.Now()
        tmpl := x509.Certificate{
            SerialNumber: new(big.Int).SetInt64(0),
            Subject: pkix.Name{
                CommonName:   cfg.CommonName,
                Organization: cfg.Organization,
            },
            NotBefore:             now.UTC(),
            //这里已经调整为10年有效期
            NotAfter:              now.Add(duration365d * 10).UTC(),
            KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
            BasicConstraintsValid: true,
            IsCA:                  true,
        }
    
        certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &tmpl, &tmpl, key.Public(), key)
        if err != nil {
            return nil, err
        }
        return x509.ParseCertificate(certDERBytes)
    }

    如上所示,通过NewSelfSignedCACert这个方法签发的证书都默认为10年有效期了,但这个只影响部分证书,但这样还没满足我们的需求,个别证书的有效期调整,在经过对源码的分析后,找到了如下的逻辑:

    发现部分证书是通过NewSignedCert这个方法签发,而这个方法签发的证书默认只有一年有效期,查看代码逻辑:
    代码: cmd/kubeadm/app/util/pkiutil/pki_helpers.go

    const duration365d = time.Hour * 24 * 365
    
    func NewSignedCert(cfg *certutil.Config, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer) (*x509.Certificate, error) {
        serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
        if err != nil {
            return nil, err
        }
        if len(cfg.CommonName) == 0 {
            return nil, errors.New("must specify a CommonName")
        }
        if len(cfg.Usages) == 0 {
            return nil, errors.New("must specify at least one ExtKeyUsage")
        }
    
        certTmpl := x509.Certificate{
            Subject: pkix.Name{
                CommonName:   cfg.CommonName,
                Organization: cfg.Organization,
            },
            DNSNames:     cfg.AltNames.DNSNames,
            IPAddresses:  cfg.AltNames.IPs,
            SerialNumber: serial,
            NotBefore:    caCert.NotBefore,
            // 只有一年有效期
            NotAfter:     time.Now().Add(duration365d).UTC(),
            KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
            ExtKeyUsage:  cfg.Usages,
        }
        certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &certTmpl, caCert, key.Public(), caKey)
        if err != nil {
            return nil, err
        }
        return x509.ParseCertificate(certDERBytes)
    }

    至此,调整NewSignedCert这个方法,重新进行编译,将证书有效期调整为你想要的任何时间。

    原文链接:

    http://icyxp.github.io/blog/2019/05/k8s-kubeadm14-ca-upgrade.html
  • 相关阅读:
    基础算法:求目标值 &字符串反转
    算法计算出股票最佳交易时间点
    Python 设计模式—命令模式
    Python 设计模式—代理模式
    有趣的算法题~单调栈
    令人头大的字符串—算法处理
    WebUI 自动化测试的经典设计模式:PO
    双指针—滑动窗口算法解析
    Python 设计模式—观察者模式
    多线程之读写锁原理
  • 原文地址:https://www.cnblogs.com/skymyyang/p/11093686.html
Copyright © 2020-2023  润新知