平台工程实战:用Score和Humanitec部署线上精品店示例应用
2024/12/30 21:03:21
本文主要是介绍平台工程实战:用Score和Humanitec部署线上精品店示例应用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
最近,随着KubeCon Paris 2024和Google Cloud Next 2024的召开,我一直在准备并展示关于Score和Humanitec的大量演示。其中一个演示是基于Google Cloud提供的Online Boutique示例应用。你可以将其部署到任何Kubernetes集群(而不仅限于GKE,我也会使用Azure/AKS来做这个),使用纯Kubernetes配置文件、它的Helm Chart或者Kustomize叠加。十分方便。
让我向你展示使用Score和Humanitec部署Online Boutique示例应用的另一种方式。我们将看到如何操作,但更重要的是,我们将解释为什么。特别是围绕两个主要人物:
- 程序员
- 平台架构师
更具体地说,这里是我们将要涉及的案例:
作为一名开发者,我想:
- 定义我的工作负载和它们的依赖关系;
- 在本地部署我的工作负载;
- 将我的工作负载部署到IDP上;
- 在我的门户中查看工作负载。
作为一名平台工程师,我希望能实现:
- 在我的现有工具和平台上构建我自己的IDP;
- 集中管理和安全的最佳实践措施;
- 为开发人员配置数据库依赖关系;
干吧!
程序员
作为一名开发者,我想专注于我的应用,而无需担心基础设施和相关的 Kubernetes。
在本节中,从开发者的角度来说,我们将看到开发体验如何变得更好,开发速度如何加快了,以及认知负担如何减轻。
作为开发者,我想定义我的工作负载及其依赖关系。
作为开发者,我不仅有我的代码,还有容器化工作负载的方法。现在我要定义的是,让我的工作负载能够顺利部署需要哪些条件。我不清楚技术细节,也不了解部署的位置和如何解决依赖问题。我会让IDP(身份提供程序)来帮我搞定这些问题。
我们来看一个例子,比如cartservice
的Score文件(分数文件)。
apiVersion: score.dev/v1b1 metadata: name: cartservice 容器: cartservice: image: gcr.io/google-samples/microservices-demo/cartservice:v0.10.0 variables: REDIS_ADDR: "${resources.redis-cart.host}:${resources.redis-cart.port},user=${resources.redis-cart.username},password=${resources.redis-cart.password}" resources: limits: memory: "128Mi" cpu: "300m" requests: memory: "64Mi" cpu: "200m" resources: redis-cart: type: redis 服务: 端口: grpc: port: 7070 targetPort: 7070
在这个第一个例子中,我们可以看到cartservice
工作负载的开发人员定义了容器暴露的端口、资源限制和需求(如果有这些信息的话),以及对Redis数据库的依赖关系。至于这个Redis数据库在哪里以及连接字符串是什么,这又是另一个话题。在这个阶段,开发人员不需要关心这些细节。
比如,这里是frontend
工作负载的评分文件。
apiVersion: score.dev/v1b1 metadata: name: frontend containers: frontend: image: gcr.io/google-samples/microservices-demo/frontend:v0.10.0 livenessProbe: httpGet: path: /_healthz port: 8080 httpHeaders: - name: Cookie value: shop_session-id=x-liveness-probe readinessProbe: httpGet: path: /_healthz port: 8080 httpHeaders: - name: Cookie value: shop_session-id=x-readiness-probe variables: AD_SERVICE_ADDR: "${resources.adservice.name}:9555" CART_SERVICE_ADDR: "${resources.cartservice.name}:7070" CHECKOUT_SERVICE_ADDR: "${resources.checkoutservice.name}:5050" CURRENCY_SERVICE_ADDR: "${resources.currencyservice.name}:7000" ENABLE_PROFILER: "0" PAYMENT_SERVICE_ADDR: "${resources.paymentservice.name}:50051" PORT: "8080" PRODUCT_CATALOG_SERVICE_ADDR: "${resources.productcatalogservice.name}:3550" RECOMMENDATION_SERVICE_ADDR: "${resources.recommendationservice.name}:8080" SHIPPING_SERVICE_ADDR: "${resources.shippingservice.name}:5051" CYMBAL_BRANDING: "false" FRONTEND_MESSAGE: "" ENABLE_ASSISTANT: "false" SHOPPING_ASSISTANT_SERVICE_ADDR: "${resources.shoppingassistantservice.name}:8080" resources: limits: memory: "128Mi" cpu: "200m" requests: memory: "64Mi" cpu: "100m" resources: dns: type: dns route: type: route params: host: ${resources.dns.host} path: / port: 80 adservice: type: service cartservice: type: service checkoutservice: type: service currencyservice: type: service paymentservice: type: service productcatalogservice: type: service recommendationservice: type: service shippingservice: type: service shoppingassistantservice: type: service service: ports: http: port: 80 targetPort: 8080
在第二个例子中,我们能够看到frontend
工作负载的开发者定义了更多内容,如livenessProbe
和readinessProbe
、同时也定义了其他资源,例如与其他工作负载的依赖关系等,以及需要通过DNS将其暴露。
再次,所有这些依赖都被抽象出来了,相关的占位符在部署这个Score文件时将被平台编排器替换。
作为一名开发者,我可以专注于编写代码,同时利用IDP为我提供的这些良好支持的黄金路径。
使用 Humanitec VS Code 扩展 插件创建或编辑 Score 文件,以提高生产力,与 IDP 进行交互,查看开发人员可用的依赖资源等操作。
作为一名开发者,我需要在将工作负载及其依赖项提交到我的 Git 仓库和相关的 CI/CD 管道之前,在本地进行测试。当然,我可以在 IDE 中运行代码,但如果我想重用工作负载及其依赖项的定义并在本地部署它们之前,我该如何操作呢?这时可以使用 [score-compose](https://docs.score.dev/docs/score-implementation/score-compose/)
, 这也就是 Score 的一种实现,将 Score 文件转换成 compose.yaml
文件:
score-compose init score-compose 生成 score.yaml 文件 docker compose up --build -d (启动并构建容器)
init
命令会创建 score-compose
的工作区,并使用默认的资源提供者(如 redis
,dns
,amqp
,postgres
等)。
generate
命令将根据工作负载的 Score 文件,并通过解析资源依赖关系来生成 compose.yaml
文件。
然后可以运行 docker compose up
,并在本地测试这些容器。
[+] 运行 13/13 ✔ 容器: onlineboutique-demo-redis-iVXhMw-1 运行 ✔ onlineboutique-demo-routing-Rv5fqb-1 运行 ✔ onlineboutique-demo-wait-for-resources-1 已启动 ✔ onlineboutique-demo-emailservice-emailservice-1 已启动 ✔ onlineboutique-demo-cartservice-cartservice-1 已启动 ✔ onlineboutique-demo-checkoutservice-checkoutservice-1 已启动 ✔ onlineboutique-demo-frontend-frontend-1 已启动 ✔ onlineboutique-demo-recommendationservice-recommendationservice-1 已启动 ✔ onlineboutique-demo-shippingservice-shippingservice-1 已启动 ✔ onlineboutique-demo-paymentservice-paymentservice-1 已启动 ✔ onlineboutique-demo-productcatalogservice-productcatalogservice-1 已启动 ✔ onlineboutique-demo-currencyservice-currencyservice-1 已启动 ✔ onlineboutique-demo-adservice-adservice-1 已启动
挺酷的吧,对吧?
作为一名开发者,我现在需要将我的工作负载部署到IDP环境,以便将其部署到 staging 和生产环境中。使用 Humanitec CLI(人类科技命令行工具),您可以使用之前定义并用过的相同 Score 文件(评分文件)来完成这个过程。
humctl 评分部署 \ --app ${APP_ID} \ --env ${ENVIRONMENT_ID} \ -f score.yaml
在实际环境中,当你在 main
分支或任何功能分支中提交时,你的 CI/CD 流水线会立即处理部署。通常,这些 CI/CD 流水线模板是由平台团队提供的,开发人员可以在自己的 Git 仓库中使用这些模板。
这样的CI/CD管道可以帮助创建临时测试环境,以便测试功能分支代码。下面是一个Pull Request的示例,展示了临时环境中部署的相关信息。
在这个阶段,有趣的是我们可以查看此部署的资源图表。在那里,平台正在为开发人员解析并抽象化一个复杂的依赖关系网络。
一旦我的工作负载部署到某个特定环境后,我希望能够查看它们的部署情况、依赖关系等。这就引出了开发者门户这个概念。Humanitec 默认提供了 Humanitec 门户,以使开发人员在这些方面更加自主:
我也能够获取特定工作负载的依赖情况、容器日志等信息,而无需直接操作Kubernetes。
这一部分全部围绕着开发者的角色。我们看到了开发者的认知负担已经减少,让他们更加专注于描述他们想要的东西,而无需考虑所有技术细节的实现,比如云服务商和Kubernetes中的实现。在接下来的部分中,我们将看到,这种抽象层次是如何通过平台工程师在平台编排器(Platform Orchestrator)中配置和连接所有组件和方案来实现的。
平台架构师
作为一名平台工程师,我希望能够集中管理一个一致和安全的平台,让开发人员更自主。
在本节中,从平台工程师的视角,我们将看到如何将治理、安全和可观测性标准化并抽象化到平台。
如下面的参考架构所示,您基于现有的工具构建自己的内部开发者平台(IDP)。如图中黄色部分所示,您将 Humanitec Orchestrator 集成到 CI/CD 流水线中,并要求开发人员通过 Score 来定义他们想要怎样部署工作负载(参见前一节)。最后,不同角色可以通过 Humanitec 门户查看所有相关资源。重要的是,您的 IDP 是由工具和团队的组合构成的。安全、可观测性团队、SRE 和云团队将与平台工程团队合作,通过贡献各自的方案来支持 IDP 的构建。
你的工具链 + Humanitec = 成功的IDP
_注意:此图中显示了刚刚在 Google Cloud Next 2024 上宣布的新 Google Cloud App Hub 服务。我们与 Google 合作了,展示 Humanitec 如何轻松地将项目和工作负载迁入新的 App Hub 服务中。想了解更多关于 App Hub 的信息,可以观看这两个会议:OPS105 和 OPS100。
通过Humanitec平台被引入Google Cloud App Hub的项目和任务负载
你可以创建你自己的平台工程参考架构,也可以在Azure、AWS、Google Cloud等公有云上应用Humanitec的参考架构。
平台团队(如运维、可观测性、安全等)报告的一个问题是,开发人员因为大多数情况下这些Kubernetes清单文件(如Helm、Kustomize等)由他们自己拥有并在自己的Git仓库中托管,所以很难制作和维护这些文件。这时,平台编排器工具就能发挥作用,平台工程师可以定义一组想要标准化的标准模板。这可以是Kubernetes清单、Terraform模块等。
以下是一个示例配置,可确保Kubernetes中的任何Namespace
启用Istio服务网格并强制执行Pod安全标准(PSS):
apiVersion: entity.humanitec.io/v1b1 kind: Definition metadata: id: custom-namespace entity: name: custom-namespace type: k8s-namespace driver_type: humanitec/template driver_inputs: values: templates: init: | name: ${context.app.id}-${context.env.id} manifests: |- namespace.yaml: location: cluster data: apiVersion: v1 kind: Namespace metadata: labels: pod-security.kubernetes.io/enforce: restricted istio-injection: enabled name: {{ .init.name }} outputs: | namespace: {{ .init.name }} criteria: - {}
你也可以在这里添加更多的标签
和注释
给你的可观测性工具或FinOps(财务管理操作)工具。
一旦通过Humanitec Orchestrator部署后,我们就能看到工作负载现在透明地纳入启用了Google Cloud Service Mesh的GKE集群中。
通过Humanitec Orchestrator部署的工作负载的Google Cloud中的服务网格拓扑结构。
但现在,你是否要求你的开发人员在他们的工作负载中添加 securityContext
以提高安全性?当然不行!作为平台工程师,你也应该将这一点抽象出来。这里又有一个方案来确保和标准化这一点。
apiVersion: entity.humanitec.io/v1b1 kind: Definition metadata: id: custom-workload entity: name: custom-workload type: workload driver_type: humanitec/template driver_inputs: values: templates: outputs: | update: - op: add path: /spec/automountServiceAccountToken value: false - op: add path: /spec/securityContext value: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault {{- range $containerId, $value := .resource.spec.containers }} - op: add path: /spec/containers/{{ $containerId }}/securityContext value: allowPrivilegeEscalation: false capabilities: drop: - ALL privileged: false readOnlyRootFilesystem: true {{- end }} criteria: - {}
您的集群和工作负载现在默认就是安全的,并会在您的 GKE 安全态势仪表板中自动监控。
GKE 安全状况面板
当一个工作负载即将部署,并需要数据库支持时,该如何处理呢?作为平台工程师来说,这又是一个我可以提供的支持方案和最佳实践。
在 Humanitec Orchestrator 中可以这样简化配置集群内的 Redis 数据库:如下所示:
apiVersion: entity.humanitec.io/v1b1 kind: Definition metadata: id: redis-in-cluster entity: name: redis-in-cluster type: redis driver_type: humanitec/template driver_inputs: values: templates: init: |- name: redis port: 6379 username: "" password: "" manifests: |- deployment.yaml: location: namespace data: apiVersion: apps/v1 kind: Deployment metadata: name: {{ .init.name }} spec: selector: matchLabels: app: {{ .init.name }} template: metadata: labels: app: {{ .init.name }} spec: containers: - name: {{ .init.name }} image: redis:alpine ports: - containerPort: {{ .init.port }} service.yaml: location: namespace data: apiVersion: v1 kind: Service metadata: name: {{ .init.name }} spec: type: ClusterIP selector: app: {{ .init.name }} ports: - name: tcp-redis port: {{ .init.port }} targetPort: {{ .init.port }} outputs: | host: {{ .init.name }} port: {{ .init.port }} secrets: | username: {{ .init.username }} password: {{ .init.password }} criteria: - {}
在这种情况下,我们使用 humanitec/template
来部署任何 Kubernetes 资源清单。它是你可以用来定义资源的 Humanitec 驱动类型之一。你可以用它来与云提供商互动的另一个驱动类型是 humanitec/terraform
。下面是一个简化版本,如果你想要部署一个 Google Cloud Memorystore(Redis)数据库,你可以这样定义:
apiVersion: entity.humanitec.io/v1b1 kind: Definition metadata: id: redis-memorystore entity: driver_type: humanitec/terraform name: redis-memorystore type: redis driver_inputs: values: script: |- terraform { required_providers { google = { source = "hashicorp/google" } } } provider "google" { } resource "google_redis_instance" "memorystore" { name = "redis-cart" memory_size_gb = 1 redis_version = "REDIS_7_0" region = "REGION" auth_enabled = true # 认证启用 (zhèngmíng qǐyòng) } output "host" { value = google_redis_instance.memorystore.host } output "port" { value = google_redis_instance.memorystore.port } output "username" { value = "" sensitive = true } output "password" { value = google_redis_instance.memorystore.auth_string sensitive = true } criteria: - {}
在这个示例中,Memorystore (Redis) 实例与 GKE 集群位于同一网络中,并通过密码进行认证访问。
在这个阶段再次,当一个新的工作负载部署发生时,它将无缝地采用新的 redis
实现,开发人员无需做任何改动。
在您自己的平台及其工具之上,我们看到您如何能够提高开发者的效率,同时通过提升内部开发者平台(IDP)的稳定性和安全性来改进其抽象层次。这由三个关键组件构成:工作负载定义、编排器工具和门户。
3个关键支柱,以确保您成功实施和采用IDP。
但平台工程不仅仅关乎工具。你需要踏上平台即产品的旅程。这将确保你的开发人员感到被听到,他们会使用你的平台因为它确实帮助了他们,你简化了他们的日常工作,你为他们提供了具体的投资回报率(ROI),你提供了一系列受支持的最佳实践路径等。
平台工程不仅仅是关于工具这点,尽早开启将平台视为产品的旅程也非常重要。
- 请求免费试用 (humanitec.com)
- 获取 GoogleCloudPlatform/microservices-demo 用于 Score 和 Humanitec
- Score 在巴黎 KubeCon EU 上的展示
- 在巴黎举行的 2024 年 KubeCon 的平台工程
- 在您的平台中让本地和远程环境无缝对接
- 参考架构
- 资源包
- [PlatformCon 24] 平台编排器:内部开发者平台中的缺失组件
快乐跳跃着,快乐航行着,干杯!
这篇关于平台工程实战:用Score和Humanitec部署线上精品店示例应用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-07Kubernetes部署策略详解:滚动更新、固定更新、蓝绿部署和金丝雀发布
- 2025-01-03使用Oracle数据库、Helidon和Coherence构建Kubernetes容器,轻松又实用 — 第6部分:构建容器,享受部署的乐趣
- 2025-01-03Django微服务与Docker和Kubernetes部署(系列第五篇:实战篇)
- 2025-01-02云原生Digest:Kubernetes v1.31版本中的移除功能和重大变更
- 2024-12-31Kubernetes工作节点的自动加入方法
- 2024-12-31Docker和Kubernetes面试速成指南 ??
- 2024-12-30玩乐案例:用开源技术从Hadoop迁移到Kubernetes的PB级数据平台之旅
- 2024-12-30在Kubernetes中用NVIDIA GPU运行自己的OLLMAMA服务
- 2024-12-26使用Goldilocks优化Kubernetes资源请求和限制配置指南
- 2024-12-26Canonical Kubernetes 1.32稳定版发布:无缝集群创建与管理