FEATURED · 精选文章

Online Boutique Helm Chart 部署实战:从默认安装到 Service Mesh 安全加固与 Spanner 后端切换

发布时间 / 2026/9/13 20:54:02
来源 / 创域科博编辑部
栏目 / 资讯中心
Online Boutique Helm Chart 部署实战:从默认安装到 Service Mesh 安全加固与 Spanner 后端切换 Online Boutique Helm Chart 部署实战从默认安装到 Service Mesh 安全加固与 Spanner 后端切换【免费下载链接】microservices-demoSample cloud-first application with 10 microservices showcasing Kubernetes, Istio, and gRPC.项目地址: https://gitcode.com/GitHub_Trending/mi/microservices-demo本篇技术指南基于 helm-chart/README.md 展开介绍如何在 Kubernetes 上通过 Helm 一键部署 Google Cloud 官方示例应用 Online Boutique10 个微服务、gRPC、Istio 服务网格覆盖默认安装、高级安全场景Service Accounts、AuthorizationPolicies、NetworkPolicies、Sidecar、cartservice 后端从 Redis 切换至 Cloud Spanner 等核心配置并结合 helm-chart/values.yaml 与 helm-chart/templates 源码逐项讲解参数语义与底层渲染逻辑。读完本文你将掌握如何用一条命令完成 Online Boutique 的默认部署如何通过--set组合出面向生产的安全加固拓扑以及如何通过cartservice.database相关参数将购物车数据层无缝迁移到 Spanner。注意Online Boutique 的 Helm chart 当前标记为实验性experimental。如遇到问题可通过 GitHub Issue 反馈原文档指向 Issue #1319 及新建 Issue 入口。文章中的所有示例均以当前仓库内helm-chart目录的实际内容为准chart 版本与 app 版本均为v0.10.6见 helm-chart/Chart.yaml。一、准备工作chart 从哪来、如何获取Online Boutique 的 Helm chart 已经打包并发布到公开的 Artifact RegistryOCI Registry因此你无需从源码构建直接用 Helm 3 的 OCI 拉取能力即可安装# 默认安装 Online Boutique helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \ --installhelm upgrade ... --install是一个幂等用法若 releaseonlineboutique不存在则执行安装已存在则升级配合 OCI 引用天然适合后续的迭代更新。如果你希望了解 chart 是如何被发布到这个 Registry 的可以查看仓库中的发布脚本 docs/releasing/make-helm-chart.sh它读取TAG环境变量用gsed同步改写 helm-chart/Chart.yaml 中的version与appVersion然后依次执行helm package .与helm push onlineboutique-version.tgz oci://us-docker.pkg.dev/online-boutique-ci/charts。也就是说本文安装命令中的镜像 tag 默认取自Chart.yaml的appVersion: v0.10.6。二、Chart 结构速览一个 chart 管住 12 类工作负载在深入参数之前先建立对 chart 布局的整体认知。当前仓库的 chart 目录结构如下helm-chart/ ├── Chart.yaml # chart 元数据apiVersion: v2type: applicationversion/appVersion: v0.10.6 ├── values.yaml # 全部可配置项的默认值核心参数清单见下一节 └── templates/ ├── NOTES.txt # 安装成功后的提示信息如何获取前端地址 ├── common.yaml # 全局 deny-all NetworkPolicy / AuthorizationPolicy ├── adservice.yaml / cartservice.yaml / checkoutservice.yaml ├── currencyservice.yaml / emailservice.yaml / frontend.yaml ├── loadgenerator.yaml / opentelemetry-collector.yaml ├── paymentservice.yaml / productcatalogservice.yaml ├── recommendationservice.yaml / shippingservice.yamlChart 遵循 Helm 2.x/v2 规范apiVersion: v2应用型 chartvalues.yaml中为每个服务都提供了create开关因此可以按需裁剪组件同时每个服务的模板都遵循资源 → 网络策略 → Sidecar → 授权策略的统一四段式结构为安全场景的批量开启提供了基础。三、核心配置参数全解values.yaml 逐项拆解完整的参数清单以 helm-chart/values.yaml 为准下面按功能域分类讲解并结合模板源码说明每个参数的实际影响。3.1 镜像与发布参数默认值说明images.repositoryus-central1-docker.pkg.dev/online-boutique-ci/microservices-demo所有微服务镜像的仓库前缀模板中用{{ .Values.images.repository }}/{{ .Values.service.name }}:{{ .Values.images.tag | default .Chart.AppVersion }}拼出完整镜像地址见各服务模板。使用私有或自建镜像仓库时务必覆盖此值images.tag覆盖镜像 tag为空时回退到 chart 的appVersion即v0.10.6从 helm-chart/templates/adservice.yaml 可以看到典型的镜像渲染逻辑image: {{ .Values.images.repository }}/{{ .Values.adService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }}。因此覆盖images.repository后全部 10 个微服务镜像将统一从新仓库拉取这是离线部署与私有化环境的关键开关。3.2 安全加固开关服务账号 / 网络策略 / 授权策略 / Sidecar参数默认值说明serviceAccounts.createtrue是否为每个应用创建独立的 ServiceAccount模板中未开启时回退到serviceAccountName: defaultserviceAccounts.annotations{}附加到 ServiceAccount 上的注解典型用途是注入 Workload Identity 注解iam.gke.io/gcp-service-accountserviceAccounts.annotationsOnlyForCartservicefalse注解仅施加到 cartservice 的 ServiceAccount 上。遵循最小权限原则只有 cartservice 需要连接外部数据库如通过 Workload Identity 访问 Spanner避免把云上高权限注解扩散到所有服务networkPolicies.createfalse为每个应用生成一条细粒度 NetworkPolicy见各模板文件开启时同时生成全局 deny-all 策略见 helm-chart/templates/common.yamlsidecars.createfalse为每个应用生成细粒度 Istio Sidecar 资源白名单式声明可访问的 egress 目标见各模板文件authorizationPolicies.createfalse为每个应用生成细粒度 Istio AuthorizationPolicy与全局 deny-all 搭配形成默认拒绝、按需放行的授权模型以 helm-chart/templates/cartservice.yaml 为例开启authorizationPolicies.create后cartservice 的 AuthorizationPolicy 只允许来自frontend与checkoutservice两个 ServiceAccount 的调用且仅放行/hipstershop.CartService/AddItem、/hipstershop.CartService/GetCart、/hipstershop.CartService/EmptyCart三个 gRPC 路径的 POST 请求、端口 7070。这体现了从进程级网络可达到方法级调用授权的纵深防御思路。3.3 可观测性OpenTelemetry Collector 与 Google Cloud Operations参数默认值说明opentelemetryCollector.createfalse是否部署 OTel Collector 网关Deployment ClusterIP Service端口 4317/gRPC-OTLPopentelemetryCollector.nameopentelemetrycollectorCollector 服务名opentelemetryCollector.projectIdPROJECT_IDGCP 项目 ID保持默认值时会通过 initContainer 从 metadata server 自动获取googleCloudOperations.profilerfalse开启后向前端/结算服务注入ENABLE_PROFILER1googleCloudOperations.tracingfalse开启后注入ENABLE_TRACING1googleCloudOperations.metricsfalse指标开关预留从 helm-chart/templates/opentelemetry-collector.yaml 可以看到一个精巧的机制当projectId等于PROJECT_ID时chart 会注入一个 busybox initContainer执行sed s/PROJECT_ID/$(curl -H Metadata-Flavor: Google http://metadata.google.internal/computeMetadata/v1/project/project-id)/把配置模板中的占位符替换为真实项目 ID 后写入共享卷Collector 主容器再以--config/conf/collector-gateway-config.yaml启动。Collector 配置里receivers.otlpexporters.googlecloud形成 traces/metrics 两条直接上云的数据管道。3.4 运行时安全上下文参数默认值说明securityContext.enabletrue为 Pod 注入fsGroup/runAsGroup/runAsNonRoot/runAsUser 1000的 Pod 级 securityContextseccompProfile.enablefalse是否启用 seccompProfileseccompProfile.typeRuntimeDefaultseccomp 类型仅在 enable 时生效此外各服务容器本身都写死了安全加固字段见 helm-chart/templates/cartservice.yamlallowPrivilegeEscalation: false、capabilities.drop: [ALL]、privileged: false、readOnlyRootFilesystem: true。这些是开箱即用的容器最小权限基线。3.5 各微服务组件开关与资源配置values.yaml为每个服务提供了create、name与resources三件套默认全部开启create: true。默认资源请求/限制如下requests/limitsCPU/内存服务nameCPU 请求/限制内存请求/限制adServiceadservice200m / 300m180Mi / 300MicartServicecartservice200m / 300m128Mi / 256MicheckoutServicecheckoutservice100m / 200m64Mi / 128MicurrencyServicecurrencyservice100m / 200m128Mi / 256MiemailServiceemailservice100m / 200m64Mi / 128Mifrontendfrontend100m / 200m64Mi / 128MiloadGeneratorloadgenerator300m / 500m256Mi / 512MipaymentServicepaymentservice100m / 200m128Mi / 256MiproductCatalogServiceproductcatalogservice100m / 200m64Mi / 128MirecommendationServicerecommendationservice100m / 200m220Mi / 450MishippingServiceshippingservice100m / 200m64Mi / 128Mi两个值得注意的专项参数productCatalogService.extraLatency默认给 productcatalogservice 的每次请求注入额外延迟用于压测/演示超时与重试行为默认无额外延迟loadGenerator.checkFrontendInitContainer默认trueloadgenerator 启动前先通过 busybox initContainer 用wget --server-response轮询前端最多 12 次、间隔 10 秒见 helm-chart/templates/loadgenerator.yaml确保压测流量不会打到尚未就绪的前端。压测参数在模板中硬编码为USERS10、RATE1每秒 1 个请求/用户。3.6 前端访问与 Istio 路由参数默认值说明frontend.externalServicetrue是否额外创建frontend-external的 LoadBalancer Service保留frontendClusterIP Service 用于网格内访问frontend.cymbalBrandingfalse是否启用 Cymbal 品牌标识对应注入CYMBAL_BRANDING环境变量frontend.platformlocal部署平台标识取值local/gcp/aws/azure/onprem/alibaba之一对应注入ENV_PLATFORM环境变量前端 main.go 据此渲染部署详情。默认localGKE 上运行时自动切换为gcpfrontend.singleSharedSessionfalse是否启用单共享会话模式对应ENABLE_SINGLE_SHARED_SESSIONfrontend.virtualService.createfalse是否创建指向 ingress gateway 的 Istio VirtualServicefrontend.virtualService.hosts[*]VirtualService 的 host 列表frontend.virtualService.gateway.nameasm-ingressgateway目标 Gateway 名称frontend.virtualService.gateway.namespaceasm-ingress目标 Gateway 所在命名空间frontend.virtualService.gateway.labelKeyasm用于从 ASM 命名空间中挑选网关 Pod 的标签键frontend.virtualService.gateway.labelValueingressgateway对应标签值关键关联当frontend.externalServicefalse且frontend.virtualService.createtrue时流量路径变为Ingress Gateway → VirtualService → frontend:80NetworkPolicy 会额外放行来自网关命名空间kubernetes.io/metadata.name匹配frontend.virtualService.gateway.namespace的入站请求见 helm-chart/templates/frontend.yaml。3.7 购物车数据库Redis 与 Spanner 双后端参数默认值说明cartDatabase.typeredis购物车数据层类型可选redis或spannercartDatabase.connectionStringredis-cart:6379连接串Redis 模式为host:portSpanner 模式为projects/project/instances/instance/databases/dbcartDatabase.inClusterRedis.createtrue是否随 chart 部署一个内置 RedisDeployment Service端口 6379cartDatabase.inClusterRedis.nameredis-cart内置 Redis 名称cartDatabase.inClusterRedis.publicRepositorytrue为 true 时使用 Docker Hub 的redis:alpine官方镜像固定 digest 拉取否则改用images.repository中的 rediscartDatabase.externalRedisTlsOrigination.enablefalse是否对外部 Redis 启用 TLS 发起配合 Istio ServiceEntry/DestinationRulecartDatabase.externalRedisTlsOrigination.nameexernal-redis-tls-originationTLS 资源命名前缀注意原值拼写cartDatabase.externalRedisTlsOrigination.endpointAddress外部 Redis 端点 IPcartDatabase.externalRedisTlsOrigination.endpointPort外部 Redis 端点端口cartDatabase.externalRedisTlsOrigination.certificate用于 TLS 校验的 PEM 证书内容模板层的实际效果见 helm-chart/templates/cartservice.yaml当cartDatabase.type spanner时注入环境变量SPANNER_CONNECTION_STRING否则注入REDIS_ADDR值均取cartDatabase.connectionString开启externalRedisTlsOrigination.enable时chart 会同时生成保存 PEM 证书的 Secret、mode: SIMPLE的 DestinationRulecaCertificates 指向/etc/certs/name.pem、location: MESH_EXTERNAL的 ServiceEntryresolution: STATIC并在 cartservice Pod 上通过sidecar.istio.io/userVolumeMount注解把证书卷挂到 sidecar 的/etc/certs同时设置proxy.istio.io/config: {holdApplicationUntilProxyStarts: true}保证 sidecar 就绪后再启动应用容器。3.8 尚未纳入 Helm 的组件shoppingAssistantService购物助手当前在values.yaml中以create: false占位并标注 TODO尚未随 Helm 部署可参考 kustomize/components/shopping-assistant 的独立安装方式。四、部署命令实战默认安装与高级场景4.1 场景一默认部署helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \ --install该命令会以默认值部署全部 10 个微服务 内置 Redis loadgenerator并创建一个frontend-externalLoadBalancer Service 对外暴露前端。安装完成后chart 的 NOTES.txt 会给出获取访问地址的方法# 观察 frontend-external 的 LoadBalancer IP 就绪状态 kubectl get --namespace release-namespace svc -w frontend-external # 提取外部 IP 并打印访问地址 export SERVICE_IP$(kubectl get svc --namespace release-namespace frontend-external --template {{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}) echo http://$SERVICE_IP若开启了frontend.virtualService.createNOTES.txt 还会提示通过 ingress gateway 的地址访问同理用kubectl get svc -n gateway-namespace gateway-name提取 IP。4.2 场景二高级安全拓扑Service Mesh Spanner Workload Identity原文档给出了一条完整的进阶部署命令它同时解决了镜像私有化、关闭外部直连、购物车后端切换、服务账号/授权/网络策略/Sidecar 全量开启、Istio 网关路由与 Workload Identity 注解等问题helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \ --install \ --create-namespace \ --set images.repositoryus-docker.pkg.dev/my-project/microservices-demo \ --set frontend.externalServicefalse \ --set redis.createfalse \ --set cartservice.database.typespanner \ --set cartservice.database.connectionStringprojects/my-project/instances/onlineboutique/databases/carts \ --set serviceAccounts.createtrue \ --set authorizationPolicies.createtrue \ --set networkPolicies.createtrue \ --set sidecars.createtrue \ --set frontend.virtualService.createtrue \ --set serviceAccounts.annotations.iam\.gke\.io/gcp-service-accountspanner-db-usermy-project.iam.gserviceaccount.com \ --set serviceAccounts.annotationsOnlyForCartservicetrue \ -n onlineboutique逐项解读这条命令的意图参数作用--create-namespace-n onlineboutique自动创建并指定 release 命名空间images.repository指向你私有项目下的镜像仓库如 GCR/Artifact Registry 镜像迁移后frontend.externalServicefalse关闭 LoadBalancer 直连对外流量统一走 Istio Ingress Gatewayredis.createfalse不部署内置 RedisRedis 已不再需要因为后端切换为 Spannercartservice.database.typespanner将购物车数据层切换为 Cloud Spannercartservice.database.connectionString指定 Spanner 数据库连接串项目/实例/数据库三级路径serviceAccounts.createtrue每个服务独立 ServiceAccount为方法级授权提供身份基础authorizationPolicies.createtrue开启 Istio 方法级授权策略配合 common.yaml 的 deny-all 形成默认拒绝模型networkPolicies.createtrue开启细粒度 Kubernetes NetworkPolicy同样配合 deny-all 基线sidecars.createtrue开启 Istio Sidecar 资源收敛每个 Pod 的 egress 白名单serviceAccounts.annotations.iam\.gke\.io/gcp-service-account...为 ServiceAccount 注入 Workload Identity 注解注意键中的点需要用\.转义serviceAccounts.annotationsOnlyForCartservicetrue注解只落在 cartservice 上最小权限原则只有 cartservice 需要以spanner-db-user身份访问外部 Spanner这个场景同时印证了源码中的几处设计Spanner 模式仅注入SPANNER_CONNECTION_STRING见 helm-chart/templates/cartservice.yamlannotationsOnlyForCartservice控制注解是否只加到 cartservice 的 ServiceAccount其余服务模板中均以{{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }}守卫cartservice 的 AuthorizationPolicy 只放行 frontend/checkoutservice 的特定 gRPC 方法。4.3 与源码的对应关系为什么cartservice.database.typespanner会生效cartservice 的底层实现也支持双后端仓库中 src/cartservice/src/cartstore/ICartStore.cs 定义了存储抽象RedisCartStore.cs 与 SpannerCartStore.cs 分别实现两种后端其中 SpannerCartStore 通过读取SPANNER_CONNECTION_STRING以及SPANNER_PROJECT、SPANNER_INSTANCE、SPANNER_DATABASE完成连接初始化。这正是 Helm 模板注入SPANNER_CONNECTION_STRING环境变量后能够无缝切换的底层依据——配置驱动、代码无感知。五、从源码本地安装 chart离线 / 调试场景如果你希望基于当前仓库的 chart 源码直接部署例如验证模板改动或离线环境可以省略 OCI 拉取直接引用本地目录helm upgrade onlineboutique ./helm-chart \ --install \ -n onlineboutique --create-namespace也可以先用helm template ./helm-chart渲染 YAML 检查输出再决定是否执行。chart 的发布流程版本号同步、helm package、helm push见 docs/releasing/make-helm-chart.sh。六、验证与卸载健康检查chart 为各服务配置了 Kubernetes 1.24 支持的 gRPC 探针readinessProbe/livenessProbe中的grpc:字段见 adservice/checkoutservice/cartservice 等模板例如 cartservice 的 gRPC 探针位于端口 7070initialDelaySeconds: 15前端则使用带 Cookie 的 HTTP 探针访问/_healthz见 helm-chart/templates/frontend.yaml。查看 release 状态helm status onlineboutique -n onlineboutique查看资源kubectl get pods,svc -n onlineboutique。卸载helm uninstall onlineboutique -n onlineboutique。七、小结与延伸阅读本文完整覆盖了 Online Boutique Helm chart 的默认安装、全部核心配置参数镜像、安全加固、可观测性、数据库后端、Istio 路由与高级安全场景实战并逐层对应到 helm-chart/values.yaml 与 helm-chart/templates 的模板源码。你可以在此基础上继续探索仓库内与之互补的部署方案面向 GitOps 的 kustomize 变体kustomize/README.md 及 kustomize/components 下的spanner、memorystore、service-mesh-istio、google-cloud-operations等组件手写清单版本kubernetes-manifests 与 istio-manifests含 frontend gateway 与 VirtualService底层服务实现cartservice 的 C# 实现见 src/cartservice购物车双后端存储类见 src/cartservice/src/cartstoreTerraform 基础设施terraform/README.mdGKE 集群与 Memorystore 的 IaC 定义。原文档还给出了三篇延伸博客主题借助 Helm chart 简化 Service Mesh 与 GitOps 下的高级安全场景配置、Kubernetes 1.24 的 gRPC 健康探针、以及为 Online Boutique 接入 Cloud Spanner。结合本仓库源码阅读这些主题可以更深入理解 chart 中每个开关背后的设计动机。【免费下载链接】microservices-demoSample cloud-first application with 10 microservices showcasing Kubernetes, Istio, and gRPC.项目地址: https://gitcode.com/GitHub_Trending/mi/microservices-demo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻