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

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

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

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

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

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

掃碼添加小助手

加入工程師交流群

一、概述

1.1 背景介紹

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

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

1.2 核心語義

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

1.3 適用場景

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

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

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

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

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

1.4 環(huán)境要求

組件 版本要求 說明
Kubernetes 1.32+ 目標集群版本,需與 Chart apiVersion 兼容
Helm v3.17+ OCI registry 默認支持,無需額外 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 排障坐標系

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: 資源運行時異常      → Pod/Service/Ingress 層面的運行時排查
Layer 4: Hook 執(zhí)行失敗       → Job/Pod 日志層面

二、詳細步驟

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

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

一個標準的 Helm Chart 目錄結(jié)構(gòu):

mychart/
├── Chart.yaml       # Chart 元數(shù)據(jù):名稱、版本、依賴
├── Chart.lock       # 依賴鎖定文件
├── values.yaml      # 默認參數(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)?;煜簐ersion是 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 的詳細信息
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 當前活躍版本 正常,無需處理
superseded 已被新版本取代 保留用于回滾參考
failed 安裝或升級失敗 查看 helm status 中的 NOTES 和 events
pending-install 安裝中 檢查 hook Job 是否卡住
pending-upgrade 升級中 檢查 hook Job 和資源創(chuàng)建狀態(tài)
pending-rollback 回滾中 檢查回滾目標版本的資源兼容性
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

# 嚴格模式
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 值類型不匹配、運行時資源沖突、鏡像不存在。

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

# 渲染并校驗 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)生的差異(不實際執(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è)計

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)鍵語法點

語法 作用 常見錯誤
{{ .Values.xxx }} 引用 values 值 路徑寫錯不報錯,渲染為空
{{- ... -}} 去除左/右空白 過度使用導致 YAML 縮進錯誤
{{ include "tpl" . }} 調(diào)用命名模板 忘記傳遞.上下文
{{ toYaml . | nindent N }} 轉(zhuǎn) YAML 并縮進 N 格 nindent 值錯誤導致 YAML 解析失敗
{{ with .Values.xxx }} 條件塊并切換上下文 塊內(nèi)無法訪問.Release等頂級對象
{{ range .Values.list }} 遍歷列表 塊內(nèi).指向當前元素,需$.Values訪問頂級
{{ default "val" .Values.xxx }} 默認值 空字符串不觸發(fā) default
{{ required "msg" .Values.xxx }} 必填校驗 僅在渲染時觸發(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標識
*/}}
{{-define"myapp.chart"-}}
{{-printf"%s-%s".Chart.Name.Chart.Version|replace"+""_"|trunc63|trimSuffix"-"}}
{{-end}}

{{/*
通用標簽
*/}}
{{-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標簽—不可變,用于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}}

{{/*
名稱截斷
*/}}
{{-define"myapp.name"-}}
{{-default.Chart.Name.Values.nameOverride|trunc63|trimSuffix"-"}}
{{-end}}

63 字符截斷是 Kubernetes 對 label value 的硬限制,在命名模板中必須始終保留這個約束。

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

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

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

values.yaml 設(shè)計原則

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

image:
repository:registry.myorg.com/myapp
pullPolicy:IfNotPresent
tag:""# 留空,默認使用 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)象 層級 可能原因 診斷命令 修復方向
helm install 報 YAML 解析錯誤 L0 模板縮進錯誤、nindent 值不對 helm template 查看渲染結(jié)果 修正模板縮進
helm install 報 "cannot re-use a name" L2 同名 Release 已存在(可能是 failed 狀態(tài)) helm list -A --all helm uninstall 舊 Release 或換名
upgrade 報 "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中運行 改用helm install --dry-run lookup 只在連接集群時可用
"chart requires kubeVersion >=1.28" L0 集群版本低于 Chart 要求 kubectl version 升級集群或調(diào)整 Chart.yaml
OCI pull 401 Unauthorized L2 Registry 認證失敗 helm registry login 測試 檢查憑證配置
values 中的 list 被 --set 覆蓋而非追加 L1 Helm --set 對 list 是替換行為 helm template 對比渲染結(jié)果 使用 --set-json 或 -f 文件
CRD 升級未生效 L0 Helm 不管理 CRD 的升級(只負責首次安裝) kubectl get crd -o yaml 手動 kubectl apply CRD

2.5 處理與驗證

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 就緒后才標記 Release 為 deployed,否則即使 Pod 還沒啟動完就返回成功

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

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

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

2.5.2 部署后驗證清單

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

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

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

# 4. 確認 Service 端點
kubectl get endpoints -n production -l app.kubernetes.io/instance=myapp

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

# 6. 運行 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í)行時機:

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

Hook 刪除策略:

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

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

三、示例代碼和配置

3.1 OCI Registry 操作

Helm v3.17+ 中 OCI 是默認支持的 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è)計

Library Chart 不直接生成 Kubernetes 資源,而是提供可復用的模板片段給其他 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 只需維護 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']
# 運行測試
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 進行全面健康檢查,輸出診斷報告
# 適用場景:Release 部署后狀態(tài)異常、Pod 未就緒、Service 無端點時使用
# 使用方法:./helm-release-diagnose.sh  
# 輸入?yún)?shù):$1=Release名稱 $2=命名空間
# 輸出結(jié)果:終端輸出診斷報告,包含 Release 狀態(tài)、Pod 狀態(tài)、事件、日志摘要
# 風險提示:只讀操作,不修改任何資源。需要 helm 和 kubectl 權(quán)限

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

echo"=========================================="
echo"Helm Release 診斷報告"
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. 當前生效 Values(非默認值) ---"
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 端點 ---"
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)驗證
# 適用場景:MR/PR 提交時自動觸發(fā),防止有語法錯誤或渲染異常的 Chart 合入主分支
# 使用方法:./helm-chart-ci-validate.sh  [values-file1] [values-file2] ...
# 輸入?yún)?shù):$1=Chart目錄 $2+=可選的 values 文件列表
# 輸出結(jié)果:通過則退出碼 0,失敗則退出碼 1 并輸出錯誤詳情
# 風險提示:只讀操作。需要 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=目標環(huán)境 --chart-version=Chart版本 --dry-run=僅模擬不執(zhí)行
# 輸出結(jié)果:每個 Release 的升級結(jié)果日志
# 風險提示:生產(chǎn)環(huán)境務(wù)必先 --dry-run。批量操作前確認變更窗口。升級順序:基礎(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 報告
# 適用場景:新環(huá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 格式)
# 風險提示:只讀操作。大型 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 ==="

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

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

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

第一輪判斷

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

# 查看 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 完成。

修復動作

先推送正確的鏡像到 Registry

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

修復 CI/CD 流水線中 stage 之間的依賴關(guā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 卡住導致 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 正好不夠(因為還有其他 Pending Pod 占用請求)。

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

修復動作

# 降低遷移 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 # 一次只替換一個

修復后驗證

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 預留空間匹配

在 CI 中加入 ResourceQuota 余量檢查

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

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

現(xiàn)場現(xiàn)象:使用 Helmfile 部署三個組件(postgresql、redis、myapp),myapp 部署后 Pod 反復 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,但實際還在初始化
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 默認并發(fā)安裝所有 Release,myapp 在 PostgreSQL 完成初始化之前就開始連接數(shù)據(jù)庫。

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

修復動作

# 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']

修復后驗證

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 或連接重試機制,不依賴部署順序保證可用性

設(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報錯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 的認證配置
cat ~/.config/helm/registry/config.json
# 發(fā)現(xiàn) auth 字段存在但對應(yīng)的 credsStore 配置指向了 docker-credential-desktop

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

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

修復動作

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

# 直接寫入認證信息
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

修復后驗證

# 確認推送成功
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)境變量指定認證配置文件

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

在流水線開始時加helm registry login的連通性驗證步驟

五、最佳實踐和注意事項

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

5.1.1 版本管理

Chart version 遵循 SemVer:Breaking change 升主版本,新功能升次版本,Bug 修復升補丁版本

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

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

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

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

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

使用required函數(shù)標記生產(chǎn)環(huán)境必填項

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

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

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

# values.yaml 中用 required 標記必填項的模板用法
# 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)

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

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

5.1.4 Umbrella Chart 架構(gòu)

platform-chart/
├── Chart.yaml     # type: application
├── values.yaml    # 全局默認值
├── 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 注意事項

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 渲染后縮進不對,K8s API 拒絕 用helm template檢查輸出格式
with 塊內(nèi)訪問頂級對象 {{ .Values.xxx }} 變成空 使用{{ $.Values.xxx }}
range 塊內(nèi)的. . 指向當前迭代元素而非根 使用$引用根上下文
數(shù)字值未加 quote YAML 解析為科學計數(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 失敗
├── 報錯"YAML parse error"/"template render error"
│  ├── 檢查 helm template 輸出
│  ├── 定位到具體模板文件和行號
│  └── 常見:nindent 錯誤、括號未閉合、函數(shù)名拼寫
├── 報錯"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):等待或強制清理
├── 報錯"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
├── 報錯"admission webhook denied"
│  ├── 檢查 ValidatingWebhookConfiguration
│  ├── 查看 webhook 服務(wù)是否可用
│  └── 臨時繞過:刪除 webhook 或加 exclude annotation
├── 部署成功但功能異常
│  ├── helm get values 確認 values 生效
│  ├── helm get manifest 確認渲染結(jié)果
│  ├── kubectl describe / logs 查看運行時狀態(tài)
│  └── Service/Endpoints/Ingress 鏈路檢查
└── OCI Registry 相關(guān)
  ├── 401 Unauthorized:檢查 helm registry login
  ├── not found:確認 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 部署指標

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

# 部署耗時統(tǒng)計
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))

# 推送指標到 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 常見問題速查

問題 快速診斷 快速修復
"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 檢查層級 確認 values 中用子 Chart 名稱作為 key

七、總結(jié)

7.1 技術(shù)要點回顧

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縮進值

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

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

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

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

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

7.2 排障鏈路總結(jié)

完整的 Helm 部署排障鏈路:

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

7.3 進階學習方向

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

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

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

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

7.3 參考資料

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

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          # 查看默認 values

# OCI Registry
helm registry login         # 登錄
helm push  oci:///# 推送
helm pull oci:/// --version X # 拉取
helm show chart oci:///    # 查看遠程 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                # 查看當前 values
helm get manifest  -n               # 查看當前 manifest
helm get hooks  -n                # 查看 hooks
helmtest -n                   # 運行測試

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

    關(guān)注

    0

    文章

    533

    瀏覽量

    22981
  • kubernetes
    +關(guān)注

    關(guān)注

    0

    文章

    266

    瀏覽量

    9501

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

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

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

掃碼添加小助手

加入工程師交流群

    評論

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

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

    摘要: Helm 是啥? 微服務(wù)和容器給復雜應(yīng)用部署管理帶來了極大的挑戰(zhàn)。Helm是目前Kubernetes服務(wù)編排領(lǐ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 ?9237次閱讀

    Helm部署MinIO集群

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

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

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

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

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

    Helm倉庫管理常用配置

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

    Helm詳細介紹和使用

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

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

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

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

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