Solo  当前访客:2 开始使用

k8s集群一年证书过期解决

2021-01-26 21:23:14 imadiaos
0  评论    0  浏览

k8s集群一年证书过期解决

运维同事在公司搭建了一个k8s开发环境,由于是摸石头过河,当时能用了就没再考虑。
直到一年后的某一天,我们再次打开系统的时候,发现各种莫名的问题。

多番检查以后发现,kubectl直接报地址或端口错误(记不太清了)。

k8s中的证书文件介绍

/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key
......

k8s中的证书更新相关介绍

stable.txt 或 kube-config.xml

kubeadm命令升级master证书时,它也会默认从长城之外读取一个stable.txt的文件,也许可能生产环境访问不到。

这时候就需要自备的kube-config.yaml文件。生成方式如下命令:
kubeadm config view > kube-config.yaml

环境已经GG,没办法现在生成那就自己写一个kube-config.yaml,内容如下:
apiVersion: kubeadm.k8s.io/v1beta1  
kind: ClusterConfiguration  
kubernetesVersion: v1.14.1 #-->这里改成你集群对应的版本  
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers  
#这里使用国内的镜像仓库,否则在重新签发的时候会报错:could not fetch a Kubernetes version from the internet: unable to get URL "https://dl.k8s.io/release/stable-1.txt"

这个配置还是有办法导出来的,因为我们并非生产环境,所以骚操作就是把系统时间调到证书过期以前。

date -s '2020-01-01'

这时候还需要重启kubelet

systemctl restart kubelet

此时,再次调用 kubectl get node等等,发现功能都回来了。

通过文章中写的 kubeadm config view > kube-config.yaml命令,可以导出kube-config.xml,这个文件作用很大。

开始更新

备份及清理工作

cd /etc/kubernetes
mkdir ./pki_bak
mkdir ./pki_bak/etcd
mkdir ./conf_bak
mv pki/apiserver* ./pki_bak/
mv pki/front-proxy-client.* ./pki_bak/
mv pki/etcd/healthcheck-client.* ./pki_bak/etcd/
mv pki/etcd/peer.* ./pki_bak/etcd/
mv pki/etcd/server.* ./pki_bak/etcd/
mv ./admin.conf ./conf_bak/
mv ./kubelet.conf ./conf_bak/
mv ./controller-manager.conf ./conf_bak/
mv ./scheduler.conf ./conf_bak/

开始更新

# 这个是版本比较老的kubeadm
# kube-config.yaml看着点路径
kubeadm alpha certs renew all --config=kube-config.yaml

# 完成后重启kube-apiserver,kube-controller,kube-scheduler,etcd这4个容器

————————————————
# 这是比较新的kubeadm
kubeadm alpha phase certs all  --config=kube-config.yaml
# 或者
kubeadm alpha phase certs all --apiserver-advertise-address=${MASTER_API_SERVER_IP} --apiserver-cert-extra-sans=主机内网ip,主机公网ip

kubeadm alpha phase kubeconfig all --config=kube-config.yaml
# 或者
kubeadm alpha phase kubeconfig all --apiserver-advertise-address=${MASTER_API_SERVER_IP}

# 完成后重启kube-apiserver,kube-controller,kube-scheduler,etcd这4个容器
# 如果有多台master,则将第一台生成的相关证书拷贝到其余master即可

经过测试,我们的版本是1.11.x,已经很老的版本了,但是在这篇文章里对应的是比较新的kubeadm。

由于有kube-config.xml文件,省事不少。

kubeadm alpha phase certs all  --config=kube-config.yaml
kubeadm alpha phase kubeconfig all --config=kube-config.yaml

证书生成好之后,需要重启kubelet。由于是集群,每个节点都是master,除了k8s的证书以外,还要处理每个集群节点,以及etcd的证书。

# 1.etcd证书

# 1:设置cfssl环境
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
chmod +x cfssljson_linux-amd64
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
chmod +x cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
export PATH=/usr/local/bin:$PATH

# 2:创建 CA 配置文件(下面配置的IP为etc节点的IP)
mkdir /root/ssl
cd /root/ssl
cat >  ca-config.json <<EOF
{
"signing": {
"default": {
  "expiry": "8760h"
},
"profiles": {
  "kubernetes-Soulmate": {
    "usages": [
        "signing",
        "key encipherment",
        "server auth",
        "client auth"
    ],
    "expiry": "8760h"
  }
}
}
}
EOF
?
cat >  ca-csr.json <<EOF
{
"CN": "kubernetes-Soulmate",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
  "C": "CN",
  "ST": "shanghai",
  "L": "shanghai",
  "O": "k8s",
  "OU": "System"
}
]
}
EOF
?
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
?
cat > etcd-csr.json <<EOF
{
  "CN": "etcd",
  "hosts": [
    "127.0.0.1",
    "192.168.4.21",
    "192.168.4.22",
    "192.168.4.23"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "shanghai",
      "L": "shanghai",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
?
cfssl gencert -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes-Soulmate etcd-csr.json | cfssljson -bare etcd
  
# 3:node01分发etcd证书到node02、node03上面
mkdir -p /etc/etcd/ssl
cp etcd.pem etcd-key.pem ca.pem /etc/etcd/ssl/
ssh -n node02 "mkdir -p /etc/etcd/ssl && exit"
ssh -n node03 "mkdir -p /etc/etcd/ssl && exit"
scp -r /etc/etcd/ssl/*.pem node02:/etc/etcd/ssl/
scp -r /etc/etcd/ssl/*.pem node03:/etc/etcd/ssl/

我们的系统依然没有配置自动轮换证书的功能。但是文章中提供了,所以并没有验证:

kubelet 证书分为 server 和 client 两种, k8s 1.9 默认启用了 client 证书的自动轮换,但 server 证书自动轮换需要用户开启

增加 kubelet 参数
# 在/etc/systemd/system/kubelet.service.d/10-kubeadm.conf 增加如下参数
Environment="KUBELET_EXTRA_ARGS=--feature-gates=RotateKubeletServerCertificate=true"
增加 controller-manager 参数
# 在/etc/kubernetes/manifests/kube-controller-manager.yaml 添加如下参数
  - command:
    - kube-controller-manager
    - --experimental-cluster-signing-duration=87600h0m0s
    - --feature-gates=RotateKubeletServerCertificate=true
    - ....
创建 rbac 对象
# 创建rbac对象,允许节点轮换kubelet server证书:
cat > ca-update.yaml << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:certificates.k8s.io:certificatesigningrequests:selfnodeserver
rules:
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests/selfnodeserver
  verbs:
  - create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubeadm:node-autoapprove-certificate-server
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:certificates.k8s.io:certificatesigningrequests:selfnodeserver
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:nodes
EOF

kubectl create –f ca-update.yaml
,
TOP