Rancher-v2.8.5域名地址变更

需求

在高可用 Rancher 环境中,变更 Rancher 域名。

环境

App Version
Rancher v2.8.5-ent
K8s v1.28.15+rke2r1

前提

  • 准备好所有集群直连 Apiserver 的 kubeconfig 配置文件。(重要)
  • Rancher 的 local 集群和下游集群的所有节点状态均正常。
  • 所有的集群已经做好了 etcd 数据备份。

步骤

准备证书

如果是权威证书,直接从证书授信渠道进行下载即可。

如果是替换自签名证书,则需要先准备好自签名的证书,可以参考这个脚本准备自签名证书。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#!/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
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

复制以上代码另存为create_self-signed-cert.sh,脚本参数说明:

1
2
3
4
5
6
7
8
--ssl-domain: 生成ssl证书需要的主域名,如不指定则默认为www.rancher.local,如果是ip访问服务,则可忽略;
--ssl-trusted-ip: 一般ssl证书只信任域名的访问请求,有时候需要使用ip去访问server,那么需要给ssl证书添加扩展IP,多个IP用逗号隔开;
--ssl-trusted-domain: 如果想多个域名访问,则添加扩展域名(TRUSTED_DOMAIN),多个TRUSTED_DOMAIN用逗号隔开;
--ssl-size: ssl加密位数,默认2048;
--ssl-cn: 国家代码(2个字母的代号),默认CN;
使用示例:
./create_self-signed-cert.sh --ssl-domain=www.test.com --ssl-trusted-domain=www.test2.com \
--ssl-trusted-ip=1.1.1.1,2.2.2.2,3.3.3.3 --ssl-size=2048 --ssl-date=3650

更新证书

4 层负载均衡

  1. 备份并删除旧证书
1
2
3
4
5
6
7
8
9
10
11
## 备份 Rancher 证书
kubectl -n cattle-system get secret tls-rancher-ingress -o yaml > tls-ingress.yml

## 备份自签名根证书(可选)
kubectl -n cattle-system get secret tls-ca -o yaml > tls-ca.yml

## 删除 Rancher 证书
kubectl -n cattle-system delete secret tls-rancher-ingress

## 删除自签名根证书(可选操作)
kubectl -n cattle-system delete secret tls-ca
  1. 上传新证书
1
2
3
4
kubectl -n cattle-system create secret tls tls-rancher-ingress --cert=./tls.crt --key=./tls.key

## 自签名证书需要上传根证书
kubectl -n cattle-system create secret generic tls-ca --from-file=cacerts.pem

7 层负载均衡

  1. 自签名根证书(可选)
1
2
3
4
5
6
7
## 备份自签名根证书
kubectl -n cattle-system get secret tls-ca -o yaml > tls-ca.yml

## 删除自签名根证书
kubectl -n cattle-system delete secret tls-ca

## 上传自签名根证书
  1. Rancher 证书

7 层负载均衡在 Rancher 这边这会管理根证书,Rancher 自己的证书在 7 层负载均衡上,需要在负载均衡上自行更新对应的证书,例如 nginx 可以需要更新如下配置所在的证书:

1
2
3
4
5
6
7
...
server {
listen 443 ssl http2;
server_name FQDN;
ssl_certificate 证书路径;
ssl_certificate_key 证书私钥路径;
...

更新 Rancher 配置

  1. helm 更新 Rancher 域名
1
2
3
4
5
6
7
8
## 导出 values
helm get values rancher -n cattle-system -o yaml > rancher-values.yaml

## 修改其中的 hostname
hostname: test2.zerchin.xyz

## 更新 Rancher
helm upgrade rancher -n cattle-system -f rancher-values.yaml rancher-2.8.5-ent.tgz
  1. 重启 Rancher
1
2
3
kubectl -n cattle-system delete pod -l app=rancher

kubectl -n cattle-system get pod -w
  1. Rancher UI 修改 Server URL 地址

访问新的域名,例如这里我需要访问 https://test2.zerchin.xyz 这个地址,使用 admin 登录。

接着进入 Global Settings,找到 server-url,将其修改成新的 Rancher 域名,如下:

再次重启 Rancher 触发更新

1
2
3
kubectl -n cattle-system delete pod -l app=rancher

kubectl -n cattle-system get pod -w

更新下游集群

RKE2 集群

  1. 进入 Cluster Management,点击进入 RKE2 集群,查看 Machines 列表,其中会有一台 Master 处于 Reconciling状态并伴有Waiting for plan to be applied 日志输出,记录该节点。
  1. 接着切换到 Registration,根据这台 Reconcilling状态的角色,勾选对应的 Rule,例如我这里的角色是 All,所以所有的角色我都要勾选上。如果有自定义节点名称。这里如果节点自定义了节点名称的话,在执行注册命令时也要加上对应的节点名称,否则可能恢复失败,使得恢复过程出现不可预期的风险!
  1. 将这个节点注册的命令,复制到刚刚那台Reconcilling状态的节点上执行即可。

等待该节点状态恢复Running状态之后,集群也就可以访问了。

  1. 此时其他节点的也会进入到Reconcilling状态,按照同样的操作,根据节点的角色勾选对应的 Rule,复制到节点上执行即可。
  1. 最后进入集群检查各个组件的状态。

RKE 集群

RKE 集群需要更新 agent 配置。

  1. 进入 Cluster Management,点击进入 RKE 的集群,查看 Machines 列表,记住其中任意一台 Master 的角色。
  1. 接着切换到 Registration,勾选对应的 Rule,例如我这里的角色是 All,所以所有的角色我都要勾选上。(如果只有 control plane、etcd则只勾选这两个) 这里如果节点自定义了节点名称的话,在执行注册命令时也要加上对应的节点名称,否则可能恢复失败,使得恢复过程出现不可预期的风险!
  1. 将这个节点注册的命令,复制到刚刚 Master 节点上运行即可。

  2. 执行如下命令触发 agent 重新部署,等待集群 agent 更新完毕后,集群就能恢复正常访问。

1
2
3
## 在 local 集群中执行
## 替换其中的 Cluster ID
kubectl annotate clusters.management.cattle.io <Cluster ID> io.cattle.agent.force.deploy=true
  1. 最后进入集群检查各个组件的状态。