AWS EKS部署Dynamia AI平台:Helm交付与OIDC安全实践

📅 2026/7/16 3:31:20
AWS EKS部署Dynamia AI平台:Helm交付与OIDC安全实践
1. 项目概述这不是一次普通部署而是一次云原生AI平台的“心脏移植”在 AWS 上使用 EKS 部署 Dynamia AI 平台这八个字背后藏着一套完整的现代AI基础设施交付范式。它不是把一个单体应用扔进K8s就完事而是要让 Dynamia AI 这个面向数据科学家和MLOps工程师的协作平台在AWS公有云上真正“活”起来——具备弹性伸缩能力、细粒度权限控制、安全的模型资产隔离、与企业身份体系无缝对接以及生产级可观测性。我做过不下二十个类似规模的AI平台上云项目从早期用CloudFormation硬编排到后来用Terraform模块化管理再到如今以EKS为底座、Helm为交付语言、OIDC为信任锚点的标准化流水线每一次演进都踩过坑、交过学费。核心关键词 AWS、EKS、Dynamia AI、Helm、OIDC每一个都不是孤立存在AWS 提供底层计算、网络与存储的确定性保障EKS 是那个不让你操心Kubernetes控制平面稳定性的“托管管家”Dynamia AI 是业务价值的最终载体它的组件拆分合理性、资源画像准确性、依赖服务耦合度直接决定部署成败Helm 则是让这套复杂系统能被版本化、可复现、可审计的“乐高说明书”而 OIDC是整套方案安全可信的基石——它让 Dynamia AI 不再需要自己维护用户数据库而是把身份认证这件事稳稳托付给 AWS IAM Identity Center原 AWS SSO或企业已有的 Okta/ADFS。你可能会问为什么不用简单的用户名密码因为当你的平台要接入几十个业务部门、上百名数据科学家且他们各自归属不同AD域组时手动同步账号就是一场灾难。而 OIDC AWS IAM Roles for Service AccountsIRSA的组合能让每个Kubernetes Pod 在调用 S3 模型桶、Secrets Manager 密钥或 SageMaker 端点时自动获得最小权限的临时凭证连AccessKey都不用碰。这不仅是合规要求更是运维效率的分水岭。适合谁来看如果你是正在规划AI平台云迁移的架构师是负责落地的SRE或平台工程师或是想搞懂“为什么我们团队的Dynamia AI总在半夜OOM”的数据平台负责人这篇内容就是为你写的。它不讲虚的概念只聊实操中每一步为什么这么选、参数怎么算、报错怎么看、日志往哪查。2. 整体架构设计与技术选型逻辑2.1 为什么必须是 EKS 而非自建 K8s 或 ECS这个问题我被客户问过至少十五次。答案从来不是“EKS更先进”而是“EKS在当前阶段对 Dynamia AI 这类中大型AI平台综合成本最低、风险最小”。先说自建K8s你得自己维护etcd集群的备份与恢复、处理control plane节点的滚动升级、应对API Server突发429限流、排查kube-proxy规则冲突导致的Service流量异常……这些工作在AI平台上线初期会直接挤占你本该用于优化模型训练Pipeline的工程师时间。而EKSAWS帮你扛下了所有control plane的SLA——99.95%可用性、自动打补丁、跨AZ高可用部署你只需要专注在worker node group的配置上。再说ECS它确实简单但Dynamia AI 的核心组件——比如模型推理服务通常基于Triton或vLLM、特征存储Feast或Redis Cluster、元数据管理MLflow或Dagster——天然就是为K8s的Pod生命周期、Service发现、ConfigMap/Secret热更新而设计的。强行塞进ECS你会发现自己在写大量胶水脚本模拟K8s行为比如用SNSLambda监听ECS任务状态来触发下游流程或者用Route53健康检查替代K8s readiness probe。这不仅增加复杂度更埋下监控盲区。EKS的胜出在于它把“基础设施的确定性”和“应用部署的灵活性”做了最优解耦。你用eksctl一条命令就能拉起一个带GPU节点组的集群用kubectl apply -f就能部署Dynamia AI的Helm Chart中间没有抽象层损耗。更重要的是EKS深度集成了AWS生态ALB Ingress Controller能自动创建带WAF和ACM证书的负载均衡器EBS CSI Driver让PVC动态绑定到加密的GP3卷而最关键的IRSA让Pod安全访问AWS服务成为开箱即用的能力。这省下的不是几行代码而是数月的权限治理成本。2.2 Helm 作为交付引擎为什么不是 Kustomize 或纯 YAMLDynamia AI 平台绝非几个Deployment那么简单。它通常包含前端UIReact、后端APIPython/FastAPI、异步任务队列Celery Redis、对象存储网关MinIO或S3兼容层、向量数据库Qdrant或Weaviate、模型注册中心MLflow、以及可选的GPU推理服务Triton。这些组件之间有强依赖关系——比如API服务启动前必须确保Redis已就绪且密码正确模型服务加载时需挂载S3上的模型权重桶。Helm 的核心价值在于它把这种“拓扑依赖”变成了可声明、可参数化的逻辑。一个values.yaml文件就能统一控制所有组件的镜像版本、副本数、资源请求requests、环境变量、Ingress主机名甚至数据库连接字符串的加密方式。对比Kustomize它擅长打补丁但面对Dynamia AI这种多环境dev/staging/prod差异巨大的场景你需要为每个环境维护一套kustomization.yaml而Helm只需一个Chart加三个values-*.yaml文件通过helm install -f values-prod.yaml一键切换。更重要的是Helm的dependency机制能将Dynamia AI Chart与Bitnami的PostgreSQL Chart、Redis Chart进行组合形成一个原子发布的“应用包”。当你执行helm upgrade时Helm会智能计算出哪些资源需要创建、更新或删除并按依赖顺序执行——这比手动kubectl apply一堆YAML文件然后祈祷顺序别出错可靠了太多。至于纯YAML那等于把整个平台的部署逻辑散落在几十个文件里版本管理混乱回滚困难审计无从下手。我见过最惨的案例某客户用纯YAML部署因一个ConfigMap的key名拼写错误导致所有模型训练任务静默失败三天最后靠逐行diff才发现问题。Helm的helm lint和helm template --debug就是你的第一道质量防火墙。2.3 OIDC不是锦上添花而是安全架构的“地基”把 Dynamia AI 接入企业SSO很多人第一反应是“为了登录方便”。这理解太浅了。真正的价值在于构建一个零信任的权限模型。Dynamia AI 平台内部有敏感操作删除生产模型、导出客户数据、修改特征工程代码。如果这些操作只靠应用层的RBACRole-Based Access Control一旦Dynamia AI自身的鉴权逻辑出现漏洞比如JWT token校验绕过攻击者就能长驱直入。而OIDC IRSA的组合实现了“双保险”用户登录时由Okta或AWS IAM Identity Center颁发ID TokenDynamia AI的OAuth2 Proxy只做token验证不存用户密码当Dynamia AI的某个Pod比如模型训练Job需要读取S3上的训练数据桶时它不使用长期AccessKey而是通过IRSA向EKS的Service Account关联的IAM Role申请临时凭证。这个过程完全由K8s和AWS底层完成应用代码无感知。关键在于这个IAM Role的Policy可以精确到Resource: arn:aws:s3:::dynamia-prod-data/*且只允许s3:GetObject。这意味着即使Dynamia AI的代码被攻破攻击者也无法凭此Pod的身份去删除整个S3桶或访问其他部门的数据。我在实际项目中曾用aws sts get-caller-identity在Pod内验证凭证来源输出明确显示Arn: arn:aws:sts::123456789012:assumed-role/eks-dynamia-prod-sa-model-trainer/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345......实际输出会截断但关键字段AssumedRoleUser清晰表明这是由EKS Service Account触发的临时会话。这种“凭证即代码”的理念是云原生安全的基石。它让安全团队不再需要审计Dynamia AI的每一行代码而是聚焦于IAM Policy的最小权限原则——这才是可落地、可度量的安全。2.4 整体架构图从用户请求到模型推理的全链路整个部署不是单点技术堆砌而是一条端到端的数据与控制流。我们来拆解一次典型用户操作数据科学家在Dynamia AI Web UI上点击“启动新训练任务”。这个请求的旅程如下入口层用户浏览器访问https://ai.yourcompany.comDNS解析到ALB。ALB配置了ACM证书启用HTTP/2并集成了AWS WAF规则如SQLi、XSS防护。Ingress Controller监听K8s Ingress资源自动将域名映射到dynamia-uiService。身份认证层dynamia-uiPod内嵌OAuth2 Proxy将未认证请求重定向至Okta登录页。用户输入企业AD账号密码后Okta返回ID Token和Access Token。OAuth2 Proxy验证签名并提取用户信息如email、groups注入X-Forwarded-User头转发给后端API。业务逻辑层dynamia-api服务收到请求解析用户组信息检查其是否有ml-train-prodIAM Role绑定的权限通过调用Dynamia内部RBAC服务。验证通过后API向Redis队列推送一个训练Job消息。异步执行层dynamia-workerPod属于ml-trainDeployment监听Redis队列。它启动一个K8s Job该Job的Pod Spec中指定了Service Accountdynamia-sa-trainer。安全凭证层dynamia-sa-trainer已通过IRSA关联到IAM Rolearn:aws:iam::123456789012:role/eks-dynamia-prod-sa-trainer。该Role的Policy明确允许s3:GetObject访问dynamia-prod-data桶sagemaker:CreateTrainingJob调用SageMaker以及logs:CreateLogStream写入CloudWatch Logs。模型服务层训练完成后模型权重存入S3。dynamia-model-serverDeployment使用Triton镜像启动其Init Container通过aws s3 cp命令将S3上的模型文件同步到本地空目录卷。主容器启动Triton Server监听0.0.0.0:8000并通过K8s Service暴露。可观测性层所有Pod都注入了Datadog Agent DaemonSet自动采集CPU/Memory/Network指标Prometheus Operator监控K8s核心组件Loki收集结构化日志JSON格式含job_id,user_email,model_name等字段Grafana Dashboard整合所有视图告警规则基于rate(container_cpu_usage_seconds_total{jobdynamia-worker}[5m]) 0.8等阈值触发。这个架构里没有一个环节是孤立的。ALB的WAF规则保护了OAuth2 ProxyIRSA确保Worker Pod只能访问授权S3路径Loki的日志结构化让user_email成为所有日志的关联ID方便审计。这就是为什么说部署Dynamia AI本质是在AWS上构建一个可信赖的AI协作空间。3. 核心组件部署与实操细节3.1 EKS 集群创建从 eksctl 到生产级加固别被eksctl create cluster的简单命令迷惑。生产环境的EKS集群必须从第一天就考虑安全、成本与可维护性。我推荐的标准流程是先用eksctl生成基础配置再用kubectl和awscli进行精细化加固。以下是经过十多个项目验证的cluster.yaml核心片段# cluster.yaml apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: dynamia-prod region: us-west-2 version: 1.28 managedNodeGroups: - name: ng-gpu instanceType: g4dn.xlarge minSize: 1 maxSize: 5 desiredCapacity: 2 labels: { role: gpu-worker } taints: - key: nvidia.com/gpu value: present effect: NoSchedule iam: withAddonPolicies: imageBuilder: true autoScaler: true ebs: true fsx: true - name: ng-cpu instanceType: m6i.2xlarge minSize: 3 maxSize: 10 desiredCapacity: 5 labels: { role: cpu-worker } iam: withAddonPolicies: albIngress: true cloudWatch: true efs: true关键点解析版本选择1.28是当前EKS GA的最新稳定版支持K8s原生的TopologySpreadConstraints能避免GPU节点组因调度不均导致的资源浪费。切忌盲目追新1.29虽已发布但EKS官方文档明确标注“Not yet supported”。GPU节点组g4dn.xlarge是性价比之选单卡T4适合Dynamia AI的模型微调和小规模推理。taints设置至关重要——它强制只有带tolerations的Pod如dynamia-model-server才能调度到GPU节点防止普通API服务抢占昂贵GPU资源。desiredCapacity: 2而非1是为了避免单点故障当一台GPU节点升级时另一台仍可提供服务。IAM策略精简withAddonPolicies只开启必需项。比如ebs策略仅用于动态PValbIngress用于Ingress Controller绝不开启fullAccess。这符合最小权限原则也是后续通过aws sts get-caller-identity验证凭证来源的基础。网络规划eksctl默认在指定VPC的公有子网创建控制平面Endpoint但生产环境强烈建议将其置于私有子网并通过NAT Gateway或VPC Endpoint访问互联网。我在us-west-2区域的实践是为EKS集群单独创建一个dynamia-prodVPCCIDR10.100.0.0/16其中10.100.1.0/24为私有子网AZ A10.100.2.0/24为私有子网AZ B控制平面Endpoint仅绑定这两个子网。这样即使公网ALB被攻破攻击者也无法直接访问EKS API Server。创建集群后立即执行加固步骤禁用匿名访问kubectl edit cm -n kube-system aws-auth删除mapUsers中所有system:anonymous相关条目。这是最基础的安全红线。启用Pod Security Admission (PSA)K8s 1.25默认启用需为Dynamia AI命名空间配置baseline或restricted策略。kubectl label ns dynamia-prod pod-security.kubernetes.io/enforcebaseline。这能阻止Pod以root用户运行、挂载宿主机敏感路径等高危行为。安装Cluster Autoscalerhelm repo add autoscaler https://kubernetes.github.io/autoscaler然后helm install cluster-autoscaler autoscaler/cluster-autoscaler --set autoDiscovery.clusterNamedynamia-prod --set awsRegionus-west-2。它会根据Pending Pod的资源请求自动伸缩Node Group。注意GPU节点组需单独配置--set nodeGroup.nameng-gpu因为CPU和GPU实例的伸缩逻辑完全不同。提示eksctl创建的集群默认启用了Amazon VPC CNI插件这是EKS网络的核心。它让每个Pod获得VPC内的真实IP便于与RDS、ElastiCache等AWS服务直接通信。切勿替换为Calico等第三方CNI除非你有极其特殊的网络需求——那会引入额外的复杂性和故障点。3.2 Dynamia AI Helm Chart 结构解析与 values.yaml 定制Dynamia AI 官方通常提供Helm Chart但直接helm install几乎必然失败。原因在于Chart的values.yaml是面向通用场景的而你的AWS环境有独特约束S3桶名全球唯一、RDS实例名需符合公司命名规范、ALB的SSL证书ARN需手动填入。因此我们必须创建自己的values-prod.yaml覆盖所有关键参数。一个健壮的values-prod.yaml应包含以下核心区块# values-prod.yaml global: # 全局命名空间与镜像仓库 namespace: dynamia-prod imageRegistry: 123456789012.dkr.ecr.us-west-2.amazonaws.com # 全局TLS证书由ACM颁发 tls: enabled: true certificateArn: arn:aws:acm:us-west-2:123456789012:certificate/abcd1234-ef56-gh78-ij90-klmnopqrstuv ui: # 前端UI服务 replicaCount: 3 service: type: ClusterIP ingress: enabled: true hosts: - host: ai.yourcompany.com paths: [/] annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/healthcheck-path: /healthz api: # 后端API服务 replicaCount: 5 resources: requests: memory: 2Gi cpu: 1000m limits: memory: 4Gi cpu: 2000m # 数据库连接指向外部RDS database: host: dynamia-prod-rds.cluster-xyz123.us-west-2.rds.amazonaws.com port: 5432 name: dynamia_prod username: dynamia_app # 密码从Secret读取非明文 passwordSecret: dynamia-db-secret passwordKey: password worker: # 异步Worker服务 replicaCount: 3 # GPU推理服务专用配置 gpu: enabled: true # 指定GPU节点组的Label Selector nodeSelector: role: gpu-worker tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule modelServer: # Triton模型服务器 replicaCount: 2 # 模型存储位置S3路径 modelRepositoryPath: s3://dynamia-prod-models/ # S3访问凭证通过IRSA实现此处为空 s3: accessKey: secretKey: region: us-west-2 # 外部依赖服务由Bitnami Chart提供 externalServices: redis: enabled: true auth: enabled: true # Redis密码从Secret读取 passwordSecret: dynamia-redis-secret passwordKey: password postgresql: enabled: false # 使用外部RDS禁用内置PostgreSQL关键定制逻辑imageRegistry必须指向你的ECR仓库。Dynamia AI的镜像不能直接从Docker Hub拉取因为生产环境要求镜像扫描、漏洞修复和版本锁定。eksctl创建集群时会自动为ECR创建ecr:GetAuthorizationToken权限确保Node能拉取镜像。tls.certificateArn这是ALB Ingress的命脉。你必须提前在ACM中申请通配符证书*.yourcompany.com并确保其状态为ISSUED。ALB Ingress Controller会自动将此ARN注入ALB Listener。database.host指向外部RDS而非Chart内置的PostgreSQL。理由很现实Dynamia AI的元数据是核心资产必须与应用生命周期解耦。RDS提供自动备份、读写分离、跨区域快照等企业级能力远超Helm部署的StatefulSet。worker.gpu.nodeSelectortolerations这是让Worker Pod精准调度到GPU节点的关键。nodeSelector匹配节点Labeltolerations容忍节点Taint。两者缺一不可否则Pod会一直处于Pending状态。modelServer.s3accessKey和secretKey留空这是IRSA生效的前提。如果这里填了密钥Pod就会绕过IRSA使用明文凭证彻底破坏安全模型。注意values-prod.yaml中的所有Secret引用如passwordSecret必须对应真实的K8s Secret资源。创建方式kubectl create secret generic dynamia-db-secret --from-literalpasswordMy$tr0ngPssw0rd -n dynamia-prod。绝不能在values.yaml中明文写密码这是安全审计的致命伤。3.3 OIDC 身份联合从 AWS IAM Identity Center 到 K8s Service Account这是整个方案中最易出错、也最关键的环节。OIDC联合不是“点几下鼠标就完事”它涉及三个独立系统的信任链建立AWS IAM Identity CenterIdP、EKS集群RP、Dynamia AI应用SP。任何一环断裂用户就会看到“Login Failed”错误。以下是经过生产环境千锤百炼的步骤第一步在 AWS IAM Identity Center 中配置应用程序进入 AWS IAM Identity Center 控制台选择你的实例如https://yourcompany.awsapps.com/start。导航到Applications Add a new application Custom SAML 2.0 application。填写应用名称Dynamia AI Prod勾选Enable this application。在SAML metadata区域点击Download metadata file保存为dynamia-idp-metadata.xml。这个文件包含了IdP的证书和SSO URL是后续配置的信任根。在Attribute mappings中添加两个关键映射https://aws.amazon.com/SAML/Attributes/Role→https://aws.amazon.com/SAML/Attributes/Role用于角色传递https://aws.amazon.com/SAML/Attributes/RoleSessionName→https://aws.amazon.com/SAML/Attributes/RoleSessionName用于会话名https://aws.amazon.com/SAML/Attributes/Groups→https://aws.amazon.com/SAML/Attributes/Groups用于用户组第二步在 EKS 集群中配置 OIDC Provider获取EKS集群的OIDC Issuer URLaws eks describe-cluster --name dynamia-prod --query cluster.identity.oidc.issuer --output text。输出类似https://oidc.eks.us-west-2.amazonaws.com/id/ABCD1234EF567890ABCDEF1234567890。将此URL注册为IAM OIDC Provideraws iam create-open-id-connect-provider --url https://oidc.eks.us-west-2.amazonaws.com/id/ABCD1234EF567890ABCDEF1234567890 --client-id-list sts.amazonaws.com --thumbprint-list 9e99a48a9960b14926bb7f3b5b999d2661c8048b。thumbprint-list是Issuer URL证书的SHA1指纹可通过openssl x509 -in (curl -s https://oidc.eks.us-west-2.amazonaws.com/id/ABCD1234EF567890ABCDEF1234567890/.well-known/openid-configuration | jq -r .jwks_uri | xargs curl -s) -fingerprint -noout | sed s/SHA1 Fingerprint// | tr -d :获取。第三步创建 IAM Role 并关联 Service Account创建信任策略文件trust-policy.json{ Version: 2012-10-17, Statement: [ { Effect: Allow, Principal: { Federated: arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/ABCD1234EF567890ABCDEF1234567890 }, Action: sts:AssumeRoleWithWebIdentity, Condition: { StringEquals: { oidc.eks.us-west-2.amazonaws.com/id/ABCD1234EF567890ABCDEF1234567890:sub: system:serviceaccount:dynamia-prod:dynamia-sa-trainer } } } ] }创建IAM Roleaws iam create-role --role-name eks-dynamia-prod-sa-trainer --assume-role-policy-document file://trust-policy.json。附加权限策略例如只允许访问特定S3桶aws iam attach-role-policy --role-name eks-dynamia-prod-sa-trainer --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess # 但更佳实践是自定义策略精确到桶和前缀 cat s3-policy.json EOF { Version: 2012-10-17, Statement: [ { Effect: Allow, Action: [s3:GetObject], Resource: [arn:aws:s3:::dynamia-prod-data/*] } ] } EOF aws iam create-policy --policy-name dynamia-s3-read-only --policy-document file://s3-policy.json aws iam attach-role-policy --role-name eks-dynamia-prod-sa-trainer --policy-arn arn:aws:iam::123456789012:policy/dynamia-s3-read-only在K8s中创建Service Account并打上Annotationkubectl create namespace dynamia-prod kubectl create serviceaccount dynamia-sa-trainer -n dynamia-prod kubectl annotate serviceaccount dynamia-sa-trainer -n dynamia-prod \ eks.amazonaws.com/role-arnarn:aws:iam::123456789012:role/eks-dynamia-prod-sa-trainer第四步在 Dynamia AI 的 values.yaml 中启用 OIDC在values-prod.yaml中找到auth区块auth: oidc: enabled: true issuerUrl: https://yourcompany.awsapps.com/start clientId: dynamia-prod-app-id clientSecret: dynamia-prod-app-secret # Dynamia AI会将此作为回调URL redirectUri: https://ai.yourcompany.com/oauth2/callback # 映射到K8s Service Account的用户名 usernameClaim: email # 映射到K8s RBAC的组 groupsClaim: https://aws.amazon.com/SAML/Attributes/GroupsclientId和clientSecret是在IAM Identity Center中为Dynamia AI应用生成的。redirectUri必须与IAM Identity Center中配置的完全一致包括末尾的斜杠。实操心得OIDC调试的黄金法则——看日志。当登录失败时首先检查dynamia-uiPod的日志kubectl logs -n dynamia-prod deploy/dynamia-ui | grep -i oauth\|oidc。常见错误如invalid issuer说明issuerUrl填错了invalid_client说明clientId或clientSecret不匹配invalid_grant通常是redirectUri不一致。另一个神器是kubectl get sa -n dynamia-prod dynamia-sa-trainer -o yaml确认Annotation是否正确写入。我曾在一个项目中因trust-policy.json里的sub值多了一个空格导致IRSA失效三天最终靠aws sts assume-role-with-web-identity命令手动测试才定位到问题。3.4 ALB Ingress 与 Harbor 镜像仓库的集成解决“无法访问”问题网络热词中提到“helm部署harbor 通过ingress 但无法访问”这几乎是EKS上Harbor部署的标配问题。根本原因在于Harbor的core服务处理API和UI和registry服务处理镜像上传下载是两个独立进程它们需要不同的Ingress路由规则且Harbor的external_url配置必须与Ingress的host完全一致否则前端JS会尝试访问错误的后端地址。Dynamia AI虽然不直接依赖Harbor但如果你用Harbor托管Dynamia AI的私有镜像这个集成就是刚需。标准解决方案如下Helm部署Harborhelm repo add harbor https://helm.goharbor.io helm install harbor harbor/harbor \ --namespace harbor \ --create-namespace \ --set expose.ingress.hosts.coreharbor.yourcompany.com \ --set expose.ingress.hosts.notarynotary.yourcompany.com \ --set externalURLhttps://harbor.yourcompany.com \ --set persistence.persistentVolumeClaim.registry.storageClassgp3-encrypted \ --set persistence.persistentVolumeClaim.database.storageClassgp3-encrypted \ --set persistence.persistentVolumeClaim.redis.storageClassgp3-encrypted关键参数expose.ingress.hosts.core必须与你计划在ALB Ingress中使用的host完全一致。externalURL这是Harbor内部所有重定向和API响应的根URL必须是HTTPS且与hosts.core匹配。如果填成http://harbor.yourcompany.com前端会报Mixed Content错误。storageClass指向你创建的加密GP3存储类确保持久化数据安全。创建ALB Ingress资源harbor-ingress.yamlapiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: harbor-ingress namespace: harbor annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip # 关键启用HTTP重定向到HTTPS alb.ingress.kubernetes.io/ssl-redirect: 443 # 关键为Harbor的registry服务启用特殊路径 alb.ingress.kubernetes.io/actions.ssl-redirect: {Type:redirect,RedirectConfig:{Protocol:HTTPS,Port:443,StatusCode:HTTP_301}} spec: rules: - host: harbor.yourcompany.com http: paths: - path: /* pathType: ImplementationSpecific backend: service: name: ssl-redirect port: name: use-annotation - path: / pathType: Prefix backend: service: name: harbor-core port: number: 80 - path: /v2/ pathType: Prefix backend: service: name: harbor-registry port: number: 80 - path: /service/ pathType: Prefix backend: service: name: harbor-core port: number: 80这个Ingress的精妙之处在于第一条规则/ /*是全局重定向将所有HTTP请求301跳转到HTTPS。第二条/规则将根路径请求路由到harbor-core服务UI和API。第三条/v2/规则将所有Docker客户端的镜像拉取/推送请求docker pull harbor.yourcompany.com/library/nginx路由到harbor-registry服务。这是Harbor正常工作的核心缺失此规则docker login成功但docker push会失败。第四条/service/规则是Harbor内部服务发现所需不能省略。验证与排错kubectl get ingress -n harbor确认ALB DNS已生成。curl -I https://harbor.yourcompany.com应返回HTTP/2 200。curl -I https://harbor.yourcompany.com/v2/应返回HTTP/2 401未授权证明registry服务可达。如果/v2/返回404检查harbor-registryService是否正常kubectl get svc -n harbor harbor-registry确保其CLUSTER-IP不为空且Endpoints有值。注意Harbor的core服务默认监听80端口但它的健康检查探针liveness/readiness是/api/v2.0/ping。确保Ingress的backend配置正确否则ALB会认为服务不健康而剔除目标组。我见过最隐蔽的坑Harbor Chart的expose.tls.enabled默认为false但如果你的ALB只监听HTTPS就必须显式设置--set expose.tls.enabledtrue否则core服务会拒绝HTTPS请求。4. 实操过程与核心环节实现4.1 从零开始的完整部署流水线部署Dynamia AI不是单次性的手工操作而是一套可重复、可审计、可回滚的CI/CD流水线。我推荐使用GitHub Actions或GitLab CI作为触发器AWS CodeBuild作为构建环境最终通过helm upgrade完成部署。以下是核心步骤的详细分解每一步都附带命令和预期输出阶段一环境准备与基础设施即代码IaC初始化Terraform工作区cd terraform terraform init -backend-configbucketyour-tfstate-bucket -backend-configkeydynamia-prod.tfstate规划变更Planterraform plan -var-fileprod.tfvars -outplan.out # 输出应显示22 to add, 0 to change, 0 to destroy. # 关键检查点确认aws_eks_cluster.dynamia_prod的version为1.28aws_vpc.dynamia_vpc的cidr_block为10.100.0.0/16。执行部署Applyterraform apply plan.out # 等待约15分钟直到输出Apply complete! Resources: 22 added, 0 changed, 0 destroyed. # 此时EKS集群、VPC、RDS、S3桶等基础设施已就绪。阶段二K8s集群配置与依赖安装配置kubectl上下文aws eks update-kubeconfig --name dynamia-prod --region us-west-2 # 验证kubectl get nodes 应显示3个cpu-worker节点和2个gpu-worker节点状态为Ready。安装必要Add-ons# 安装Metrics Server用于HPA kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.3/components.yaml # 安装Cluster Autoscaler针对CPU节点组 helm install cluster-autoscaler autoscaler/cluster-autoscaler \ --set autoDiscovery.clusterNamedynamia-prod \ --set awsRegionus-west-2 \ --set nodeGroup.nameng-cpu # 安装Datadog Agent可选但强烈推荐 helm repo add datadog https://helm.datadoghq.com helm install datadog datadog/datadog \ --set datadog.apiKeyYOUR_DATADOG_API_KEY \ --set clusterAgent.enabledtrue \ --set agents.useHostNetworktrue阶段三Dynamia AI平台部署创建命名空间与Secretkubectl create namespace dynamia-prod kubectl create secret generic dynamia-db-secret \ --from-literalpasswordMy$tr0ngPssw0rd \ -n dynamia-prod kubectl create secret generic dynamia-redis-secret \ --from-literalpasswordMy$tr0ngPssw0rd \ -n dynamia-prod # 创建Service Account并关联IRSA Role见3.3节 kubectl create serviceaccount dynamia-sa-trainer -n dynamia-prod kubectl annotate serviceaccount dynamia-sa-trainer -n dynamia-prod \ eks.amazonaws.com/role-arnarn:aws:iam::123456789012:role/eks-dynamia-prod-sa-trainer首次安装Dynamia AI# 添加Dynamia AI官方Helm仓库 helm repo add dynamia https://charts.dynamia.ai helm repo update # 执行安装 helm install dynamia-prod dynamia/dynamia-platform \ --namespace dynamia-prod \ --values ./helm/values-prod.yaml \ --timeout 15m \ --wait # --wait 参数至关重要它会让helm命令阻塞直到所有Pod的readiness probe都通过。 # 预期输出NAME: dynamia-prodSTATUS: deployedREVISION: 1。验证部署状态# 检查所有Pod是否Running kubectl get pods -n dynamia-prod # 应看到dynamia-ui-xxx, dynamia-api-xxx, dynamia-worker-xxx, dynamia-model-server-xxx, all in Running state. # 检查Ingress是否创建ALB kubectl get ingress -n dynamia-prod # 输出应显示ALB的DNS名称如dynamia-prod-dynamia-prod-xxxxxx.us-west-2.elb.amazonaws.com # 检查ALB Target Groups健康状态 aws elbv2 describe-target-health \ --target-group-arn arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/dynamia-prod-ui/xxxxxx \ --query TargetHealthDescriptions[*].TargetHealth.State --output text # 输出应为healthy healthy healthy阶段四OIDC登录与功能验证访问UI并触发登录 在浏览器打开https://ai.yourcompany.com页面会自动重定向至Okta或AWS IAM Identity Center的登录页。使用企业AD账号登录 输入>kubectl exec -it -n dynamia-prod deploy/dynamia-worker -- sh # 在Pod内执行 aws sts get-caller-identity # 输出应显示Arn: arn:aws:sts::123456789012:assumed-role/eks-dynamia-prod-sa-trainer/...证明IRSA生效。4.2 Dynamia AI 核心组件资源画像与调优Dynamia AI不是“一刀切”的应用它的不同组件对计算、内存、网络的要求天差地别。盲目设置resources.limits会导致OOMKilled或CPU Throttling影响用户体验。以下是基于真实生产负载的资源画像与调优指南组件CPU Requests/LimitsMemory Requests/Limits网络IO存储IO调优要点UI (React)100m / 500m256Mi / 512Mi低极低主要消耗在浏览器端。K8s侧只需保证快速响应静态资源。replicaCount: 3即可应对万级并发。API (FastAPI)1000m / 2000m2Gi / 4Gi中中是整个平台的“大脑”。Requests需足够高避免因CPU饥饿导致请求排队。limits设为2000m防止单个Pod吃光节点CPU。Worker (Celery)500m / 1500m1Gi / 3Gi中高处理异步任务训练、评估。requests设为500m确保能被调度limits设为1500m防止单个长任务拖垮节点。Model Server (Triton)2000m / 4000m4Gi / 16Gi高高GPU密集型。CPU Requests必须≥2核否则Triton无法有效利用GPU。Memory Limits