版本:v25.12

自定义集群证书使用指导

背景信息

openFuyao支持使用自定义CA证书来签发Kubernetes集群内所有组件的证书,以满足企业级安全合规要求。通过导入用户全局CA证书、私钥和证书链,以及配置证书签发策略和签发请求(CSR),可以实现对集群证书体系的完全控制。

本指南基于Kubernetes官方PKI证书配置要求,参考文档:https://kubernetes.io/zh-cn/docs/setup/best-practices/certificates/

Kubernetes集群内共需要15个PKI证书,用于不同组件之间的安全通信和身份认证。详细的证书配置信息请参见附录:PKI证书配置表

前提条件

在开始配置自定义证书之前,请确保满足以下条件:

  1. 证书私钥规格要求。

    • 证书类型:必须具有CA签发功能的X.509公钥证书。
    • 私钥格式:必须为PKCS#1格式。

    如不满足,使用以下命令检查私钥格式并进行转换:

    bash
    # 检查私钥是否为PKCS#1格式
    openssl rsa -in <私钥文件> -text -noout
    bash
    # 将私钥转换为PKCS#1格式
    openssl rsa -in <原始私钥文件> -out <转换后的私钥文件>
  2. 文件准备。

    • 已准备好全局CA证书文件(global-ca.crt)。
    • 已准备好全局CA私钥文件(global-ca.key)。
    • (可选) 证书链文件(trust-chain.crt)。
      • 如果没有提供此文件,apiserver会默认挂载ca.crt
    • (可选) 17个JSON配置文件(2个签发策略文件 + 15个CSR配置文件)。
      • 如果没有提供这些配置文件,系统将使用代码内置的默认签发策略。
  3. 操作时机。

    • 必需的证书文件(global-ca.crtglobal-ca.key)必须在引导节点创建之前完成导入。
    • 可选的证书链文件和配置文件(如需要)也应在引导节点创建之前完成导入。
    • 确保有足够的权限访问目标路径。

使用限制

在配置和导入自定义证书签发策略与签发请求时,请务必注意以下限制:

  1. 文件名不可修改。

    • 每个组件的CSR请求文件名和对应的签发策略文件名均为系统识别依据,文件名必须与模板保持一致
    • 若文件名被更改,系统在加载ConfigMap时将无法正确匹配对应的组件配置,导致证书签发失败或组件启动异常。
  2. CN(Common Name)与O(Organization)字段必须正确配置。

    • 这两个字段直接影响Kubernetes的基于证书的身份认证RBAC授权
    • 必须严格按照集群规范填写,否则组件将无法通过API Server的认证,可以参见附录:PKI证书配置表
    • 若CN/O配置错误,组件或用户将无法通过证书身份认证,表现为连接被拒绝(如"Unauthorized"或"x509: certificate signed by unknown authority")。
  3. 签发策略(profiles)名称需与组件一致。

    • profiles字段中的每个签发策略名称应与实际组件名称对应。
    • 若名称不匹配,组件将无法找到正确的签发配置,证书生成失败。
  4. 证书用途(keyUsage / extKeyUsage)配置必须正确。

    • 用途配置错误将导致组件之间TLS握手失败,集群通信中断。
  5. 必须包含默认签发策略(default profile)。

    • 若缺少default策略,部分使用默认签发规则的请求(如节点加入或自动签发)将被拒绝。
  6. CA签发策略文件不可出错。

    • CA是整个集群证书体系的根。若CA签发策略配置错误,所有下级组件证书将无法签发,导致控制平面服务(API Server、Scheduler、Controller Manager等)无法启动。
  7. kubelet证书CN字段限制。

    • kubelet-kubeconfig-csr.json的CN字段必须为system:node:<nodeName>
    • <nodeName>的值必须与kubelet向apiserver注册时提供的节点名称的值完全匹配。
    • 在高可用情况下,不同节点的名称值不同,bke会自动为kubelet证书的CN字段配置对应的节点名称。
  8. 负载均衡器要求提前准备。

    • 用户若要配置外部负载均衡器,需要提前将负载均衡器准备好,再将对应IP地址写入bc.yaml文件,否则集群节点启动会阻塞。

操作步骤

  1. 导入用户全局CA证书、私钥和证书链。

    1.1 准备证书文件。

    必须准备以下两个文件:

    • global-ca.crt:全局CA证书。
    • global-ca.key:全局CA私钥(必须是PKCS#1格式)。
    • (可选) trust-chain.crt:证书链文件。
      • 如果没有提供此文件,系统将使用global-ca.crt作为证书链,apiserver会挂载ca.crt

    1.2 放置证书文件。

    • 引导节点创建之前,将证书文件放置在指定路径:/etc/openFuyao/certs/
    • 文件名固定,不可修改:
      • global-ca.crt(必需)
      • global-ca.key(必需)
      • trust-chain.crt(可选)

      说明

      • PEM、CRT和KEY格式本质上都是相同的PEM编码格式,只是文件扩展名不同,都可以正常使用,只要满足前提条件即可。
      • 如果没有提供trust-chain.crt,系统会自动使用global-ca.crt作为证书链。
  2. 导入证书签发策略和签发请求CSR(可选)。

    说明

    此步骤为可选操作。如果没有提供这些配置文件,系统将使用代码内置的默认签发策略。

    2.1 文件组成说明。

    如需自定义证书签发策略和CSR配置,共需准备17个JSON文件,分为两类:

    • 证书签发请求(CSR)。

      • 15个JSON文件
      • 每个文件对应一个集群组件的证书签发请求(例如:apiserver、controller-manager、scheduler、kubelet等)。
      • 文件内容定义了该组件的证书主题信息(如CN、O、SAN、用途等),用于向CA发起签发请求。
    • 证书签发策略(Signing Policy)。

      • 2个JSON文件
      • 集群CA签发策略文件cluster-ca-policy.json) :定义集群根CA的签发规则和默认策略(default profile)。
      • 组件签发策略文件sign-policy.json) :定义除集群CA以外所有14个组件的签发策略以及一个通用的默认策略(default profile) ,这些策略存放在文件中的profiles字段下,每个profile对应一个组件证书的签发参数(有效期、用途、扩展属性等)。

    2.2 导入配置文件。

    引导节点创建之前,将2个签发策略和15个签发请求CSR配置JSON文件一起存放在指定路径:/etc/openFuyao/certs/cert_config/

    说明

    如果没有提供这些配置文件,系统将使用代码内置的默认签发策略,无需手动配置。

    2.3 配置文件模板。

    以下是证书配置文件的模板示例(该模板仅供参考)。涉及组件权限问题时,用户需要自行修改O字段。

    配置文件列表:

    序号文件名类型说明
    1cluster-ca-policy.json签发策略集群CA签发策略配置
    2cluster-ca-csr.jsonCSR配置集群CA证书签发请求
    3sign-policy.json签发策略集群组件签发策略配置
    4apiserver-csr.jsonCSR配置API Server证书签发请求
    5apiserver-etcd-client-csr.jsonCSR配置API Server访问etcd的客户端证书签发请求
    6front-proxy-client-csr.jsonCSR配置Front Proxy客户端证书签发请求
    7apiserver-kubelet-client-csr.jsonCSR配置API Server访问kubelet的客户端证书签发请求
    8front-proxy-ca-csr.jsonCSR配置Front Proxy CA证书签发请求
    9etcd-ca-csr.jsonCSR配置Etcd CA证书签发请求
    10etcd-server-csr.jsonCSR配置Etcd Server证书签发请求
    11etcd-healthcheck-client-csr.jsonCSR配置Etcd健康检查客户端证书签发请求
    12etcd-peer-csr.jsonCSR配置Etcd Peer证书签发请求
    13admin-kubeconfig-csr.jsonCSR配置Admin Kubeconfig证书签发请求
    14kubelet-kubeconfig-csr.jsonCSR配置Kubelet Kubeconfig证书签发请求
    15controller-manager-csr.jsonCSR配置Controller Manager证书签发请求
    16scheduler-csr.jsonCSR配置Scheduler证书签发请求
    17kube-proxy-csr.jsonCSR配置Kube-proxy证书签发请求

    2.3.1. 集群CA签发策略配置cluster-ca-policy.json

    JSON
    {
      "signing": {
        "default": {
          "usages": ["cert sign", "crl sign"],
          "expiry": "87600h",
          "ca_constraint": {
            "is_ca": true,
            "max_path_len": 0
          }
        },
        "profiles": {
          "ca": {
            "usages": ["cert sign", "crl sign"],
            "expiry": "87600h",
            "ca_constraint": {
              "is_ca": true,
              "max_path_len_zero": true
            }
          }
        }
      }
    }

    2.3.2. 集群CA CSR配置cluster-ca-csr.json

    JSON
    {
        "CN": "kubernetes",
        "C": "CN",
        "ST": "Beijing",
        "L": "Beijing",
        "OU": "Kubernetes",
        "key": {
          "algo": "rsa",
          "size": 2048
        },
        "hosts": ["kubernetes", "kubernetes.default"]
    }

    2.3.3. 集群组件签发策略配置sign-policy.json

    JSON
    {
      "signing": {
        "default": {
          "usages": ["digital signature", "key encipherment"],
          "expiry": "87600h"
        },
        "profiles": {
          "ca": {
            "usages": ["cert sign", "crl sign"],
            "expiry": "87600h",
            "ca_constraint": {
              "is_ca": true,
              "max_path_len": 0
            }
          },
          "apiserver": {
            "usages": ["digital signature", "key encipherment", "server auth"],
            "expiry": "87600h"
          },
          "apiserver-etcd-client": {
            "usages": ["digital signature", "key encipherment", "client auth"],
            "expiry": "87600h"
          },
          "apiserver-kubelet-client": {
            "usages": ["digital signature", "key encipherment", "client auth"],
            "expiry": "87600h"
          },
          "front-proxy-client": {
            "usages": ["digital signature", "key encipherment", "client auth"],
            "expiry": "87600h"
          },
          "front-proxy-ca": {
            "usages": ["cert sign", "crl sign"],
            "expiry": "87600h",
            "ca_constraint": {
              "is_ca": true,
              "max_path_len": 1
            }
          },
          "etcd/ca": {
            "usages": ["cert sign", "crl sign"],
            "expiry": "87600h",
            "ca_constraint": {
              "is_ca": true,
              "max_path_len": 1
            }
          },
          "etcd/server": {
            "usages": ["digital signature", "key encipherment", "server auth", "client auth"],
            "expiry": "87600h"
          },
          "etcd/peer": {
            "usages": ["digital signature", "key encipherment", "server auth", "client auth"],
            "expiry": "87600h"
          },
          "etcd/healthcheck-client": {
            "usages": ["digital signature", "key encipherment", "client auth"],
            "expiry": "87600h"
          },
          "controller-manager": {
            "usages": ["digital signature", "key encipherment", "client auth"],
            "expiry": "87600h"
          },
          "scheduler": {
            "usages": ["digital signature", "key encipherment", "client auth"],
            "expiry": "87600h"
          },
          "kubelet": {
            "usages": ["digital signature", "key encipherment", "server auth", "client auth"],
            "expiry": "87600h"
          },
          "admin": {
            "usages": ["digital signature", "key encipherment", "client auth"],
            "expiry": "87600h"
          },
          "kube-proxy": {
            "usages": ["digital signature", "key encipherment", "client auth"],
            "expiry": "87600h"
          }
        }
      }
    }

    2.3.4. API Server CSR配置apiserver-csr.json

    JSON
    {
      "CN": "kube-apiserver",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": [
        "kubernetes",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster.local",
        "10.0.0.1"
      ]
    }

    2.3.5. API Server Etcd Client CSR配置apiserver-etcd-client-csr.json

    JSON
    {
        "CN": "kube-apiserver-etcd-client",
        "C": "CN",
        "ST": "Beijing",
        "L": "Beijing",
        "OU": "Kubernetes",
        "key": {
          "algo": "rsa",
          "size": 2048
        },
        "hosts": []
    }

    2.3.6. Front Proxy Client CSR配置front-proxy-client-csr.json

    JSON
    {
      "CN": "front-proxy-client",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.7. API Server Kubelet Client CSR配置apiserver-kubelet-client-csr.json

    JSON
    {
      "CN": "kube-apiserver-kubelet-client",
      "O": "system:masters",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.8. Front Proxy CA CSR配置front-proxy-ca-csr.json

    JSON
    {
      "CN": "front-proxy-ca",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.9. Etcd CA CSR配置etcd-ca-csr.json

    JSON
    {
      "CN": "etcd-ca",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.10. Etcd Server CSR配置etcd-server-csr.json

    JSON
    {
      "CN": "etcd-server",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": ["localhost", "127.0.0.1"]
    }

    2.3.11. Etcd Healthcheck Client CSR配置etcd-healthcheck-client-csr.json

    JSON
    {
      "CN": "kube-etcd-healthcheck-client",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.12. Etcd Peer CSR配置etcd-peer-csr.json

    JSON
    {
      "CN": "etcd-peer",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.13. Admin Kubeconfig CSR配置admin-kubeconfig-csr.json

    JSON
    {
      "CN": "kubernetes-admin",
      "O": "system:masters",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.14. Kubelet Kubeconfig CSR配置kubelet-kubeconfig-csr.json

    说明

    kubelet-kubeconfig-csr.json的CN字段必须为system:node:<nodeName><nodeName>的值必须与kubelet向apiserver注册时提供的节点名称的值完全匹配。由于高可用情况下不同节点的名称值不同,所以不同节点的kubelet-kubeconfig-csr.json无法通过一个配置文件指定,bke会为kubelet证书的CN字段配置对应的节点名称,用户无需担心。

    JSON
    {
      "CN": "system:node:test-node",
      "O": "system:nodes",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.15. Controller Manager CSR配置controller-manager-csr.json

    JSON
    {
      "CN": "system:kube-controller-manager",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.16. Scheduler CSR配置scheduler-csr.json

    JSON
    {
      "CN": "system:kube-scheduler",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }

    2.3.17. Kube-proxy CSR配置kube-proxy-csr.json

    JSON
    {
      "CN": "system:kube-proxy",
      "O": "system:node-proxier",
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "OU": "Kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "hosts": []
    }
  3. 负载均衡器可选配(可选)。

    为证书写入外部负载均衡器IP地址:

    如果用户需要配置bke外部负载均衡器,需要在bc.yaml中添加对应的值,具体操作如下:

    3.1 在customExtra下添加对应的key、value值

    • key值固定,不可修改。
    • value值填写负载均衡器对应的IP地址。

    3.2 同步修改controlPlaneEndpoint

    • host改为负载均衡器对应的IP地址。

    配置示例:

    image

相关操作

验证证书配置

在引导节点创建后,可以通过以下方式验证证书是否正确配置:

  1. 检查证书文件。

    bash
    # 检查证书文件是否存在
    ls -la /etc/openFuyao/certs/
    ls -la /etc/openFuyao/certs/cert_config/
  2. 验证证书内容。

    bash
    # 查看证书信息
    openssl x509 -in /etc/openFuyao/certs/global-ca.crt -text -noout
  3. 检查集群组件状态。

    bash
    # 检查API Server是否正常启动
    kubectl get nodes
    kubectl get pods -n kube-system

FAQ

1. 私钥格式转换失败怎么办?

确保原始私钥文件格式正确,可以使用以下命令检查:

bash
# 检查私钥类型
file <私钥文件>
# 如果是PKCS#8格式,使用以下命令转换
openssl pkcs8 -topk8 -nocrypt -in <原始私钥文件> -out <临时文件>
openssl rsa -in <临时文件> -out <转换后的私钥文件>

2. 证书文件路径可以修改吗?

不可以。系统固定使用以下路径:

  • 全局CA证书:/etc/openFuyao/certs/
  • 证书配置文件:/etc/openFuyao/certs/cert_config/

3. 配置文件中的O字段如何配置?

O字段用于RBAC权限控制,需要根据实际需求配置:

  • system:masters:集群管理员权限
  • system:nodes:节点权限
  • system:kube-controller-manager:Controller Manager权限
  • system:kube-scheduler:Scheduler权限
  • system:node-proxier:Kube-proxy权限

4. 证书有效期如何设置?

在签发策略配置文件的expiry字段中设置,格式为时间单位(如87600h表示10年)。建议根据企业安全策略设置合理的有效期。

5. 高可用集群中kubelet证书如何配置?

在高可用情况下,不同节点的kubelet证书CN字段会自动配置为对应的节点名称,用户无需为每个节点单独配置。bke会在节点加入时自动处理。

附录

PKI证书配置表

表1展示了Kubernetes集群内所需要的15个PKI证书及其通用名称(CN)、组织(O)和证书用途:

表 1 PKI证书配置表

组件/证书名称CN(Common Name)O(Organization)用途 (usages)说明
Cluster CA (根CA)kubernetes(无)cert sign, crl sign集群根证书,用于签发所有子证书
Etcd CAetcd-ca(无)cert sign, crl sign签发etcd相关通信证书
Front-Proxy CAfront-proxy-ca(无)cert sign, crl sign用于API聚合层相关客户端证书
apiserverkube-apiserver(无)server authkube-apiserver服务端证书
apiserver-kubelet-clientkube-apiserver-kubelet-clientsystem:mastersclient authAPI Server访问kubelet的客户端证书
apiserver-etcd-clientkube-apiserver-etcd-client(无)client authAPI Server访问etcd的客户端证书
front-proxy-clientfront-proxy-client(无)client auth聚合层前端代理客户端证书
etcd-serveretcd-server(无)server authetcd服务端证书
etcd-peeretcd-peer(无)server auth, client authetcd节点间 (peer) 通信
etcd-healthcheck-clientkube-etcd-healthcheck-client(无)client auth健康检查客户端访问etcd
kubelet客户端 (kubeconfig)system:node:<nodeName>system:nodesclient authkubelet访问API Server的客户端证书
admin (kubeconfig)adminsystem:mastersclient auth集群管理员客户端证书(kubectl使用)
controller-manager (kubeconfig)system:kube-controller-manager(无)client authcontroller-manager使用的kubeconfig证书
scheduler (kubeconfig)system:kube-scheduler(无)client authscheduler使用的kubeconfig证书
kube-proxy(kubeconfig)system:kube-proxysystem:node-proxierclient authkube-proxy使用的kubeconfig证书

术语

表2展示了本文档中涉及的主要术语解释如下:

表 2 术语

中文名称英文全称略缩语说明
证书颁发机构Certificate AuthorityCA负责签发和管理数字证书的权威机构
公钥基础设施Public Key InfrastructurePKI用于管理数字证书和公钥-私钥对的系统
证书签发请求Certificate Signing RequestCSR包含证书申请者信息的文件,用于向CA申请证书
X.509标准-X.509国际电信联盟(ITU)制定的公钥证书标准,定义了数字证书的格式和结构
PKCS#1标准Public-Key Cryptography Standards #1PKCS#1RSA加密标准,定义了RSA私钥的存储格式
通用名称Common NameCNX.509证书中的字段,通常用于标识证书持有者的名称
组织OrganizationOX.509证书中的字段,用于标识证书持有者所属的组织
主题备用名称Subject Alternative NameSAN证书中用于指定多个域名或IP地址的扩展字段
基于角色的访问控制Role-Based Access ControlRBACKubernetes中的授权机制
传输层安全协议Transport Layer SecurityTLS用于在网络上提供加密通信
隐私增强邮件格式Privacy-Enhanced MailPEM一种Base64编码的证书和密钥存储格式
证书文件扩展名CertificateCRT通常用于存储X.509证书
私钥文件扩展名KeyKEY用于存储私钥
配置映射Configuration MapConfigMapKubernetes中的配置对象,用于存储非敏感的配置数据
Kubernetes配置文件Kubernetes Configurationkubeconfig包含集群访问信息、认证信息和上下文配置
配置项ProfileProfile签发策略配置中的配置项,定义了特定类型证书的签发参数
密钥用途Key UsagekeyUsage证书扩展字段,指定证书密钥的用途(如数字签名、密钥加密等)
扩展密钥用途Extended Key UsageextKeyUsage证书扩展字段,指定证书的特定用途(如服务器认证、客户端认证等)
证书撤销列表Certificate Revocation ListCRL包含已被撤销证书的列表
引导节点Bootstrap Node-集群初始化时创建的第一个节点,用于引导整个集群的创建过程
负载均衡器Load Balancer-用于在多个服务器之间分配网络流量的设备或服务
API服务器API ServerapiserverKubernetes API服务器,提供集群的REST API接口
-etcdetcd分布式键值存储系统,Kubernetes用于存储集群状态和配置数据
-kubeletkubeletKubernetes节点代理,运行在每个节点上,负责管理Pod和容器
控制器管理器Controller Managercontroller-managerKubernetes控制器管理器,运行各种控制器来维护集群状态
调度器schedulerschedulerKubernetes调度器,负责将Pod调度到合适的节点上运行
-kube-proxykube-proxyKubernetes网络代理,负责维护节点上的网络规则和负载均衡

说明