文档首页/ 云容器引擎 CCE/ 用户指南/ 权限/ 在CCE中使用Dex进行OIDC身份验证
更新时间:2025-08-19 GMT+08:00

在CCE中使用Dex进行OIDC身份验证

Dex是一个开源的OpenID Connect(OIDC)身份提供商,在Kubernetes中使用Dex可以为集群提供灵活的身份认证和联邦身份管理能力。Dex充当中间层,将多种身份源(如LDAP、GitHub、SAML等)转换为标准的OIDC协议,供Kubernetes和其他应用使用。

OIDC是一种基于OAuth 2.0协议的认证方式,在使用访问令牌(Access Token)之外还会返回一个ID Token(ID 令牌)。ID Token是一个由服务器签名的JWT(JSON Web Token)令牌,包含用户的邮箱地址等预知字段。Kubernetes可以根据ID Token中包含的用户信息进行RBAC授权,从而实现第三方身份源与Kubernetes权限的转换,详情请参见OpenID Connect(OIDC)令牌

典型应用场景如下:

  • 企业LDAP/AD集成:企业内部已有LDAP,希望Kubernetes直接继承现有用户体系。
  • 多集群统一认证:多个Kubernetes集群共享同一个Dex实例,实现统一登录。
  • 统一身份联邦:多团队协作时,将不同来源的用户身份认证(如GitHub、Gitlab等)通过Dex统一转换为OIDC协议,并获取 Kubernetes可识别的OIDC Token。

本文演示使用LDAP OAuth账户的方式完成CCE OIDC的认证。

方案原理

在Kubernetes集群中使用Dex进行OIDC身份验证时,主要包含Dex和dex-k8s-authenticator两个组件:

  • Dex充当其他身份提供商的门户,负责将身份验证请求推送到LDAP服务器、SAML提供商或其他网络身份提供商(如 GitHub、Gitlab等)。
  • dex-k8s-authenticator是一个web-app,它可以与Dex进行交互并获取Dex生成的token,然后提供创建和修改kubeconfig文件的命令。用户执行这些生成的命令后可以完成kubeconfig文件配置。
图1 Dex登录验证流程

使用Dex登录验证的流程如下所示:

  1. 用户访问登录页面。
  2. 系统会将登录请求重定向到Dex进行身份登录验证。
  3. Dex将身份验证请求转发给第三方身份认证服务(Identity Provider)。
  4. 如果用户的凭证通过了第三方身份认证服务的验证,身份认证服务将返回id_token。
  5. 用户在使用kubectl时,将id_token设置为--token标志的值,或者将其直接添加到kubeconfig中进行使用。
  6. kubectl将id_token放在HTTP请求的Authorization头部,并发起请求到Kubernetes API服务器。
  7. API服务器接收到请求后,会验证Authorization头部中的JWT签名,以确认其有效性。
  8. API服务器会与Dex通信以验证id_token是否已经被授权。
  9. Dex确认该用户已授权,并返回验证结果。
  10. 鉴权成功之后,API服务器向kubectl返回响应。
  11. 最后,kubectl将API服务器的响应以可读的形式呈现给用户。

准备工作

  1. 创建CCE集群:在华为云控制台创建一个CCE集群,且集群版本要求v1.30及以上,详情请参见购买Standard/Turbo集群
  2. 准备kubectl及Helm工具:在集群所在VPC内准备一台可访问公网的虚拟机,安装kubectl连接集群,并安装Helm v3
  3. 创建ELB并绑定公网IP:创建一个ELB实例,并绑定一个公网IP,具体操作请参见购买独享型负载均衡器
  4. 准备域名
    • 公网域名1:dex.k8s.example.com,此域名为dex服务的访问域名地址。
    • 公网域名2:login.k8s.example.com,此域名为dex-k8s-authenticator服务的域名地址。
  5. 配置DNS A记录:为上述两个域名配置DNS公网解析,具体操作请参见配置公网域名解析。如果仅使用内网访问该域名则可以通过节点host进行配置。
  6. 安装Nginx Ingress插件:选择步骤3中创建的ELB实例,详情请参见NGINX Ingress控制器
  7. 已有LDAP服务:确保LDAP服务已部署,并创建好用户组和用户。
  8. (可选)节点子网配置SNAT:如果Dex部署在其他集群,需要为集群所在VPC和节点所在子网创建公网NAT网关,允许kube-apiserver访问公网。具体操作请参见购买公网NAT网关

步骤一:创建密钥(已有证书请忽略)

  1. 登录已安装kubectl和Helm的虚拟机。
  2. 创建Dex自签证书。如果通过HTTPS访问Dex需要证书认证,因此需要先自签名服务器证书和CA证书。

    创建create_cert.sh脚本文件,文件内容如下:
    #!/bin/bash
    mkdir -p ssl
    cat << EOF > ssl/req.cnf
    [req]
    req_extensions = v3_req
    distinguished_name = req_distinguished_name
    
    [req_distinguished_name]
    
    [ v3_req ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName = @alt_names
    
    [alt_names]
    DNS.1 = *.k8s.example.com  #  所有k8s.example.com后缀的域名都是此证书的信任范围
    EOF
    
    openssl genrsa -out ssl/ca-key.pem 2048
    openssl req -x509 -new -nodes -key ssl/ca-key.pem -days 3650 -out ssl/ca.pem -subj "/CN=kube-ca"
    
    openssl genrsa -out ssl/key.pem 2048
    openssl req -new -key ssl/key.pem -out ssl/csr.pem -subj "/CN=kube-ca" -config ssl/req.cnf
    openssl x509 -req -in ssl/csr.pem -CA ssl/ca.pem -CAkey ssl/ca-key.pem -CAcreateserial -out ssl/cert.pem -days 3650 -extensions v3_req -extfile ssl/req.cnf

    执行脚本:

    chmod +x create_cert.sh
    ./create_cert.sh

  3. 生成服务器证书Secret,访问 dex.k8s.example.com 和 login.k8s.example.com 需要使用该密钥。本示例中密钥名称为dex.example.com.tls

    kubectl create ns dex
    cd ssl; mv key.pem tls.key; mv cert.pem tls.crt
    kubectl create secret tls -n dex dex.example.com.tls \
       --cert=tls.crt\
       --key=tls.key

步骤二:部署Dex应用

使用Helm部署Dex应用,操作详情请参见通过Dex进行Kubernetes身份验证

  1. 登录已安装kubectl和Helm的虚拟机,添加Helm仓库。

    helm repo add dex https://charts.dexidp.io
    helm repo update

  2. 创建dex-values.yaml文件,用于自定义配置Dex参数,该文件中定义了Dex的访问方式和Dex中注册的LDAP后端服务。

    文件示例如下:
    tls: 
      enabled: true 
      clientCA: "" 
    ingress: 
      enabled: true 
      className: nginx   # 创建Nginx Ingress
      hosts: 
        - host: dex.k8s.example.com   # Dex的访问域名
          paths: 
            - path: / 
              pathType: ImplementationSpecific 
      tls: 
        - secretName: dex.example.com.tls  # 步骤一中创建Dex的访问密钥
          hosts: 
            - dex.k8s.example.com   # Dex的访问域名
    config: 
      issuer: https://dex.k8s.example.com   # Dex的访问域名,访问地址也可以填http 
      storage: 
        type: kubernetes 
        config: 
          inCluster: true 
      oauth2:
        responseTypes: ["code", "token", "id_token"] 
        skipApprovalScreen: true 
      connectors: 
       - type: ldap 
         id: ldap 
         name: LDAP 
         config:  
           host: xxx.xxx.xxx.xxx:389 # ldap server 
           insecureNoSSL: true 
           insecureSkipVerify: true 
           bindDN: CN=admin,DC=example,DC=com # 管理员DN(Distinguished Name),是LDAP目录中的唯一标识符
           bindPW: "*****" # 请设置管理员密码
           userSearch: # 查询LDAP中的用户信息映射到Dex中
             baseDN: dc=example,dc=com 
             filter: "(objectClass=posixAccount)" 
             username: uid  # 用户登录名
             idAttr: DN # 本示例中将LDAP记录中的DN映射到Dex
             emailAttr: mail # 本示例中将LDAP记录中的mail字段映射到Dex
             nameAttr: cn # 本示例中将LDAP记录中的cn字段映射到Dex
           groupSearch: 
             baseDN: dc=example,dc=com 
             filter: "(objectClass=posixGroup)" 
             userMatchers: 
             - userAttr: uid 
               groupAttr: memberUid 
             nameAttr: cn 
      staticClients: 
        - id: kubernetes    # 注册客户端ID
          secret: *****    # 设置客户端密码
          name: "kubernetes" 
          redirectURIs: 
           - https://login.k8s.example.com/callback   # dex-k8s-authenticator的访问域名

    更多参数配置请参考官方示例:

  3. 根据自定义配置安装Dex。

    helm install dex dex/dex --namespace dex --create-namespace --version 0.19.1 --values dex-values.yaml

    执行以下命令查看已安装的模板实例。

    helm list

步骤三:配置集群内域名解析

  1. 登录CCE控制台,单击集群名称进入集群。
  2. 在左侧导航栏中选择“插件中心”,在CoreDNS 域名解析下单击“编辑”,进入插件详情页。
  3. “参数配置”下编辑“扩展参数配置”,在plugins字段添加以下内容,增加Dex服务域名解析。

    {
      "configBlock": "10.247.82.158 dex.k8s.example.com\nfallthrough", 
      "name": "hosts"
    }

    其中IP 10.247.82.158为nginx-ingress-controller Service的ClusterIP。

  4. 单击“确定”。

步骤四:部署dex-k8s-authenticator应用

  1. 添加Helm仓库。

    helm repo add skm https://charts.sagikazarmark.dev
    helm repo update

  2. 创建authen-values.yaml文件,用于自定义配置dex-k8s-authenticator参数。配置示例详情请参见https://github.com/mintel/dex-k8s-authenticator/blob/master/docs/config.md

    config: 
      clusters: 
        - name: Hello-CCE 
          short_description: "Your cluster" 
          description: "Your cluster" 
          issuer: https://dex.k8s.example.com    # Dex的访问域名
          client_id: kubernetes                  # 对应步骤二中Dex config中的client_id 
          client_secret: *****                   # 对应步骤二中Dex config中的client_secret 
          redirect_uri: https://login.k8s.example.com/callback        # dex-k8s-authenticator的访问域名
          k8s_master_uri: https://192.168.0.158:5443                  # 集群API Server访问地址 
          #集群的CA证书
          k8s_ca_pem: | 
            -----BEGIN CERTIFICATE----- 
            ...
            -----END CERTIFICATE----- 
      # 如果Dex访问为https, 需要提供Dex域名的CA证书
      trusted_root_ca: |
        -----BEGIN CERTIFICATE----- 
        ...
        -----END CERTIFICATE----- 
    ingress: 
      enabled: true 
      className: nginx 
      hosts: 
        - host: login.k8s.example.com # 修改为dex-k8s-authenticator的访问域名
          paths: 
            - path: / 
              pathType: ImplementationSpecific 
      tls: 
        - secretName: dex.example.com.tls  # 步骤一中创建Dex的访问密钥
          hosts: 
            - login.k8s.example.com    # 修改为dex-k8s-authenticator的访问域名

  3. 根据自定义配置安装dex-k8s-authenticator。

    helm install dex-k8s-authenticator skm/dex-k8s-authenticator --namespace dex --version 0.0.3 --values authen-values.yaml

步骤五:修改APIserver启动参数

  1. 登录CCE控制台,单击集群名称进入集群。
  2. 在集群控制台左侧导航栏中选择“配置中心”。
  3. 切换至“集群访问配置”页签,启用OIDC,并配置kube-apiserver使用OIDC所需的参数。

    参数

    说明

    示例

    发布者URL (oidc-issuer-url)

    提供OpenID Connect认证服务的URL,必须是HTTPS协议。

    https://dex.k8s.example.com

    客户端ID (oidc-client-id)

    OpenID Connect认证服务中注册的客户端ID,例如步骤二中注册的客户端ID为kubernetes。

    kubernetes

    注册用户名 (oidc-username-claim)

    指定JWT令牌中的字段,获取该字段的值作为用户名。默认值为sub,这通常是最终用户的唯一标识符,您也可以选择其他字段,如email或name。

    后续可以在集群中根据用户名授予Kubernetes权限,参见步骤六:为第三方用户授予Kubernetes权限

    email

    该参数值设置为email,表示将JWT中email字段的值,即电子邮件地址作为用户名。

    注册组 (oidc-groups-claim)

    指定JWT令牌中的字段,获取该字段的值作为用户组,表示用户组的字段名称通常为groups。后续可以根据用户组授予Kubernetes权限,参见步骤六:为第三方用户授予Kubernetes权限

    groups

    该参数值设置为groups,表示将JWT中groups字段的值作为用户组。

    认证CA证书 (oidc-ca-pem)

    PEM格式的CA证书,用于签署身份提供商的Web证书。

    步骤一中Dex域名的CA证书

  4. 单击“确认配置”。

步骤六:为第三方用户授予Kubernetes权限

由于Dex只是对用户进行认证,并没有Kubernetes授权,所以需要为经过Dex认证的用户添加Kubernetes权限。

本示例中,根据步骤五中设置的注册组groups进行授权,即对认证返回的JWT中的用户组授予Kubernetes权限(本示例中用户组名称为CCE)。如果登录用户属于该用户组,则具有相应的Kubernetes权限。配置ClusterRoleBinding和ClusterRole的示例如下,您可以根据自己的实际需求分配对应的权限:

kind: ClusterRoleBinding 
apiVersion: rbac.authorization.k8s.io/v1 
metadata: 
  name: cce-admin 
subjects: 
- kind: Group 
  name: "CCE"  # CCE用户组是LDAP中用户所属用户组,为该用户组中的用户授权Kubernetes权限
  apiGroup: rbac.authorization.k8s.io 
roleRef: 
  kind: ClusterRole 
  name: cluster-admin 
   apiGroup: rbac.authorization.k8s.io 

步骤七:登录测试

  1. 在浏览器中打开dex-k8s-authenticator域名,本示例中为login.k8s.example.com。
  2. 输入LDAP中CCE用户组下的用户账号密码。
  3. 登录成功后,dex-k8s-authenticator会提供可执行的命令,帮助用户配置kubeconfig,请按照页面指导执行命令。

  4. 执行以上命令,完成kubeconfig配置后,使用kubectl访问Kubernetes资源进行测试。