You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为访问GKE Kubernetes API挂载证书的问题求助

问题:GKE工作负载身份模式下挂载Kubernetes集群CA证书以访问API

背景

将Django管理命令迁移至配置了服务账号与工作负载身份的私有GKE集群,该命令通过Kubernetes API修改HPA配置。原集群依赖默认服务账号自动挂载的/var/run/secrets/kubernetes.io/serviceaccount/token和ca.crt文件建立API连接,但新集群未自动生成该目录及文件,已通过Helm手动挂载服务账号token,但缺少集群CA证书导致SSL连接失败。

错误信息

HTTPSConnectionPool(host='10.255.240.1', port=443): Max retries exceeded with url: /apis/autoscaling/v1/namespaces/staging/horizontalpodautoscalers/draft-nginx (Caused by SSLError(FileNotFoundError(2, 'No such file or directory')))

堆栈跟踪

File "/usr/src/app/drafty/core/management/commands/scale_workloads.py", line 198, in scale_pods
    api.patch_namespaced_horizontal_pod_autoscaler(
  File "/usr/local/lib/python3.11/site-packages/kubernetes/client/api/autoscaling_v1_api.py", line 983, in patch_namespaced_horizontal_pod_autoscaler
    return self.patch_namespaced_horizontal_pod_autoscaler_with_http_info(name, namespace, body, **kwargs)  # noqa: E501
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/kubernetes/client/api/autoscaling_v1_api.py", line 1098, in patch_namespaced_horizontal_pod_autoscaler_with_http_info
    return self.api_client.call_api(
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/kubernetes/client/api_client.py", line 348, in call_api
    return self.__call_api(resource_path, method,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/kubernetes/client/api_client.py", line 180, in __call_api
    response_data = self.request(
                    ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/kubernetes/client/api_client.py", line 407, in request
    return self.rest_client.PATCH(url,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/kubernetes/client/rest.py", line 296, in PATCH
    return self.request("PATCH", url,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/kubernetes/client/rest.py", line 169, in request
    r = self.pool_manager.request(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/request.py", line 78, in request
    return self.request_encode_body(
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/request.py", line 170, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/poolmanager.py", line 376, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 826, in urlopen
    return self.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 826, in urlopen
    return self.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 826, in urlopen
    return self.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 798, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/util/retry.py", line 592, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='10.255.240.1', port=443): Max retries exceeded with url: /apis/autoscaling/v1/namespaces/staging/horizontalpodautoscalers/draft-nginx (Caused by SSLError(FileNotFoundError(2, 'No such file or directory')))

相关代码

API配置代码

configuration = kubernetes.client.Configuration()
    configuration.api_key["authorization"] = token
    configuration.api_key_prefix["authorization"] = "Bearer"
    configuration.host = server
    configuration.ssl_ca_cert = cert

    api = kubernetes.client.AutoscalingV1Api(
        kubernetes.client.ApiClient(configuration)
    )

原项目参数配置

parser.add_argument(
        "--cert",
        action="store",
        dest="cert",
        default="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt",
        help="File containing valid certificate to make request",
    )
    parser.add_argument(
        "--token",
        action="store",
        dest="token",
        type=argparse.FileType("r"),
        default="/var/run/secrets/kubernetes.io/serviceaccount/token",
        help="File containing token to make request",
    )

Helm挂载token配置

containers:
            - name: scale-workloads
              image: {{ .Values.gke_registry }}/base_python:{{ .Values.global.build }}
              imagePullPolicy: Always
              command:
                - python -m django
              args:
                - scale_workloads
                - --namespace={{ .Release.Namespace }}
                - --appserver={{ .Values.pods.appserver.minReplicas | default 1 }}
                - --nginx={{ .Values.pods.nginx.minReplicas | default 1 }}
              env:
                {{- include "proj.sharedEnv" $ | nindent 16 }}
                - name: DJANGO_SETTINGS_MODULE
                  value: {{ .Values.django_settings_module }}
              resources:
                requests:
                  cpu: 1000m
                  memory: 500Mi
              volumeMounts:
                - mountPath: /etc/config
                  name: configs
                - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
                  name: ksa-token
          volumes:
          - name: configs
            projected:
              defaultMode: 420
              sources:
              - secret:
                  name: proj-secrets
          - name: ksa-token
            projected:
              sources:
                - serviceAccountToken:
                    path: ksa-token
                    expirationSeconds: 86400
                    audience: some-oidc-audience

解决方案

1. 修改Helm配置,添加CA证书挂载

GKE集群默认在每个命名空间下都存在kube-root-ca.crt ConfigMap,包含集群根CA证书。只需修改ksa-token这个Projected Volume的配置,添加该ConfigMap作为源,将证书文件挂载到原路径;同时调整token路径与原代码默认值一致:

修改后的volumes部分:

- name: ksa-token
            projected:
              sources:
                - serviceAccountToken:
                    path: token  # 改为原代码默认的token文件名
                    expirationSeconds: 86400
                    audience: some-oidc-audience
                - configMap:
                    name: kube-root-ca.crt
                    items:
                    - key: ca.crt
                      path: ca.crt  # 挂载到原代码默认的证书路径

2. 验证挂载结果

部署后进入Pod,执行以下命令验证文件存在:

ls -l /var/run/secrets/kubernetes.io/serviceaccount/
cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

3. 确认API访问正常

重新运行Django管理命令,确认SSL错误消失,API调用成功。

内容的提问来源于stack exchange,提问作者markwalker_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 23:49:54