十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SkyPilot API Server 部署实战:GKE + GCP Cloud SQL 持久化数据库(IAM 与密码认证双方案)

SkyPilot API Server 部署实战:GKE + GCP Cloud SQL 持久化数据库(IAM 与密码认证双方案) SkyPilot API Server 部署实战GKE GCP Cloud SQL 持久化数据库IAM 与密码认证双方案【免费下载链接】skypilotThe AI Compute Platform for frontier teams. SkyPilot turns fragmented AI compute into one AI supercomputer, so frontier AI teams build custom intelligence faster.项目地址: https://gitcode.com/GitHub_Trending/sk/skypilot本指南以 SkyPilot 官方 Helm 图表为基础完整讲解如何在 GKE 集群上部署 SkyPilot API Server并使用 GCP Cloud SQLPostgreSQL作为其持久化后端数据库支持IAM 认证与密码认证两种接入方式。读完本文你将掌握从创建 GKE 集群、配置 Cloud SQL 实例、授权服务账号到通过helm upgrade --install完成生产级部署的全流程并理解 Helm 图表底层如何把数据库连接串注入 API Server 进程。为什么需要为 API Server 配置外部数据库SkyPilot API Server 默认使用 SQLite 保存集群、任务、用户等状态数据。当它以 Kubernetes 工作负载形式运行时SQLite 文件所在卷的持久性、多副本一致性都难以保障因此官方 Helm 图表支持把状态存储切换到外部关系型数据库PostgreSQL/MySQL 等通过 SQLAlchemy 连接串接入。这一点可以从 charts/skypilot/values.yaml 的字段定义得到印证apiService.dbConnectionSecretName与apiService.dbConnectionString二选一即可启用外部数据库同时有一个硬性约束——一旦配置外部数据库apiService.config必须为null后续通过 Web Dashboard 再补充配置。在 charts/skypilot/templates/db-secrets.yaml 中Helm 渲染阶段会直接fail阻止“既用外部库又带 config”的非法组合{{- if or .Values.apiService.dbConnectionSecretName .Values.apiService.dbConnectionString }} {{- if .Values.apiService.config }} {{- fail When using database connection, .Values.apiService.config must be null. Deploy the API server with null config and add the config via the dashboard. }} {{- end }}而在 charts/skypilot/templates/api-deployment.yaml 中图表会把 secret 里的connection_string键映射为 API Server 的环境变量SKYPILOT_DB_CONNECTION_URIAPI Server 进程启动时即据此连接外部数据库。提示GKE 集群默认自带可用的持久卷但本指南展示的是把状态数据库托管在 Cloud SQL 上的生产级方案数据独立于 Pod 生命周期且天然支持未来RollingUpdate升级策略。两种数据库认证方式IAM 认证 vs 密码认证SkyPilot API Server 部署在 k8s 集群上时访问 Cloud SQL 实例有两种方式维度IAM 认证推荐密码认证安全性更高基于 GCP 服务账号的短期令牌无需静态口令较低需在集群中保存数据库密码与密钥文件集群要求必须使用启用了Workload Identity的 GKE 集群任何 k8s 集群均可不限于 GKE凭据载体GKE Service Account 通过iam.gke.io/gcp-service-account注解绑定 GCP 服务账号Kubernetes Secret 保存 GCP 服务账号 JSON 密钥适用场景生产环境部署的推荐选择非 GKE 集群或无法启用 Workload Identity 的环境IAM 认证因省去静态密钥的保存与轮换负担、且具备 GCP 原生的身份审计能力官方文档明确建议生产环境优先使用 IAM 认证。前提条件开始前请准备好以下工具与访问权限Helm部署 SkyPilot Helm 图表kubectl管理 GKE 集群gcloud CLI创建与管理 GCP 资源GCP 控制台访问权限创建服务账号、Cloud SQL 实例第一步创建 GKE 集群IAM 认证路线启用 Workload Identity 的集群Workload Identity 允许 GKE 中的工作负载以 GCP 服务账号身份调用 Google Cloud API是 IAM 认证的地基。强烈建议在创建集群时就启用——对已存在的集群事后启用非常复杂不推荐。CLI 方式在gcloud container clusters create命令中增加--workload-pool标志gcloud container clusters create cluster-name \ ... \ --workload-poolproject-id.svc.id.googWeb Console 方式创建标准 GKE 集群时进入Security标签页勾选Enable Workload Identity。密码认证路线普通集群密码认证无需 Workload Identity按常规方式创建 GKE 集群即可甚至可以是其他厂商的 k8s 集群。第二步创建 GCP 服务账号在 IAM and Admin 控制台 → Service Accounts 页面点击Create Service Account服务账号名称与 ID 统一设置为skypilot-cloud-sql-access点击Create and Continue进入 Permissions 页面根据认证方式授予角色IAM 认证授予Cloud SQL Client与Cloud SQL Instance User两个角色前者用于连接 Cloud SQL后者用于以 IAM 用户身份访问实例密码认证仅授予Cloud SQL Client角色连接实例即可身份认证走数据库用户口令点击Continue再点击Done完成创建。第三步创建 Cloud SQL 实例在 Cloud SQL 控制台 中点击Create instance数据库引擎选择PostgreSQL实例 ID 设置为cloud-sql-skypilot-instance为postgres超级用户设置密码选择实例区域可用区。数据库的区域/可用区应与 GKE 集群保持一致以降低跨区延迟、避免跨区域流量费用点击Create Instance。第四步配置 Cloud SQL 实例创建数据库与用户实例创建完成后需要为 SkyPilot API Server 准备一个数据库和一个可登录的账号。创建数据库使用 gcloud CLIDB_NAMEskypilot-db DB_INSTANCE_NAMEcloud-sql-skypilot-instance gcloud sql databases create ${DB_NAME} --instance ${DB_INSTANCE_NAME}创建用户——两条路线命令不同IAM 认证创建 IAM 服务账号类型的用户用户名即 IAM 账号标识GCP_PROJECT_IDyour gcp project id GCP_SERVICE_ACCOUNTskypilot-cloud-sql-access DB_INSTANCE_NAMEcloud-sql-skypilot-instance gcloud sql users create ${GCP_SERVICE_ACCOUNT}${GCP_PROJECT_ID}.iam \ --instance${DB_INSTANCE_NAME} \ --typecloud_iam_service_account注意IAM 服务账号用户默认在数据库内没有任何权限必须手动授权。进入 Cloud SQL 控制台点击cloud-sql-skypilot-instance在侧边栏进入Cloud SQL Studio以postgres用户身份认证并连接到skypilot-db数据库执行GRANT cloudsqlsuperuser TO skypilot-cloud-sql-accessgcp-project-id.iam密码认证创建普通数据库用户DB_USERskypilot DB_PASSWORDcreate a password DB_INSTANCE_NAMEcloud-sql-skypilot-instance gcloud sql users create ${DB_USER} --instance ${DB_INSTANCE_NAME} --password ${DB_PASSWORD}第五步授权 API Server 使用 GCP 服务账号先创建命名空间NAMESPACEskypilot kubectl create namespace ${NAMESPACE}随后按认证方式把上一步的服务账号“交给”运行在 GKE 中的 API Server 使用。IAM 认证在 GCP 服务账号上创建一条 IAM Policy Binding将其绑定到 GKE 内的 Kubernetes Service Account示例中名为skypilot-api-sa该名字须与后续 Helm 部署的rbac.serviceAccountName保持一致NAMESPACEskypilot GCP_PROJECT_IDyour gcp project id GCP_SERVICE_ACCOUNTskypilot-cloud-sql-access GKE_SERVICE_ACCOUNTskypilot-api-sa gcloud iam service-accounts add-iam-policy-binding \ --roleroles/iam.workloadIdentityUser \ --memberserviceAccount:${GCP_PROJECT_ID}.svc.id.goog[${NAMESPACE}/${GKE_SERVICE_ACCOUNT}] \ ${GCP_SERVICE_ACCOUNT}${GCP_PROJECT_ID}.iam.gserviceaccount.com密码认证先把 GCP 服务账号的 JSON 密钥下载到本地再以 Kubernetes Secret 形式保存GCP_PROJECT_IDyour gcp project id GCP_SERVICE_ACCOUNTskypilot-cloud-sql-access gcloud iam service-accounts keys create gcp-key.json \ --iam-account${GCP_SERVICE_ACCOUNT}${GCP_PROJECT_ID}.iam.gserviceaccount.com \ --project${GCP_PROJECT_ID}NAMESPACEskypilot kubectl create secret generic cloud-sql-credentials \ --from-fileservice-account-key.jsongcp-key.json -n ${NAMESPACE}第六步创建数据库连接 SecretAPI Server 通过名为skypilot-db-connection-uri的 Secret 获得数据库连接串。连接串的主机部分统一写为localhost因为真正的数据库访问将由同 Pod 内的 Cloud SQL Auth Proxy 在 5432 端口转发完成。IAM 认证——连接串不包含密码直接引用 IAM 用户注意需 URL 编码为%40NAMESPACEskypilot DB_NAMEskypilot-db GCP_PROJECT_IDyour gcp project id kubectl create secret generic skypilot-db-connection-uri \ --namespace ${NAMESPACE} \ --from-literal connection_stringpostgresql://localhost/${DB_NAME}?userskypilot-cloud-sql-access%40${GCP_PROJECT_ID}.iam密码认证——连接串携带数据库用户与口令NAMESPACEskypilot DB_USERskypilot DB_PASSWORDpassword for the skypilot user DB_NAMEskypilot-db kubectl create secret generic skypilot-db-connection-uri \ --namespace ${NAMESPACE} \ --from-literal connection_stringpostgresql://${DB_USER}:${DB_PASSWORD}localhost/${DB_NAME}第七步编写 values.yaml 并通过 Helm 部署将下面两段values.yaml中的GCP_PROJECT_ID与REGION替换为实际值REGION是 Cloud SQL 实例所在区域例如us-central1二选一使用。IAM 认证的 values.yamlapiService: dbConnectionSecretName: skypilot-db-connection-uri # config must be null when using an external database. # To set the config, use the web dashboard once the API server is deployed. config: null rbac: serviceAccountName: skypilot-api-sa serviceAccountAnnotations: # TODO: fill in GCP_PROJECT_ID iam.gke.io/gcp-service-account: skypilot-cloud-sql-accessGCP_PROJECT_ID.iam.gserviceaccount.com # Extra init containers to run before the api container extraInitContainers: - name: cloud-sql-proxy restartPolicy: Always # It is recommended to use the latest version of the Cloud SQL Auth Proxy # Make sure to update on a regular schedule! image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.14.1 args: # If connecting from a VPC-native GKE cluster, you can use the # following flag to have the proxy connect over private IP # - --private-ip # If you are not connecting with Automatic IAM, you can delete # the following flag. - --auto-iam-authn # Enable structured logging with LogEntry format: - --structured-logs # Replace DB_PORT with the port the proxy should listen on - --port5432 # TODO: fill in GCP_PROJECT_ID and REGION - GCP_PROJECT_ID:REGION:cloud-sql-skypilot-instance securityContext: # The default Cloud SQL Auth Proxy image runs as the # nonroot user and group (uid: 65532) by default. runAsNonRoot: true # You should use resource requests/limits as a best practice to prevent # pods from consuming too many resources and affecting the execution of # other pods. You should adjust the following values based on what your # application needs. For details, see # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ resources: requests: # The proxys memory use scales linearly with the number of active # connections. Fewer open connections will use less memory. Adjust # this value based on your applications requirements. memory: 2Gi # The proxys CPU use scales linearly with the amount of IO between # the database and the application. Adjust this value based on your # applications requirements. cpu: 1密码认证的 values.yaml与 IAM 版本的关键差异通过apiService.extraVolumes挂载保存了服务账号密钥的cloud-sql-credentialsSecret并把cloud-sql-proxy的参数从--auto-iam-authn换成--credentials-file/var/secrets/google/service-account-key.json同时新增volumeMounts把该 Secret 只读挂载到代理容器apiService: extraVolumes: - name: cloud-sql-credentials secret: secretName: cloud-sql-credentials dbConnectionSecretName: skypilot-db-connection-uri # config must be null when using an external database. # To set the config, use the web dashboard once the API server is deployed. config: null # Extra init containers to run before the api container extraInitContainers: - name: cloud-sql-proxy restartPolicy: Always # It is recommended to use the latest version of the Cloud SQL Auth Proxy # Make sure to update on a regular schedule! image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.14.1 args: # If connecting from a VPC-native GKE cluster, you can use the # following flag to have the proxy connect over private IP # - --private-ip # Use service account key file for authentication - --credentials-file/var/secrets/google/service-account-key.json # Enable structured logging with LogEntry format: - --structured-logs # Replace DB_PORT with the port the proxy should listen on - --port5432 # TODO: fill in GCP_PROJECT_ID and REGION - GCP_PROJECT_ID:REGION:cloud-sql-skypilot-instance securityContext: # The default Cloud SQL Auth Proxy image runs as the # nonroot user and group (uid: 65532) by default. runAsNonRoot: true # You should use resource requests/limits as a best practice to prevent # pods from consuming too many resources and affecting the execution of # other pods. You should adjust the following values based on what your # application needs. For details, see # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ resources: requests: # The proxys memory use scales linearly with the number of active # connections. Fewer open connections will use less memory. Adjust # this value based on your applications requirements. memory: 2Gi # The proxys CPU use scales linearly with the amount of IO between # the database and the application. Adjust this value based on your # applications requirements. cpu: 1 volumeMounts: - name: cloud-sql-credentials mountPath: /var/secrets/google readOnly: true执行 Helm 部署两种认证方式使用同一条部署命令。--set ingress.authCredentials$AUTH_STRING为 API Server 配置 Nginx 入口的 Basic Auth 访问保护NAMESPACEskypilot RELEASE_NAMEskypilot WEB_USERNAMEskypilot WEB_PASSWORDcreate a password AUTH_STRING$(htpasswd -nb $WEB_USERNAME $WEB_PASSWORD) helm upgrade --install $RELEASE_NAME skypilot/skypilot-nightly --devel \ --namespace $NAMESPACE \ -f values.yaml \ --set ingress.authCredentials$AUTH_STRING部署后的验证与运维要点部署完成后可确认 API Server Pod 正常运行kubectl get pods --namespace $NAMESPACE -l app${RELEASE_NAME}-api --watch若 Pod 初始化异常可参考 API Server 故障排查指南 定位问题。健康检查通过后即可通过 Web Dashboard 补充 SkyPilot config因为外部数据库模式下apiService.config必须为null并将本地 SkyPilot 客户端接入该 API Server。源码级原理解读连接串如何注入 API Server理解 Helm 图表的底层实现有助于排查部署问题Secret 值到环境变量的映射api-deployment.yaml 中当设置了apiService.dbConnectionSecretName时图表从该 Secret 读取键connection_string注入环境变量SKYPILOT_DB_CONNECTION_URI若改设apiService.dbConnectionString不建 Secret 直接写连接串图表则先在 db-secrets.yaml 中自动生成名为release-db-connection的 Secret再走同样的注入路径。非法组合的硬校验db-secrets.yaml 在dbConnectionSecretName或dbConnectionString存在时若apiService.config非空会直接渲染失败——这正是官方约束“外部数据库 config 二选一”在代码层面的落地。对应的 Helm 单元测试 也覆盖了“仅配置外部 Secret 不生成新 Secret”“未配置任何连接串时不生成 Secret”“config 与 Secret 同时设置时报错”等场景。Cloud SQL Auth Proxy 的角色API Server 容器与cloud-sql-proxyinit 容器同处一个 Pod代理监听本机5432端口把localhost连接转发到远端cloud-sql-skypilot-instance实例因此连接串中主机名固定为localhost。这也是 VPC-native GKE 集群可选用--private-ip走内网直连的原因。如需深入了解连接串以外的 Helm 配置项如apiService.config、dbConnectionString的完整说明与默认值可查阅 Helm Values 规格文档关于 API Server 的整体部署、云账号凭据配置AWS/GCP/RunPod/Lambda 等与多集群接入参见 API Server 管理员部署指南。【免费下载链接】skypilotThe AI Compute Platform for frontier teams. SkyPilot turns fragmented AI compute into one AI supercomputer, so frontier AI teams build custom intelligence faster.项目地址: https://gitcode.com/GitHub_Trending/sk/skypilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表