本文发布于Cylon的收藏册,转载请著名原文链接~
tls 证书在 k8s 集群上大量使用的话,当到期时会存在批量替换的难度,比如说每个名称空间,多个业务的使用,在这篇博文中,将尝试批量替换整个集群的证书(前提,在没有使用 vault, cert-manager这类组件的集群之上)。
基本操作
步骤1:首先不知道有多少个名称空间使用了这个证书,所以需要遍历所有的名称空间,这里使用 kubectl 的 json path 实现
$ kubectl get ns -o jsonpath='{range $.items[*]}{.metadata.name}{"\n"}{end}'
步骤2:拿到名称空间的名字后,就需要循环这个名称空间下所有的 secret
for ns in `kubectl get ns -o jsonpath='{range $.items[*]}{.metadata.name}{"\n"}{end}'`
do
kubectl get secret -n $ns -o jsonpath='{range $.items[*]}{.metadata.name}{"\n"}{end}'
done
步骤3:找到与这个匹配的证书进行替换
把步骤3拆解为下面几个步骤:
- 拿去到符合要求的secret的名字
- 匹配名称是否为修改的secret
- 做替换操作
由于步骤2使用的是 jsonpath 拿到的 secret name,由于 kubectl 并不支持高级jsonpath语法,官方推荐使用jq,那么使用jq获取名字
kubectl get secret -n $ns -o json|jq -r .items[].metadata.name
使用 awk 做字符串匹配,匹配是否包含对应的字符串关键词
awk '$1 ~ /xxxx/ { print }'
最后使用 kubectl replace 替换现有的 secret
kubectl create secret tls $secertName -n $ns --cert=xxx.crt --key=xxx.key --dry-run -o yaml| kubectl replace -f -
三个步骤整个为一个命令,如下所示:
for ns in `kubectl get ns -o jsonpath='{range $.items[*]}{.metadata.name}{"\n"}{end}'`
do
for secertName in `kubectl get secret -n $ns -o json|jq -r .items[].metadata.name|awk '$1 ~ /xxxx/ { print }';
do
kubectl create secret tls $secertName -n $ns --cert=xxx.crt --key=xxx.key --dry-run -o yaml| kubectl replace -f -
done
done
注意:
- ingress 使用的证书会立即更新
- 如果是作为 secret 挂在到 Pod 中需要重启,这是因为 kubelet volume 机制导致的。
高级用法
查询证书内容,并根据域名进行替换
查看证书域名的命令
ns=xxx
secret_name=xxx
keywords=xxx
_command=xxxx
openssl x509 -in <(
${_command} get secret -n $ns $secret_name -ojson | \
jq --arg secret_key $(
${_command} get secret -n ${ns} ${secret_name} -ojson | \
jq -r '.data | keys[]' | \
awk -v keywords=${keywords} '$0 ~ keywords { print }'
) -r '.data | .[$secret_key]' | base64 -d
) -text -noout | \
grep -i "subject: "
步骤拆解
# 替换的名称空间
ns=kube-system
# 替换的secret_name
secret_name=test
# 替换key的关键词,通常secret作为tls存在时,为xxx.crt
keywords=crt
# kubectl命令
_command=kubectl --kubeconfig=kubeconfig
# shell语法,将一个命令的输出作为openssl的输入
openssl x509 -in <(
${_command} get secret -n $ns $secret_name -ojson | \
# jq --arg secret_key 是 jq语法,将 $() 命名为secret_key作为变量传入到下个命令使用
jq --arg secret_key $(
${_command} get secret -n ${ns} ${secret_name} -ojson | \
jq -r '.data | keys[]' | \
# awk -v keywords=${keywords} 是awk语法,将keyworkd作为变量传递到awk内部
# '$0 ~ keywords { print }' 打印出符合条件的行
awk -v keywords=${keywords} '$0 ~ keywords { print }'
) -r '.data | .[$secret_key]' | base64 -d
) -text -noout | \
grep -i "subject: "
更新前没出意外需要备份下对应资源,批量备份集群内指定域名的 secret 命令
```bash
# 指定域名的secret
keywords=xxx
_command=xxxx
for ns in `${_command} get ns -o jsonpath='{range $.items[*]}{.metadata.name}{"\n"}{"end"}'`
do
for secret_name in `${_command} get secret -n $ns -o json|jq -r '.items[] | select( .type == "kubernetes.io/tls") | .metadata.name'`
do
openssl x509 -in <(
${_command} get secret -n ${ns} ${secret_name} -ojson | \
jq --arg secret_key $(
${_command} get secret -n ${ns} ${secret_name} -ojson |
jq -r '.data | keys[]' | \
awk '$0 ~ /crt/ { print }'
) -r '.data|.[$secret_key]'|base64 -d
) -text -noout | \
grep -i "subject: "| \
awk -v ns=${ns} -v secret_name=${secret_name} -v cmd=${_command} -v kw=${keywords} \
'$0 ~ kw { system(
cmd" get secret -n "ns" "secret_name" -oyaml > primetive/"ns"."secret_name".yaml"
)}'
done
done
批量替换命令,查询 tls 签发域名,并进行替换
keywords=xxx
_command=xxxx
for ns in `${_command} get ns -o jsonpath='range $.items[*]}{.metadata.name}{"\n"}{"end"}'
do
for secret_name in `${_command} get secret -n $ns -o json|jq -r '.items[] | select( .type == "kubernetes.io/tls") | .metadta.name'`
do
openssl x509 -n <(
${_command} get secret -n ${ns} ${secret_name} -ojson | \
jq --arg secret_key $(${_command} get secret -n ${ns} ${secret_name} -ojson | \
jq -r '.data | .keys[]' | \
awk '$0 ~ /crt/ { print }' -r '.data|.[$secret_key]'|base64 -d
) -text -noout | \
grep -i "subject: "| \
awk -v ns=${ns} -v secret_name=${secret_name} -v commond=${_command}\
'$0 ~ ${keywords} { system(
command" create secret tls -n "ns" "secret_name" --cert=ca.crt --key=key.key --dry-run -oyaml|command" replace -f -"
)}'
done
done
本文发布于Cylon的收藏册,转载请著名原文链接~
链接:https://www.oomkill.com/2024/02/kubernetes-update-secert/
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。