为访问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_
相关产品推荐
相关产品推荐

