1. 项目概述:当自动化运维遇上Kubernetes
如果你和我一样,在运维和DevOps这条路上摸爬滚打了十几年,那你一定经历过从手动敲命令到脚本化,再到追求自动化编排的整个历程。自动化运维平台,比如StackStorm,就是这条路上的一个关键里程碑。它通过“事件驱动自动化”的理念,将各种工具、API和脚本连接起来,形成一个可以感知事件、自动决策并执行动作的“运维大脑”。简单来说,就是让系统自己发现问题、分析问题,甚至解决问题。
然而,当整个基础设施的基石转向容器化和Kubernetes时,我们熟悉的运维模式迎来了新的挑战。传统的虚拟机部署方式变得笨重,如何让StackStorm这个“大脑”本身也享受云原生的红利——具备弹性伸缩、声明式配置、高可用和易于管理的特性?这就是stackstorm-k8s项目要解决的核心问题。它不是一个全新的产品,而是将成熟的StackStorm自动化平台,以云原生的方式,完整地部署和运行在Kubernetes集群中。
这个项目对于正在或计划将运维体系全面容器化的团队来说,价值巨大。它意味着你的自动化中枢能够与你的K8s集群无缝融合,同样通过kubectl和YAML文件来管理,同样可以基于资源使用率自动扩缩容,同样具备从开发到生产环境的一致性。无论你是想监控K8s集群内的事件来自动修复应用,还是想用StackStorm的动作去操作集群外的传统设施,一个运行在K8s内部的StackStorm都提供了最直接、最现代的集成方案。
2. 整体架构与设计思路拆解
将StackStorm这样一个由多个组件(Web UI、API、规则引擎、工作流引擎、传感器、执行器)构成的复杂状态应用容器化,并不是简单地把每个进程塞进一个Docker镜像那么简单。stackstorm-k8s项目体现的是一种深思熟虑的、符合Kubernetes最佳实践的架构设计思想。
2.1 核心设计哲学:微服务化与Operator模式
传统的StackStorm部署(如通过st2ctl或systemd)将所有核心服务部署在同一台或几台机器上,服务间通过本地进程或网络通信。在K8s环境下,stackstorm-k8s的首要任务是将这些服务拆分为独立的、可单独部署和管理的Kubernetes工作负载。这通常意味着:
- API服务 (
st2api)和流服务 (st2stream)会作为独立的Deployment,并通过Service对外暴露。 - 规则引擎 (
st2rulesengine)、工作流引擎 (st2workflowengine)、定时器引擎 (st2timersengine)等核心后台服务,也被拆分为独立的Deployment,因为它们承担着不同的处理职责,独立扩缩容更有意义。 - 传感器容器 (
st2sensorcontainer)可能需要特殊考虑,因为用户自定义的传感器需要在这里运行。项目通常会提供一种机制,让用户能够注入自己的传感器代码,这可能通过ConfigMap挂载或Init Container来实现。 - Web UI (
st2web)通常作为一个静态文件服务,由Nginx等Web服务器容器提供,或者直接集成到API服务的路由中。
更高级的设计会采用Operator模式。Operator是Kubernetes的一种扩展,它通过自定义资源(CRD)和控制器来管理和运维复杂的有状态应用。一个理想的StackStorm Operator可以让你通过一个YAML文件(例如StackStorm自定义资源)来声明你想要部署的StackStorm实例的版本、组件副本数、资源限制、数据库连接信息等。Operator控制器会监听这个资源,并自动创建和管理对应的Deployment、StatefulSet、Service、ConfigMap等一系列K8s资源,大大简化了部署和生命周期管理的复杂度。stackstorm-k8s项目可能直接提供Operator,或者其部署清单本身就隐含了这种模式的思想。
2.2 有状态与无状态的分离
这是云原生设计的关键。StackStorm依赖几个核心的有状态服务:
- 数据库 (MongoDB):存储动作、规则、执行历史等元数据。
- 消息队列 (RabbitMQ):作为服务间通信的骨干,传递触发器和执行请求。
- 键值存储 (Redis):用于工作流状态缓存、分布式锁等。
在K8s中,这些有状态服务绝不应该与无状态的业务组件(如st2api,st2rulesengine)混在同一个Pod里。stackstorm-k8s的部署清单会清晰地体现这一点:
- 无状态组件:使用
Deployment,可以随意扩缩容和滚动更新。 - 有状态组件:使用
StatefulSet,为每个Pod提供稳定的网络标识和持久化存储卷(Persistent Volume)。例如,MongoDB和RabbitMQ集群的部署就需要StatefulSet来保证数据安全和有序管理。
项目可能会选择将这些中间件作为依赖,在部署StackStorm时一并拉起(通过Helm Chart的依赖项dependencies),更常见的生产级做法是让StackStorm连接集群外部的、由专业团队维护的高可用数据库和消息队列服务。部署清单需要灵活支持这两种配置方式。
2.3 配置管理:ConfigMap与Secret
StackStorm有大量的配置文件(如/etc/st2/st2.conf,/opt/stackstorm/packs/下的包配置)。在K8s中,硬编码进镜像或通过环境变量传递复杂配置都是不合适的。stackstorm-k8s会充分利用:
- ConfigMap:存储非机密的配置数据,如API监听端口、日志级别、传感器列表。可以将整个
st2.conf拆分成多个ConfigMap,按功能模块管理。 - Secret:存储密码、API令牌、SSL证书等敏感信息。数据库连接密码、RabbitMQ密码、StackStorm自身的认证密钥都必须通过Secret注入。
这些配置会以卷(Volume)的形式挂载到各个Pod的特定路径,实现配置与镜像的解耦。当配置变更时,只需更新ConfigMap或Secret,并滚动重启相关的Deployment即可生效。
3. 核心组件部署与配置详解
理解了整体架构,我们深入到具体组件的部署和配置细节。这里假设stackstorm-k8s项目提供的是基于Helm Chart的部署方式,这是目前管理复杂K8s应用的事实标准。
3.1 Helm Chart结构解析
一个成熟的stackstorm-k8sHelm Chart目录结构通常如下:
stackstorm-k8s/ ├── Chart.yaml # Chart元信息(名称、版本、依赖) ├── values.yaml # 默认配置值,用户主要修改的文件 ├── templates/ # Kubernetes资源模板目录 │ ├── deployment-*.yaml # 各种无状态组件的Deployment │ ├── statefulset-*.yaml # 有状态组件的StatefulSet │ ├── service-*.yaml # 对应的Service │ ├── configmap-*.yaml # 配置文件 │ ├── secret-*.yaml # 密钥文件(通常通过`helm install`时生成) │ └── ingress-*.yaml # 入口路由配置 └── requirements.yaml 或 Chart.yaml的dependencies # 依赖的中间件Chart(如MongoDB、RabbitMQ)在values.yaml中,你会看到高度可配置的选项,例如:
# values.yaml 示例片段 stackstorm: version: “3.9.0” image: repository: stackstorm/stackstorm tag: “3.9.0” pullPolicy: IfNotPresent components: api: replicaCount: 2 resources: requests: memory: “512Mi” cpu: “200m” rulesengine: replicaCount: 2 workflowengine: replicaCount: 2 externalDatabase: enabled: false # 如果为true,则使用外部MongoDB host: “mongodb.example.com” port: 27017 database: “stackstorm” username: “stackstorm” # password通过secret引用 rabbitmq: enabled: true # 使用Chart内嵌的RabbitMQ replicaCount: 3 persistence: enabled: true size: “8Gi”3.2 关键部署模板剖析
以st2api的Deployment模板为例,我们看看它是如何将上述设计落地的:
# templates/deployment-st2api.yaml (简化版) apiVersion: apps/v1 kind: Deployment metadata: name: {{ include “stackstorm.fullname” . }}-st2api spec: replicas: {{ .Values.components.api.replicaCount }} selector: matchLabels: app: {{ include “stackstorm.name” . }} component: st2api template: metadata: labels: (同上) spec: containers: - name: st2api image: “{{ .Values.stackstorm.image.repository }}:{{ .Values.stackstorm.image.tag }}” imagePullPolicy: {{ .Values.stackstorm.image.pullPolicy }} command: [“/opt/stackstorm/st2/bin/st2api”] ports: - containerPort: 9101 env: - name: ST2_CONFIG_FILE value: “/etc/st2/st2.conf” - name: PYTHONPATH value: “/opt/stackstorm/st2/lib/python3.6/site-packages” volumeMounts: - name: config-volume mountPath: /etc/st2 - name: packs-volume mountPath: /opt/stackstorm/packs - name: virtualenvs-volume mountPath: /opt/stackstorm/virtualenvs resources: {{- toYaml .Values.components.api.resources | nindent 12 }} volumes: - name: config-volume configMap: name: {{ include “stackstorm.fullname” . }}-config - name: packs-volume emptyDir: {} # 或使用PersistentVolumeClaim用于生产级共享 - name: virtualenvs-volume emptyDir: {}从这个模板可以看到:
- 镜像与命令:使用统一的StackStorm镜像,但通过
command指定运行st2api进程。 - 配置注入:通过名为
config-volume的卷,将整个ConfigMap挂载到容器的/etc/st2目录。 - 包管理:
packs-volume和virtualenvs-volume通常使用emptyDir,这意味着用户安装的包和Python虚拟环境在Pod重启后会丢失。对于生产环境,这里需要替换为持久化存储或设计一个初始化容器(Init Container)来从Git仓库或对象存储中同步包。
3.3 网络与服务暴露
内部服务通过Kubernetes Service进行发现和通信。例如,st2apiService的类型可能是ClusterIP,供集群内其他组件(如Web UI)调用。
# templates/service-st2api.yaml apiVersion: v1 kind: Service metadata: name: {{ include “stackstorm.fullname” . }}-st2api spec: type: ClusterIP ports: - port: 9101 targetPort: 9101 protocol: TCP name: api selector: app: {{ include “stackstorm.name” . }} component: st2api要让用户能从集群外部访问Web UI或API,需要配置Ingress。现代Ingress Controller(如Nginx, Traefik)支持基于路径的路由。
# templates/ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ include “stackstorm.fullname” . }}-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - host: stackstorm.example.com http: paths: - path: /api(/|$)(.*) pathType: Prefix backend: service: name: {{ include “stackstorm.fullname” . }}-st2api port: number: 9101 - path: /auth(/|$)(.*) pathType: Prefix backend: service: name: {{ include “stackstorm.fullname” . }}-st2auth port: number: 9100 - path: /stream(/|$)(.*) pathType: Prefix backend: service: name: {{ include “stackstorm.fullname” . }}-st2stream port: number: 9102 - path: / pathType: Prefix backend: service: name: {{ include “stackstorm.fullname” . }}-st2web port: number: 80这个Ingress配置将所有流量导向同一个域名stackstorm.example.com,但根据路径前缀分发到不同的后端服务,完美模拟了StackStorm原生的访问方式。
4. 持久化存储与数据管理策略
在K8s中运行有状态应用,持久化存储是重中之重,处理不当会导致数据丢失,服务无法恢复。
4.1 中间件数据持久化
对于MongoDB和RabbitMQ,必须使用持久化卷(Persistent Volume, PV)和持久化卷声明(Persistent Volume Claim, PVC)。在Helm Chart中,这通常通过子Chart(如bitnami/mongodb,bitnami/rabbitmq)的配置来完成。
# 在values.yaml中配置内嵌MongoDB的持久化 mongodb: enabled: true architecture: replicaset # 生产环境务必用副本集 persistence: enabled: true size: 20Gi storageClass: “ssd-fast” # 指定StorageClass,由集群管理员提供 auth: enabled: true rootPassword: “” # 留空,Helm会生成并存入Secret username: “stackstorm” password: “” # 留空,Helm会生成 database: “stackstorm” rabbitmq: enabled: true replicaCount: 3 persistence: enabled: true size: 8Gi storageClass: “ssd-fast” auth: username: “stackstorm” password: “” # 留空,Helm会生成 erlangCookie: “” # 留空,Helm会生成重要提示:
storageClass的选择至关重要。在生产环境,你需要与基础设施团队确认可用的StorageClass及其后端类型(如SSD、NVMe)、性能(IOPS)和可靠性(副本策略)。错误的存储选择会成为整个系统的性能瓶颈。
4.2 StackStorm自身数据的持久化
StackStorm本身产生的数据主要是:
- 日志文件:默认输出到
/var/log/st2/。建议配置所有容器的日志驱动为stdout和stderr,然后由集群级的日志收集方案(如Fluentd + Elasticsearch)统一处理,而不是持久化在容器内。 - 用户上传的包和虚拟环境:这是需要重点考虑持久化的。如前所述,使用
emptyDir不适用于生产。有两种主流方案:- Init Container同步:在
st2sensorcontainer等Pod启动前,使用一个Init Container从Git仓库(如GitLab, GitHub)或对象存储(如S3/MinIO)中拉取指定的Pack代码到共享的emptyDir卷中。这种方式更符合GitOps理念,包版本由代码仓库管理。 - 持久化共享存储:为
/opt/stackstorm/packs和/opt/stackstorm/virtualenvs创建PVC,使用支持ReadWriteMany访问模式的存储(如NFS、CephFS、云厂商提供的文件存储)。这样所有需要访问包的Pod都能挂载同一个卷,确保包的一致性。但要注意文件锁和并发写入问题。
- Init Container同步:在
4.3 备份与恢复
无论存储多么可靠,备份都是必须的。你需要为K8s环境下的StackStorm设计备份策略:
- MongoDB备份:使用
mongodump定期执行,备份文件存入对象存储。可以使用Kubernetes CronJob来运行备份任务。 - RabbitMQ定义备份:备份其队列、交换机的定义(而非消息数据本身)。可以通过管理API导出。
- Pack代码备份:如果你的包代码存放在Git中,这本身就是备份。如果放在持久化卷里,需要定期对卷做快照(如果存储支持)或使用
rsync同步到异地。
恢复流程则需要反向操作:先恢复MongoDB数据,再恢复RabbitMQ定义,最后确保Pack卷数据就位,然后重新部署StackStorm应用。
5. 安全与权限管控实践
将自动化平台部署在K8s内,安全考量需要从两个层面进行:Kubernetes层面的安全,以及StackStorm应用自身的安全。
5.1 Kubernetes RBAC与网络策略
StackStorm的各个组件需要访问K8s API(例如,通过K8s Sensor监听资源事件,通过K8s Action操作资源)。因此,需要为其创建细粒度的ServiceAccount和RBAC角色。
# templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: name: {{ include “stackstorm.fullname” . }}-sa # templates/clusterrole.yaml (如果需要集群范围权限) apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ include “stackstorm.fullname” . }}-clusterrole rules: - apiGroups: [“”] resources: [“pods”, “events”, “services”] verbs: [“get”, “list”, “watch”] # 传感器通常只需要读权限 - apiGroups: [“apps”] resources: [“deployments”] verbs: [“get”, “list”, “watch”, “update”, “patch”] # 执行器可能需要更新资源 # templates/clusterrolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ include “stackstorm.fullname” . }}-crb subjects: - kind: ServiceAccount name: {{ include “stackstorm.fullname” . }}-sa namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ include “stackstorm.fullname” . }}-clusterrole apiGroup: rbac.authorization.k8s.io然后,在每个需要K8s API权限的Deployment的Pod Spec中,指定这个ServiceAccount。
spec: serviceAccountName: {{ include “stackstorm.fullname” . }}-sa # ... 其他配置此外,应配置NetworkPolicy来限制Pod间的网络流量,实现最小权限原则。例如,只允许st2apiService被Ingress Controller和内部组件访问,限制st2rulesengine只能与MongoDB和RabbitMQ通信。
5.2 StackStorm应用层安全
- TLS/HTTPS:必须为所有对外服务(API、Web UI)启用TLS。这可以通过在Ingress层面配置SSL终止(使用Cert-Manager自动签发Let‘s Encrypt证书)来实现。
- 认证与密钥管理:StackStorm的API密钥、ChatOps服务令牌等敏感信息,必须通过Kubernetes Secret管理,并以环境变量或文件挂载的方式注入容器,绝对禁止硬编码在ConfigMap或镜像中。
- 包安全:用户安装的Pack可能包含任意Python代码。在K8s环境中,可以通过Pod的SecurityContext设置
readOnlyRootFilesystem: true和runAsNonRoot: true来限制容器的权限,减少攻击面。对于运行自定义传感器的st2sensorcontainer,可以考虑使用更严格的安全策略,甚至将其部署在独立的、具有特定权限的命名空间中。
6. 高可用与弹性伸缩配置
云原生的核心优势之一就是高可用和弹性。stackstorm-k8s部署必须充分利用这一点。
6.1 组件多副本与反亲和性
对于所有无状态组件(st2api,st2rulesengine,st2workflowengine等),在values.yaml中将其replicaCount设置为至少2。这确保了单个节点或Pod故障时,服务不会中断。
components: api: replicaCount: 2 rulesengine: replicaCount: 2 workflowengine: replicaCount: 3 # 工作流引擎负载可能更重,可以多设几个仅仅设置多副本还不够,如果所有副本都被调度到同一个Kubernetes节点上,那么该节点故障会导致服务完全不可用。因此,需要配置Pod反亲和性,让同一组件的Pod尽量分散在不同的节点上。
# 在Deployment模板的spec.template.spec中添加 affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: component operator: In values: - st2api # 确保st2api的Pod不扎堆 topologyKey: kubernetes.io/hostname6.2 有状态服务的高可用
- MongoDB:必须部署为副本集(Replica Set)。
bitnami/mongodbChart默认支持。一个典型的三节点副本集(一主两从)可以提供数据冗余和读扩展。 - RabbitMQ:必须部署为集群模式。
bitnami/rabbitmqChart也支持。RabbitMQ集群可以确保消息队列的高可用,但需要注意网络分区(“脑裂”)的处理策略。 - Redis:如果用作缓存,可以使用主从模式;如果用于分布式锁等关键场景,建议使用Redis Sentinel或Redis Cluster。
这些中间件的高可用配置相对复杂,stackstorm-k8s项目如果将其作为子Chart包含,通常会在values.yaml中提供开关和配置项。你需要仔细阅读子Chart的文档,正确配置持久化、副本数、仲裁节点等参数。
6.3 基于HPA的自动伸缩
对于无状态组件,可以配置Horizontal Pod Autoscaler,根据CPU/内存使用率或自定义指标(如API请求QPS)自动调整副本数。
# 可以作为一个独立的HPA模板,或在Deployment中声明 apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: {{ include “stackstorm.fullname” . }}-st2api-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: {{ include “stackstorm.fullname” . }}-st2api minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70在实际生产中,st2api和st2stream这类面向用户的组件更适合配置HPA。而st2rulesengine和st2workflowengine的负载与规则/工作流执行频率相关,伸缩策略可能需要更精细的定制。
7. 监控、日志与故障排查体系
一个在K8s中运行的系统,其可观测性必须建立在集群级的监控日志体系之上。
7.1 监控指标暴露与收集
StackStorm组件本身会通过HTTP端点暴露Prometheus格式的指标(如/metrics)。你需要:
- 配置ServiceMonitor:如果你使用Prometheus Operator,可以为每个StackStorm Service创建ServiceMonitor资源,告诉Prometheus去哪里抓取指标。
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: stackstorm-api-monitor spec: selector: matchLabels: component: st2api # 匹配st2api Service的标签 endpoints: - port: api # 对应Service中定义的端口名称 path: /metrics - 定义关键告警规则:在Prometheus中设置告警规则,监控:
- 各组件Pod是否就绪(
kube_pod_status_ready)。 - API请求错误率(
rate(st2http_response_total{status=~“5..”}[5m]))。 - 消息队列积压(通过RabbitMQ exporter获取)。
- 规则引擎处理延迟。
- 各组件Pod是否就绪(
7.2 集中式日志收集
确保所有StackStorm容器的日志都输出到标准输出(stdout)和标准错误(stderr)。Kubernetes会自动捕获这些日志(通过kubectl logs查看)。但生产环境需要更强大的方案:
- EFK Stack:使用Fluentd或Fluent Bit作为日志代理(DaemonSet部署),收集所有Pod的日志,发送到Elasticsearch进行索引和存储,最后通过Kibana进行可视化查询。
- Loki Stack:更轻量级的方案,使用Promtail收集日志,发送到Loki,通过Grafana查看。
在Grafana或Kibana中,你可以按app=stackstorm的标签过滤,查看所有相关组件的日志,并设置关键错误日志的告警。
7.3 故障排查实战指南
当StackStorm在K8s中出现问题时,可以按照以下步骤排查:
检查Pod状态:
kubectl -n stackstorm get pods查看是否有
CrashLoopBackOff、ImagePullBackOff、Pending状态的Pod。查看Pod事件和日志:
kubectl -n stackstorm describe pod <pod-name> kubectl -n stackstorm logs <pod-name> [-c <container-name>] # 查看指定容器日志 kubectl -n stackstorm logs <pod-name> --previous # 查看之前崩溃容器的日志常见错误:镜像拉取失败、资源配置不足(CPU/Memory)、持久化卷挂载失败、健康检查失败。
检查服务与端点:
kubectl -n stackstorm get svc kubectl -n stackstorm get endpoints <service-name> # 查看Service背后健康的Pod IP如果Endpoint为空,说明没有健康的Pod匹配Service的标签选择器。
检查Ingress:
kubectl -n stackstorm get ingress kubectl -n stackstorm describe ingress <ingress-name>检查Ingress Controller是否已正确配置,域名解析是否正确。
进入容器内部调试:
kubectl -n stackstorm exec -it <pod-name> -- /bin/bash进入容器后,可以检查配置文件、网络连通性(如
curl内部服务)、进程状态等。检查依赖服务:
kubectl -n stackstorm get pods | grep -E “(mongo|rabbit|redis)” kubectl -n stackstorm logs <mongodb-pod-name>很多问题根源在于MongoDB或RabbitMQ连接失败。
查看StackStorm服务自身状态:如果API服务已启动,可以通过其健康端点或CLI(在容器内执行
st2ctl status)检查内部组件状态。
8. 生产环境部署清单与持续交付
最后,我们将所有要点汇总成一个生产级部署清单,并探讨如何将其集成到CI/CD流程中。
8.1 生产环境部署检查清单
在执行helm install或kubectl apply之前,请逐项核对:
- [ ]命名空间:已创建独立的命名空间(如
stackstorm-prod),实现资源隔离。 - [ ]存储类:已确认并测试了可用的、性能符合要求的StorageClass。
- [ ]镜像仓库:已将所有需要的镜像(StackStorm、MongoDB、RabbitMQ等)拉取或推送到私有仓库,并在
values.yaml中更新了镜像地址。 - [ ]资源配置:根据预估负载,在
values.yaml中调整了各组件的resources.requests/limits。避免“饥饿”或“浪费”。 - [ ]高可用配置:关键无状态组件
replicaCount >= 2,并检查了反亲和性配置。MongoDB、RabbitMQ已配置为集群模式。 - [ ]安全配置:
- 所有密码、密钥均已通过Secret管理,并在
values.yaml中引用。 - 已配置TLS证书(如使用Cert-Manager自动签发)。
- 已创建最小权限的ServiceAccount和RBAC。
- 已考虑Pod Security Context。
- 所有密码、密钥均已通过Secret管理,并在
- [ ]网络策略:已定义并应用了限制Pod间流量的NetworkPolicy。
- [ ]外部访问:已正确配置Ingress,域名解析已指向Ingress Controller。
- [ ]监控与日志:已配置ServiceMonitor和日志收集的标签,确保指标和日志能被集群监控系统抓取。
- [ ]备份方案:已制定并测试了MongoDB和RabbitMQ的备份与恢复流程。
8.2 使用Helm进行版本管理与升级
Helm是管理K8s应用生命周期的最佳工具。
- 首次安装:
helm repo add stackstorm https://charts.stackstorm.net # 假设有官方Chart仓库 helm install stackstorm-prod stackstorm/stackstorm-k8s -n stackstorm-prod -f my-production-values.yaml - 升级版本:
升级前务必备份数据库,并仔细阅读新版本的Release Notes,看是否有破坏性变更需要处理(如数据库迁移)。helm upgrade stackstorm-prod stackstorm/stackstorm-k8s -n stackstorm-prod -f my-production-values.yaml --version <new-chart-version> - 回滚:
helm rollback stackstorm-prod <revision-number> -n stackstorm-prod
8.3 集成CI/CD流水线
将stackstorm-k8s的部署纳入GitOps流程是理想选择。你可以将定制后的values.yaml和任何自定义的K8s资源文件(如NetworkPolicy)存放在一个Git仓库中。
- 代码仓库:存放Helm Chart(或Kustomize配置)和定制的
values.yaml。 - CI流程:当向仓库推送变更时,CI流水线可以:
- 使用
helm template或kustomize build渲染出最终的K8s YAML清单。 - 使用
kubeval或kubeconform进行语法验证。 - (可选)将渲染后的清单部署到一个预览环境进行测试。
- 使用
- CD流程:通过GitOps工具(如Argo CD, Flux CD)监听仓库。当
values.yaml或Chart版本更新时,GitOps工具会自动同步变更到目标Kubernetes集群,实现声明式、自动化的部署。
通过这套组合拳,你不仅拥有了一个运行在K8s上的、高可用的StackStorm,更拥有了一套现代化的、可重复的、安全的运维平台管理实践。这正是一个资深运维工程师在云原生时代,将经典工具与崭新平台深度融合的典型范例。