本文永久链接: https://www.xtplayer.cn/rancher/replace-ip-domain/

准备全部集群的直连 kubeconfig 配置文件

默认情况,在 Rancher UI 上复制的 kubeconfig 是通过 cluster agent 代理连接到 K8S 集群的。在变更 SSL 证书后,因为一些参数发送变化,需要通过 kubectl 命令行去修改配置。在变更 SSL 证书后会导致 cluster agent 无法连接 Rancher server,从而导致 kubectl 无法使用 Rancher UI 上复制的 kubeconfig 去操作 K8S 集群。因此,建议在做域名或 IP 变更之前,准备好所有集群的直连 kubeconfig 配置文件。具体可参考:恢复 kubectl 配置文件

提示

  1. 2.1.x 以前的版本,可在 Master 节点的 /etc/kubernetes/.tmp 路径下找到 kubecfg-kube-admin.yml,这个是具有集群管理员权限的直连 kubeconfig 配置文件;

  2. 操作之前备份 Rancher Server

准备证书

SSL 证书与域名或 IP 有绑定关系,客户端在访问 Server 端时,ssl 证书用于客户端访问地址的检验作用。客户端通过域名或 IP 访问 Server 端时,会先进行 SSL 证书验证,如果客户端访问的 IP 或域名与 SSL 证书中预先绑定的 IP 或域名不一致,那么 SSL 可以认为 Server 端是伪造了,SSL 验证无法通过从而导致客户端无法连接 Server 端。

因此,如果更换了 Server 端的 IP 或域名,一般就会涉及到 SSL 证书更换,除非在最开始生成 SSL 证书的时候加入了后期可能需要更换的 IP 或域名

  • 自签名 ssl 证书

    复制以下代码另存为 create_self-signed-cert.sh 或者其他您喜欢的文件名。修改代码开头的 CN(域名),如果需要使用 ip 去访问 Rancher Server,那么需要给 ssl 证书添加扩展 IP,多个 IP 用逗号隔开。如果想实现多个域名访问 Rancher Server,则添加扩展域名(SSL_DNS),多个 SSL_DNS 用逗号隔开。

    #!/bin/bash

    help ()
    {
    echo ' ================================================================ '
    echo ' --ssl-domain: 生成ssl证书需要的主域名,如不指定则默认为www.rancher.local,如果是ip访问服务,则可忽略;'
    echo ' --ssl-trusted-ip: 一般ssl证书只信任域名的访问请求,有时候需要使用ip去访问 server,那么需要给ssl证书添加扩展IP,多个IP用逗号隔开;'
    echo ' --ssl-trusted-domain: 如果想多个域名访问,则添加扩展域名(SSL_TRUSTED_DOMAIN),多个扩展域名用逗号隔开;'
    echo ' --ssl-size: ssl加密位数,默认 2048;'
    echo ' --ssl-cn: 国家代码(2个字母的代号),默认 CN;'
    echo ' --ca-cert-recreate: 是否重新创建 ca-cert,ca 证书默认有效期 10 年,创建的 ssl 证书有效期如果是一年需要续签,那么可以直接复用原来的 ca 证书,默认 false;'
    echo ' 使用示例:'
    echo ' ./create_self-signed-cert.sh --ssl-domain=www.test.com --ssl-trusted-domain=www.test2.com \ '
    echo ' --ssl-trusted-ip=1.1.1.1,2.2.2.2,3.3.3.3 --ssl-size=2048 --ssl-date=3650'
    echo ' ================================================================'
    }

    case "$1" in
    -h|--help) help; exit;;
    esac

    if [[ $1 == '' ]];then
    help;
    exit;
    fi

    CMDOPTS="$*"
    for OPTS in $CMDOPTS;
    do
    key=$(echo ${OPTS} | awk -F"=" '{print $1}' )
    value=$(echo ${OPTS} | awk -F"=" '{print $2}' )
    case "$key" in
    --ssl-domain) SSL_DOMAIN=$value ;;
    --ssl-trusted-ip) SSL_TRUSTED_IP=$value ;;
    --ssl-trusted-domain) SSL_TRUSTED_DOMAIN=$value ;;
    --ssl-size) SSL_SIZE=$value ;;
    --ssl-date) SSL_DATE=$value ;;
    --ca-date) CA_DATE=$value ;;
    --ssl-cn) CN=$value ;;
    --ca-cert-recreate) CA_CERT_RECREATE=$value ;;
    --ca-key-recreate) CA_KEY_RECREATE=$value ;;
    esac
    done

    # CA相关配置
    CA_KEY_RECREATE=${CA_KEY_RECREATE:-false}
    CA_CERT_RECREATE=${CA_CERT_RECREATE:-false}

    CA_DATE=${CA_DATE:-3650}
    CA_KEY=${CA_KEY:-cakey.pem}
    CA_CERT=${CA_CERT:-cacerts.pem}
    CA_DOMAIN=cattle-ca

    # ssl相关配置
    SSL_CONFIG=${SSL_CONFIG:-$PWD/openssl.cnf}
    SSL_DOMAIN=${SSL_DOMAIN:-'www.rancher.local'}
    SSL_DATE=${SSL_DATE:-3650}
    SSL_SIZE=${SSL_SIZE:-2048}

    ## 国家代码(2个字母的代号),默认CN;
    CN=${CN:-CN}

    SSL_KEY=$SSL_DOMAIN.key
    SSL_CSR=$SSL_DOMAIN.csr
    SSL_CERT=$SSL_DOMAIN.crt

    echo -e "\033[32m ---------------------------- \033[0m"
    echo -e "\033[32m | 生成 SSL Cert | \033[0m"
    echo -e "\033[32m ---------------------------- \033[0m"

    # 如果存在 ca-key, 并且需要重新创建 ca-key
    if [[ -e ./${CA_KEY} ]] && [[ ${CA_KEY_RECREATE} == 'true' ]]; then

    # 先备份旧 ca-key,然后重新创建 ca-key
    echo -e "\033[32m ====> 1. 发现已存在 CA 私钥,备份 "${CA_KEY}" 为 "${CA_KEY}"-bak,然后重新创建 \033[0m"
    mv ${CA_KEY} "${CA_KEY}"-bak-$(date +"%Y%m%d%H%M")
    openssl genrsa -out ${CA_KEY} ${SSL_SIZE}

    # 如果存在 ca-cert,因为 ca-key 重新创建,则需要重新创建 ca-cert。先备份然后重新创建 ca-cert
    if [[ -e ./${CA_CERT} ]]; then
    echo -e "\033[32m ====> 2. 发现已存在 CA 证书,先备份 "${CA_CERT}" 为 "${CA_CERT}"-bak,然后重新创建 \033[0m"
    mv ${CA_CERT} "${CA_CERT}"-bak-$(date +"%Y%m%d%H%M")
    openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}"
    else
    # 如果不存在 ca-cert,直接创建 ca-cert
    echo -e "\033[32m ====> 2. 生成新的 CA 证书 ${CA_CERT} \033[0m"
    openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}"
    fi

    # 如果存在 ca-key,并且不需要重新创建 ca-key
    elif [[ -e ./${CA_KEY} ]] && [[ ${CA_KEY_RECREATE} == 'false' ]]; then

    # 存在旧 ca-key,不需要重新创建,直接复用
    echo -e "\033[32m ====> 1. 发现已存在 CA 私钥,直接复用 CA 私钥 "${CA_KEY}" \033[0m"

    # 如果存在 ca-cert,并且需要重新创建 ca-cert。先备份然后重新创建
    if [[ -e ./${CA_CERT} ]] && [[ ${CA_CERT_RECREATE} == 'true' ]]; then
    echo -e "\033[32m ====> 2. 发现已存在 CA 证书,先备份 "${CA_CERT}" 为 "${CA_CERT}"-bak,然后重新创建 \033[0m"
    mv ${CA_CERT} "${CA_CERT}"-bak-$(date +"%Y%m%d%H%M")
    openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}"

    # 如果存在 ca-cert,并且不需要重新创建 ca-cert,直接复用
    elif [[ -e ./${CA_CERT} ]] && [[ ${CA_CERT_RECREATE} == 'false' ]]; then
    echo -e "\033[32m ====> 2. 发现已存在 CA 证书,直接复用 CA 证书 "${CA_CERT}" \033[0m"
    else
    # 如果不存在 ca-cert ,直接创建 ca-cert
    echo -e "\033[32m ====> 2. 生成新的 CA 证书 ${CA_CERT} \033[0m"
    openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}"
    fi

    # 如果不存在 ca-key
    else
    # ca-key 不存在,直接生成
    echo -e "\033[32m ====> 1. 生成新的 CA 私钥 ${CA_KEY} \033[0m"
    openssl genrsa -out ${CA_KEY} ${SSL_SIZE}

    # 如果存在旧的 ca-cert,先做备份,然后重新生成 ca-cert
    if [[ -e ./${CA_CERT} ]]; then
    echo -e "\033[32m ====> 2. 发现已存在 CA 证书,先备份 "${CA_CERT}" 为 "${CA_CERT}"-bak,然后重新创建 \033[0m"
    mv ${CA_CERT} "${CA_CERT}"-bak-$(date +"%Y%m%d%H%M")
    openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}"
    else
    # 不存在旧的 ca-cert,直接生成 ca-cert
    echo -e "\033[32m ====> 2. 生成新的 CA 证书 ${CA_CERT} \033[0m"
    openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}"
    fi

    fi

    echo -e "\033[32m ====> 3. 生成 Openssl 配置文件 ${SSL_CONFIG} \033[0m"
    cat > ${SSL_CONFIG} <<EOM
    [req]
    req_extensions = v3_req
    distinguished_name = req_distinguished_name
    [req_distinguished_name]
    [ v3_req ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage = clientAuth, serverAuth
    EOM

    if [[ -n ${SSL_TRUSTED_IP} || -n ${SSL_TRUSTED_DOMAIN} || -n ${SSL_DOMAIN} ]]; then
    cat >> ${SSL_CONFIG} <<EOM
    subjectAltName = @alt_names
    [alt_names]
    EOM
    IFS=","
    dns=(${SSL_TRUSTED_DOMAIN})
    dns+=(${SSL_DOMAIN})
    for i in "${!dns[@]}"; do
    echo DNS.$((i+1)) = ${dns[$i]} >> ${SSL_CONFIG}
    done

    if [[ -n ${SSL_TRUSTED_IP} ]]; then
    ip=(${SSL_TRUSTED_IP})
    for i in "${!ip[@]}"; do
    echo IP.$((i+1)) = ${ip[$i]} >> ${SSL_CONFIG}
    done
    fi
    fi

    echo -e "\033[32m ====> 4. 生成服务 SSL KEY ${SSL_KEY} \033[0m"
    openssl genrsa -out ${SSL_KEY} ${SSL_SIZE}

    echo -e "\033[32m ====> 5. 生成服务 SSL CSR ${SSL_CSR} \033[0m"
    openssl req -sha256 -new -key ${SSL_KEY} -out ${SSL_CSR} -subj "/C=${CN}/CN=${SSL_DOMAIN}" -config ${SSL_CONFIG}

    echo -e "\033[32m ====> 6. 生成服务 SSL CERT ${SSL_CERT} \033[0m"
    openssl x509 -sha256 -req -in ${SSL_CSR} -CA ${CA_CERT} \
    -CAkey ${CA_KEY} -CAcreateserial -out ${SSL_CERT} \
    -days ${SSL_DATE} -extensions v3_req \
    -extfile ${SSL_CONFIG}

    echo -e "\033[32m ====> 7. 证书制作完成 \033[0m"
    echo -e "\033[32m ====> 8. 以 YAML 格式输出结果 \033[0m"
    echo "----------------------------------------------------------"
    echo "ca_key: |"
    cat $CA_KEY | sed 's/^/ /'
    echo
    echo "ca_cert: |"
    cat $CA_CERT | sed 's/^/ /'
    echo
    echo "ssl_key: |"
    cat $SSL_KEY | sed 's/^/ /'
    echo
    echo "ssl_csr: |"
    cat $SSL_CSR | sed 's/^/ /'
    echo
    echo "ssl_cert: |"
    cat $SSL_CERT | sed 's/^/ /'
    echo

    echo -e "\033[32m ====> 9. 附加 CA 证书到 Cert 文件 \033[0m"
    cat ${CA_CERT} >> ${SSL_CERT}
    echo "ssl_cert: |"
    cat $SSL_CERT | sed 's/^/ /'
    echo

    echo -e "\033[32m ====> 10. 重命名服务证书 \033[0m"
    echo "cp ${SSL_DOMAIN}.key tls.key"
    cp ${SSL_DOMAIN}.key tls.key
    echo "cp ${SSL_DOMAIN}.crt tls.crt"
    cp ${SSL_DOMAIN}.crt tls.crt
  • 权威认证证书

    把权威证书文件重命名为需要的文件名:

    cp xxx.key tls.key
    cp xxx.crt tls.crt

更新证书(可选)

提示

证书与域名或 IP 有绑定关系,一般情况更换域名或 IP 需更换证书。如果之前配置的证书是一个通配证书或者之前配置的证书已经包含了需要变更的域名或 IP,那么证书则可以不用更换。

Rancher 单节点运行(默认容器自动生成自签名 SSL 证书)

默认情况,通过 docker run 运行的 Rancher server 容器,会自动为 Rancher 生成 SSL 证书,这个证书会自动绑定 Rancher 系统设置中 server-url 配置的域名或 IP。如果更换了域名或 IP,证书会自动更新,无需单独操作。

Rancher 单节点运行(外置自签名 SSL 证书)

注意:操作前先备份,备份和恢复

如果是以映射证书文件的方式运行的单容器 Rancher Server,只需要停止原有 Rancher Server 容器,用新证书替换旧证书,保持文件名不变,然后重新运行容器即可。

Rancher HA 运行

注意:操作前先备份,备份和恢复

  1. 备份原有证书 YAML 文件

    kubectl --kubeconfig=kube_configxxx.yml -n cattle-system \
    get secret tls-rancher-ingress -o yaml > tls-ingress.yml

    kubectl --kubeconfig=kube_configxxx.yml -n cattle-system \
    get secret tls-ca -o yaml > tls-ca.yml
  2. 删除旧的 secret,然后创建新的 secret

    # 指定 kube 配置文件路径

    kubeconfig=xxx.yaml

    # 删除旧的 secret
    kubectl --kubeconfig=$kubeconfig -n cattle-system \
    delete secret tls-rancher-ingress

    kubectl --kubeconfig=$kubeconfig -n cattle-system \
    delete secret tls-ca

    # 创建新的 secret
    kubectl --kubeconfig=$kubeconfig -n cattle-system \
    create secret tls tls-rancher-ingress --cert=./tls.crt --key=./tls.key

    kubectl --kubeconfig=$kubeconfig -n cattle-system \
    create secret generic tls-ca --from-file=cacerts.pem

    # 重启 Pod
    kubectl --kubeconfig=$kubeconfig -n cattle-system \
    delete pod `kubectl --kubeconfig=$kubeconfig -n cattle-system \
    get pod |grep -E "cattle-cluster-agent|cattle-node-agent|rancher" | awk '{print $1}'`

重要提示: 如果环境不是按照标准的 rancher 安装文档安装,secret 名称可能不相同,请根据实际 secret 名称操作。

修改 Rancher Server IP 或域名

  1. 依次访问全局 》系统设置,页面往下翻找到 server-url

  2. 点击右侧的省略号菜单,选择升级;

  3. 修改 server-url 地址;

  4. 最后点击 保存

更新 agent 配置文件

  1. 通过新域名或 IP 登录 Rancher Server;

    警告: 这一步非常重要!

  2. 通过浏览器地址栏查询集群 IDc/ 后面以 c 开头的字段即为集群 ID;

  3. 访问 https://<新的 server_url>/v3/clusters/<集群 ID>/clusterregistrationtokens 页面;

  4. 打开clusterRegistrationTokens页面后,定位到 data 字段;

  5. 找到 insecureCommand 字段,复制 YAML 连接备用;

    警告: 可能会有多组"baseType": "clusterRegistrationToken",如下图。这种情况以 createdTS 最大、时间最新的一组为准,一般是最后一组。

  6. 使用 kubectl 工具,通过第一步准备的直连 kubeconfig 配置文件和上面步骤中获取的 YAML 文件,执行以下命令更新 agent 相关配置。

    curl -L -k <替换为上面步骤获取的 YAML 文件链接> | kubectl --kubeconfig=<直连 kubeconfig 配置文件> apply -f -

其他所有集群均需按照以上方法进行 agent 配置更新。