91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

企業(yè)級應(yīng)用模板化部署與Helm包管理實(shí)戰(zhàn)

馬哥Linux運(yùn)維 ? 來源:馬哥Linux運(yùn)維 ? 2026-03-17 14:32 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、概述

1.1 背景介紹

生產(chǎn)環(huán)境中一個微服務(wù)體系動輒幾十個 Deployment、Service、ConfigMap、Secret、Ingress,如果全部用裸 YAML 手工維護(hù),版本迭代時改錯一個 label selector 就能導(dǎo)致滾動更新斷流。Helm 作為 Kubernetes 的包管理器,把一組關(guān)聯(lián)資源打包成 Chart,通過模板變量實(shí)現(xiàn)環(huán)境差異化渲染,通過 Release 管理實(shí)現(xiàn)一鍵部署、升級、回滾。從 Helm v3 開始去掉了集群端的 Tiller 組件,直接使用 kubeconfig 鑒權(quán),安全模型大幅簡化。v3.17+ 進(jìn)一步將 OCI Registry 作為原生存儲后端,Chart 的分發(fā)方式與容器鏡像完全對齊。

本文面向一線運(yùn)維和 SRE,以排障手冊的形式覆蓋 Helm Chart 從設(shè)計(jì)、開發(fā)、測試到部署上線的全鏈路,重點(diǎn)放在企業(yè)級場景下的 Chart 模板化設(shè)計(jì)模式、多環(huán)境分層覆蓋策略、OCI Registry 集成、Helmfile 編排以及常見部署故障的根因定位。

1.2 核心語義

概念 語義 排障關(guān)聯(lián)
Chart 一組 Kubernetes 資源模板的打包單元 Chart 結(jié)構(gòu)錯誤直接導(dǎo)致 helm install 失敗
Release Chart 的一次安裝實(shí)例,帶版本歷史 Release 狀態(tài)異常是回滾和升級故障的入口
Values 模板渲染參數(shù),支持多層覆蓋 Values 層級錯誤導(dǎo)致渲染結(jié)果不符合預(yù)期
Repository / OCI Registry Chart 的存儲和分發(fā)通道 認(rèn)證、網(wǎng)絡(luò)問題導(dǎo)致 chart pull 失敗
Hook Release 生命周期中的自定義動作 Hook 執(zhí)行失敗會阻塞整個 install/upgrade 流程

1.3 適用場景

多環(huán)境(dev/staging/prod)同一套應(yīng)用需要差異化配置部署

微服務(wù)體系需要統(tǒng)一模板、批量發(fā)布、版本化管理

需要在 CI/CD 流水線中實(shí)現(xiàn)聲明式部署并支持自動回滾

跨團(tuán)隊(duì)共享基礎(chǔ)設(shè)施組件(中間件、監(jiān)控棧、日志采集器)的標(biāo)準(zhǔn)化交付

需要將內(nèi)部 Chart 推送到私有 OCI Registry 進(jìn)行版本管理

1.4 環(huán)境要求

組件 版本要求 說明
Kubernetes 1.32+ 目標(biāo)集群版本,需與 Chart apiVersion 兼容
Helm v3.17+ OCI registry 默認(rèn)支持,無需額外 feature gate
kubectl 匹配集群版本 helm 底層依賴 kubectl 的 kubeconfig
Docker Engine 27.x 用于構(gòu)建鏡像和本地 OCI registry 測試
Container Registry Harbor 2.x / ECR / ACR / GCR OCI 兼容的 Chart 存儲后端
Helmfile v0.169+ 多 Release 批量編排(可選)

1.5 排障坐標(biāo)系

Helm 部署故障的排查可以沿兩個軸展開:

時間軸(Release 生命周期):

helm install → pre-install hooks → 資源創(chuàng)建 → post-install hooks → Ready 檢查
helm upgrade → pre-upgrade hooks → 資源更新 → post-upgrade hooks → Ready 檢查
helm rollback → pre-rollback hooks → 資源回退 → post-rollback hooks
helm uninstall → pre-delete hooks → 資源刪除 → post-delete hooks

空間軸(問題域分層):

Layer 0: Chart 結(jié)構(gòu) / 語法錯誤   → helm lint / helm template 可發(fā)現(xiàn)
Layer 1: Values 渲染結(jié)果異常    → helm template + diff 可發(fā)現(xiàn)
Layer 2: Kubernetes API 拒絕    → kubectl apply --dry-run=server 級別
Layer 3: 資源運(yùn)行時異常      → Pod/Service/Ingress 層面的運(yùn)行時排查
Layer 4: Hook 執(zhí)行失敗       → Job/Pod 日志層面

二、詳細(xì)步驟

2.1 觀測面:Chart 結(jié)構(gòu)與 Release 狀態(tài)

2.1.1 Chart 目錄結(jié)構(gòu)

一個標(biāo)準(zhǔn)的 Helm Chart 目錄結(jié)構(gòu):

mychart/
├── Chart.yaml       # Chart 元數(shù)據(jù):名稱、版本、依賴
├── Chart.lock       # 依賴鎖定文件
├── values.yaml      # 默認(rèn)參數(shù)
├── values-dev.yaml    # 開發(fā)環(huán)境覆蓋(可選,推薦放 Chart 外部)
├── values-prod.yaml    # 生產(chǎn)環(huán)境覆蓋
├── charts/        # 子 Chart(依賴)
├── crds/         # CRD 定義(install 時自動應(yīng)用)
├── templates/       # 模板文件
│  ├── _helpers.tpl    # 命名模板(partial templates)
│  ├── deployment.yaml
│  ├── service.yaml
│  ├── ingress.yaml
│  ├── configmap.yaml
│  ├── secret.yaml
│  ├── hpa.yaml
│  ├── serviceaccount.yaml
│  ├── NOTES.txt     # install 后的提示信息
│  └── tests/
│    └──test-connection.yaml
└── .helmignore      # 打包時忽略的文件

2.1.2 Chart.yaml 詳解

apiVersion:v2         # Helm v3 固定為 v2
name:myapp
description:Aproduction-gradewebapplicationchart
type:application        # application 或 library
version:1.4.2         # Chart 版本,遵循 SemVer
appVersion:"3.8.1"       # 應(yīng)用程序版本,僅展示用途
kubeVersion:">=1.28.0-0"    # 兼容的 K8s 版本范圍
home:https://github.com/myorg/myapp
maintainers:
-name:sre-team
 email:sre@myorg.com
dependencies:
-name:postgresql
 version:"15.5.x"
 repository:"oci://registry.myorg.com/charts"
 condition:postgresql.enabled
 tags:
  -database
-name:redis
 version:"19.x.x"
 repository:"oci://registry.myorg.com/charts"
 condition:redis.enabled
 tags:
  -cache
-name:common
 version:"2.x.x"
 repository:"oci://registry.myorg.com/charts"
 tags:
  -infra

version和appVersion的區(qū)別經(jīng)常混淆:version是 Chart 自身的版本號,每次模板變更都應(yīng)遞增;appVersion是 Chart 部署的應(yīng)用版本,變更應(yīng)用鏡像 tag 時更新。CI/CD 中應(yīng)該自動同步這兩個版本號。

2.1.3 Release 狀態(tài)查看

# 列出所有 namespace 的 release
helm list -A

# 查看特定 release 的詳細(xì)信息
helm status myapp -n production

# 查看 release 歷史版本
helmhistorymyapp -n production

# 輸出示例
# REVISION  UPDATED           STATUS    CHART      APP VERSION  DESCRIPTION
# 1      2026-02-10 1000     superseded  myapp-1.2.0   3.6.0     Install complete
# 2      2026-02-15 1400     superseded  myapp-1.3.0   3.7.0     Upgrade complete
# 3      2026-03-01 0900     deployed   myapp-1.4.2   3.8.1     Upgrade complete

Release 的 STATUS 字段是排障第一入口:

STATUS 含義 下一步動作
deployed 當(dāng)前活躍版本 正常,無需處理
superseded 已被新版本取代 保留用于回滾參考
failed 安裝或升級失敗 查看 helm status 中的 NOTES 和 events
pending-install 安裝中 檢查 hook Job 是否卡住
pending-upgrade 升級中 檢查 hook Job 和資源創(chuàng)建狀態(tài)
pending-rollback 回滾中 檢查回滾目標(biāo)版本的資源兼容性
uninstalling 刪除中 檢查 finalizer 和 pre-delete hook

2.2 第一輪判斷:模板渲染與語法檢查

2.2.1 helm lint — 靜態(tài)檢查

# 基礎(chǔ) lint
helm lint ./mychart

# 帶 values 文件的 lint
helm lint ./mychart -f values-prod.yaml

# 嚴(yán)格模式
helm lint ./mychart --strict

# 輸出示例(有問題時)
# ==> Linting ./mychart
# [ERROR] Chart.yaml: version is required
# [WARNING] templates/deployment.yaml: object name does not conform to Kubernetes naming requirements
# [INFO] Chart.yaml: icon is recommended
#
# Error: 1 chart(s) linted, 1 chart(s) failed

helm lint能捕獲的問題:Chart.yaml 必填字段缺失、模板語法錯誤(括號未閉合、函數(shù)不存在)、資源名稱不符合 K8s 命名規(guī)范。它不能捕獲的問題:Values 值類型不匹配、運(yùn)行時資源沖突、鏡像不存在。

2.2.2 helm template — 本地渲染

# 完整渲染輸出
helm template myapp ./mychart -f values-prod.yaml -n production

# 只渲染特定模板
helm template myapp ./mychart -s templates/deployment.yaml -f values-prod.yaml

# 渲染并校驗(yàn) API 版本(連接集群)
helm template myapp ./mychart -f values-prod.yaml --validate

# 渲染結(jié)果重定向到文件,方便 diff
helm template myapp ./mychart -f values-dev.yaml > rendered-dev.yaml
helm template myapp ./mychart -f values-prod.yaml > rendered-prod.yaml
diff rendered-dev.yaml rendered-prod.yaml

helm template是排查 Values 渲染問題的核心工具。在 CI/CD 中,建議每次 merge request 都執(zhí)行helm template并與主分支的渲染結(jié)果做 diff,任何意外的資源變更都應(yīng)觸發(fā)人工審核。

2.2.3 helm diff 插件

# 安裝 diff 插件
helm plugin install https://github.com/databus23/helm-diff

# 查看升級將產(chǎn)生的差異(不實(shí)際執(zhí)行)
helm diff upgrade myapp ./mychart -f values-prod.yaml -n production

# 輸出示例
# production, myapp-deployment, Deployment (apps) has changed:
#  spec:
#   template:
#    spec:
#     containers:
#     - name: myapp
# -     image: registry.myorg.com/myapp:3.7.0
# +     image: registry.myorg.com/myapp:3.8.1
# -     resources:
# -      limits:
# -       memory: 512Mi
# +     resources:
# +      limits:
# +       memory: 1Gi

helm diff在執(zhí)行helm upgrade之前展示所有即將變更的資源,是生產(chǎn)環(huán)境變更審批的必備環(huán)節(jié)。

2.3 第二輪下鉆:Go 模板語法與 Values 設(shè)計(jì)

2.3.1 Go 模板語法核心

變量引用與內(nèi)置對象

# templates/deployment.yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:{{include"myapp.fullname".}}
labels:
 {{-include"myapp.labels".|nindent4}}
annotations:
 helm.sh/chart:{{include"myapp.chart".}}
 app.kubernetes.io/managed-by:{{.Release.Service}}
spec:
{{-ifnot.Values.autoscaling.enabled}}
replicas:{{.Values.replicaCount}}
{{-end}}
selector:
 matchLabels:
  {{-include"myapp.selectorLabels".|nindent6}}
template:
 metadata:
  annotations:
   checksum/config:{{include(print$.Template.BasePath"/configmap.yaml").|sha256sum}}
  labels:
   {{-include"myapp.selectorLabels".|nindent8}}
 spec:
  {{-with.Values.imagePullSecrets}}
  imagePullSecrets:
   {{-toYaml.|nindent8}}
  {{-end}}
  serviceAccountName:{{include"myapp.serviceAccountName".}}
  containers:
   -name:{{.Chart.Name}}
    image:"{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
    imagePullPolicy:{{.Values.image.pullPolicy}}
    ports:
     -name:http
      containerPort:{{.Values.service.port}}
      protocol:TCP
    {{-if.Values.probes.liveness.enabled}}
    livenessProbe:
     httpGet:
      path:{{.Values.probes.liveness.path}}
      port:http
     initialDelaySeconds:{{.Values.probes.liveness.initialDelaySeconds}}
     periodSeconds:{{.Values.probes.liveness.periodSeconds}}
     failureThreshold:{{.Values.probes.liveness.failureThreshold}}
    {{-end}}
    {{-if.Values.probes.readiness.enabled}}
    readinessProbe:
     httpGet:
      path:{{.Values.probes.readiness.path}}
      port:http
     initialDelaySeconds:{{.Values.probes.readiness.initialDelaySeconds}}
     periodSeconds:{{.Values.probes.readiness.periodSeconds}}
    {{-end}}
    resources:
     {{-toYaml.Values.resources|nindent12}}
    {{-if.Values.extraEnv}}
    env:
     {{-range.Values.extraEnv}}
     -name:{{.name}}
      value:{{.value|quote}}
     {{-end}}
    {{-end}}
    volumeMounts:
     -name:config
      mountPath:/etc/myapp
      readOnly:true
  volumes:
   -name:config
    configMap:
     name:{{include"myapp.fullname".}}-config
  {{-with.Values.nodeSelector}}
  nodeSelector:
   {{-toYaml.|nindent8}}
  {{-end}}
  {{-with.Values.tolerations}}
  tolerations:
   {{-toYaml.|nindent8}}
  {{-end}}
  {{-with.Values.affinity}}
  affinity:
   {{-toYaml.|nindent8}}
  {{-end}}

關(guān)鍵語法點(diǎn)

語法 作用 常見錯誤
{{ .Values.xxx }} 引用 values 值 路徑寫錯不報(bào)錯,渲染為空
{{- ... -}} 去除左/右空白 過度使用導(dǎo)致 YAML 縮進(jìn)錯誤
{{ include "tpl" . }} 調(diào)用命名模板 忘記傳遞.上下文
{{ toYaml . | nindent N }} 轉(zhuǎn) YAML 并縮進(jìn) N 格 nindent 值錯誤導(dǎo)致 YAML 解析失敗
{{ with .Values.xxx }} 條件塊并切換上下文 塊內(nèi)無法訪問.Release等頂級對象
{{ range .Values.list }} 遍歷列表 塊內(nèi).指向當(dāng)前元素,需$.Values訪問頂級
{{ default "val" .Values.xxx }} 默認(rèn)值 空字符串不觸發(fā) default
{{ required "msg" .Values.xxx }} 必填校驗(yàn) 僅在渲染時觸發(fā),lint 不檢查
{{ quote .Values.xxx }} 加引號 數(shù)字類型意外變字符串

2.3.2 _helpers.tpl 命名模板

# templates/_helpers.tpl

{{/*
Chart完整名稱,帶releasename前綴
*/}}
{{-define"myapp.fullname"-}}
{{-if.Values.fullnameOverride}}
{{-.Values.fullnameOverride|trunc63|trimSuffix"-"}}
{{-else}}
{{-$name:=default.Chart.Name.Values.nameOverride}}
{{-ifcontains$name.Release.Name}}
{{-.Release.Name|trunc63|trimSuffix"-"}}
{{-else}}
{{-printf"%s-%s".Release.Name$name|trunc63|trimSuffix"-"}}
{{-end}}
{{-end}}
{{-end}}

{{/*
Chart標(biāo)識
*/}}
{{-define"myapp.chart"-}}
{{-printf"%s-%s".Chart.Name.Chart.Version|replace"+""_"|trunc63|trimSuffix"-"}}
{{-end}}

{{/*
通用標(biāo)簽
*/}}
{{-define"myapp.labels"-}}
helm.sh/chart:{{include"myapp.chart".}}
{{include"myapp.selectorLabels".}}
{{-if.Chart.AppVersion}}
app.kubernetes.io/version:{{.Chart.AppVersion|quote}}
{{-end}}
app.kubernetes.io/managed-by:{{.Release.Service}}
{{-end}}

{{/*
Selector標(biāo)簽—不可變,用于Deploymentselector
*/}}
{{-define"myapp.selectorLabels"-}}
app.kubernetes.io/name:{{include"myapp.name".}}
app.kubernetes.io/instance:{{.Release.Name}}
{{-end}}

{{/*
ServiceAccount名稱
*/}}
{{-define"myapp.serviceAccountName"-}}
{{-if.Values.serviceAccount.create}}
{{-default(include"myapp.fullname".).Values.serviceAccount.name}}
{{-else}}
{{-default"default".Values.serviceAccount.name}}
{{-end}}
{{-end}}

{{/*
名稱截?cái)?*/}}
{{-define"myapp.name"-}}
{{-default.Chart.Name.Values.nameOverride|trunc63|trimSuffix"-"}}
{{-end}}

63 字符截?cái)嗍?Kubernetes 對 label value 的硬限制,在命名模板中必須始終保留這個約束。

2.3.3 Values 分層覆蓋設(shè)計(jì)

Helm Values 的合并順序(后者覆蓋前者):

Chart 內(nèi) values.yaml(默認(rèn)值)
↓ 被覆蓋
父 Chart 的 values.yaml(子 Chart 依賴場景)
↓ 被覆蓋
-f / --values 指定的文件(可多個,后指定的優(yōu)先)
↓ 被覆蓋
--set/ --set-string / --set-json(命令行直接設(shè)置)

values.yaml 設(shè)計(jì)原則

# values.yaml — 默認(rèn)值,適配 dev 環(huán)境
replicaCount:1

image:
repository:registry.myorg.com/myapp
pullPolicy:IfNotPresent
tag:""# 留空,默認(rèn)使用 Chart.AppVersion

imagePullSecrets:
-name:registry-credentials

serviceAccount:
create:true
name:""
annotations:{}

service:
type:ClusterIP
port:8080

ingress:
enabled:false
className:nginx
annotations:{}
hosts:
 -host:myapp.dev.myorg.com
  paths:
   -path:/
    pathType:Prefix
tls:[]

resources:
limits:
 cpu:500m
 memory:512Mi
requests:
 cpu:100m
 memory:128Mi

autoscaling:
enabled:false
minReplicas:2
maxReplicas:10
targetCPUUtilizationPercentage:70
targetMemoryUtilizationPercentage:80

probes:
liveness:
 enabled:true
 path:/healthz
 initialDelaySeconds:10
 periodSeconds:15
 failureThreshold:3
readiness:
 enabled:true
 path:/readyz
 initialDelaySeconds:5
 periodSeconds:10

extraEnv:[]

nodeSelector:{}
tolerations:[]
affinity:{}

# 子 Chart 開關(guān)
postgresql:
enabled:true
auth:
 database:myapp
 username:myapp
primary:
 persistence:
  size:10Gi

redis:
enabled:false

values-prod.yaml — 生產(chǎn)環(huán)境覆蓋

# values-prod.yaml
replicaCount:3

image:
tag:"3.8.1"

ingress:
enabled:true
className:nginx
annotations:
 cert-manager.io/cluster-issuer:letsencrypt-prod
 nginx.ingress.kubernetes.io/rate-limit:"100"
 nginx.ingress.kubernetes.io/ssl-redirect:"true"
hosts:
 -host:myapp.myorg.com
  paths:
   -path:/
    pathType:Prefix
tls:
 -secretName:myapp-tls
  hosts:
   -myapp.myorg.com

resources:
limits:
 cpu:"2"
 memory:2Gi
requests:
 cpu:500m
 memory:512Mi

autoscaling:
enabled:true
minReplicas:3
maxReplicas:20
targetCPUUtilizationPercentage:65

probes:
liveness:
 initialDelaySeconds:30
 failureThreshold:5

nodeSelector:
node-role:app

tolerations:
-key:dedicated
 operator:Equal
 value:app
 effect:NoSchedule

affinity:
podAntiAffinity:
 preferredDuringSchedulingIgnoredDuringExecution:
  -weight:100
   podAffinityTerm:
    labelSelector:
     matchExpressions:
      -key:app.kubernetes.io/name
       operator:In
       values:
        -myapp
    topologyKey:kubernetes.io/hostname

postgresql:
primary:
 persistence:
  size:100Gi
 resources:
  limits:
   cpu:"4"
   memory:8Gi
  requests:
   cpu:"1"
   memory:2Gi

敏感值處理

生產(chǎn)環(huán)境的 Secret 不應(yīng)寫在 values 文件中。推薦方案:

# 方案一:通過 --set 在 CI/CD 中注入
helm upgrade myapp ./mychart 
 -f values-prod.yaml 
 --setsecrets.dbPassword="${DB_PASSWORD}"
 --setsecrets.apiKey="${API_KEY}"
 -n production

# 方案二:External Secrets Operator(推薦)
# 在 Chart 模板中引用 ExternalSecret 資源,從 AWS Secrets Manager / Vault 同步
# templates/external-secret.yaml
{{-if.Values.externalSecrets.enabled}}
apiVersion:external-secrets.io/v1beta1
kind:ExternalSecret
metadata:
name:{{include"myapp.fullname".}}-secrets
labels:
 {{-include"myapp.labels".|nindent4}}
spec:
refreshInterval:1h
secretStoreRef:
 name:{{.Values.externalSecrets.storeRef}}
 kind:ClusterSecretStore
target:
 name:{{include"myapp.fullname".}}-secrets
data:
 {{-range.Values.externalSecrets.keys}}
 -secretKey:{{.secretKey}}
  remoteRef:
   key:{{.remoteKey}}
   property:{{.property}}
 {{-end}}
{{-end}}

2.4 根因矩陣:Helm 部署常見故障

故障現(xiàn)象 層級 可能原因 診斷命令 修復(fù)方向
helm install 報(bào) YAML 解析錯誤 L0 模板縮進(jìn)錯誤、nindent 值不對 helm template 查看渲染結(jié)果 修正模板縮進(jìn)
helm install 報(bào) "cannot re-use a name" L2 同名 Release 已存在(可能是 failed 狀態(tài)) helm list -A --all helm uninstall 舊 Release 或換名
upgrade 報(bào) "has no deployed releases" L2 首次 install 失敗,Release 停在 pending-install helm list --pending -A helm uninstall --no-hooks 清理后重新 install
upgrade 后 Pod 未更新 L1 image.tag 未變更,Deployment spec 無變化 helm diff upgrade 檢查差異 在 annotation 中加 checksum/config 觸發(fā)滾動
hook Job 卡在 Pending L4 資源配額不足、nodeSelector 不匹配 kubectl describe job 調(diào)整 Job 資源或調(diào)度約束
"lookup function not supported" L0 使用lookup函數(shù)但在helm template中運(yùn)行 改用helm install --dry-run lookup 只在連接集群時可用
"chart requires kubeVersion >=1.28" L0 集群版本低于 Chart 要求 kubectl version 升級集群或調(diào)整 Chart.yaml
OCI pull 401 Unauthorized L2 Registry 認(rèn)證失敗 helm registry login 測試 檢查憑證配置
values 中的 list 被 --set 覆蓋而非追加 L1 Helm --set 對 list 是替換行為 helm template 對比渲染結(jié)果 使用 --set-json 或 -f 文件
CRD 升級未生效 L0 Helm 不管理 CRD 的升級(只負(fù)責(zé)首次安裝) kubectl get crd -o yaml 手動 kubectl apply CRD

2.5 處理與驗(yàn)證

2.5.1 Release 部署操作

# 首次安裝
helm install myapp ./mychart 
 -f values-prod.yaml 
 -n production 
 --create-namespace 
 --wait
 --timeout 10m

# 升級(帶原子操作:失敗自動回滾)
helm upgrade myapp ./mychart 
 -f values-prod.yaml 
 -n production 
 --atomic 
 --timeout 10m

# 手動回滾到上一個版本
helm rollback myapp 0 -n production --wait

# 回滾到指定版本
helm rollback myapp 2 -n production --wait

# 卸載
helm uninstall myapp -n production --keep-history

關(guān)鍵參數(shù)說明:

--wait:等待所有 Pod 就緒后才標(biāo)記 Release 為 deployed,否則即使 Pod 還沒啟動完就返回成功

--atomic:如果升級失?。?-wait 超時、hook 失?。?,自動回滾到上一個成功版本

--timeout:與 --wait 配合,設(shè)置等待超時。默認(rèn) 5m,復(fù)雜應(yīng)用建議調(diào)到 10-15m

--keep-history:uninstall 時保留歷史,后續(xù)可以 rollback

2.5.2 部署后驗(yàn)證清單

# 1. 確認(rèn) Release 狀態(tài)
helm status myapp -n production

# 2. 確認(rèn)渲染結(jié)果符合預(yù)期
helm get values myapp -n production    # 查看當(dāng)前生效的 values
helm get manifest myapp -n production   # 查看當(dāng)前生效的完整 manifest

# 3. 確認(rèn) Pod 狀態(tài)
kubectl get pods -n production -l app.kubernetes.io/instance=myapp

# 4. 確認(rèn) Service 端點(diǎn)
kubectl get endpoints -n production -l app.kubernetes.io/instance=myapp

# 5. 確認(rèn) Ingress
kubectl get ingress -n production -l app.kubernetes.io/instance=myapp

# 6. 運(yùn)行 Chart 測試
helmtestmyapp -n production

2.5.3 Helm Hooks 詳解

# templates/hooks/db-migration.yaml
apiVersion:batch/v1
kind:Job
metadata:
name:{{include"myapp.fullname".}}-db-migrate
labels:
 {{-include"myapp.labels".|nindent4}}
annotations:
 "helm.sh/hook":pre-upgrade,pre-install
 "helm.sh/hook-weight":"-5"     # 權(quán)重越小越先執(zhí)行
 "helm.sh/hook-delete-policy":before-hook-creation,hook-succeeded
spec:
backoffLimit:3
activeDeadlineSeconds:600
template:
 metadata:
  labels:
   {{-include"myapp.selectorLabels".|nindent8}}
 spec:
  restartPolicy:Never
  containers:
   -name:migrate
    image:"{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
    command:["./migrate","--direction","up"]
    env:
     -name:DATABASE_URL
      valueFrom:
       secretKeyRef:
        name:{{include"myapp.fullname".}}-secrets
        key:database-url
  {{-with.Values.imagePullSecrets}}
  imagePullSecrets:
   {{-toYaml.|nindent8}}
  {{-end}}

Hook 類型與執(zhí)行時機(jī):

Hook 觸發(fā)時機(jī) 典型用途
pre-install install 前,資源創(chuàng)建前 數(shù)據(jù)庫初始化、前置檢查
post-install install 后,所有資源創(chuàng)建后 注冊服務(wù)、發(fā)送通知
pre-upgrade upgrade 前 數(shù)據(jù)庫遷移、數(shù)據(jù)備份
post-upgrade upgrade 后 緩存預(yù)熱、健康檢查
pre-rollback rollback 前 數(shù)據(jù)庫回退遷移
post-rollback rollback 后 狀態(tài)清理
pre-delete uninstall 前 資源清理、數(shù)據(jù)導(dǎo)出
post-delete uninstall 后 外部資源清理
test helm test 執(zhí)行時 連通性測試、功能驗(yàn)證

Hook 刪除策略:

策略 含義
before-hook-creation 執(zhí)行新 hook 前刪除舊的同名資源
hook-succeeded hook 成功后刪除
hook-failed hook 失敗后刪除

生產(chǎn)建議:始終設(shè)置before-hook-creation,否則第二次 upgrade 時會因?yàn)橥?Job 已存在而失敗。

三、示例代碼和配置

3.1 OCI Registry 操作

Helm v3.17+ 中 OCI 是默認(rèn)支持的 Chart 存儲格式,不再需要設(shè)置環(huán)境變量HELM_EXPERIMENTAL_OCI=1。

# 登錄 OCI Registry
helm registry login registry.myorg.com 
 --username admin 
 --password-stdin <<

3.2 完整 CI/CD 集成示例

# .gitlab-ci.yml — Helm Chart CI/CD 流水線
stages:
-lint
-package
-deploy-staging
-deploy-prod

variables:
CHART_DIR:"./charts/myapp"
REGISTRY:"registry.myorg.com"
CHART_REPO:"oci://${REGISTRY}/charts"

lint:
stage:lint
image:alpine/helm:3.17.0
script:
 -helmlint${CHART_DIR}--strict
 -helmtemplatetest-release${CHART_DIR}-f${CHART_DIR}/values.yaml>/dev/null
 -helmtemplatetest-release${CHART_DIR}-fvalues-staging.yaml>/dev/null
 -helmtemplatetest-release${CHART_DIR}-fvalues-prod.yaml>/dev/null
rules:
 -changes:
   -"charts/**/*"

package-and-push:
stage:package
image:alpine/helm:3.17.0
script:
 -helmdependencyupdate${CHART_DIR}
 -helmpackage${CHART_DIR}
 -helmregistrylogin${REGISTRY}--username${REGISTRY_USER}--password${REGISTRY_PASSWORD}
 -helmpushmyapp-*.tgz${CHART_REPO}
rules:
 -if:'$CI_COMMIT_BRANCH == "main"'
  changes:
   -"charts/**/*"

deploy-staging:
stage:deploy-staging
image:alpine/helm:3.17.0
script:
 -helmregistrylogin${REGISTRY}--username${REGISTRY_USER}--password${REGISTRY_PASSWORD}
 -helmdiffupgrademyapp${CHART_REPO}/myapp
   --version${CHART_VERSION}
   -fvalues-staging.yaml
   -nstaging||true
 -helmupgrade--installmyapp${CHART_REPO}/myapp
   --version${CHART_VERSION}
   -fvalues-staging.yaml
   -nstaging
   --create-namespace
   --atomic
   --timeout10m
 -helmtestmyapp-nstaging
environment:
 name:staging
rules:
 -if:'$CI_COMMIT_BRANCH == "main"'

deploy-prod:
stage:deploy-prod
image:alpine/helm:3.17.0
script:
 -helmregistrylogin${REGISTRY}--username${REGISTRY_USER}--password${REGISTRY_PASSWORD}
 -helmdiffupgrademyapp${CHART_REPO}/myapp
   --version${CHART_VERSION}
   -fvalues-prod.yaml
   -nproduction
 -helmupgrade--installmyapp${CHART_REPO}/myapp
   --version${CHART_VERSION}
   -fvalues-prod.yaml
   -nproduction
   --atomic
   --timeout15m
   --setsecrets.dbPassword="${DB_PASSWORD_PROD}"
 -helmtestmyapp-nproduction
environment:
 name:production
rules:
 -if:'$CI_COMMIT_BRANCH == "main"'
  when:manual

3.3 Helmfile 多環(huán)境批量編排

# helmfile.yaml
---
repositories:[]# OCI registry 不需要 repositories 聲明

environments:
dev:
 values:
  -environments/dev/defaults.yaml
staging:
 values:
  -environments/staging/defaults.yaml
production:
 values:
  -environments/production/defaults.yaml
 secrets:
  -environments/production/secrets.yaml# sops 加密

---

helmDefaults:
wait:true
timeout:600
atomic:true
createNamespace:true

releases:
-name:myapp
 namespace:{{.Environment.Name}}
 chart:oci://registry.myorg.com/charts/myapp
 version:1.4.2
 values:
  -values-{{.Environment.Name}}.yaml
  -image:
    tag:{{requiredEnv"APP_VERSION"}}
 hooks:
  -events:["presync"]
   showlogs:true
   command:"kubectl"
   args:
    -"get"
    -"ns"
    -"{{ .Environment.Name }}"

-name:postgresql
 namespace:{{.Environment.Name}}
 chart:oci://registry.myorg.com/charts/postgresql
 version:15.5.38
 condition:postgresql.enabled
 values:
  -postgresql-values-{{.Environment.Name}}.yaml

-name:redis
 namespace:{{.Environment.Name}}
 chart:oci://registry.myorg.com/charts/redis
 version:19.6.4
 condition:redis.enabled
 values:
  -redis-values-{{.Environment.Name}}.yaml

-name:prometheus-stack
 namespace:monitoring
 chart:oci://registry.myorg.com/charts/kube-prometheus-stack
 version:65.8.1
 values:
  -monitoring-values.yaml
# Helmfile 操作命令
# 查看 diff
helmfile -e production diff

# 部署到指定環(huán)境
helmfile -e production apply

# 只部署特定 release
helmfile -e production -l name=myapp apply

# 銷毀環(huán)境
helmfile -e staging destroy

3.4 Library Chart 設(shè)計(jì)

Library Chart 不直接生成 Kubernetes 資源,而是提供可復(fù)用的模板片段給其他 Chart 引用。

# common-library/Chart.yaml
apiVersion:v2
name:common-library
version:2.1.0
type:library # 關(guān)鍵:聲明為 library 類型
description:Commontemplatesforallapplicationcharts
# common-library/templates/_deployment.tpl
{{-define"common.deployment"-}}
apiVersion:apps/v1
kind:Deployment
metadata:
name:{{include"common.fullname".}}
labels:
 {{-include"common.labels".|nindent4}}
spec:
{{-ifnot.Values.autoscaling.enabled}}
replicas:{{.Values.replicaCount|default1}}
{{-end}}
strategy:
 type:RollingUpdate
 rollingUpdate:
  maxSurge:25%
  maxUnavailable:0
selector:
 matchLabels:
  {{-include"common.selectorLabels".|nindent6}}
template:
 metadata:
  annotations:
   {{-if.Values.configHash}}
   checksum/config:{{.Values.configHash}}
   {{-end}}
  labels:
   {{-include"common.selectorLabels".|nindent8}}
 spec:
  serviceAccountName:{{include"common.serviceAccountName".}}
  {{-with.Values.imagePullSecrets}}
  imagePullSecrets:
   {{-toYaml.|nindent8}}
  {{-end}}
  securityContext:
   runAsNonRoot:true
   seccompProfile:
    type:RuntimeDefault
  containers:
   -name:{{.Chart.Name}}
    image:"{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
    imagePullPolicy:{{.Values.image.pullPolicy|default"IfNotPresent"}}
    securityContext:
     allowPrivilegeEscalation:false
     capabilities:
      drop:
       -ALL
     readOnlyRootFilesystem:true
    {{-with.Values.ports}}
    ports:
     {{-toYaml.|nindent12}}
    {{-end}}
    {{-with.Values.resources}}
    resources:
     {{-toYaml.|nindent12}}
    {{-end}}
  {{-with.Values.nodeSelector}}
  nodeSelector:
   {{-toYaml.|nindent8}}
  {{-end}}
{{-end-}}

在應(yīng)用 Chart 中引用 Library Chart:

# myapp/Chart.yaml
dependencies:
-name:common-library
 version:"2.x.x"
 repository:"oci://registry.myorg.com/charts"
# myapp/templates/deployment.yaml
{{-include"common.deployment".}}

這樣組織內(nèi)所有微服務(wù) Chart 只需維護(hù) values 差異,Deployment 的基礎(chǔ)結(jié)構(gòu)由 Library Chart 統(tǒng)一管理。

3.5 Chart 測試模板

# templates/tests/test-connection.yaml
apiVersion:v1
kind:Pod
metadata:
name:"{{ include "myapp.fullname" . }}-test-connection"
labels:
 {{-include"myapp.labels".|nindent4}}
annotations:
 "helm.sh/hook":test
 "helm.sh/hook-delete-policy":before-hook-creation,hook-succeeded
spec:
restartPolicy:Never
containers:
 -name:wget
  image:busybox:1.37
  command:['wget']
  args:['{{include"myapp.fullname".}}:{{.Values.service.port}}/healthz','-q','-O-','-T','10']
 -name:curl-api
  image:curlimages/curl:8.10.1
  command:['curl']
  args:['-sf','--max-time','10','http://{{ include "myapp.fullname" . }}:{{ .Values.service.port }}/api/v1/status']
# 運(yùn)行測試
helmtestmyapp -n production --timeout 5m

# 查看測試 Pod 日志
kubectl logs myapp-test-connection -n production -c wget
kubectl logs myapp-test-connection -n production -c curl-api

3.6 自動化診斷腳本

#!/usr/bin/env bash
set-euo pipefail

# 文件名:helm-release-diagnose.sh
# 作用:對指定 Helm Release 進(jìn)行全面健康檢查,輸出診斷報(bào)告
# 適用場景:Release 部署后狀態(tài)異常、Pod 未就緒、Service 無端點(diǎn)時使用
# 使用方法:./helm-release-diagnose.sh  
# 輸入?yún)?shù):$1=Release名稱 $2=命名空間
# 輸出結(jié)果:終端輸出診斷報(bào)告,包含 Release 狀態(tài)、Pod 狀態(tài)、事件、日志摘要
# 風(fēng)險提示:只讀操作,不修改任何資源。需要 helm 和 kubectl 權(quán)限

RELEASE="${1:?Usage: $0  }"
NAMESPACE="${2:?Usage: $0  }"

echo"=========================================="
echo"Helm Release 診斷報(bào)告"
echo"Release:${RELEASE}"
echo"Namespace:${NAMESPACE}"
echo"Time:$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo"=========================================="

echo""
echo"--- 1. Release 狀態(tài) ---"
helm status"${RELEASE}"-n"${NAMESPACE}"2>&1 ||echo"ERROR: Release 不存在或無法訪問"

echo""
echo"--- 2. Release 歷史 ---"
helmhistory"${RELEASE}"-n"${NAMESPACE}"--max 5 2>&1 ||echo"ERROR: 無法獲取歷史"

echo""
echo"--- 3. 當(dāng)前生效 Values(非默認(rèn)值) ---"
helm get values"${RELEASE}"-n"${NAMESPACE}"2>&1 ||echo"ERROR: 無法獲取 values"

echo""
echo"--- 4. Release 關(guān)聯(lián)的 Pod ---"
PODS=$(kubectl get pods -n"${NAMESPACE}"-l"app.kubernetes.io/instance=${RELEASE}"-o wide 2>&1)
echo"${PODS}"

# 檢查是否有異常 Pod
echo""
echo"--- 5. 異常 Pod 詳情 ---"
ABNORMAL_PODS=$(kubectl get pods -n"${NAMESPACE}"-l"app.kubernetes.io/instance=${RELEASE}"
 --field-selector='status.phase!=Running,status.phase!=Succeeded'-o name 2>/dev/null ||true)

if[[ -z"${ABNORMAL_PODS}"]];then
 echo"所有 Pod 狀態(tài)正常"
else
 forpodin${ABNORMAL_PODS};do
   echo"---${pod}---"
    kubectl describe"${pod}"-n"${NAMESPACE}"| tail -30
   echo""
    kubectl logs"${pod}"-n"${NAMESPACE}"--tail=20 2>/dev/null ||echo"無法獲取日志"
   echo""
 done
fi

echo""
echo"--- 6. 近期事件(Warning) ---"
kubectl get events -n"${NAMESPACE}"
 --field-selector="type=Warning"
 --sort-by='.lastTimestamp'2>&1 | tail -20

echo""
echo"--- 7. Service 端點(diǎn) ---"
kubectl get endpoints -n"${NAMESPACE}"-l"app.kubernetes.io/instance=${RELEASE}"2>&1

echo""
echo"--- 8. Ingress 狀態(tài) ---"
kubectl get ingress -n"${NAMESPACE}"-l"app.kubernetes.io/instance=${RELEASE}"2>&1 ||echo"無 Ingress"

echo""
echo"=========================================="
echo"診斷完成"
echo"=========================================="
#!/usr/bin/env bash
set-euo pipefail

# 文件名:helm-chart-ci-validate.sh
# 作用:在 CI 流水線中對 Chart 執(zhí)行完整的靜態(tài)驗(yàn)證
# 適用場景:MR/PR 提交時自動觸發(fā),防止有語法錯誤或渲染異常的 Chart 合入主分支
# 使用方法:./helm-chart-ci-validate.sh  [values-file1] [values-file2] ...
# 輸入?yún)?shù):$1=Chart目錄 $2+=可選的 values 文件列表
# 輸出結(jié)果:通過則退出碼 0,失敗則退出碼 1 并輸出錯誤詳情
# 風(fēng)險提示:只讀操作。需要 helm 3.17+

CHART_DIR="${1:?Usage: $0  [values-files...]}"
shift
VALUES_FILES=("$@")

ERRORS=0

echo"=== Helm Chart CI Validation ==="
echo"Chart:${CHART_DIR}"
echo"Values files:${VALUES_FILES[*]:-none}"
echo""

# Step 1: lint
echo"--- Step 1: helm lint (strict) ---"
if! helm lint"${CHART_DIR}"--strict;then
 echo"FAIL: helm lint failed"
  ((ERRORS++))
fi

# Step 2: dependency check
echo""
echo"--- Step 2: dependency update ---"
if! helm dependency update"${CHART_DIR}";then
 echo"FAIL: dependency update failed"
  ((ERRORS++))
fi

# Step 3: template render with default values
echo""
echo"--- Step 3: template render (default values) ---"
if! helm template ci-test"${CHART_DIR}"> /dev/null;then
 echo"FAIL: template render with default values failed"
  ((ERRORS++))
fi

# Step 4: template render with each values file
forvfin"${VALUES_FILES[@]}";do
 echo""
 echo"--- Step 4: template render with${vf}---"
 if! helm template ci-test"${CHART_DIR}"-f"${vf}"> /dev/null;then
   echo"FAIL: template render with${vf}failed"
    ((ERRORS++))
 fi
done

# Step 5: check for deprecated API versions
echo""
echo"--- Step 5: deprecated API check ---"
RENDERED=$(helm template ci-test"${CHART_DIR}"2>/dev/null ||true)
DEPRECATED_APIS=("extensions/v1beta1""apps/v1beta1""apps/v1beta2""networking.k8s.io/v1beta1")
forapiin"${DEPRECATED_APIS[@]}";do
 ifecho"${RENDERED}"| grep -q"apiVersion:${api}";then
   echo"WARN: Deprecated API found:${api}"
 fi
done

echo""
if[[${ERRORS}-gt 0 ]];then
 echo"RESULT: FAILED (${ERRORS}errors)"
 exit1
else
 echo"RESULT: PASSED"
 exit0
fi
#!/usr/bin/env bash
set-euo pipefail

# 文件名:helm-bulk-upgrade.sh
# 作用:批量升級多個 Helm Release,支持 dry-run 和回滾
# 適用場景:基礎(chǔ)組件(如 common-library)升級后需要批量更新所有引用該 library 的應(yīng)用 Chart
# 使用方法:./helm-bulk-upgrade.sh --env production --chart-version 1.4.2 [--dry-run]
# 輸入?yún)?shù):--env=目標(biāo)環(huán)境 --chart-version=Chart版本 --dry-run=僅模擬不執(zhí)行
# 輸出結(jié)果:每個 Release 的升級結(jié)果日志
# 風(fēng)險提示:生產(chǎn)環(huán)境務(wù)必先 --dry-run。批量操作前確認(rèn)變更窗口。升級順序:基礎(chǔ)設(shè)施 → 中間件 → 應(yīng)用

ENV=""
CHART_VERSION=""
DRY_RUN=false

while[[$#-gt 0 ]];do
 case$1in
    --env) ENV="$2";shift2 ;;
    --chart-version) CHART_VERSION="$2";shift2 ;;
    --dry-run) DRY_RUN=true;shift;;
    *)echo"Unknown option:$1";exit1 ;;
 esac
done

[[ -z"${ENV}"]] && {echo"Error: --env is required";exit1; }
[[ -z"${CHART_VERSION}"]] && {echo"Error: --chart-version is required";exit1; }

REGISTRY="oci://registry.myorg.com/charts"
RELEASES=("myapp-api""myapp-web""myapp-worker""myapp-scheduler")
NAMESPACE="${ENV}"

echo"Bulk upgrade started"
echo"Environment:${ENV}"
echo"Chart version:${CHART_VERSION}"
echo"Dry run:${DRY_RUN}"
echo""

FAILED=()
SUCCEEDED=()

forreleasein"${RELEASES[@]}";do
 echo"--- Upgrading${release}---"
  VALUES_FILE="values/${release}-${ENV}.yaml"

 if[[ ! -f"${VALUES_FILE}"]];then
   echo"SKIP:${VALUES_FILE}not found"
   continue
 fi

  CMD="helm upgrade --install${release}${REGISTRY}/myapp 
    --version${CHART_VERSION}
    -f${VALUES_FILE}
    -n${NAMESPACE}
    --atomic 
    --timeout 10m"

 if[["${DRY_RUN}"=="true"]];then
    CMD="${CMD}--dry-run"
 fi

 ifeval"${CMD}";then
    SUCCEEDED+=("${release}")
   echo"OK:${release}upgraded successfully"
 else
    FAILED+=("${release}")
   echo"FAIL:${release}upgrade failed"
   if[["${DRY_RUN}"=="false"]];then
     echo"Note: --atomic flag should have triggered auto-rollback"
   fi
 fi
 echo""
done

echo"=========================================="
echo"Summary"
echo"Succeeded:${SUCCEEDED[*]:-none}"
echo"Failed:${FAILED[*]:-none}"
echo"=========================================="

[[${#FAILED[@]}-eq 0 ]] ||exit1
#!/usr/bin/env bash
set-euo pipefail

# 文件名:helm-values-diff.sh
# 作用:對比兩個環(huán)境的 values 渲染差異,輸出人類可讀的 diff 報(bào)告
# 適用場景:新環(huán)境上線前確認(rèn)與已有環(huán)境的配置差異,防止遺漏關(guān)鍵配置
# 使用方法:./helm-values-diff.sh   
# 輸入?yún)?shù):$1=Chart目錄 $2=環(huán)境A的values文件 $3=環(huán)境B的values文件
# 輸出結(jié)果:兩個環(huán)境渲染后的資源 diff(類似 kubectl diff 格式)
# 風(fēng)險提示:只讀操作。大型 Chart 渲染可能消耗較多內(nèi)存

CHART_DIR="${1:?Usage: $0   }"
VALUES_A="${2:?Usage: $0   }"
VALUES_B="${3:?Usage: $0   }"

TMPDIR=$(mktemp -d)
trap'rm -rf "${TMPDIR}"'EXIT

echo"Rendering${VALUES_A}..."
helm template compare"${CHART_DIR}"-f"${VALUES_A}">"${TMPDIR}/a.yaml"

echo"Rendering${VALUES_B}..."
helm template compare"${CHART_DIR}"-f"${VALUES_B}">"${TMPDIR}/b.yaml"

echo""
echo"=== Diff:${VALUES_A}vs${VALUES_B}==="
diff -u"${TMPDIR}/a.yaml""${TMPDIR}/b.yaml"
  --label"${VALUES_A}"
  --label"${VALUES_B}"||true
echo""
echo"=== End of diff ==="

四、實(shí)際應(yīng)用案例

4.1 案例一:helm upgrade 后 Pod 未滾動更新

現(xiàn)場現(xiàn)象:執(zhí)行helm upgrade myapp ./mychart -f values-prod.yaml -n production返回成功,但 Pod 仍在運(yùn)行舊版本鏡像。helm history顯示新 Revision 為 deployed 狀態(tài)。

第一輪判斷

# 查看當(dāng)前渲染的 manifest 中的鏡像
helm get manifest myapp -n production | grep"image:"
# 輸出:image: "registry.myorg.com/myapp:3.8.1" — 鏡像 tag 確實(shí)已更新

# 查看 Deployment 是否有變更
kubectl get deployment myapp -n production -o jsonpath='{.spec.template.spec.containers[0].image}'
# 輸出:registry.myorg.com/myapp:3.8.1 — Deployment spec 已更新

# 查看 Pod 的鏡像
kubectl get pods -n production -l app.kubernetes.io/instance=myapp -o jsonpath='{.items[*].spec.containers[0].image}'
# 輸出:registry.myorg.com/myapp:3.7.0 registry.myorg.com/myapp:3.7.0 — Pod 仍是舊版本

第二輪下鉆

# 查看 Deployment 的 rollout 狀態(tài)
kubectl rollout status deployment/myapp -n production
# 輸出:Waiting for deployment "myapp" rollout to finish: 0 of 3 updated replicas are available...

# 查看 ReplicaSet
kubectl get rs -n production -l app.kubernetes.io/instance=myapp
# NAME        DESIRED  CURRENT  READY  AGE
# myapp-6d4f8b7c9   3     3     3    10d   ← 舊 RS
# myapp-7a5e9c3d1   3     3     0    2m   ← 新 RS,Pod 未 Ready

# 查看新 RS 的 Pod 為什么未 Ready
kubectl describe pod myapp-7a5e9c3d1-xxxxx -n production
# Events:
#  Warning Failed 2m kubelet Failed to pull image "registry.myorg.com/myapp:3.8.1":
#      rpc error: code = NotFound desc = failed to pull and unpack image: not found

關(guān)鍵證據(jù):鏡像3.8.1在 Registry 中不存在。CI/CD 流水線在鏡像構(gòu)建完成前就觸發(fā)了 Helm upgrade。

根因:流水線中 build 和 deploy stage 的依賴關(guān)系配置錯誤,deploy 未等待 build 完成。

修復(fù)動作

先推送正確的鏡像到 Registry

新 Pod 會自動拉取成功并變?yōu)?Ready

修復(fù) CI/CD 流水線中 stage 之間的依賴關(guān)系

修復(fù)后驗(yàn)證

kubectl rollout status deployment/myapp -n production --timeout=5m
# deployment "myapp" successfully rolled out

kubectl get pods -n production -l app.kubernetes.io/instance=myapp -o jsonpath='{.items[*].spec.containers[0].image}'
# registry.myorg.com/myapp:3.8.1 registry.myorg.com/myapp:3.8.1 registry.myorg.com/myapp:3.8.1

防再發(fā)建議

CI/CD 中在 deploy 之前加鏡像存在性檢查:docker manifest inspect registry.myorg.com/myapp:3.8.1

Helm upgrade 使用--atomic,鏡像拉取失敗會自動回滾

4.2 案例二:pre-upgrade Hook Job 卡住導(dǎo)致 upgrade 超時

現(xiàn)場現(xiàn)象:helm upgrade myapp ./mychart -f values-prod.yaml -n production --timeout 10m --atomic執(zhí)行 10 分鐘后超時,Release 狀態(tài)變?yōu)閒ailed,然后自動回滾。但數(shù)據(jù)庫遷移 Job 一直卡在 Pending。

第一輪判斷

helmhistorymyapp -n production
# REVISION STATUS   DESCRIPTION
# 5     deployed  Upgrade complete
# 6     failed   pre-upgrade hook "myapp-db-migrate" timed out

kubectl getjobs-n production | grep migrate
# myapp-db-migrate  0/1  10m  10m

第二輪下鉆

kubectl describe job myapp-db-migrate -n production
# Events:
#  Warning FailedCreate 10m job-controller Error creating: pods "myapp-db-migrate-xxxxx"
#      is forbidden: exceeded quota: compute-quota, requested: cpu=2, used: cpu=14, limited: cpu=16

kubectl get resourcequota -n production
# NAME       AGE  REQUEST            LIMIT
# compute-quota  30d  requests.cpu: 14/16, ...   limits.cpu: 28/32, ...

關(guān)鍵證據(jù):數(shù)據(jù)庫遷移 Job 請求 2 CPU,但命名空間的 ResourceQuota 已經(jīng)用了 14/16,剩余 2 CPU 正好不夠(因?yàn)檫€有其他 Pending Pod 占用請求)。

根因:遷移 Job 的資源請求過高,且在 upgrade 期間新舊 Pod 同時存在導(dǎo)致 CPU 請求總量超限。

修復(fù)動作

# 降低遷移 Job 的資源請求
# templates/hooks/db-migration.yaml
spec:
template:
 spec:
  containers:
   -name:migrate
    resources:
     requests:
      cpu:200m  # 從 2 降到 200m
      memory:256Mi
     limits:
      cpu:"1"
      memory:512Mi

或者調(diào)整升級策略,確保新舊 Pod 不會同時大量并存:

# Deployment 使用 Recreate 策略或更保守的 RollingUpdate
spec:
strategy:
 type:RollingUpdate
 rollingUpdate:
  maxSurge:0    # 不額外創(chuàng)建新 Pod
  maxUnavailable:1 # 一次只替換一個

修復(fù)后驗(yàn)證

helm upgrade myapp ./mychart -f values-prod.yaml -n production --atomic --timeout 10m
# Release "myapp" has been upgraded. Happy Helming!

kubectl getjobs-n production | grep migrate
# myapp-db-migrate  1/1  45s  1m

防再發(fā)建議

Hook Job 的資源請求應(yīng)與 ResourceQuota 預(yù)留空間匹配

在 CI 中加入 ResourceQuota 余量檢查

考慮將數(shù)據(jù)庫遷移從 Helm Hook 移到獨(dú)立的 Job,在 upgrade 之前手動執(zhí)行

4.3 案例三:Helmfile 多 Release 部署順序?qū)е乱蕾囄淳途w

現(xiàn)場現(xiàn)象:使用 Helmfile 部署三個組件(postgresql、redis、myapp),myapp 部署后 Pod 反復(fù) CrashLoopBackOff,日志顯示 "connection refused" 無法連接 PostgreSQL。

第一輪判斷

helmfile -e production status
# NAME     NAMESPACE  REVISION STATUS
# postgresql  production  1     deployed
# redis    production  1     deployed
# myapp    production  1     deployed

kubectl get pods -n production
# postgresql-0    1/1  Running      0  2m
# redis-master-0   1/1  Running      0  2m
# myapp-xxx      0/1  CrashLoopBackOff  3  2m

kubectl logs myapp-xxx -n production
# level=fatal msg="failed to connect to database" error="dial tcp 10.96.45.123 connection refused"

第二輪下鉆

# PostgreSQL Pod 雖然 Running,但實(shí)際還在初始化
kubectl logs postgresql-0 -n production | tail -5
# 2026-03-01 0930 UTC [1] LOG: database system is ready to accept connections
# 上面這行出現(xiàn)在 myapp 啟動之后

# 查看時間線
kubectl get events -n production --sort-by='.firstTimestamp'| grep -E"(postgresql|myapp)"
# 0900 postgresql-0 Created
# 0905 myapp-xxx Created      ← myapp 在 postgresql 初始化完成前就啟動了
# 0920 myapp-xxx BackOff
# 0930 postgresql-0 Ready

關(guān)鍵證據(jù):Helmfile 默認(rèn)并發(fā)安裝所有 Release,myapp 在 PostgreSQL 完成初始化之前就開始連接數(shù)據(jù)庫。

根因:Helmfile 缺少 Release 之間的依賴和順序聲明。

修復(fù)動作

# helmfile.yaml — 添加 needs 聲明
releases:
-name:postgresql
 namespace:production
 chart:oci://registry.myorg.com/charts/postgresql
 version:15.5.38
 values:
  -postgresql-values-production.yaml

-name:redis
 namespace:production
 chart:oci://registry.myorg.com/charts/redis
 version:19.6.4
 values:
  -redis-values-production.yaml

-name:myapp
 namespace:production
 chart:oci://registry.myorg.com/charts/myapp
 version:1.4.2
 needs:           # 聲明依賴
  -production/postgresql
  -production/redis
 values:
  -values-production.yaml

同時在 myapp 的 Chart 中增加 initContainer 做連接等待:

# values-production.yaml
initContainers:
-name:wait-for-db
 image:busybox:1.37
 command:['sh','-c','until nc -z postgresql 5432; do echo waiting for db; sleep 2; done']

修復(fù)后驗(yàn)證

helmfile -e production apply
# postgresql deployed first, then redis, then myapp

kubectl get pods -n production
# postgresql-0  1/1  Running  0  3m
# redis-master-0 1/1  Running  0  2m
# myapp-xxx   1/1  Running  0  1m

防再發(fā)建議

始終在 Helmfile 中用needs聲明 Release 之間的啟動依賴

應(yīng)用端使用 initContainer 或連接重試機(jī)制,不依賴部署順序保證可用性

設(shè)置合理的 readinessProbe,讓 K8s 在應(yīng)用真正就緒后才接入流量

4.4 案例四:OCI Registry 推送 Chart 時 401 Unauthorized

現(xiàn)場現(xiàn)象:CI/CD 流水線中執(zhí)行helm push myapp-1.4.2.tgz oci://registry.myorg.com/charts報(bào)錯Error: unexpected status from HEAD request to https://registry.myorg.com/v2/charts/myapp/blobs/sha256 401 Unauthorized。

第一輪判斷

# 測試 registry 登錄
helm registry login registry.myorg.com --username ci-bot --password"${REGISTRY_PASSWORD}"
# Login Succeeded — 登錄沒問題

# 手動推送
helm push myapp-1.4.2.tgz oci://registry.myorg.com/charts
# Error: unexpected status from HEAD request... 401 Unauthorized

第二輪下鉆

# 檢查 OCI 兼容性
curl -u"ci-bot:${REGISTRY_PASSWORD}"https://registry.myorg.com/v2/
# {"errors":[{"code":"UNAUTHORIZED","message":"authentication required"}]}

# 檢查是否需要 Bearer token
curl -v https://registry.myorg.com/v2/ 2>&1 | grep -i www-authenticate
# Www-Authenticate: Bearer realm="https://auth.myorg.com/service/token",service="registry.myorg.com"

# 檢查 helm 的認(rèn)證配置
cat ~/.config/helm/registry/config.json
# 發(fā)現(xiàn) auth 字段存在但對應(yīng)的 credsStore 配置指向了 docker-credential-desktop

關(guān)鍵證據(jù):Helm 的 registry 認(rèn)證走的是 Docker credential store,在 CI 環(huán)境中docker-credential-desktop不存在,導(dǎo)致雖然helm registry login顯示成功(寫入了 config.json),但實(shí)際推送時 credential helper 找不到憑證。

根因:CI 環(huán)境缺少 Docker credential helper,Helm 的 registry 認(rèn)證依賴 Docker 的憑證存儲體系。

修復(fù)動作

# 方案一:在 CI 中禁用 credential helper,使用純文件認(rèn)證
exportDOCKER_CONFIG="${HOME}/.docker-helm"
mkdir -p"${DOCKER_CONFIG}"

# 直接寫入認(rèn)證信息
echo'{"auths":{"registry.myorg.com":{"auth":"'$(echo-n"ci-bot:${REGISTRY_PASSWORD}"| base64)'"}}}'
 >"${DOCKER_CONFIG}/config.json"

# 重新執(zhí)行 helm push
helm push myapp-1.4.2.tgz oci://registry.myorg.com/charts
# Pushed: registry.myorg.com/charts/myapp:1.4.2
# 方案二:使用 HELM_REGISTRY_CONFIG 環(huán)境變量
exportHELM_REGISTRY_CONFIG="/tmp/helm-registry-config.json"
helm registry login registry.myorg.com --username ci-bot --password"${REGISTRY_PASSWORD}"
helm push myapp-1.4.2.tgz oci://registry.myorg.com/charts

修復(fù)后驗(yàn)證

# 確認(rèn)推送成功
helm pull oci://registry.myorg.com/charts/myapp --version 1.4.2
# Pulled: registry.myorg.com/charts/myapp:1.4.2

helm show chart oci://registry.myorg.com/charts/myapp --version 1.4.2
# apiVersion: v2
# name: myapp
# version: 1.4.2

防再發(fā)建議

CI 環(huán)境中統(tǒng)一使用HELM_REGISTRY_CONFIG或DOCKER_CONFIG環(huán)境變量指定認(rèn)證配置文件

不依賴系統(tǒng)級的 credential helper

在流水線開始時加helm registry login的連通性驗(yàn)證步驟

五、最佳實(shí)踐和注意事項(xiàng)

5.1 Chart 設(shè)計(jì)最佳實(shí)踐

5.1.1 版本管理

Chart version 遵循 SemVer:Breaking change 升主版本,新功能升次版本,Bug 修復(fù)升補(bǔ)丁版本

appVersion 與應(yīng)用鏡像 tag 保持同步

使用 Git tag 觸發(fā) Chart 打包和推送

Chart.lock 提交到版本庫,保證依賴版本可復(fù)現(xiàn)

5.1.2 Values 設(shè)計(jì)規(guī)范

所有可配置項(xiàng)都應(yīng)有默認(rèn)值,helm install裸裝必須能跑起來(至少在 dev 環(huán)境)

使用required函數(shù)標(biāo)記生產(chǎn)環(huán)境必填項(xiàng)

敏感值不寫入 values 文件,使用 External Secrets Operator 或 --set 注入

布爾開關(guān)命名統(tǒng)一:xxx.enabled

資源配置使用嵌套結(jié)構(gòu):resources.requests.cpu,不要拍平成requestsCpu

# values.yaml 中用 required 標(biāo)記必填項(xiàng)的模板用法
# templates/deployment.yaml
env:
-name:DATABASE_URL
 value:{{required"database.url is required for production".Values.database.url}}

5.1.3 模板組織

公共邏輯提取到_helpers.tpl

每個 Kubernetes 資源一個模板文件,命名與資源類型對應(yīng)

復(fù)雜的條件渲染用命名模板封裝,而不是在資源模板中嵌套大量 if-else

使用{{- include ... | nindent N }}而非{{ template ... }}(template 不能管道傳遞)

5.1.4 Umbrella Chart 架構(gòu)

platform-chart/
├── Chart.yaml     # type: application
├── values.yaml    # 全局默認(rèn)值
├── charts/
│  ├── api/      # 子 Chart: API 服務(wù)
│  ├── web/      # 子 Chart: Web 前端
│  ├── worker/    # 子 Chart: 后臺任務(wù)
│  └── common/    # Library Chart
└── templates/
  ├── _helpers.tpl
  └── shared-configmap.yaml # 跨子 Chart 共享的資源

Umbrella Chart 的 values.yaml 中通過子 Chart 名稱作為 key 傳遞參數(shù):

# platform-chart/values.yaml
global:
imageRegistry:registry.myorg.com
environment:production

api:
replicaCount:3
image:
 repository:registry.myorg.com/myapp-api
 tag:"2.1.0"

web:
replicaCount:2
image:
 repository:registry.myorg.com/myapp-web
 tag:"1.8.0"

worker:
replicaCount:5
image:
 repository:registry.myorg.com/myapp-worker
 tag:"2.1.0"

5.2 安全加固

5.2.1 RBAC 最小權(quán)限

# 為 Helm 操作創(chuàng)建專用 ServiceAccount(CI/CD 場景)
apiVersion:v1
kind:ServiceAccount
metadata:
name:helm-deployer
namespace:kube-system
---
apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRole
metadata:
name:helm-deployer
rules:
-apiGroups:["","apps","batch","networking.k8s.io","autoscaling"]
 resources:["*"]
 verbs:["get","list","watch","create","update","patch","delete"]
-apiGroups:[""]
 resources:["secrets"]
 verbs:["get","list","watch","create","update","patch","delete"]
 # Helm 存儲 Release 信息到 Secret
---
apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRoleBinding
metadata:
name:helm-deployer
roleRef:
apiGroup:rbac.authorization.k8s.io
kind:ClusterRole
name:helm-deployer
subjects:
-kind:ServiceAccount
 name:helm-deployer
 namespace:kube-system

5.2.2 Chart 安全掃描

# 使用 kubeaudit 掃描渲染后的 manifest
helm template myapp ./mychart -f values-prod.yaml | kubeaudit all -f -

# 使用 checkov 做合規(guī)掃描
helm template myapp ./mychart -f values-prod.yaml > rendered.yaml
checkov -f rendered.yaml --framework kubernetes

# 使用 trivy 掃描 Chart 中的配置問題
trivy config ./mychart

5.3 注意事項(xiàng)

5.3.1 CRD 管理陷阱

Helm 對 CRD 的處理有特殊限制:

CRD 放在crds/目錄下,僅在首次helm install時安裝

helm upgrade不會更新 CRD

helm uninstall不會刪除 CRD

因此 CRD 的生命周期管理需要額外處理:

# 手動更新 CRD
kubectl apply -f mychart/crds/

# 或者將 CRD 從 crds/ 移到 templates/ 中,但需要加注解防止意外刪除
# templates/crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
 name: myresources.myorg.com
 annotations:
 "helm.sh/resource-policy": keep  # uninstall 時保留

5.3.2 常見配置錯誤

錯誤模式 表現(xiàn) 修正方法
nindent 值錯誤 YAML 渲染后縮進(jìn)不對,K8s API 拒絕 用helm template檢查輸出格式
with 塊內(nèi)訪問頂級對象 {{ .Values.xxx }} 變成空 使用{{ $.Values.xxx }}
range 塊內(nèi)的. . 指向當(dāng)前迭代元素而非根 使用$引用根上下文
數(shù)字值未加 quote YAML 解析為科學(xué)計(jì)數(shù)法 用{{ .Values.xxx | quote }}
list 值用 --set 覆蓋 整個 list 被替換而非追加 使用--set-json或 -f 文件
Release 歷史膨脹 etcd 存儲壓力增大 設(shè)置--history-max 10

5.3.3 Release 存儲與 etcd 壓力

Helm v3 將 Release 信息存儲在 Kubernetes Secret 中(Base64 編碼 + gzip 壓縮)。每次 upgrade/rollback 都會創(chuàng)建新的 Secret。對于頻繁發(fā)布的應(yīng)用,需要限制歷史版本數(shù):

# 全局設(shè)置最大歷史版本
helm upgrade myapp ./mychart 
 -f values-prod.yaml 
 -n production 
 --history-max 10

# 清理舊 Release Secret
kubectl get secrets -n production -l owner=helm -l name=myapp --sort-by=.metadata.creationTimestamp

六、故障排查和監(jiān)控

6.1 故障排查決策樹

helm install/upgrade 失敗
├── 報(bào)錯"YAML parse error"/"template render error"
│  ├── 檢查 helm template 輸出
│  ├── 定位到具體模板文件和行號
│  └── 常見:nindent 錯誤、括號未閉合、函數(shù)名拼寫
├── 報(bào)錯"cannot re-use a name"/"has no deployed releases"
│  ├── helm list --all -n  查看現(xiàn)有 Release
│  ├── 如果是 failed 狀態(tài):helm uninstall --no-hooks
│  └── 如果是 pending-* 狀態(tài):等待或強(qiáng)制清理
├── 報(bào)錯"timed out waiting for the condition"
│  ├── 檢查 Pod 狀態(tài):kubectl get pods
│  ├── Hook Job 卡?。簁ubectl describe job
│  ├── Pod 未 Ready:kubectl describe pod / kubectl logs
│  └── 資源配額不足:kubectl get resourcequota
├── 報(bào)錯"admission webhook denied"
│  ├── 檢查 ValidatingWebhookConfiguration
│  ├── 查看 webhook 服務(wù)是否可用
│  └── 臨時繞過:刪除 webhook 或加 exclude annotation
├── 部署成功但功能異常
│  ├── helm get values 確認(rèn) values 生效
│  ├── helm get manifest 確認(rèn)渲染結(jié)果
│  ├── kubectl describe / logs 查看運(yùn)行時狀態(tài)
│  └── Service/Endpoints/Ingress 鏈路檢查
└── OCI Registry 相關(guān)
  ├── 401 Unauthorized:檢查 helm registry login
  ├── not found:確認(rèn) Chart 名稱和版本號
  └── timeout:檢查網(wǎng)絡(luò)和 DNS

6.2 Helm 操作監(jiān)控

6.2.1 Release 狀態(tài)監(jiān)控

# Prometheus 告警規(guī)則:檢測 Helm Release 異常狀態(tài)
# 需要 helm-exporter(https://github.com/sstarber/helm-exporter)
groups:
-name:helm-release-alerts
 rules:
  -alert:HelmReleaseFailed
   expr:helm_chart_info{status="failed"}==1
   for:5m
   labels:
    severity:critical
   annotations:
    summary:"Helm Release{{ $labels.release }}處于 failed 狀態(tài)"
    description:"Release{{ $labels.release }}in namespace{{ $labels.namespace }}has been in failed state for 5 minutes. Chart:{{ $labels.chart }}"

  -alert:HelmReleasePending
   expr:helm_chart_info{status=~"pending-.*"}==1
   for:15m
   labels:
    severity:warning
   annotations:
    summary:"Helm Release{{ $labels.release }}處于 pending 狀態(tài)"
    description:"Release{{ $labels.release }}in namespace{{ $labels.namespace }}has been pending for 15 minutes."

6.2.2 CI/CD 部署指標(biāo)

在 CI/CD 流水線中記錄 Helm 部署的關(guān)鍵指標(biāo):

# 部署耗時統(tǒng)計(jì)
START_TIME=$(date +%s)
helm upgrade --install myapp ./mychart -f values-prod.yaml -n production --atomic --timeout 10m
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))

# 推送指標(biāo)到 Prometheus Pushgateway
cat <

6.3 日志排查路徑

# Helm 自身調(diào)試日志
helm upgrade myapp ./mychart -f values-prod.yaml -n production --debug 2>&1 | tee helm-debug.log

# 從 debug 日志中提取關(guān)鍵信息
grep -E"(error|Error|FAIL|WARNING)"helm-debug.log

# 查看 Helm 發(fā)送給 K8s API 的請求
helm upgrade myapp ./mychart -f values-prod.yaml -n production --debug --dry-run 2>&1 | head -100

6.4 常見問題速查

問題 快速診斷 快速修復(fù)
"release: already exists" helm list --all -n helm uninstall -n
"UPGRADE FAILED: has no deployed releases" helm list --pending -A helm uninstall --no-hooks -n 后重新 install
Secret 超過 1MB(etcd 限制) helm get manifest | wc -c 拆分 Chart 或減少嵌入數(shù)據(jù)
lookup 在 CI 中失敗 helm template 模式不支持 lookup 改用--dry-run=server或移除 lookup
子 Chart values 未生效 helm get values 檢查層級 確認(rèn) values 中用子 Chart 名稱作為 key

七、總結(jié)

7.1 技術(shù)要點(diǎn)回顧

Helm v3.17+ 去除 Tiller,直接使用 kubeconfig 鑒權(quán),OCI Registry 作為原生 Chart 存儲后端

Chart 結(jié)構(gòu)的核心三要素:Chart.yaml(元數(shù)據(jù))、values.yaml(參數(shù)化)、templates/(模板渲染)

Go 模板語法中最常見的坑:with塊上下文切換、range塊中.的含義變化、nindent縮進(jìn)值

Values 分層覆蓋遵循「默認(rèn)值 → 父 Chart → -f 文件 → --set」的優(yōu)先級鏈

Hook 的before-hook-creation刪除策略是防止 Job 沖突的關(guān)鍵配置

--atomic參數(shù)保證升級失敗時自動回滾,是生產(chǎn)環(huán)境部署的必選項(xiàng)

Library Chart + Umbrella Chart 是企業(yè)級多微服務(wù) Chart 管理的標(biāo)準(zhǔn)架構(gòu)模式

Release 歷史存儲在 etcd 中,必須通過--history-max限制版本數(shù)量

7.2 排障鏈路總結(jié)

完整的 Helm 部署排障鏈路:

helm lint → helm template → helm diff → helm upgrade --dry-run
→ helm upgrade(實(shí)際執(zhí)行)
→ 失敗時:helm status → helmhistory→ kubectl describe/logs
→ 定位到具體層級(Chart 語法 / Values 渲染 / K8s API / 運(yùn)行時 / Hook)
→ 修復(fù)后:helm upgrade --atomic → helmtest→ 驗(yàn)證

7.3 進(jìn)階學(xué)習(xí)方向

Helm SDK 集成:在 Go 程序中直接調(diào)用 Helm SDK 實(shí)現(xiàn)自定義部署控制器

Chart Testing(ct)工具:在 CI 中自動檢測 Chart 變更并運(yùn)行集成測試

ArgoCD + Helm:GitOps 模式下的 Helm Chart 自動同步和漂移檢測

Sigstore 簽名驗(yàn)證:對 Chart 進(jìn)行數(shù)字簽名,在部署前驗(yàn)證完整性

7.3 參考資料

Helm 官方文檔— Chart 開發(fā)、最佳實(shí)踐、命令參考

Helm GitHub— 源碼、Issue 跟蹤

Artifact Hub— 公共 Chart 搜索

Helmfile 文檔— 多 Release 編排

附錄

A. Helm 命令速查表

# Chart 開發(fā)
helm create mychart             # 創(chuàng)建 Chart 腳手架
helm lint ./mychart --strict         # 靜態(tài)檢查
helm template myapp ./mychart -f values.yaml # 本地渲染
helm package ./mychart            # 打包為 .tgz
helm dependency update ./mychart       # 更新依賴
helm dependency list ./mychart        # 查看依賴狀態(tài)
helm show chart ./mychart          # 查看 Chart.yaml
helm show values ./mychart          # 查看默認(rèn) values

# OCI Registry
helm registry login         # 登錄
helm push  oci:///# 推送
helm pull oci:/// --version X # 拉取
helm show chart oci:///    # 查看遠(yuǎn)程 Chart

# Release 管理
helm install   -f  -n       # 安裝
helm upgrade --install   -f  -n  # 升級(不存在則安裝)
helm rollback   -n           # 回滾
helm uninstall  -n                # 卸載
helm list -A                        # 列出所有 Release
helm status  -n                  # 查看狀態(tài)
helmhistory -n                 # 查看歷史

# 調(diào)試
helm upgrade   --dry-run --debug       # 模擬升級
helm get values  -n                # 查看當(dāng)前 values
helm get manifest  -n               # 查看當(dāng)前 manifest
helm get hooks  -n                # 查看 hooks
helmtest -n                   # 運(yùn)行測試

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 容器
    +關(guān)注

    關(guān)注

    0

    文章

    533

    瀏覽量

    22981
  • kubernetes
    +關(guān)注

    關(guān)注

    0

    文章

    266

    瀏覽量

    9500

原文標(biāo)題:Helm包管理實(shí)戰(zhàn):企業(yè)級應(yīng)用模板化部署

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    Kubernetes Helm入門指南

    Helm 是 Kubernetes 的包管理工具,它允許開發(fā)者和系統(tǒng)管理員通過定義、打包和部署應(yīng)用程序來簡化 Kubernetes 應(yīng)用的管理
    的頭像 發(fā)表于 04-30 13:42 ?3118次閱讀
    Kubernetes <b class='flag-5'>Helm</b>入門指南

    2017年企業(yè)級SaaS服務(wù)發(fā)展趨勢?

    域創(chuàng)業(yè)項(xiàng)目數(shù)量有近400家,涉及20余個領(lǐng)域,包括CRM、ERP、HR、OA、企業(yè)報(bào)銷、企業(yè)商旅、及協(xié)同辦公、收銀支付、考勤管理等。 在經(jīng)過兩三年的市場洗禮后,2017企業(yè)級服務(wù)的市場
    發(fā)表于 07-17 10:22

    使用Helm 在容器服務(wù)k8s集群一鍵部署wordpress

    摘要: Helm 是啥? 微服務(wù)和容器給復(fù)雜應(yīng)用部署管理帶來了極大的挑戰(zhàn)。Helm是目前Kubernetes服務(wù)編排領(lǐng)域的唯一開源子項(xiàng)目
    發(fā)表于 03-29 13:38

    企業(yè)級的LInux系統(tǒng)日志管理

    企業(yè)級LInux系統(tǒng)日志管理
    發(fā)表于 05-29 11:33

    iPhone OS企業(yè)級部署指南

    iPhone OS企業(yè)級部署指南
    發(fā)表于 12-10 14:51 ?57次下載

    庫神企業(yè)級包管理系統(tǒng)介紹

    針對目前的現(xiàn)狀,為了更好的服務(wù)于區(qū)塊鏈領(lǐng)域企業(yè),包括加密資產(chǎn)交易平臺、托管平臺、支付平臺、金融衍生業(yè)務(wù)平臺等,庫神公司自主研發(fā)出一套綜合性加密資產(chǎn)管理系統(tǒng),即庫神企業(yè)級包管理系統(tǒng)(C
    發(fā)表于 04-25 11:00 ?2146次閱讀

    Helm Kubernetes包管理

    helm.zip
    發(fā)表于 04-27 14:25 ?2次下載
    <b class='flag-5'>Helm</b> Kubernetes<b class='flag-5'>包管理</b>器

    Helm常用命令(chart安裝、升級、回滾、卸載等操作)

    Helm 針對 Kubernetes 的 Helm 包管理器。
    的頭像 發(fā)表于 09-13 14:54 ?9236次閱讀

    Helm部署MinIO集群

    Helm部署MinIO集群
    的頭像 發(fā)表于 12-03 09:44 ?1602次閱讀
    <b class='flag-5'>Helm</b><b class='flag-5'>部署</b>MinIO集群

    DeepSeek企業(yè)級部署實(shí)戰(zhàn)指南:以Raksmart企業(yè)服務(wù)器為例

    隨著人工智能技術(shù)的快速發(fā)展,DeepSeek作為一款強(qiáng)大的AI工具,正在成為企業(yè)智能轉(zhuǎn)型的重要驅(qū)動力。本文將結(jié)合Raksmart企業(yè)服務(wù)器的實(shí)際案例,詳細(xì)解析DeepSeek的企業(yè)級
    的頭像 發(fā)表于 03-12 11:33 ?1145次閱讀

    Kubernetes包管理工具Helm的安裝和使用

    Helm 可以幫助我們管理 Kubernetes 應(yīng)用程序 - Helm Charts 可以定義、安裝和升級復(fù)雜的 Kubernetes 應(yīng)用程序,Charts 包很容易創(chuàng)建、版本管理
    的頭像 發(fā)表于 03-13 16:06 ?2216次閱讀

    Helm倉庫管理常用配置

    Helm 倉庫(Repository)是存儲 Helm 圖表(Chart)的地方,類似于軟件包管理器的倉庫(如 apt、yum 倉庫)。
    的頭像 發(fā)表于 06-07 09:27 ?1352次閱讀

    Helm詳細(xì)介紹和使用

    Helm是Kubernetes 應(yīng)用的包管理工具,主要用來管理 Charts,類似Linux系統(tǒng)的yum。
    的頭像 發(fā)表于 06-17 13:56 ?1298次閱讀

    企業(yè)級MySQL數(shù)據(jù)庫管理指南

    在當(dāng)今數(shù)字化時代,MySQL作為全球最受歡迎的開源關(guān)系型數(shù)據(jù)庫,承載著企業(yè)核心業(yè)務(wù)數(shù)據(jù)的存儲與處理。作為數(shù)據(jù)庫管理員(DBA),掌握MySQL的企業(yè)級部署、優(yōu)化、維護(hù)技能至關(guān)重要。本文
    的頭像 發(fā)表于 07-09 09:50 ?755次閱讀

    Helm包管理模板部署實(shí)戰(zhàn)

    直接用kubectl管理K8s資源,10個微服務(wù)就要維護(hù)幾十個YAML文件,版本管理靠文件夾命名,回滾靠手動替換文件。Helm把一組相關(guān)的K8s資源打包成Chart,支持模板
    的頭像 發(fā)表于 02-26 16:37 ?257次閱讀