zoukankan      html  css  js  c++  java
  • kubeadm证书过期解决方案

    整个集群过期. date -s "2022-08-29 16:48:50"

    [root@master kubernetes]# kubectl get nodes
    Unable to connect to the server: x509: certificate has expired or is not yet valid: current time 2022-08-29T16:49:57+08:00 is after 2022-08-29T08:49:33Z
    
    
    /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --hostname-override=master1 --network-plugin=cni --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
    
    /opt/MegaRAID/MegaCli/MegaCli64 -LdPdInfo -aALL | egrep "Slot Number" | awk -F " " '{print $3}'
    

    kubeadm安装的集群证书过期

    查看证书的时间

    kubeadm alpha certs check-expiration
    

    使用openssl命令查看

    openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text
    

    重新生成证书

    kubeadm alpha certs renew all
    

    重新生成配置文件,默认是向后延期一年

    kubeadm init phase kubeconfig all
    

    重新生成config证书

    cp /etc/kubernetes/admin.conf ~/.kube/config
    

    移除集群自动生成的证书

    mv /var/lib/kubelet/pki /var/lib/kubelet/pki.old
    

    重启k8s组件服务

    docker ps -a | grep -v pause | grep -E "etcd|scheduler|controller|apiserver" | awk '{print $1}' | awk '{print "docker","restart",$1}' | bash
    

    重启kubelet

    systemctl restart kubelet
    systemctl status kubelet
    

    开始授权

    kubectl get csr     				# 获取第一列的csr
    kubectl certificate approve csr-xxxx
    

    shell脚本

    #!/bin/bash
    
    set -o errexit
    set -o pipefail
    # set -o xtrace
    
    log::err() {
      printf "[$(date +'%Y-%m-%dT%H:%M:%S.%N%z')]: 33[31mERROR: 33[0m$@
    "
    }
    
    log::info() {
      printf "[$(date +'%Y-%m-%dT%H:%M:%S.%N%z')]: 33[32mINFO: 33[0m$@
    "
    }
    
    log::warning() {
      printf "[$(date +'%Y-%m-%dT%H:%M:%S.%N%z')]: 33[33mWARNING: 33[0m$@
    "
    }
    
    check_file() {
      if [[ ! -r  ${1} ]]; then
        log::err "can not find ${1}"
        exit 1
      fi
    }
    
    # get x509v3 subject alternative name from the old certificate
    cert::get_subject_alt_name() {
      local cert=${1}.crt
      check_file "${cert}"
      local alt_name=$(openssl x509 -text -noout -in ${cert} | grep -A1 'Alternative' | tail -n1 | sed 's/[[:space:]]*Address//g')
      printf "${alt_name}
    "
    }
    
    # get subject from the old certificate
    cert::get_subj() {
      local cert=${1}.crt
      check_file "${cert}"
      local subj=$(openssl x509 -text -noout -in ${cert}  | grep "Subject:" | sed 's/Subject:///g;s/\,///;s/[[:space:]]//g')
      printf "${subj}
    "
    }
    
    cert::backup_file() {
      local file=${1}
      if [[ ! -e ${file}.old-$(date +%Y%m%d) ]]; then
        cp -rp ${file} ${file}.old-$(date +%Y%m%d)
        log::info "backup ${file} to ${file}.old-$(date +%Y%m%d)"
      else
        log::warning "does not backup, ${file}.old-$(date +%Y%m%d) already exists"
      fi
    }
    
    # generate certificate whit client, server or peer
    # Args:
    #   $1 (the name of certificate)
    #   $2 (the type of certificate, must be one of client, server, peer)
    #   $3 (the subject of certificates)
    #   $4 (the validity of certificates) (days)
    #   $5 (the x509v3 subject alternative name of certificate when the type of certificate is server or peer)
    cert::gen_cert() {
      local cert_name=${1}
      local cert_type=${2}
      local subj=${3}
      local cert_days=${4}
      local alt_name=${5}
      local cert=${cert_name}.crt
      local key=${cert_name}.key
      local csr=${cert_name}.csr
      local csr_conf="distinguished_name = dn
    [dn]
    [v3_ext]
    keyUsage = critical, digitalSignature, keyEncipherment
    "
    
      check_file "${key}"
      check_file "${cert}"
    
      # backup certificate when certificate not in ${kubeconf_arr[@]}
      # kubeconf_arr=("controller-manager.crt" "scheduler.crt" "admin.crt" "kubelet.crt")
      # if [[ ! "${kubeconf_arr[@]}" =~ "${cert##*/}" ]]; then
      #   cert::backup_file "${cert}"
      # fi
    
      case "${cert_type}" in
        client)
          openssl req -new  -key ${key} -subj "${subj}" -reqexts v3_ext 
            -config <(printf "${csr_conf} extendedKeyUsage = clientAuth
    ") -out ${csr}
          openssl x509 -in ${csr} -req -CA ${CA_CERT} -CAkey ${CA_KEY} -CAcreateserial -extensions v3_ext 
            -extfile <(printf "${csr_conf} extendedKeyUsage = clientAuth
    ") -days ${cert_days} -out ${cert}
          log::info "generated ${cert}"
        ;;
        server)
          openssl req -new  -key ${key} -subj "${subj}" -reqexts v3_ext 
            -config <(printf "${csr_conf} extendedKeyUsage = serverAuth
    subjectAltName = ${alt_name}
    ") -out ${csr}
          openssl x509 -in ${csr} -req -CA ${CA_CERT} -CAkey ${CA_KEY} -CAcreateserial -extensions v3_ext 
            -extfile <(printf "${csr_conf} extendedKeyUsage = serverAuth
    subjectAltName = ${alt_name}
    ") -days ${cert_days} -out ${cert}
          log::info "generated ${cert}"
        ;;
        peer)
          openssl req -new  -key ${key} -subj "${subj}" -reqexts v3_ext 
            -config <(printf "${csr_conf} extendedKeyUsage = serverAuth, clientAuth
    subjectAltName = ${alt_name}
    ") -out ${csr}
          openssl x509 -in ${csr} -req -CA ${CA_CERT} -CAkey ${CA_KEY} -CAcreateserial -extensions v3_ext 
            -extfile <(printf "${csr_conf} extendedKeyUsage = serverAuth, clientAuth
    subjectAltName = ${alt_name}
    ") -days ${cert_days} -out ${cert}
          log::info "generated ${cert}"
        ;;
        *)
          log::err "unknow, unsupported etcd certs type: ${cert_type}, supported type: client, server, peer"
          exit 1
      esac
    
      rm -f ${csr}
    }
    
    cert::update_kubeconf() {
      local cert_name=${1}
      local kubeconf_file=${cert_name}.conf
      local cert=${cert_name}.crt
      local key=${cert_name}.key
    
      # generate  certificate
      check_file ${kubeconf_file}
      # get the key from the old kubeconf
      grep "client-key-data" ${kubeconf_file} | awk {'print$2'} | base64 -d > ${key}
      # get the old certificate from the old kubeconf
      grep "client-certificate-data" ${kubeconf_file} | awk {'print$2'} | base64 -d > ${cert}
      # get subject from the old certificate
      local subj=$(cert::get_subj ${cert_name})
      cert::gen_cert "${cert_name}" "client" "${subj}" "${CAER_DAYS}"
      # get certificate base64 code
      local cert_base64=$(base64 -w 0 ${cert})
    
      # backup kubeconf
      # cert::backup_file "${kubeconf_file}"
    
      # set certificate base64 code to kubeconf
      sed -i 's/client-certificate-data:.*/client-certificate-data: '${cert_base64}'/g' ${kubeconf_file}
    
      log::info "generated new ${kubeconf_file}"
      rm -f ${cert}
      rm -f ${key}
    
      # set config for kubectl
      if [[ ${cert_name##*/} == "admin" ]]; then
        mkdir -p ${HOME}/.kube
        local config=${HOME}/.kube/config
        local config_backup=${HOME}/.kube/config.old-$(date +%Y%m%d)
        if [[ -f ${config} ]] && [[ ! -f ${config_backup} ]]; then
          cp -fp ${config} ${config_backup}
          log::info "backup ${config} to ${config_backup}"
        fi
        cp -fp ${kubeconf_file} ${HOME}/.kube/config
        log::info "copy the admin.conf to ${HOME}/.kube/config for kubectl"
      fi
    }
    
    cert::update_etcd_cert() {
      PKI_PATH=${KUBE_PATH}/pki/etcd
      CA_CERT=${PKI_PATH}/ca.crt
      CA_KEY=${PKI_PATH}/ca.key
    
      check_file "${CA_CERT}"
      check_file "${CA_KEY}"
    
      # generate etcd server certificate
      # /etc/kubernetes/pki/etcd/server
      CART_NAME=${PKI_PATH}/server
      subject_alt_name=$(cert::get_subject_alt_name ${CART_NAME})
      cert::gen_cert "${CART_NAME}" "peer" "/CN=etcd-server" "${CAER_DAYS}" "${subject_alt_name}"
    
      # generate etcd peer certificate
      # /etc/kubernetes/pki/etcd/peer
      CART_NAME=${PKI_PATH}/peer
      subject_alt_name=$(cert::get_subject_alt_name ${CART_NAME})
      cert::gen_cert "${CART_NAME}" "peer" "/CN=etcd-peer" "${CAER_DAYS}" "${subject_alt_name}"
    
      # generate etcd healthcheck-client certificate
      # /etc/kubernetes/pki/etcd/healthcheck-client
      CART_NAME=${PKI_PATH}/healthcheck-client
      cert::gen_cert "${CART_NAME}" "client" "/O=system:masters/CN=kube-etcd-healthcheck-client" "${CAER_DAYS}"
    
      # generate apiserver-etcd-client certificate
      # /etc/kubernetes/pki/apiserver-etcd-client
      check_file "${CA_CERT}"
      check_file "${CA_KEY}"
      PKI_PATH=${KUBE_PATH}/pki
      CART_NAME=${PKI_PATH}/apiserver-etcd-client
      cert::gen_cert "${CART_NAME}" "client" "/O=system:masters/CN=kube-apiserver-etcd-client" "${CAER_DAYS}"
    
      # restart etcd
      docker ps | awk '/k8s_etcd/{print$1}' | xargs -r -I '{}' docker restart {} || true
      log::info "restarted etcd"
    }
    
    cert::update_master_cert() {
      PKI_PATH=${KUBE_PATH}/pki
      CA_CERT=${PKI_PATH}/ca.crt
      CA_KEY=${PKI_PATH}/ca.key
    
      check_file "${CA_CERT}"
      check_file "${CA_KEY}"
    
      # generate apiserver server certificate
      # /etc/kubernetes/pki/apiserver
      CART_NAME=${PKI_PATH}/apiserver
      subject_alt_name=$(cert::get_subject_alt_name ${CART_NAME})
      cert::gen_cert "${CART_NAME}" "server" "/CN=kube-apiserver" "${CAER_DAYS}" "${subject_alt_name}"
    
      # generate apiserver-kubelet-client certificate
      # /etc/kubernetes/pki/apiserver-kubelet-client
      CART_NAME=${PKI_PATH}/apiserver-kubelet-client
      cert::gen_cert "${CART_NAME}" "client" "/O=system:masters/CN=kube-apiserver-kubelet-client" "${CAER_DAYS}"
    
      # generate kubeconf for controller-manager,scheduler,kubectl and kubelet
      # /etc/kubernetes/controller-manager,scheduler,admin,kubelet.conf
      cert::update_kubeconf "${KUBE_PATH}/controller-manager"
      cert::update_kubeconf "${KUBE_PATH}/scheduler"
      cert::update_kubeconf "${KUBE_PATH}/admin"
      # check kubelet.conf
      # https://github.com/kubernetes/kubeadm/issues/1753
      set +e
      grep kubelet-client-current.pem /etc/kubernetes/kubelet.conf > /dev/null 2>&1
      kubelet_cert_auto_update=$?
      set -e
      if [[ "$kubelet_cert_auto_update" == "0" ]]; then
        log::warning "does not need to update kubelet.conf"
      else
        cert::update_kubeconf "${KUBE_PATH}/kubelet"
      fi
    
      # generate front-proxy-client certificate
      # use front-proxy-client ca
      CA_CERT=${PKI_PATH}/front-proxy-ca.crt
      CA_KEY=${PKI_PATH}/front-proxy-ca.key
      check_file "${CA_CERT}"
      check_file "${CA_KEY}"
      CART_NAME=${PKI_PATH}/front-proxy-client
      cert::gen_cert "${CART_NAME}" "client" "/CN=front-proxy-client" "${CAER_DAYS}"
    
      # restart apiserve, controller-manager, scheduler and kubelet
      docker ps | awk '/k8s_kube-apiserver/{print$1}' | xargs -r -I '{}' docker restart {} || true
      log::info "restarted kube-apiserver"
      docker ps | awk '/k8s_kube-controller-manager/{print$1}' | xargs -r -I '{}' docker restart {} || true
      log::info "restarted kube-controller-manager"
      docker ps | awk '/k8s_kube-scheduler/{print$1}' | xargs -r -I '{}' docker restart {} || true
      log::info "restarted kube-scheduler"
      systemctl restart kubelet
      log::info "restarted kubelet"
    }
    
    main() {
      local node_tpye=$1
      
      KUBE_PATH=/etc/kubernetes
      CAER_DAYS=3650
    
      case ${node_tpye} in
        # etcd)
    	  # # update etcd certificates
        #   cert::update_etcd_cert
        # ;;
        master)
          # backup $KUBE_PATH to $KUBE_PATH.old-$(date +%Y%m%d)
          cert::backup_file "${KUBE_PATH}"
    	    # update master certificates and kubeconf
          cert::update_master_cert
        ;;
        all)
          # backup $KUBE_PATH to $KUBE_PATH.old-$(date +%Y%m%d)
          cert::backup_file "${KUBE_PATH}"
          # update etcd certificates
          cert::update_etcd_cert
          # update master certificates and kubeconf
          cert::update_master_cert
        ;;
        *)
          log::err "unknow, unsupported certs type: ${node_tpye}, supported type: all, master"
          printf "Documentation: https://github.com/yuyicai/update-kube-cert
      example:
        '33[32m./update-kubeadm-cert.sh all33[0m' update all etcd certificates, master certificates and kubeconf
          /etc/kubernetes
          ├── admin.conf
          ├── controller-manager.conf
          ├── scheduler.conf
          ├── kubelet.conf
          └── pki
              ├── apiserver.crt
              ├── apiserver-etcd-client.crt
              ├── apiserver-kubelet-client.crt
              ├── front-proxy-client.crt
              └── etcd
                  ├── healthcheck-client.crt
                  ├── peer.crt
                  └── server.crt
        '33[32m./update-kubeadm-cert.sh master33[0m' update only master certificates and kubeconf
          /etc/kubernetes
          ├── admin.conf
          ├── controller-manager.conf
          ├── scheduler.conf
          ├── kubelet.conf
          └── pki
              ├── apiserver.crt
              ├── apiserver-kubelet-client.crt
              └── front-proxy-client.crt
    "
          exit 1
        esac
    }
    
    main "$@"
    
  • 相关阅读:
    《解密腾讯海量服务之道》讲座笔记
    图解 Paxos 一致性协议
    向量时钟算法简介——本质类似MVCC
    logback配置
    Protocol Buffers简明教程
    分布式调用技术 RPC VS REST
    Dubbo和Spring Cloud微服务架构对比
    Spring Boot学习笔记
    relatedTarget、fromElement、toElement相关元素
    12个不可不知的Sublime Text应用技巧和诀窍
  • 原文地址:https://www.cnblogs.com/FengGeBlog/p/15271640.html
Copyright © 2011-2022 走看看