Skip to content

Instantly share code, notes, and snippets.

@AGou-ops
Created August 22, 2025 09:19
Show Gist options
  • Select an option

  • Save AGou-ops/4bf4b18b33b98c58f90e1ca69cc106d4 to your computer and use it in GitHub Desktop.

Select an option

Save AGou-ops/4bf4b18b33b98c58f90e1ca69cc106d4 to your computer and use it in GitHub Desktop.

Revisions

  1. AGou-ops revised this gist Aug 22, 2025. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions renew_k8s_certs.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@
    ```shell
    #!/bin/bash
    set -euo pipefail

    @@ -240,4 +239,3 @@ success "admin.conf generated at $HOME/.kube/config"

    echo
    echo -e "${GREEN}\u2705 Kubernetes certificates update completed${RESET}"
    ```
  2. AGou-ops created this gist Aug 22, 2025.
    243 changes: 243 additions & 0 deletions renew_k8s_certs.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,243 @@
    ```shell
    #!/bin/bash
    set -euo pipefail
    # ================== Configuration ==================
    VALIDITY_DAYS=$((999 * 365)) # 999 years
    PKI_DIR="/etc/kubernetes/pki"
    BACKUP_DIR="/etc/kubernetes/pki.bak.$(date +%F-%H-%M-%S)"
    ADMIN_CONF="/etc/kubernetes/admin.conf"
    KUBELET_CONF="/etc/kubernetes/kubelet.conf"
    MASTER_IP=$(hostname -I | awk '{print $1}')
    # ===================================================
    # ============== Color & Logging ===================
    GREEN="\e[32m"
    YELLOW="\e[33m"
    BLUE="\e[34m"
    RED="\e[31m"
    RESET="\e[0m"
    info() { echo ; echo -e "${BLUE}[INFO] $*${RESET}"; }
    success() { echo -e "${GREEN}[OK] $*${RESET}"; }
    warn() { echo -e "${YELLOW}[WARN] $*${RESET}"; }
    error() { echo -e "${RED}[ERROR] $*${RESET}"; }
    run_cmd() {
    echo -e "${BLUE}>>> $1${RESET}"
    eval "$1"
    }
    # ============== Step 1: Backup ===================
    info "Step 1: Backup old certificates..."
    mv "$PKI_DIR" "$BACKUP_DIR/" || echo "skip..."
    mkdir -p "$PKI_DIR"
    success "Backup completed: $BACKUP_DIR"
    # ============== Step 2: Generate CA ===================
    info "Step 2: Generate Kubernetes CA..."
    run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/ca.key -pkeyopt rsa_keygen_bits:2048"
    run_cmd "openssl req -new -x509 -key $PKI_DIR/ca.key -out $PKI_DIR/ca.crt -days $VALIDITY_DAYS -subj '/CN=kubernetes-ca'"
    success "Kubernetes CA generated"
    # ============== Step 3: Generate etcd CA ===================
    info "Step 3: Generate etcd CA..."
    # mkdir -p $PKI_DIR/etcd
    # run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/etcd/ca.key -pkeyopt rsa_keygen_bits:2048"
    # run_cmd "openssl req -new -x509 -key $PKI_DIR/etcd/ca.key -out $PKI_DIR/etcd/ca.crt -days $VALIDITY_DAYS -subj '/CN=etcd-ca'"
    success "Skip etcd CA generating..."
    # ============== Step 4: Generate API Server TLS ===================
    info "Step 4: Generate API server certificate..."
    APISERVER_CONF="/tmp/apiserver.cnf"
    cat > $APISERVER_CONF <<EOF
    [ req ]
    distinguished_name = req_distinguished_name
    req_extensions = v3_req
    prompt = no
    [ req_distinguished_name ]
    CN = kubernetes
    [ v3_req ]
    keyUsage = critical, digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    [ alt_names ]
    DNS.1 = kubernetes
    DNS.2 = kubernetes.default
    DNS.3 = kubernetes.default.svc
    DNS.4 = kubernetes.default.svc.cluster.local
    DNS.5 = localhost
    DNS.6 = master1
    DNS.7 = master2
    DNS.8 = master3
    IP.1 = 127.0.0.1
    IP.2 = ${MASTER_IP}
    EOF
    run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/apiserver.key -pkeyopt rsa_keygen_bits:2048"
    run_cmd "openssl req -new -key $PKI_DIR/apiserver.key -out $PKI_DIR/apiserver.csr -config $APISERVER_CONF"
    run_cmd "openssl x509 -req -in $PKI_DIR/apiserver.csr -CA $PKI_DIR/ca.crt -CAkey $PKI_DIR/ca.key \
    -CAcreateserial -out $PKI_DIR/apiserver.crt -days $VALIDITY_DAYS -extensions v3_req -extfile $APISERVER_CONF"
    success "API server certificate generated"
    # ============== Step 5: Generate admin user ===================
    info "Step 5: Generate admin user certificate..."
    run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/admin.key -pkeyopt rsa_keygen_bits:2048"
    run_cmd "openssl req -new -key $PKI_DIR/admin.key -out $PKI_DIR/admin.csr -subj '/CN=kubernetes-admin/O=system:masters'"
    run_cmd "openssl x509 -req -in $PKI_DIR/admin.csr -CA $PKI_DIR/ca.crt -CAkey $PKI_DIR/ca.key \
    -CAcreateserial -out $PKI_DIR/admin.crt -days $VALIDITY_DAYS"
    success "Admin certificate generated"
    # ============== Step 6: API Server Kubelet Client ===================
    info "Step 6: Generate apiserver-kubelet-client certificate..."
    run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/apiserver-kubelet-client.key -pkeyopt rsa_keygen_bits:2048"
    run_cmd "openssl req -new -key $PKI_DIR/apiserver-kubelet-client.key -out $PKI_DIR/apiserver-kubelet-client.csr -subj '/CN=kube-apiserver-kubelet-client/O=system:masters'"
    run_cmd "openssl x509 -req -in $PKI_DIR/apiserver-kubelet-client.csr -CA $PKI_DIR/ca.crt -CAkey $PKI_DIR/ca.key \
    -CAcreateserial -out $PKI_DIR/apiserver-kubelet-client.crt -days $VALIDITY_DAYS"
    success "apiserver-kubelet-client certificate generated"
    # ============== Step 7: Generate front-proxy CA and certificates ===================
    info "Step 7: Generate front-proxy CA and certificates..."
    # Generate front-proxy CA
    run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/front-proxy-ca.key -pkeyopt rsa_keygen_bits:2048"
    run_cmd "openssl req -new -x509 -key $PKI_DIR/front-proxy-ca.key -out $PKI_DIR/front-proxy-ca.crt -days $VALIDITY_DAYS -subj '/CN=front-proxy-ca'"
    success "front-proxy CA generated"
    # Generate front-proxy client certificate
    run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/front-proxy-client.key -pkeyopt rsa_keygen_bits:2048"
    run_cmd "openssl req -new -key $PKI_DIR/front-proxy-client.key -out $PKI_DIR/front-proxy-client.csr -subj '/CN=front-proxy-client'"
    run_cmd "openssl x509 -req -in $PKI_DIR/front-proxy-client.csr -CA $PKI_DIR/front-proxy-ca.crt -CAkey $PKI_DIR/front-proxy-ca.key \
    -CAcreateserial -out $PKI_DIR/front-proxy-client.crt -days $VALIDITY_DAYS"
    success "front-proxy client certificate generated"
    # Generate front-proxy server certificate
    run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/front-proxy-server.key -pkeyopt rsa_keygen_bits:2048"
    run_cmd "openssl req -new -key $PKI_DIR/front-proxy-server.key -out $PKI_DIR/front-proxy-server.csr -subj '/CN=aggregator'"
    run_cmd "openssl x509 -req -in $PKI_DIR/front-proxy-server.csr -CA $PKI_DIR/front-proxy-ca.crt -CAkey $PKI_DIR/front-proxy-ca.key \
    -CAcreateserial -out $PKI_DIR/front-proxy-server.crt -days $VALIDITY_DAYS"
    success "front-proxy server certificate generated"
    # ============== Step 8: Service account ===================
    info "Step 8: Generate service account key..."
    run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/sa.key -pkeyopt rsa_keygen_bits:2048"
    run_cmd "openssl rsa -in $PKI_DIR/sa.key -pubout -out $PKI_DIR/sa.pub"
    success "Service account key generated"
    # ============== Step 9: etcd certificates ===================
    info "Step 9: Generate etcd server/peer/healthcheck-client certificates..."
    # ETCD_CONF="/tmp/etcd.cnf"
    # cat > $ETCD_CONF <<EOF
    # [ req ]
    # distinguished_name = req_distinguished_name
    # req_extensions = v3_req
    # prompt = no
    #
    # [ req_distinguished_name ]
    # CN = etcd
    #
    # [ v3_req ]
    # keyUsage = critical, digitalSignature, keyEncipherment
    # extendedKeyUsage = serverAuth, clientAuth
    # subjectAltName = @alt_names
    #
    # [ alt_names ]
    # IP.1 = ${MASTER_IP}
    # IP.2 = 127.0.0.1
    # EOF
    #
    # for name in server peer healthcheck-client; do
    # run_cmd "openssl genpkey -algorithm RSA -out $PKI_DIR/etcd/$name.key -pkeyopt rsa_keygen_bits:2048"
    # run_cmd "openssl req -new -key $PKI_DIR/etcd/$name.key -out $PKI_DIR/etcd/$name.csr -subj \"/CN=etcd-${name}\" -config $ETCD_CONF"
    # run_cmd "openssl x509 -req -in $PKI_DIR/etcd/$name.csr -CA $PKI_DIR/etcd/ca.crt -CAkey $PKI_DIR/etcd/ca.key \
    # -CAcreateserial -out $PKI_DIR/etcd/$name.crt -days $VALIDITY_DAYS -extensions v3_req -extfile $ETCD_CONF"
    # done
    success "Skip etcd certificates generating..."
    # ============== Step 10: Generate new kubelet.conf ===================
    info "Step 10: Generating new kubelet.conf..."
    cat > $KUBELET_CONF <<EOF
    apiVersion: v1
    clusters:
    - cluster:
    certificate-authority-data: $(cat $PKI_DIR/ca.crt | base64 -w0)
    server: https://localhost:9443
    name: kubernetes
    contexts:
    - context:
    cluster: kubernetes
    user: system:node:master1
    name: system:node:master1@kubernetes
    current-context: system:node:master1@kubernetes
    kind: Config
    preferences: {}
    users:
    - name: system:node:master1
    user:
    client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
    client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
    EOF
    unlink /var/lib/kubelet/pki/kubelet-client-current.pem
    KUBELET_PEM_FILE=/var/lib/kubelet/pki/kubelet-client-"$(date +%F-%H-%M-%S)".pem
    cat "$PKI_DIR"/apiserver-kubelet-client.crt "$PKI_DIR"/apiserver-kubelet-client.key > "$KUBELET_PEM_FILE"
    ln -sv "$KUBELET_PEM_FILE" /var/lib/kubelet/pki/kubelet-client-current.pem
    success "Generate new kubelet.conf successfully"
    # ============== Step 11: Restart Kubernetes ===================
    info "Step 11: Restart kubelet and control plane components..."
    run_cmd "systemctl restart kubelet"
    for component in kube-apiserver kube-controller-manager kube-scheduler etcd; do
    run_cmd "touch /etc/kubernetes/manifests/$component.yaml"
    done
    success "Kubernetes components restarted"
    # ============== Step 12: Verify certificates ===================
    info "Step 12: Verify certificates expiration..."
    for cert in apiserver apiserver-kubelet-client admin front-proxy-client front-proxy-server; do
    run_cmd "openssl x509 -in $PKI_DIR/$cert.crt -noout -text | grep 'Not After'"
    done
    # for cert in etcd/ca etcd/server etcd/peer etcd/healthcheck-client; do
    # run_cmd "openssl x509 -in $PKI_DIR/$cert.crt -noout -text | grep 'Not After'"
    # done
    success "Certificate verification completed"
    # ============== Step 13: Generate admin.conf ===================
    info "Step 13: Generate admin.conf..."
    cat > $ADMIN_CONF <<EOF
    apiVersion: v1
    kind: Config
    clusters:
    - name: kubernetes
    cluster:
    certificate-authority-data: $(cat $PKI_DIR/ca.crt | base64 -w0)
    server: https://localhost:9443
    contexts:
    - name: kubernetes-admin@kubernetes
    context:
    cluster: kubernetes
    user: kubernetes-admin
    current-context: kubernetes-admin@kubernetes
    users:
    - name: kubernetes-admin
    user:
    client-certificate-data: $(cat $PKI_DIR/admin.crt | base64 -w0)
    client-key-data: $(cat $PKI_DIR/admin.key | base64 -w0)
    EOF
    mkdir -p "$HOME"/.kube || echo
    cp -a "$HOME"/.kube/config "$HOME"/.kube/config.bak."$(date +%F-%H-%M-%S)"
    cp -af $ADMIN_CONF "$HOME"/.kube/config
    chown "$(id -u)":"$(id -g)" "$HOME"/.kube/config
    success "admin.conf generated at $HOME/.kube/config"
    echo
    echo -e "${GREEN}\u2705 Kubernetes certificates update completed${RESET}"
    ```