zoukankan      html  css  js  c++  java
  • 013.Kubernetes二进制所有节点部署kubelet

    一 部署 kubelet

    kubelet 运行在每个 worker 节点上,接收 kube-apiserver 发送的请求,管理 Pod 容器,执行交互式命令,如 exec、run、logs 等。

    kubelet 启动时自动向 kube-apiserver 注册节点信息,内置的 cadvisor 统计和监控节点的资源使用情况。

    为确保安全,部署时关闭了 kubelet 的非安全 http 端口,对请求进行认证和授权,拒绝未授权的访问(如 apiserver、heapster 的请求)。

    1.1 获取kubelet

    提示:master01节点已下载相应二进制,可直接分发至worker节点。

    1.2 分发kubelet

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 [root@master01 work]# for all_ip in ${ALL_IPS[@]}
      4   do
      5     echo ">>> ${all_ip}"
      6     scp kubernetes/server/bin/kubelet root@${all_ip}:/opt/k8s/bin/
      7     ssh root@${all_ip} "chmod +x /opt/k8s/bin/*"
      8   done

    提示:本步骤操作仅需要在master01节点操作。

    1.3 分发kubeconfig

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 [root@master01 work]# for all_name in ${ALL_NAMES[@]}
      4   do
      5     echo ">>> ${all_name}"
      6 
      7     # 创建 token
      8     export BOOTSTRAP_TOKEN=$(kubeadm token create 
      9       --description kubelet-bootstrap-token 
     10       --groups system:bootstrappers:${all_name} 
     11       --kubeconfig ~/.kube/config)
     12 
     13     # 设置集群参数
     14     kubectl config set-cluster kubernetes 
     15       --certificate-authority=/etc/kubernetes/cert/ca.pem 
     16       --embed-certs=true 
     17       --server=${KUBE_APISERVER} 
     18       --kubeconfig=kubelet-bootstrap-${all_name}.kubeconfig
     19 
     20     # 设置客户端认证参数
     21     kubectl config set-credentials kubelet-bootstrap 
     22       --token=${BOOTSTRAP_TOKEN} 
     23       --kubeconfig=kubelet-bootstrap-${all_name}.kubeconfig
     24 
     25     # 设置上下文参数
     26     kubectl config set-context default 
     27       --cluster=kubernetes 
     28       --user=kubelet-bootstrap 
     29       --kubeconfig=kubelet-bootstrap-${all_name}.kubeconfig
     30 
     31     # 设置默认上下文
     32     kubectl config use-context default --kubeconfig=kubelet-bootstrap-${all_name}.kubeconfig
     33   done

    解释:

    向 kubeconfig 写入的是 token,bootstrap 结束后 kube-controller-manager 为 kubelet 创建 client 和 server 证书。

    token 有效期为 1 天,超期后将不能再被用来 boostrap kubelet,且会被 kube-controller-manager 的 tokencleaner 清理;

    kube-apiserver 接收 kubelet 的 bootstrap token 后,将请求的 user 设置为 system:bootstrap:<Token ID>,group 设置为 system:bootstrappers,后续将为这个 group 设置 ClusterRoleBinding。

      1 [root@master01 work]# kubeadm token list --kubeconfig ~/.kube/config	     #查看 kubeadm 为各节点创建的 token
      2 [root@master01 work]# kubectl get secrets  -n kube-system|grep bootstrap-token   #查看各 token 关联的 Secret

    clipboard

    提示:本步骤操作仅需要在master01节点操作。

    1.4 分发bootstrap kubeconfig

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 [root@master01 work]# for all_name in ${ALL_NAMES[@]}
      4   do
      5     echo ">>> ${all_name}"
      6     scp kubelet-bootstrap-${all_name}.kubeconfig root@${all_name}:/etc/kubernetes/kubelet-bootstrap.kubeconfig
      7   done

    提示:本步骤操作仅需要在master01节点操作。

    1.5 创建kubelet 参数配置文件

    从 v1.10 开始,部分 kubelet 参数需在配置文件中配置,建议创建kubelet配置文件。

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 
      4 [root@master01 work]# cat > kubelet-config.yaml.template <<EOF
      5 kind: KubeletConfiguration
      6 apiVersion: kubelet.config.k8s.io/v1beta1
      7 address: "##ALL_IP##"
      8 staticPodPath: ""
      9 syncFrequency: 1m
     10 fileCheckFrequency: 20s
     11 httpCheckFrequency: 20s
     12 staticPodURL: ""
     13 port: 10250
     14 readOnlyPort: 0
     15 rotateCertificates: true
     16 serverTLSBootstrap: true
     17 authentication:
     18   anonymous:
     19     enabled: false
     20   webhook:
     21     enabled: true
     22   x509:
     23     clientCAFile: "/etc/kubernetes/cert/ca.pem"
     24 authorization:
     25   mode: Webhook
     26 registryPullQPS: 0
     27 registryBurst: 20
     28 eventRecordQPS: 0
     29 eventBurst: 20
     30 enableDebuggingHandlers: true
     31 enableContentionProfiling: true
     32 healthzPort: 10248
     33 healthzBindAddress: "##ALL_IP##"
     34 clusterDomain: "${CLUSTER_DNS_DOMAIN}"
     35 clusterDNS:
     36   - "${CLUSTER_DNS_SVC_IP}"
     37 nodeStatusUpdateFrequency: 10s
     38 nodeStatusReportFrequency: 1m
     39 imageMinimumGCAge: 2m
     40 imageGCHighThresholdPercent: 85
     41 imageGCLowThresholdPercent: 80
     42 volumeStatsAggPeriod: 1m
     43 kubeletCgroups: ""
     44 systemCgroups: ""
     45 cgroupRoot: ""
     46 cgroupsPerQOS: true
     47 cgroupDriver: cgroupfs
     48 runtimeRequestTimeout: 10m
     49 hairpinMode: promiscuous-bridge
     50 maxPods: 220
     51 podCIDR: "${CLUSTER_CIDR}"
     52 podPidsLimit: -1
     53 resolvConf: /etc/resolv.conf
     54 maxOpenFiles: 1000000
     55 kubeAPIQPS: 1000
     56 kubeAPIBurst: 2000
     57 serializeImagePulls: false
     58 evictionHard:
     59   memory.available:  "100Mi"
     60 nodefs.available:  "10%"
     61 nodefs.inodesFree: "5%"
     62 imagefs.available: "15%"
     63 evictionSoft: {}
     64 enableControllerAttachDetach: true
     65 failSwapOn: true
     66 containerLogMaxSize: 20Mi
     67 containerLogMaxFiles: 10
     68 systemReserved: {}
     69 kubeReserved: {}
     70 systemReservedCgroup: ""
     71 kubeReservedCgroup: ""
     72 enforceNodeAllocatable: ["pods"]
     73 EOF

    提示:本步骤操作仅需要在master01节点操作。

    1.6 分发kubelet 参数配置文件

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 [root@master01 work]# for all_ip in ${ALL_IPS[@]}
      4   do
      5     echo ">>> ${all_ip}"
      6     sed -e "s/##ALL_IP##/${all_ip}/" kubelet-config.yaml.template > kubelet-config-${all_ip}.yaml.template
      7     scp kubelet-config-${all_ip}.yaml.template root@${all_ip}:/etc/kubernetes/kubelet-config.yaml
      8   done

    提示:本步骤操作仅需要在master01节点操作。

    1.7 创建kubelet systemd

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 [root@master01 work]# cat > kubelet.service.template <<EOF
      4 [Unit]
      5 Description=Kubernetes Kubelet
      6 Documentation=https://github.com/GoogleCloudPlatform/kubernetes
      7 After=docker.service
      8 Requires=docker.service
      9 
     10 [Service]
     11 WorkingDirectory=${K8S_DIR}/kubelet
     12 ExecStart=/opt/k8s/bin/kubelet \
     13   --bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig \
     14   --cert-dir=/etc/kubernetes/cert \
     15   --cgroup-driver=cgroupfs \
     16   --cni-conf-dir=/etc/cni/net.d \
     17   --container-runtime=docker \
     18   --container-runtime-endpoint=unix:///var/run/dockershim.sock \
     19   --root-dir=${K8S_DIR}/kubelet \
     20   --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
     21   --config=/etc/kubernetes/kubelet-config.yaml \
     22   --hostname-override=##ALL_NAME## \
     23   --pod-infra-container-image=k8s.gcr.io/pause-amd64:3.2 \
     24   --image-pull-progress-deadline=15m \
     25   --volume-plugin-dir=${K8S_DIR}/kubelet/kubelet-plugins/volume/exec/ \
     26   --logtostderr=true \
     27   --v=2
     28 Restart=always
     29 RestartSec=5
     30 StartLimitInterval=0
     31 
     32 [Install]
     33 WantedBy=multi-user.target
     34 EOF

    提示:本步骤操作仅需要在master01节点操作。

    解释:

    • 如果设置了 --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 镜像,它不能回收容器的僵尸。

    1.8 分发kubelet systemd

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 [root@master01 work]# for all_name in ${ALL_NAMES[@]}
      4   do
      5     echo ">>> ${all_name}"
      6     sed -e "s/##ALL_NAME##/${all_name}/" kubelet.service.template > kubelet-${all_name}.service
      7     scp kubelet-${all_name}.service root@${all_name}:/etc/systemd/system/kubelet.service
      8   done

    提示:本步骤操作仅需要在master01节点操作。

    二 启动验证

    2.1 授权

    kubelet 启动时查找 --kubeletconfig 参数对应的文件是否存在,如果不存在则使用 --bootstrap-kubeconfig 指定的 kubeconfig 文件向 kube-apiserver 发送证书签名请求 (CSR)。

    kube-apiserver 收到 CSR 请求后,对其中的 Token 进行认证,认证通过后将请求的 user 设置为 system:bootstrap:<Token ID>,group 设置为 system:bootstrappers,这一过程称为 Bootstrap Token Auth。

    默认情况下,这个 user 和 group 没有创建 CSR 的权限,因此kubelet 会启动失败,可通过如下方式创建一个 clusterrolebinding,将 group system:bootstrappers 和 clusterrole system:node-bootstrapper 绑定。

      1 [root@master01 ~]# kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --group=system:bootstrappers

    提示:本步骤操作仅需要在master01节点操作。

    2.2 启动kubelet

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 [root@master01 work]# for all_name in ${ALL_NAMES[@]}
      4   do
      5     echo ">>> ${all_name}"
      6     ssh root@${all_name} "mkdir -p ${K8S_DIR}/kubelet/kubelet-plugins/volume/exec/"
      7     ssh root@${all_name} "/usr/sbin/swapoff -a"
      8     ssh root@${all_name} "systemctl daemon-reload && systemctl enable kubelet && systemctl restart kubelet"
      9   done

    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 创建证书和私钥。

    提示:启动服务前必须先创建工作目录;

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

    提示:本步骤操作仅需要在master01节点操作。

    2.3 查看kubelet服务

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 [root@master01 work]# for all_name in ${ALL_NAMES[@]}
      4   do
      5     echo ">>> ${all_name}"
      6     ssh root@${all_name} "systemctl status kubelet"
      7   done
      8 [root@master01 work]# kubectl get csr
      9 [root@master01 work]# kubectl get nodes

    clipboard

    提示:本步骤操作仅需要在master01节点操作。

    三 approve CSR 请求

    3.1 自动 approve CSR 请求

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

      1 [root@master01 ~]# cd /opt/k8s/work
      2 [root@master01 work]# source /root/environment.sh
      3 [root@master01 work]# cat > csr-crb.yaml <<EOF
      4  # Approve all CSRs for the group "system:bootstrappers"
      5  kind: ClusterRoleBinding
      6  apiVersion: rbac.authorization.k8s.io/v1
      7  metadata:
      8    name: auto-approve-csrs-for-group
      9  subjects:
     10  - kind: Group
     11    name: system:bootstrappers
     12    apiGroup: rbac.authorization.k8s.io
     13  roleRef:
     14    kind: ClusterRole
     15    name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
     16    apiGroup: rbac.authorization.k8s.io
     17 ---
     18  # To let a node of the group "system:nodes" renew its own credentials
     19  kind: ClusterRoleBinding
     20  apiVersion: rbac.authorization.k8s.io/v1
     21  metadata:
     22    name: node-client-cert-renewal
     23  subjects:
     24  - kind: Group
     25    name: system:nodes
     26    apiGroup: rbac.authorization.k8s.io
     27  roleRef:
     28    kind: ClusterRole
     29    name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
     30    apiGroup: rbac.authorization.k8s.io
     31 ---
     32 # A ClusterRole which instructs the CSR approver to approve a node requesting a
     33 # serving cert matching its client cert.
     34 kind: ClusterRole
     35 apiVersion: rbac.authorization.k8s.io/v1
     36 metadata:
     37   name: approve-node-server-renewal-csr
     38 rules:
     39 - apiGroups: ["certificates.k8s.io"]
     40   resources: ["certificatesigningrequests/selfnodeserver"]
     41   verbs: ["create"]
     42 ---
     43  # To let a node of the group "system:nodes" renew its own server credentials
     44  kind: ClusterRoleBinding
     45  apiVersion: rbac.authorization.k8s.io/v1
     46  metadata:
     47    name: node-server-cert-renewal
     48  subjects:
     49  - kind: Group
     50    name: system:nodes
     51    apiGroup: rbac.authorization.k8s.io
     52  roleRef:
     53    kind: ClusterRole
     54    name: approve-node-server-renewal-csr
     55    apiGroup: rbac.authorization.k8s.io
     56 EOF
     57 [root@master01 work]# kubectl apply -f 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 为 system:nodes。

    提示:本步骤操作仅需要在master01节点操作。

    3.2 查看 kubelet 的情况

      1 [root@master01 work]# kubectl get csr | grep boot	#等待一段时间(1-10 分钟),三个节点的 CSR 都被自动 approved
      2 [root@master01 work]# kubectl get nodes		#所有节点均 ready

    clipboard

      1 [root@master01 ~]# ls -l /etc/kubernetes/kubelet.kubeconfig
      2 [root@master01 ~]# ls -l /etc/kubernetes/cert/ | grep kubelet

    clipboard

    提示:本步骤操作仅需要在master01节点操作。

    3.3 手动 approve server cert csr

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

      1 [root@master01 ~]# kubectl get csr | grep node

    clipboard

      1 [root@master01 ~]# kubectl get csr | grep Pending | awk '{print $1}' | xargs kubectl certificate approve
      2 [root@master01 ~]# ls -l /etc/kubernetes/cert/kubelet-*

    clipboard

    提示:本步骤操作仅需要在master01节点操作。

    四 kubelet API 接口

    4.1 kubelet 提供的 API 接口

      1 [root@master01 ~]# sudo netstat -lnpt | grep kubelet		#查看kubelet监听端口

    clipboard

    解释:

    • 10248: healthz http 服务;
    • 10250: https 服务,访问该端口时需要认证和授权(即使访问 /healthz 也需要);
    • 未开启只读端口 10255;
    • 从 K8S v1.10 开始,去除了 --cadvisor-port 参数(默认 4194 端口),不支持访问 cAdvisor UI & API。

    提示:本步骤操作仅需要在master01节点操作。

    4.2 kubelet api 认证和授权

    kubelet 配置了如下认证参数:

    • authentication.anonymous.enabled:设置为 false,不允许匿名访问 10250 端口;
    • authentication.x509.clientCAFile:指定签名客户端证书的 CA 证书,开启 HTTPs 证书认证;
    • authentication.webhook.enabled=true:开启 HTTPs bearer token 认证。

    同时配置了如下授权参数:

    authroization.mode=Webhook:开启 RBAC 授权。

    kubelet 收到请求后,使用 clientCAFile 对证书签名进行认证,或者查询 bearer token 是否有效。如果两者都没通过,则拒绝请求,提示 Unauthorized。

      1 [root@master01 ~]# curl -s --cacert /etc/kubernetes/cert/ca.pem https://172.24.8.71:10250/metrics
      2 Unauthorized
      3 [root@master01 ~]# curl -s --cacert /etc/kubernetes/cert/ca.pem -H "Authorization: Bearer 123456" https://172.24.8.71:10250/metrics
      4 Unauthorized

    若通过认证后,kubelet 使用 SubjectAccessReview API 向 kube-apiserver 发送请求,查询证书或 token 对应的 user、group 是否有操作资源的权限(RBAC)。

    提示:本步骤操作仅需要在master01节点操作。

    4.3 证书认证和授权

      1 [root@master01 ~]# curl -s --cacert /etc/kubernetes/cert/ca.pem --cert /etc/kubernetes/cert/kube-controller-manager.pem --key /etc/kubernetes/cert/kube-controller-manager-key.pem https://172.24.8.71:10250/metrics	#默认权限不足
      2 Forbidden (user=system:kube-controller-manager, verb=get, resource=nodes, subresource=metrics)
      3 [root@master01 ~]# curl -s --cacert /etc/kubernetes/cert/ca.pem --cert /opt/k8s/work/admin.pem --key /opt/k8s/work/admin-key.pem https://172.24.8.71:10250/metrics | head			#使用最高权限的admin

    clipboard

    解释:

    --cacert、--cert、--key 的参数值必须是文件路径,如上面的 ./admin.pem 不能省略 ./,否则返回 401 Unauthorized。

    提示:本步骤操作仅需要在master01节点操作。

    4.4 创建bear token 认证和授权

      1 [root@master01 ~]# kubectl create sa kubelet-api-test
      2 [root@master01 ~]# kubectl create clusterrolebinding kubelet-api-test --clusterrole=system:kubelet-api-admin --serviceaccount=default:kubelet-api-test
      3 [root@master01 ~]# SECRET=$(kubectl get secrets | grep kubelet-api-test | awk '{print $1}')
      4 [root@master01 ~]# TOKEN=$(kubectl describe secret ${SECRET} | grep -E '^token' | awk '{print $2}')
      5 [root@master01 ~]# echo ${TOKEN}

    clipboard

      1 [root@master01 ~]# curl -s --cacert /etc/kubernetes/cert/ca.pem -H "Authorization: Bearer ${TOKEN}" https://172.24.8.71:10250/metrics | head

    clipboard

    提示:本步骤操作仅需要在master01节点操作。

  • 相关阅读:
    [HNOI2009]梦幻布丁(链表+启发式合并)
    [HNOI2004]宠物收养场(Treap)
    【模板】Treap
    Monkey King(左偏树)
    【模板】左偏树
    数列分段Section II(二分)
    [HAOI2006]受欢迎的牛(tarjan缩点)
    【模板】树链剖分
    精美产品策划类企业织梦模板
    简洁的支持展开关闭的tab标签代码
  • 原文地址:https://www.cnblogs.com/itzgr/p/11880941.html
Copyright © 2011-2022 走看看