• 部署 Master
    • " level="2">准备证书
      • " level="3">为 kube-apiserver 签发证书
      • " level="3">为 kube-controller-manager 签发证书
      • " level="3">为 kube-scheduler 签发证书
      • " level="3">签发 Service Account 密钥对
      • " level="3">为管理员签发证书
    • " level="2">准备 kubeconfig
      • 确定 apiserver 访问入口
      • " level="3">为 kube-controller-manager 创建 kubeconfig
      • " level="3">为 kube-scheduler 创建 kubeconfig
      • " level="3">为管理员创建 kubeconfig
    • 下载安装控制面组件
    • " level="2">配置控制面组件
      • " level="3">配置 kube-apiserver
      • " level="3">配置 kube-controller-manager
      • " level="3">配置 kube-scheduler
    • 启动
    • RBAC 授权 kube-apiserver 访问 kubelet
    • " level="2">RBAC 授权 kubelet 创建 CSR 与自动签发和更新证书
    • " level="2">创建 Bootstrap Token 与 bootstrap-kubeconfig

    部署 Master

    " class="reference-link">准备证书

    Master 节点的准备证书操作只需要做一次,将生成的证书拷到每个 Master 节点上以复用。

    前提条件:

    • 签发证书需要用到 生成 CA 证书 时创建的 CA 证书及其密钥文件,确保它们在当前目录
    • 确保 cfssl 在当前环境已安装,安装方法参考 这里

    " class="reference-link">为 kube-apiserver 签发证书

    kube-apiserver 是 k8s 的访问核心,所有 K8S 组件和用户 kubectl 操作都会请求 kube-apiserver,通常启用 tls 证书认证,证书里面需要包含 kube-apiserver 可能被访问的地址,这样 client 校验 kube-apiserver 证书时才会通过,集群内的 Pod 一般通过 kube-apiserver 的 Service 名称访问,可能的 Service 名称有:

    • kubernetes
    • kubernetes.default
    • kubernetes.default.svc
    • kubernetes.default.svc.cluster
    • kubernetes.default.svc.cluster.local

    通过集群外也可能访问 kube-apiserver,比如使用 kubectl,或者部署在集群外的服务会连 kube-apiserver (比如部署在集群外的 Promethues 采集集群指标做监控),这里列一下通过集群外连 kube-apiserver 有哪些可能地址:

    • 127.0.0.1: 在 Master 所在机器通过 127.0.0.1 访问本机 kube-apiserver
    • Service CIDR 的第一个 IP,比如 flanneld 以 daemonset 部署在每个节点,使用 hostNetwork 而不是集群网络,这时无法通过 service 名称访问 apiserver,因为使用 hostNetwork 无法解析 service 名称 (使用的 DNS 不是集群 DNS),它会使用 apiserver 内部的 CLUSTER IP 去请求 apiserver。 kube-controller-manager 的 --service-cluster-ip-range 启动参数是 10.32.0.0/16,那么第一个 IP 就是 10.32.0.1
    • 自定义域名: 配了 DNS,通过域名访问 kube-apiserver,也要将域名写入证书
    • LB IP: 如果 Master 节点前面挂了一个负载均衡器,外界可以通过 LB IP 来访问 kube-apiserver
    • Master 节点 IP: 如果没有 Master 负载均衡器,管理员在节点上执行 kubectl 通常使用 Master 节点 IP 访问 kube-apiserver

    准备 CSR 文件:

    1. cat > apiserver-csr.json <<EOF
    2. {
    3. "CN": "kubernetes",
    4. "hosts": [
    5. "127.0.0.1",
    6. "10.32.0.1",
    7. "10.200.16.79",
    8. "kubernetes",
    9. "kubernetes.default",
    10. "kubernetes.default.svc",
    11. "kubernetes.default.svc.cluster",
    12. "kubernetes.default.svc.cluster.local"
    13. ],
    14. "key": {
    15. "algo": "rsa",
    16. "size": 2048
    17. },
    18. "names": [
    19. {
    20. "C": "CN",
    21. "ST": "SiChuan",
    22. "L": "Chengdu",
    23. "O": "Kubernetes",
    24. "OU": "Kube API Server"
    25. }
    26. ]
    27. }
    28. EOF

    hosts 这里只准备了必要的,根据需求可增加,通常 Master 节点 IP 也都要加进去,你可以执行了上面的命令后再编辑一下 apiserver-csr.json,将需要 hosts 都加进去。

    1. cfssl gencert \
    2. -ca=ca.pem \
    3. -ca-key=ca-key.pem \
    4. -config=ca-config.json \
    5. -profile=kubernetes \
    6. apiserver-csr.json | cfssljson -bare apiserver

    会生成下面两个重要的文件:

    • apiserver-key.pem: kube-apiserver 证书密钥
    • apiserver.pem: kube-apiserver 证书

    " class="reference-link">为 kube-controller-manager 签发证书

    1. cat > kube-controller-manager-csr.json <<EOF
    2. {
    3. "CN": "system:kube-controller-manager",
    4. "key": {
    5. "algo": "rsa",
    6. "size": 2048
    7. },
    8. "names": [
    9. {
    10. "C": "CN",
    11. "ST": "SiChuan",
    12. "L": "Chengdu",
    13. "O": "system:kube-controller-manager",
    14. "OU": "Kube Controller Manager"
    15. }
    16. ]
    17. }
    18. EOF
    19. cfssl gencert \
    20. -ca=ca.pem \
    21. -ca-key=ca-key.pem \
    22. -config=ca-config.json \
    23. -profile=kubernetes \
    24. kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

    生成以下两个文件:

    • kube-controller-manager-key.pem: kube-controller-manager 证书密钥
    • kube-controller-manager.pem: kube-controller-manager 证书

    " class="reference-link">为 kube-scheduler 签发证书

    1. cat > kube-scheduler-csr.json <<EOF
    2. {
    3. "CN": "system:kube-scheduler",
    4. "key": {
    5. "algo": "rsa",
    6. "size": 2048
    7. },
    8. "names": [
    9. {
    10. "C": "CN",
    11. "ST": "SiChuan",
    12. "L": "Chengdu",
    13. "O": "system:kube-scheduler",
    14. "OU": "Kube Scheduler"
    15. }
    16. ]
    17. }
    18. EOF
    19. cfssl gencert \
    20. -ca=ca.pem \
    21. -ca-key=ca-key.pem \
    22. -config=ca-config.json \
    23. -profile=kubernetes \
    24. kube-scheduler-csr.json | cfssljson -bare kube-scheduler

    生成以下两个文件:

    • kube-scheduler-key.pem: kube-scheduler 证书密钥
    • kube-scheduler.pem: kube-scheduler 证书公钥

    " class="reference-link">签发 Service Account 密钥对

    kube-controller-manager 会使用此密钥对来给 service account 签发 token,更多详情参考官方文档: https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/

    1. cat > service-account-csr.json <<EOF
    2. {
    3. "CN": "service-accounts",
    4. "key": {
    5. "algo": "rsa",
    6. "size": 2048
    7. },
    8. "names": [
    9. {
    10. "C": "CN",
    11. "ST": "SiChuan",
    12. "L": "Chengdu",
    13. "O": "Kubernetes",
    14. "OU": "Service Account"
    15. }
    16. ]
    17. }
    18. EOF
    19. cfssl gencert \
    20. -ca=ca.pem \
    21. -ca-key=ca-key.pem \
    22. -config=ca-config.json \
    23. -profile=kubernetes \
    24. service-account-csr.json | cfssljson -bare service-account

    生成以下两个文件:

    • service-account-key.pem: service account 证书公钥
    • service-account.pem: service account 证书私钥

    " class="reference-link">为管理员签发证书

    为最高权限管理员证书:

    1. cat > admin-csr.json <<EOF
    2. {
    3. "CN": "admin",
    4. "key": {
    5. "algo": "rsa",
    6. "size": 2048
    7. },
    8. "names": [
    9. {
    10. "C": "CN",
    11. "ST": "SiChuan",
    12. "L": "Chengdu",
    13. "O": "system:masters",
    14. "OU": "System"
    15. }
    16. ]
    17. }
    18. EOF
    19. cfssl gencert \
    20. -ca=ca.pem \
    21. -ca-key=ca-key.pem \
    22. -config=ca-config.json \
    23. -profile=kubernetes \
    24. admin-csr.json | cfssljson -bare admin

    生成一下两个文件:

    • admin-key.pem: 管理员证书密钥
    • admin.pem: 管理员证书

    给用户签发证书后,用户访问 kube-apiserver 的请求就带上此证书,kube-apiserver 校验成功后表示认证成功,但还需要授权才允许访问,kube-apiserver 会提取证书中字段 CN 作为用户名,这里用户名叫 admin,但这只是个名称标识,它有什么权限呢?admin 是预置最高权限的用户名吗?不是的!不过 kube-apiserver 确实预置了一个最高权限的 ClusterRole,叫做 cluster-admin,还有个预置的 ClusterRoleBindingcluster-admin 这个 ClusterRolesystem:masters 这个用户组关联起来了,所以说我们给用户签发证书只要在 system:masters 这个用户组就拥有了最高权限。

    以此类推,我们签发证书时也可以将用户设置到其它用户组,然后为其创建 RBAC 规则来细粒度的控制权限,减少安全隐患。

    更多 K8S 预置的 Role 与 RoleBinding 请参考: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#default-roles-and-role-bindings

    " class="reference-link">准备 kubeconfig

    部署 Master 的准备 kubeconfig 操作只需要做一次,将生成的 kubeconfig 拷到每个 Master 节点上以复用。

    kubeconfig 主要是各组件以及用户访问 apiserver 的必要配置,包含 apiserver 地址、client 证书与 CA 证书等信息。下面介绍为各个组件生成 kubeconfig 的方法。

    前提条件:

    • 我们使用 kubectl 来辅助生成 kubeconfig,确保 kubectl 已安装。
    • 生成 kubeconfig 会用到之前准备证书时创建的证书与密钥,确保这些生成的文件在当前目录。

    确定 apiserver 访问入口

    所有组件都会去连 apiserver,所以首先需要确定你的 apiserver 访问入口的地址:

    • 如果所有 master 组件都部署在一个节点,它们可以通过 127.0.0.1 这个 IP访问 apiserver。
    • 如果 master 有多个节点,但 apiserver 只有一个实例,可以直接写 apiserver 所在机器的内网 IP 访问地址。
    • 如果做了高可用,有多个 apiserver 实例,前面挂了负载均衡器,就可以写负载均衡器的访问地址。
    • 入口地址的域名或IP必须是在之前 为 kube-apiserver 签发证书 的 hosts 列表里。

    这里我们用 APISERVER 这个变量表示 apiserver 的访问地址,其它组件都需要配置这个地址,根据自身情况改下这个变量的值:

    1. APISERVER="https://10.200.16.79:6443"

    " class="reference-link">为 kube-controller-manager 创建 kubeconfig

    1. APISERVER="https://10.200.16.79:6443"
    1. kubectl config set-cluster roc \
    2. --certificate-authority=ca.pem \
    3. --embed-certs=true \
    4. --server=${APISERVER} \
    5. --kubeconfig=kube-controller-manager.kubeconfig
    6. kubectl config set-credentials system:kube-controller-manager \
    7. --client-certificate=kube-controller-manager.pem \
    8. --client-key=kube-controller-manager-key.pem \
    9. --embed-certs=true \
    10. --kubeconfig=kube-controller-manager.kubeconfig
    11. kubectl config set-context default \
    12. --cluster=roc \
    13. --user=system:kube-controller-manager \
    14. --kubeconfig=kube-controller-manager.kubeconfig
    15. kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig

    生成文件:

    1. kube-controller-manager.kubeconfig

    " class="reference-link">为 kube-scheduler 创建 kubeconfig

    1. APISERVER="https://10.200.16.79:6443"
    1. kubectl config set-cluster roc \
    2. --certificate-authority=ca.pem \
    3. --embed-certs=true \
    4. --server=${APISERVER} \
    5. --kubeconfig=kube-scheduler.kubeconfig
    6. kubectl config set-credentials system:kube-scheduler \
    7. --client-certificate=kube-scheduler.pem \
    8. --client-key=kube-scheduler-key.pem \
    9. --embed-certs=true \
    10. --kubeconfig=kube-scheduler.kubeconfig
    11. kubectl config set-context default \
    12. --cluster=roc \
    13. --user=system:kube-scheduler \
    14. --kubeconfig=kube-scheduler.kubeconfig
    15. kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig

    生成文件:

    1. kube-scheduler.kubeconfig

    " class="reference-link">为管理员创建 kubeconfig

    这里为管理员生成 kubeconfig,方便使用 kubectl 来管理集群:

    1. APISERVER="https://10.200.16.79:6443"
    1. kubectl config set-cluster roc \
    2. --certificate-authority=ca.pem \
    3. --embed-certs=true \
    4. --server=${APISERVER} \
    5. --kubeconfig=admin.kubeconfig
    6. kubectl config set-credentials admin \
    7. --client-certificate=admin.pem \
    8. --client-key=admin-key.pem \
    9. --embed-certs=true \
    10. --kubeconfig=admin.kubeconfig
    11. kubectl config set-context default \
    12. --cluster=roc \
    13. --user=admin \
    14. --kubeconfig=admin.kubeconfig
    15. kubectl config use-context default --kubeconfig=admin.kubeconfig

    生成文件:

    1. admin.kubeconfig

    admin.kubeconfig 放到需要执行 kubectl 的机器的 ~/.kube/config 这个目录,这是 kubectl 读取 kubeconfig 的默认路径,执行 kubectl 时就不需要指定 kubeconfig 路径了:

    1. mv admin.kubeconfig ~/.kube/config

    下载安装控制面组件

    1. wget -q --show-progress --https-only --timestamping \
    2. https://storage.googleapis.com/kubernetes-release/release/v1.16.1/bin/linux/amd64/kube-apiserver \
    3. https://storage.googleapis.com/kubernetes-release/release/v1.16.1/bin/linux/amd64/kube-controller-manager \
    4. https://storage.googleapis.com/kubernetes-release/release/v1.16.1/bin/linux/amd64/kube-scheduler
    5. chmod +x kube-apiserver kube-controller-manager kube-scheduler
    6. mv kube-apiserver kube-controller-manager kube-scheduler /usr/local/bin/

    " class="reference-link">配置控制面组件

    准备配置相关目录:

    1. sudo mkdir -p /etc/kubernetes/config
    2. sudo mkdir -p /var/lib/kubernetes

    确定集群的集群网段 (Pod IP 占用网段)和 serivce 网段 (service 的 cluster ip 占用网段),它们可以没有交集。

    记集群网段为 CLUSTER_CIDR:

    1. CLUSTER_CIDR=10.10.0.0/16

    记 service 网段为 SERVICE_CIDR:

    1. SERVICE_CIDR=10.32.0.0/16

    " class="reference-link">配置 kube-apiserver

    放入证书文件:

    1. sudo cp ca.pem ca-key.pem apiserver-key.pem apiserver.pem \
    2. service-account-key.pem service-account.pem /var/lib/kubernetes/

    记所有 ETCD 实例的访问地址为 ETCD_SERVERS (替换 IP 为所有 ETCD 节点内网 IP):

    1. ETCD_SERVERS="https://10.200.16.79:2379,https://10.200.17.6:2379,https://10.200.16.70:2379"

    记当前节点内网 IP 为 INTERNAL_IP:

    1. INTERNAL_IP=10.200.16.79

    配置 systemd:

    1. cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service
    2. [Unit]
    3. Description=Kubernetes API Server
    4. Documentation=https://github.com/kubernetes/kubernetes
    5. [Service]
    6. ExecStart=/usr/local/bin/kube-apiserver \\
    7. --enable-bootstrap-token-auth=true \\
    8. --advertise-address=${INTERNAL_IP} \\
    9. --allow-privileged=true \\
    10. --apiserver-count=3 \\
    11. --audit-log-maxage=30 \\
    12. --audit-log-maxbackup=3 \\
    13. --audit-log-maxsize=100 \\
    14. --audit-log-path=/var/log/audit.log \\
    15. --authorization-mode=Node,RBAC \\
    16. --bind-address=0.0.0.0 \\
    17. --client-ca-file=/var/lib/kubernetes/ca.pem \\
    18. --enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
    19. --etcd-cafile=/var/lib/kubernetes/ca.pem \\
    20. --etcd-certfile=/var/lib/kubernetes/apiserver.pem \\
    21. --etcd-keyfile=/var/lib/kubernetes/apiserver-key.pem \\
    22. --etcd-servers=${ETCD_SERVERS} \\
    23. --event-ttl=1h \\
    24. --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
    25. --kubelet-client-certificate=/var/lib/kubernetes/apiserver.pem \\
    26. --kubelet-client-key=/var/lib/kubernetes/apiserver-key.pem \\
    27. --kubelet-https=true \\
    28. --runtime-config=api/all \\
    29. --service-account-key-file=/var/lib/kubernetes/service-account.pem \\
    30. --service-cluster-ip-range=${SERVICE_CIDR} \\
    31. --service-node-port-range=30000-32767 \\
    32. --tls-cert-file=/var/lib/kubernetes/apiserver.pem \\
    33. --tls-private-key-file=/var/lib/kubernetes/apiserver-key.pem \\
    34. --v=2
    35. Restart=on-failure
    36. RestartSec=5
    37. [Install]
    38. WantedBy=multi-user.target
    39. EOF
    • --enable-bootstrap-token-auth=true 启用 bootstrap token 方式为 kubelet 签发证书

    " class="reference-link">配置 kube-controller-manager

    放入 kubeconfig:

    1. sudo cp kube-controller-manager.kubeconfig /var/lib/kubernetes/

    准备 systemd 配置 kube-controller-manager.service:

    1. CLUSTER_CIDR=10.10.0.0/16
    2. SERVICE_CIDR=10.32.0.0/16
    1. cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service
    2. [Unit]
    3. Description=Kubernetes Controller Manager
    4. Documentation=https://github.com/kubernetes/kubernetes
    5. [Service]
    6. ExecStart=/usr/local/bin/kube-controller-manager \\
    7. --address=0.0.0.0 \\
    8. --cluster-cidr=${CLUSTER_CIDR} \\
    9. --allocate-node-cidrs \\
    10. --cluster-name=kubernetes \\
    11. --cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\
    12. --cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\
    13. --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\
    14. --leader-elect=true \\
    15. --root-ca-file=/var/lib/kubernetes/ca.pem \\
    16. --service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\
    17. --service-cluster-ip-range=${SERVICE_CIDR} \\
    18. --use-service-account-credentials=true \\
    19. --v=2
    20. Restart=on-failure
    21. RestartSec=5
    22. [Install]
    23. WantedBy=multi-user.target
    24. EOF

    所有 kube-controller-manager 实例都使用相同的 systemd service 文件,可以直接将这里创建好的拷贝给其它 Master 节点

    " class="reference-link">配置 kube-scheduler

    放入 kubeconfig:

    1. sudo cp kube-scheduler.kubeconfig /var/lib/kubernetes/

    准备启动配置文件 kube-scheduler.yaml:

    1. cat <<EOF | sudo tee /etc/kubernetes/config/kube-scheduler.yaml
    2. apiVersion: kubescheduler.config.k8s.io/v1alpha1
    3. kind: KubeSchedulerConfiguration
    4. clientConnection:
    5. kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
    6. leaderElection:
    7. leaderElect: true
    8. EOF

    准备 systemd 配置 kube-scheduler.service:

    1. cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service
    2. [Unit]
    3. Description=Kubernetes Scheduler
    4. Documentation=https://github.com/kubernetes/kubernetes
    5. [Service]
    6. ExecStart=/usr/local/bin/kube-scheduler \\
    7. --config=/etc/kubernetes/config/kube-scheduler.yaml \\
    8. --v=2
    9. Restart=on-failure
    10. RestartSec=5
    11. [Install]
    12. WantedBy=multi-user.target
    13. EOF

    启动

    1. sudo systemctl daemon-reload
    2. sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler
    3. sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler

    RBAC 授权 kube-apiserver 访问 kubelet

    kube-apiserver 有些情况也会访问 kubelet,比如获取 metrics、查看容器日志或登录容器,这是 kubelet 作为 server, kube-apiserver 作为 client,kubelet 监听的 https,kube-apiserver 经过证书认证访问 kubelet,但还需要经过授权才能成功调用接口,我们通过创建 RBAC 规则授权 kube-apiserver 访问 kubelet:

    1. cat <<EOF | kubectl apply -f -
    2. apiVersion: rbac.authorization.k8s.io/v1beta1
    3. kind: ClusterRole
    4. metadata:
    5. annotations:
    6. rbac.authorization.kubernetes.io/autoupdate: "true"
    7. labels:
    8. kubernetes.io/bootstrapping: rbac-defaults
    9. name: system:kube-apiserver-to-kubelet
    10. rules:
    11. - apiGroups:
    12. - ""
    13. resources:
    14. - nodes/proxy
    15. - nodes/stats
    16. - nodes/log
    17. - nodes/spec
    18. - nodes/metrics
    19. verbs:
    20. - "*"
    21. EOF
    22. cat <<EOF | kubectl apply -f -
    23. apiVersion: rbac.authorization.k8s.io/v1beta1
    24. kind: ClusterRoleBinding
    25. metadata:
    26. name: system:kube-apiserver
    27. namespace: ""
    28. roleRef:
    29. apiGroup: rbac.authorization.k8s.io
    30. kind: ClusterRole
    31. name: system:kube-apiserver-to-kubelet
    32. subjects:
    33. - apiGroup: rbac.authorization.k8s.io
    34. kind: User
    35. name: kubernetes
    36. EOF

    " class="reference-link">RBAC 授权 kubelet 创建 CSR 与自动签发和更新证书

    节点 kubelet 通过 Bootstrap Token 调用 apiserver CSR API 请求签发证书,kubelet 通过 bootstrap token 认证后会在 system:bootstrappers 用户组里,我们还需要给它授权调用 CSR API,为这个用户组绑定预定义的 system:node-bootstrapper 这个 ClusterRole 就可以:

    1. cat <<EOF | kubectl apply -f -
    2. # enable bootstrapping nodes to create CSR
    3. apiVersion: rbac.authorization.k8s.io/v1
    4. kind: ClusterRoleBinding
    5. metadata:
    6. name: create-csrs-for-bootstrapping
    7. subjects:
    8. - kind: Group
    9. name: system:bootstrappers
    10. apiGroup: rbac.authorization.k8s.io
    11. roleRef:
    12. kind: ClusterRole
    13. name: system:node-bootstrapper
    14. apiGroup: rbac.authorization.k8s.io
    15. EOF

    这里的 CSR API 主要用于 kubelet 发起 client 和 server 证书签发请求

    给 kubelet 授权自动审批通过 client 证书的 CSR 请求权限以实现自动创建新的 client 证书 (之前没创建过 client 证书,通过 bootstrap token 认证后在 system:bootstrappers 用户组里):

    1. cat <<EOF | kubectl apply -f -
    2. # Approve all CSRs for the group "system:bootstrappers"
    3. apiVersion: rbac.authorization.k8s.io/v1
    4. kind: ClusterRoleBinding
    5. metadata:
    6. name: auto-approve-csrs-for-group
    7. subjects:
    8. - kind: Group
    9. name: system:bootstrappers
    10. apiGroup: rbac.authorization.k8s.io
    11. roleRef:
    12. kind: ClusterRole
    13. name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
    14. apiGroup: rbac.authorization.k8s.io
    15. EOF

    给已启动过的 kubelet 授权自动审批通过 server 证书的 CSR 请求权限以实现自动轮转 client 证书 (之前创建过证书,在证书还未过期前通过证书认证后在 system:nodes 用户组里):

    1. cat <<EOF | kubectl apply -f -
    2. # Approve renewal CSRs for the group "system:nodes"
    3. apiVersion: rbac.authorization.k8s.io/v1
    4. kind: ClusterRoleBinding
    5. metadata:
    6. name: auto-approve-renewals-for-nodes
    7. subjects:
    8. - kind: Group
    9. name: system:nodes
    10. apiGroup: rbac.authorization.k8s.io
    11. roleRef:
    12. kind: ClusterRole
    13. name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
    14. apiGroup: rbac.authorization.k8s.io
    15. EOF

    注意上面两个授权都只是针对于 client 证书签发的自动审批权限,server 证书目前不支持自动审批,需要管理员通过 kubectl certificate approve <csr name> 来人工审批或者自己写外部 controller 来实现自动审批 (kubelet 访问 apiserver 使用 client 证书, apiserver 主动访问 kubelet 时才会用到 server 证书,通常用于获取 metrics 的场景)

    " class="reference-link">创建 Bootstrap Token 与 bootstrap-kubeconfig

    bootstrap token 用于 kubelet 自动请求签发证书,以 Secret 形式存储,不需要事先给 apiserver 配置静态 token,这样也易于管理。

    创建了 bootstrap token 后我们利用它使用它来创建 bootstrap-kubeconfig 以供后面部署 Worker 节点用 (kubelet 使用 bootstrap-kubeconfig 自动创建证书),下面是创建方法:

    1. APISERVER="https://10.200.16.79:6443"
    1. # token id should match regex: [a-z0-9]{6}
    2. TOKEN_ID=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ' | head -c 6)
    3. # token secret should match regex: [a-z0-9]{16}
    4. TOKEN_SECRET=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ' | head -c 16)
    5. cat <<EOF | kubectl apply -f -
    6. apiVersion: v1
    7. kind: Secret
    8. metadata:
    9. # Name MUST be of form "bootstrap-token-<token id>",
    10. name: bootstrap-token-${TOKEN_ID}
    11. namespace: kube-system
    12. # Type MUST be 'bootstrap.kubernetes.io/token'
    13. type: bootstrap.kubernetes.io/token
    14. stringData:
    15. # Human readable description. Optional.
    16. description: "The default bootstrap token used for signing certificates"
    17. # Token ID and secret. Required.
    18. token-id: "${TOKEN_ID}"
    19. token-secret: "${TOKEN_SECRET}"
    20. # Expiration. Optional.
    21. # expiration: 2020-03-10T03:22:11Z
    22. # Allowed usages.
    23. usage-bootstrap-authentication: "true"
    24. usage-bootstrap-signing: "true"
    25. # Extra groups to authenticate the token as. Must start with "system:bootstrappers:"
    26. # auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress
    27. EOF
    28. kubectl config --kubeconfig=bootstrap-kubeconfig set-cluster bootstrap --server="${APISERVER}" --certificate-authority=ca.pem --embed-certs=true
    29. kubectl config --kubeconfig=bootstrap-kubeconfig set-credentials kubelet-bootstrap --token=${TOKEN_ID}.${TOKEN_SECRET}
    30. kubectl config --kubeconfig=bootstrap-kubeconfig set-context bootstrap --user=kubelet-bootstrap --cluster=bootstrap
    31. kubectl config --kubeconfig=bootstrap-kubeconfig use-context bootstrap

    bootstrap token 的 secret 格式参考: https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/#bootstrap-token-secret-format

    生成文件:

    1. bootstrap-kubeconfig