kubelet组件部署

目录

  • 前言
  • 创建 kubelet bootstrap kubeconfig 文件
  • 查看kubeadm为各个节点创建的token
  • 查看各 token 关联的 Secret
  • 创建和分发kubelet参数配置
  • 创建和分发kubelet启动文件
  • 创建user和group的CSR权限,不创建kubelet会启动失败
  • 启动 kubelet 服务
  • 查看kubelet
  • 手动approve server cert csr

前言

kubelet运行在每个worker节点上,接收kube-apiserver发送的请求,管理Pod容器,执行交互命令

kubelet启动时自动向kube-apiserver注册节点信息,内置的cAdivsor统计和监控节点的资源使用资源情况。为确保安全,部署时关闭了kubelet的非安全http端口,对请求进行认证和授权,拒绝未授权的访问

创建 kubelet bootstrap kubeconfig 文件

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_name in ${NODE_NAMES[@]}
  do
    echo ">>> ${node_name}"
    # 创建 token
    export BOOTSTRAP_TOKEN=$(kubeadm token create \
      --description kubelet-bootstrap-token \
      --groups system:bootstrappers:${node_name} \
      --kubeconfig ~/.kube/config)
    # 设置集群参数
    kubectl config set-cluster kubernetes \
      --certificate-authority=/etc/kubernetes/cert/ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --kubeconfig=kubelet-bootstrap-${node_name}.kubeconfig
    # 设置客户端认证参数
    kubectl config set-credentials kubelet-bootstrap \
      --token=${BOOTSTRAP_TOKEN} \
      --kubeconfig=kubelet-bootstrap-${node_name}.kubeconfig
    # 设置上下文参数
    kubectl config set-context default \
      --cluster=kubernetes \
      --user=kubelet-bootstrap \
      --kubeconfig=kubelet-bootstrap-${node_name}.kubeconfig
    # 设置默认上下文
    kubectl config use-context default --kubeconfig=kubelet-bootstrap-${node_name}.kubeconfig
  done

分发 bootstrap kubeconfig 文件到所有 worker 节点

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_name in ${NODE_NAMES[@]}
  do
    echo ">>> ${node_name}"
    scp kubelet-bootstrap-${node_name}.kubeconfig root@${node_name}:/etc/kubernetes/kubelet-bootstrap.kubeconfig
  done
  • 向kubeconfig写入的是token,bootstrap结束后kube-controller-manager为kubelet创建client和server证书

查看kubeadm为各个节点创建的token

[root@node01 work]# kubeadm token list --kubeconfig ~/.kube/config
TOKEN                     TTL       EXPIRES                     USAGES                   DESCRIPTION               EXTRA GROUPS
cu4q2e.ogvim78s3p252ysg   23h       2019-12-06T17:44:24+08:00   authentication,signing   kubelet-bootstrap-token   system:bootstrappers:node03
nrypmb.35fyygbwr9failr5   23h       2019-12-06T17:44:23+08:00   authentication,signing   kubelet-bootstrap-token   system:bootstrappers:node01
r5luwb.6x6c5lnit5utyotz   23h       2019-12-06T17:44:23+08:00   authentication,signing   kubelet-bootstrap-token   system:bootstrappers:node02
sx8n4m.vlltkkv8m23ogxg9   23h       2019-12-06T17:44:24+08:00   authentication,signing   kubelet-bootstrap-token   system:bootstrappers:node04
  • token有效期为1天,超期后将不能被用来bootstrap kubelet,且会被kube-controller-manager的token cleaner清理
  • kube-apiserver接收kubelet的bootstrap token后,将请求的user设置为system:bootstrap; group设置为system:bootstrappers,后续将为这个group设置ClusterRoleBinding

查看各 token 关联的 Secret

[root@node01 work]# kubectl get secrets  -n kube-system|grep bootstrap-token
bootstrap-token-cu4q2e                           bootstrap.kubernetes.io/token         7      33s
bootstrap-token-nrypmb                           bootstrap.kubernetes.io/token         7      34s
bootstrap-token-r5luwb                           bootstrap.kubernetes.io/token         7      34s
bootstrap-token-sx8n4m                           bootstrap.kubernetes.io/token         7      33s

创建和分发kubelet参数配置

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > kubelet-config.yaml.template <
  • address:kubelet 安全端口(https,10250)监听的地址,不能为 127.0.0.1,否则 kube-apiserver、heapster 等不能调用 kubelet 的 API;
  • readOnlyPort=0:关闭只读端口(默认 10255),等效为未指定;
  • authentication.anonymous.enabled:设置为 false,不允许匿名访问 10250 端口;
  • authentication.x509.clientCAFile:指定签名客户端证书的 CA 证书,开启 HTTP 证书认证;
  • authentication.webhook.enabled=true:开启 HTTPs bearer token 认证;
  • 对于未通过 x509 证书和 webhook 认证的请求(kube-apiserver 或其他客户端),将被拒绝,提示 Unauthorized;
  • authroization.mode=Webhook:kubelet 使用 SubjectAccessReview API 查询 kube-apiserver 某 user、group 是否具有操作资源的权限(RBAC);
  • featureGates.RotateKubeletClientCertificate、featureGates.RotateKubeletServerCertificate:自动 rotate 证书,证书的有效期取决于 kube-controller-manager 的 –experimental-cluster-signing-duration 参数;
  • 需要 root 账户运行;

为各个节点创建和分发kubelet配置文件

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do 
    echo ">>> ${node_ip}"
    sed -e "s/##NODE_IP##/${node_ip}/" kubelet-config.yaml.template > kubelet-config-${node_ip}.yaml.template
    scp kubelet-config-${node_ip}.yaml.template root@${node_ip}:/etc/kubernetes/kubelet-config.yaml
  done

创建和分发kubelet启动文件

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > kubelet.service.template <
  • 如果设置了 –hostname-override 选项,则 kube-proxy 也需要设置该选项,否则会出现找不到 Node 的情况;
  • –bootstrap-kubeconfig:指向 bootstrap kubeconfig 文件,kubelet 使用该文件中的用户名和 token 向 kube-apiserver 发送 TLS Bootstrapping 请求;
  • K8S approve kubelet 的 csr 请求后,在 –cert-dir 目录创建证书和私钥文件,然后写入 –kubeconfig 文件;
  • –pod-infra-container-image 不使用 redhat 的 pod-infrastructure:latest 镜像,它不能回收容器的僵尸;

分发启动文件

d /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_name in ${NODE_NAMES[@]}
  do 
    echo ">>> ${node_name}"
    sed -e "s/##NODE_NAME##/${node_name}/" kubelet.service.template > kubelet-${node_name}.service
    scp kubelet-${node_name}.service root@${node_name}:/etc/systemd/system/kubelet.service
  done

Bootstrap Token Auth 和授予权限 kubelet 启动时查找 --kubeletconfig
参数对应的文件是否存在,如果不存在则使用 --bootstrap-kubeconfig 指定的 kubeconfig 文件向
kube-apiserver 发送证书签名请求 (CSR)。 kube-apiserver 收到 CSR 请求后,对其中的 Token
进行认证,认证通过后将请求的 user 设置为 system:bootstrap:,group 设置为
system:bootstrappers,这一过程称为 Bootstrap Token Auth。

创建user和group的CSR权限,不创建kubelet会启动失败

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

启动 kubelet 服务

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p ${K8S_DIR}/kubelet/kubelet-plugins/volume/exec/"
    ssh root@${node_ip} "/usr/sbin/swapoff -a"
    ssh root@${node_ip} "systemctl daemon-reload && systemctl enable kubelet && systemctl restart kubelet"
  done

关闭 swap 分区,否则 kubelet 会启动失败;

kubelet 启动后使用 –bootstrap-kubeconfig 向 kube-apiserver 发送 CSR 请求,当这个

CSR 被 approve 后,kube-controller-manager 为 kubelet 创建 TLS 客户端证书、私钥和

–kubeletconfig 文件。 注意:kube-controller-manager 需要配置 –cluster-signing-cert-file 和 –cluster-signing-key-file 参数,才会为 TLS Bootstrap 创建证书和私钥。

[root@node01 work]# kubectl get csr
NAME        AGE    REQUESTOR                 CONDITION
csr-5ttvq   2m6s   system:bootstrap:r5luwb   Pending
csr-gmt4v   2m5s   system:bootstrap:cu4q2e   Pending
csr-hhfw4   2m6s   system:bootstrap:nrypmb   Pending
csr-qpfp8   11s    system:bootstrap:sx8n4m   Pending

这里4个节点均处于pending(等待)状态

自动approve CSR请求

创建三个ClusterRoleBinding,分别用于自动approve client、renew client、renew server证书

cd /opt/k8s/work
cat > csr-crb.yaml <
  • auto-approve-csrs-for-group 自动approve node的第一次CSR,注意第一次CSR时,请求的Group为system:bootstrappers
  • node-client-cert-renewal 自动approve node后续过期的client证书,自动生成的证书Group为system:nodes
  • node-server-cert-renewal 自动approve node后续过期的server证书,自动生成的证书Group

查看kubelet

等待1-10分钟,3个节点的CSR都会自动approved

[root@node01 work]# kubectl get csr
NAME        AGE     REQUESTOR                 CONDITION
csr-5ttvq   3m33s   system:bootstrap:r5luwb   Approved,Issued
csr-gmt4v   3m32s   system:bootstrap:cu4q2e   Approved,Issued
csr-hhfw4   3m33s   system:bootstrap:nrypmb   Approved,Issued
csr-lktrc   1s      system:node:node01        Pending
csr-qpfp8   98s     system:bootstrap:sx8n4m   Approved,Issued
csr-s4q5h   102s    system:bootstrap:sx8n4m   Approved,Issued
csr-s7fds   1s      system:node:node02        Pending
csr-wszxt   34s     system:node:node04        Pending

Pending的CSR用于创建kubelet serve证书,需要手动approve (后面步骤)

目前所有节点均为ready状态

[root@node01 work]# kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
node01   Ready       26s   v1.15.6
node02   Ready       26s   v1.15.6
node03   Ready       25s   v1.15.6
node04   Ready       59s   v1.15.6

手动approve server cert csr

基于安全考虑,CSR approving controllers不会自动approve kubelet server证书签名请求,需要手动approve

kubectl get csr | grep Pending | awk '{print $1}' | xargs kubectl certificate approve

kubelet启动后监听多个端口,用于接受kube-apiserver或其他客户端发送的请求

[root@node01 work]# netstat -lntup|grep kubelet
tcp        0      0 127.0.0.1:36615         0.0.0.0:*               LISTEN      10549/kubelet       
tcp        0      0 10.0.20.11:10248        0.0.0.0:*               LISTEN      10549/kubelet       
tcp        0      0 10.0.20.11:10250        0.0.0.0:*               LISTEN      10549/kubelet
  • 10248: healthz http 服务;
  • 10250: https 服务,访问该端口时需要认证和授权(即使访问 /healthz 也需要);
  • 未开启只读端口 10255;
  • 从 K8S v1.10 开始,去除了 –cadvisor-port 参数(默认 4194 端口),不支持访问 cAdvisor UI & API

你可能感兴趣的:(kubelet组件部署)