kubernetes v1.14 (bootstrap 部署node)

本文采用TLS bootstrap证书:在安装 k8s worker node 时,基本上 worker 的初始状态仅仅是安装了 docker 和 kubelet,worker 需要一种机制跟 master 通信。但网络通信的基本假设是通信双方谁也不信任谁。所以,kubelet bootstrap要以自动化的方式解决如下几个问题:

  • 在只知道 api server IP 地址的情况下,工作节点如何获取 api server 的 CA 证书?
  • 如何让 api server 信任 worker?因为在 api server 信任 worker 之前,worker 没有途径拿到自己的证书

Bootstrap有两种形式:bootstrap令牌以及bootstrap认证文件,相对于认证文件 令牌形式更加的灵活,所以后续演示都是通过令牌形式部署

要让api server信任工作节点,工作节点必须让master认证鉴权:

  • apiserver 开启 bootstrap token 认证,支持 kubelet TLS bootstrapping,所以apiserver启动的时候需要加入以下参数
               --authorization-mode=Node,RBAC \
               --enable-bootstrap-token-auth=true \
               --apiserver-count=3 \
               --kubelet-https \
               --kubelet-client-certificate=/etc/kubernetes/pki/cs_client.crt \
               --kubelet-client-key=/etc/kubernetes/pki/cs_client.key \
               --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \

bootstrap令牌功能 可以为每个工作节点发送一个令牌授权工作节点,这个过程主要两方面:

  1. 使用令牌ID,密钥和范围创建Kubernetes密钥。
  2. 将令牌发送到kubelet

KUBE-API服务器将其识别为一个特殊的记号,并授予任何与该令牌特殊的启动权认证,特别是对待他们的成员system:bootstrappers组。这满足了TLS引导的基本要求。

主要步骤:

建立TLS bootstrap secret来提供自动签证使用:

TOKEN_PUB=$(openssl rand -hex 3)
TOKEN_SECRET=$(openssl rand -hex 8)
BOOTSTRAP_TOKEN="${TOKEN_PUB}.${TOKEN_SECRET}"

kubectl -n kube-system create secret generic bootstrap-token-${TOKEN_PUB} \
        --type 'bootstrap.kubernetes.io/token' \
        --from-literal description="cluster bootstrap token" \
        --from-literal token-id=${TOKEN_PUB} \
        --from-literal token-secret=${TOKEN_SECRET} \
        --from-literal usage-bootstrap-authentication=true \
        --from-literal usage-bootstrap-signing=true

建立bootstrap的kubeconfig文件:

CLUSTER_NAME="kubernetes"
KUBE_USER="kubelet-bootstrap"
KUBE_CONFIG="bootstrap.kubeconfig"

# 设置集群参数
kubectl config set-cluster ${CLUSTER_NAME} \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=/etc/kubernetes/${KUBE_CONFIG}

# 设置上下文参数
kubectl config set-context ${KUBE_USER}@${CLUSTER_NAME} \
  --cluster=${CLUSTER_NAME} \
  --user=${KUBE_USER} \
  --kubeconfig=/etc/kubernetes/${KUBE_CONFIG}

# 设置客户端认证参数
kubectl config set-credentials ${KUBE_USER} \
  --token=${BOOTSTRAP_TOKEN} \
  --kubeconfig=/etc/kubernetes/${KUBE_CONFIG}

# 设置当前使用的上下文
kubectl config use-context ${KUBE_USER}@${CLUSTER_NAME} --kubeconfig=/etc/kubernetes/${KUBE_CONFIG}

# 查看生成的配置文件
kubectl config view --kubeconfig=/etc/kubernetes/${KUBE_CONFIG}

之后会在/etc/kubernetes目录生成bootstrap.kubeconfig,后续在工作节点在启动kubelet里通过参数--bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig 引入文件

授权 kubelet 可以创建 csr:

kubectl create clusterrolebinding kubeadm:kubelet-bootstrap --clusterrole system:node-bootstrapper --group system:bootstrappers


 

批准 csr 请求:

  • 允许 system:bootstrappers 组的所有 csr
cat <<EOF | kubectl apply -f -
# Approve all CSRs for the group "system:bootstrappers"
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: auto-approve-csrs-for-group
subjects:
- kind: Group
  name: system:bootstrappers
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
  apiGroup: rbac.authorization.k8s.io
EOF

允许 kubelet 能够更新自己的证书

cat <<EOF | kubectl apply -f -
# Approve renewal CSRs for the group "system:nodes"
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: auto-approve-renewals-for-nodes
subjects:
- kind: Group
  name: system:nodes
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
  apiGroup: rbac.authorization.k8s.io
EOF

配置完成之后kubelet会向apiserver申请csr证书,申请完成之后会生成自己对应的证书 例如:

在master节点通过kubectl get csr 查看申请的证书 可以看淡Approved代表申请成功:

开启自动续签:

在 1.7 后,kubelet 启动时增加 --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true 选项,则 kubelet 在证书即将到期时会自动发起一个 renew 自己证书的 CSR 请求;同时 controller manager 需要在启动时增加 --feature-gates=RotateKubeletServerCertificate=true 参数,再配合上面创建好的 ClusterRoleBinding,kubelet client 和 kubelet server 证才书会被自动签署;

注意,1.7 版本设置自动续期参数后,新的 renew 请求不会立即开始,而是在证书总有效期的 70%~90% 的时间时发起;而且经测试 1.7 版本即使自动签发了证书,kubelet 在不重启的情况下不会重新应用新证书;在 1.8 后 kubelet 组件在增加一个 --rotate-certificates 参数后,kubelet 才会自动重载新证书

证书过期问题
需要重复强调一个问题是: TLS bootstrapping 时的证书实际是由 kube-controller-manager 组件来签署的,也就是说证书有效期是 kube-controller-manager 组件控制的;所以在 1.7 版本以后(我查文档发现的从1.7开始有) kube-controller-manager 组件提供了一个 --experimental-cluster-signing-duration 参数来设置签署的证书有效时间;默认为 8760h0m0s,将其改为 87600h0m0s 即 10 年后再进行 TLS bootstrapping 签署证书即可。

发布了49 篇原创文章 · 获赞 39 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_22543991/article/details/89762682