跳转到内容

Helm Chart应用与管理

课程目标

通过本课程的学习,你将能够:

  • 理解Helm的基本概念和工作原理
  • 使用Helm安装、升级和卸载应用
  • 配置和管理Chart仓库
  • 自定义values配置覆盖默认参数
  • 管理Helm发布生命周期
  • 掌握Helm在生产环境的最佳实践

前置要求:已完成《K8s调度与资源管理》课程,了解K8S资源管理和调度策略

一、Helm概述

1.1 为什么需要Helm

在Kubernetes上部署复杂应用时,我们面临以下挑战:

挑战说明Helm解决方案
配置复杂微服务应用涉及多个YAML文件一键安装完整应用
版本管理应用升级和回滚困难版本控制和原子升级
环境差异不同环境需要不同配置values文件管理多环境
重复配置相同配置在多个文件中重复模板化配置复用
依赖管理应用依赖其他服务Chart依赖自动处理

1.2 Helm核心概念

┌─────────────────────────────────────────────────────────────────┐
│                      Helm核心概念                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐      │
│  │    Chart     │───▶│   Release    │───▶│  Revision    │      │
│  │   (安装包)    │    │   (安装实例)  │    │   (版本)      │      │
│  └──────────────┘    └──────────────┘    └──────────────┘      │
│                                                                 │
│  Chart:应用的打包格式,包含所有K8S资源定义                         │
│  Release:Chart的安装实例,可安装多次形成多个Release                │
│  Repository:Chart的存储库,用于分享和分发                          │
│  Values:配置值文件,用于自定义Chart配置                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.3 Helm版本对比

特性Helm 2Helm 3
架构Client-Server(Tiller)Client-only
安全性Tiller权限过大使用K8S RBAC
发布信息存储在ConfigMap存储在Secret
库图表需要Tiller直接操作K8S API
维护状态已停止维护推荐使用

二、Helm安装和配置

2.1 安装Helm

bash
# 下载Helm(以Linux为例)
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

# 验证安装
helm version

# 添加自动补全(可选)
helm completion bash | sudo tee /etc/bash_completion.d/helm > /dev/null
source /etc/bash_completion.d/helm

2.2 配置Chart仓库

bash
# 添加常用仓库
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

# 查看已添加的仓库
helm repo list

# 更新仓库索引
helm repo update

# 搜索Chart
helm search repo nginx
helm search repo mysql --versions

# 删除仓库
helm repo remove stable

2.3 Helm常用命令速查

bash
# ========== 仓库管理 ==========
helm repo add <name> <url>      # 添加仓库
helm repo list                   # 列出仓库
helm repo update                 # 更新仓库
helm repo remove <name>          # 删除仓库

# ========== Chart搜索和查看 ==========
helm search repo <keyword>       # 搜索Chart
helm search hub <keyword>        # 在Artifact Hub搜索
helm show chart <repo>/<chart>   # 查看Chart信息
helm show values <repo>/<chart>  # 查看可配置参数
helm show readme <repo>/<chart>  # 查看README

# ========== 安装和卸载 ==========
helm install <release> <chart>   # 安装Chart
helm upgrade <release> <chart>   # 升级Release
helm rollback <release> <rev>    # 回滚到指定版本
helm uninstall <release>         # 卸载Release

# ========== 发布管理 ==========
helm list                        # 列出所有Release
helm status <release>            # 查看Release状态
helm history <release>           # 查看Release历史
helm get values <release>        # 查看当前配置值
helm get manifest <release>      # 查看生成的K8S资源

# ========== 模板和调试 ==========
helm template <chart>            # 本地渲染模板
helm lint <chart>                # 检查Chart语法
helm install --dry-run --debug   # 模拟安装(调试用)

三、使用Helm部署应用

3.1 基础部署

bash
# 简单安装
helm install my-nginx bitnami/nginx

# 指定命名空间
helm install my-nginx bitnami/nginx -n production --create-namespace

# 指定版本
helm install my-nginx bitnami/nginx --version 13.2.0

# 查看安装状态
helm status my-nginx

# 查看安装的K8S资源
helm get manifest my-nginx

3.2 自定义配置安装

bash
# 方式1:命令行设置参数
helm install my-mysql bitnami/mysql \
  --set auth.rootPassword=secretpassword \
  --set auth.database=myapp \
  --set primary.persistence.size=10Gi

# 方式2:使用values文件(推荐)
helm install my-mysql bitnami/mysql -f my-values.yaml

# 方式3:多个values文件(后面的覆盖前面的)
helm install my-mysql bitnami/mysql \
  -f values.yaml \
  -f values-production.yaml

3.3 常用应用的values配置示例

MySQL配置示例

yaml
# mysql-values.yaml
auth:
  rootPassword: "MySecureRootPass123"
  database: "myapp"
  username: "appuser"
  password: "AppUserPass456"

primary:
  persistence:
    enabled: true
    storageClass: "standard"
    size: 20Gi
    accessModes:
      - ReadWriteOnce
  resources:
    requests:
      memory: "512Mi"
      cpu: "250m"
    limits:
      memory: "1Gi"
      cpu: "1000m"

replicaCount: 2

metrics:
  enabled: true
  serviceMonitor:
    enabled: true

Nginx Ingress Controller配置

yaml
# ingress-nginx-values.yaml
controller:
  replicaCount: 2
  
  resources:
    requests:
      cpu: 100m
      memory: 90Mi
    limits:
      cpu: 1000m
      memory: 512Mi
  
  service:
    type: LoadBalancer
    externalTrafficPolicy: Local
  
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true
  
  podAnnotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "10254"

defaultBackend:
  enabled: true

Prometheus + Grafana配置

yaml
# prometheus-values.yaml
prometheus:
  prometheusSpec:
    retention: 30d
    retentionSize: "50GB"
    resources:
      requests:
        memory: "2Gi"
        cpu: "500m"
      limits:
        memory: "4Gi"
        cpu: "2000m"
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: standard
          resources:
            requests:
              storage: 50Gi

grafana:
  enabled: true
  adminPassword: "admin123"
  persistence:
    enabled: true
    size: 10Gi
  
  ingress:
    enabled: true
    hosts:
      - grafana.example.com
    tls:
      - secretName: grafana-tls
        hosts:
          - grafana.example.com

alertmanager:
  enabled: true
  config:
    global:
      smtp_smarthost: 'smtp.example.com:587'
      smtp_from: 'alert@example.com'

四、Release生命周期管理

4.1 升级Release

bash
# 升级到最新版本
helm upgrade my-mysql bitnami/mysql

# 升级并复用上次安装的值
helm upgrade my-mysql bitnami/mysql --reuse-values

# 升级并设置新参数
helm upgrade my-mysql bitnami/mysql \
  --set primary.persistence.size=30Gi

# 升级并指定values文件
helm upgrade my-mysql bitnami/mysql -f updated-values.yaml

# 强制重启(不修改配置)
helm upgrade my-mysql bitnami/mysql --force

4.2 回滚Release

bash
# 查看Release历史
helm history my-mysql

# 输出示例:
# REVISION	UPDATED                  	STATUS      	CHART        	APP VERSION	DESCRIPTION
# 1       	Mon Jan  1 10:00:00 2024	deployed    	mysql-9.14.0	8.0.35     	Install complete
# 2       	Mon Jan  1 11:00:00 2024	superseded  	mysql-9.14.0	8.0.35     	Upgrade complete
# 3       	Mon Jan  1 12:00:00 2024	deployed    	mysql-9.14.0	8.0.35     	Upgrade complete

# 回滚到指定版本
helm rollback my-mysql 2

# 回滚并查看详细输出
helm rollback my-mysql 2 --debug

4.3 卸载Release

bash
# 卸载Release(保留历史记录)
helm uninstall my-mysql

# 卸载并清除所有资源(包括PVC)
helm uninstall my-mysql --keep-history=false

# 卸载特定命名空间的Release
helm uninstall my-mysql -n production

注意:默认情况下,Helm不会删除PVC以保护数据。如果需要删除,请手动执行:

bash
kubectl delete pvc <pvc-name>

五、生产环境最佳实践

5.1 配置管理策略

bash
# 目录结构建议
helm-configs/
├── base/                      # 基础配置
   ├── mysql-base.yaml
   └── nginx-base.yaml
├── environments/              # 环境特定配置
   ├── dev/
   ├── mysql-values.yaml
   └── nginx-values.yaml
   ├── staging/
   ├── mysql-values.yaml
   └── nginx-values.yaml
   └── production/
       ├── mysql-values.yaml
       └── nginx-values.yaml
└── secrets/                   # 加密配置(使用Sealed Secrets等)
    └── production/

环境配置示例

yaml
# environments/dev/mysql-values.yaml
auth:
  rootPassword: "dev-root-pass"
  database: "myapp_dev"

primary:
  persistence:
    size: 5Gi
  resources:
    requests:
      memory: "256Mi"
      cpu: "100m"

replicaCount: 1

metrics:
  enabled: false
yaml
# environments/production/mysql-values.yaml
auth:
  rootPassword: "prod-root-pass-change-me"
  database: "myapp_prod"

primary:
  persistence:
    size: 100Gi
    storageClass: "fast-ssd"
  resources:
    requests:
      memory: "2Gi"
      cpu: "1000m"
    limits:
      memory: "4Gi"
      cpu: "2000m"

replicaCount: 2

metrics:
  enabled: true
  serviceMonitor:
    enabled: true

backup:
  enabled: true
  schedule: "0 2 * * *"  # 每天凌晨2点备份

5.2 安全最佳实践

bash
# 1. 验证Chart来源
helm install my-app ./my-chart --verify

# 2. 使用特定版本(避免意外升级)
helm install my-app bitnami/mysql --version 9.14.0

# 3. 限制Release权限(使用ServiceAccount)
helm install my-app bitnami/mysql \
  --set serviceAccount.create=true \
  --set serviceAccount.name=mysql-sa

# 4. 敏感信息使用Secret(而非values文件)
kubectl create secret generic mysql-auth \
  --from-literal=root-password='SecurePass123'

# 然后在values中引用
# auth:
#   existingSecret: mysql-auth

5.3 高可用和备份策略

yaml
# 生产环境MySQL高可用配置
architecture: replication

auth:
  rootPassword: "SecureRootPass"
  replicationPassword: "SecureReplPass"

primary:
  persistence:
    enabled: true
    size: 100Gi
    storageClass: "fast-ssd"
  
  resources:
    requests:
      memory: "4Gi"
      cpu: "2000m"

secondary:
  replicaCount: 2
  persistence:
    enabled: true
    size: 100Gi
  
  resources:
    requests:
      memory: "4Gi"
      cpu: "2000m"

# 备份配置
backup:
  enabled: true
  cronjob:
    schedule: "0 2 * * *"
    backupCommands:
      - mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --all-databases > /backup/all-databases.sql
  
  storage:
    s3:
      region: "us-east-1"
      bucket: "my-backup-bucket"
      path: "/mysql-backups"

5.4 监控和告警

yaml
# 启用Prometheus监控
metrics:
  enabled: true
  serviceMonitor:
    enabled: true
    namespace: monitoring
    interval: 30s
    scrapeTimeout: 10s

# 告警规则
prometheusRule:
  enabled: true
  namespace: monitoring
  rules:
    - alert: MySQLDown
      expr: mysql_up == 0
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: "MySQL instance is down"
    
    - alert: MySQLHighConnections
      expr: |
        (mysql_global_status_threads_connected / mysql_global_variables_max_connections) * 100 > 80
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "MySQL has high connection usage"

六、实战案例:完整应用部署

6.1 部署LNMP应用栈

bash
#!/bin/bash
# deploy-lnmp.sh - 部署LNMP环境

NAMESPACE="webapp"
ENV="production"

# 创建命名空间
kubectl create namespace $NAMESPACE --dry-run=client -o yaml | kubectl apply -f -

# 1. 部署Nginx Ingress Controller
echo "部署Nginx Ingress Controller..."
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.replicaCount=2 \
  --set controller.service.type=LoadBalancer \
  --wait

# 2. 部署MySQL
echo "部署MySQL..."
helm upgrade --install mysql bitnami/mysql \
  --namespace $NAMESPACE \
  -f environments/$ENV/mysql-values.yaml \
  --wait

# 3. 部署Redis
echo "部署Redis..."
helm upgrade --install redis bitnami/redis \
  --namespace $NAMESPACE \
  --set architecture=standalone \
  --set auth.enabled=true \
  --set auth.password=redispass123 \
  --set master.persistence.size=10Gi \
  --wait

# 4. 部署PHP应用
echo "部署PHP应用..."
helm upgrade --install myapp ./myapp-chart \
  --namespace $NAMESPACE \
  -f environments/$ENV/myapp-values.yaml \
  --set mysql.host=mysql.$NAMESPACE.svc.cluster.local \
  --set redis.host=redis-master.$NAMESPACE.svc.cluster.local \
  --wait

echo "部署完成!"

6.2 部署监控栈

bash
#!/bin/bash
# deploy-monitoring.sh - 部署监控栈

NAMESPACE="monitoring"

# 添加仓库
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# 部署kube-prometheus-stack
echo "部署Prometheus + Grafana..."
helm upgrade --install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
  --namespace $NAMESPACE \
  --create-namespace \
  --set prometheus.prometheusSpec.retention=30d \
  --set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=50Gi \
  --set grafana.adminPassword=admin123 \
  --set grafana.persistence.enabled=true \
  --set grafana.persistence.size=10Gi \
  --wait

echo "监控栈部署完成!"
echo "Grafana访问地址:"
kubectl get svc -n $NAMESPACE kube-prometheus-stack-grafana -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
echo ""
echo "默认账号:admin / admin123"

6.3 备份和恢复脚本

bash
#!/bin/bash
# backup-releases.sh - 备份所有Release配置

BACKUP_DIR="/backup/helm/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR

# 获取所有Release
releases=$(helm list -q --all-namespaces)

for release in $releases; do
  namespace=$(helm list -f $release -o json | jq -r '.[0].namespace')
  
  echo "备份Release: $release (namespace: $namespace)"
  
  # 备份values
  helm get values $release -n $namespace > $BACKUP_DIR/${release}-values.yaml
  
  # 备份manifest
  helm get manifest $release -n $namespace > $BACKUP_DIR/${release}-manifest.yaml
  
  # 备份历史
  helm history $release -n $namespace > $BACKUP_DIR/${release}-history.txt
done

echo "备份完成,保存到: $BACKUP_DIR"

七、常见问题排查

7.1 安装失败排查

bash
# 查看详细错误信息
helm install my-app bitnami/mysql --debug --dry-run

# 查看Pod状态
kubectl get pods -n <namespace>
kubectl describe pod <pod-name> -n <namespace>
kubectl logs <pod-name> -n <namespace>

# 查看Helm Release状态
helm status my-app -n <namespace>
helm history my-app -n <namespace>

7.2 常见错误及解决

错误原因解决方案
Error: cannot re-use a nameRelease名称已存在使用新名称或先卸载旧Release
Error: Kubernetes cluster unreachableK8S连接问题检查kubeconfig和集群状态
Error: failed to downloadChart下载失败检查网络,更新repo索引
Pod Pending资源不足或调度失败检查节点资源和调度约束
CrashLoopBackOff应用启动失败查看Pod日志排查应用问题
PVC Pending存储类问题检查StorageClass和PV可用性

7.3 调试技巧

bash
# 本地渲染模板(不安装)
helm template my-app bitnami/mysql -f my-values.yaml

# 模拟安装并查看生成的资源
helm install my-app bitnami/mysql -f my-values.yaml --dry-run --debug

# 查看Chart依赖
helm dependency list ./my-chart

# 验证Chart语法
helm lint ./my-chart

八、总结

核心概念回顾

Helm核心流程
├── 仓库管理
│   ├── helm repo add/update/list/remove
│   └── Chart搜索和发现

├── 安装部署
│   ├── helm install(首次安装)
│   ├── helm upgrade(升级)
│   └── helm rollback(回滚)

├── 配置管理
│   ├── values文件(推荐)
│   ├── --set参数(临时覆盖)
│   └── 多环境配置分离

└── 生命周期
    ├── Release版本管理
    ├── 原子升级和回滚
    └── 历史记录保留

生产环境检查清单

bash
# ✅ 部署前检查
helm lint <chart>                    # 验证Chart语法
helm template <chart> | kubectl apply --dry-run=client -f -  # 验证K8S资源
helm install --dry-run --debug       # 模拟安装

# ✅ 部署时配置
--version <specific-version>         # 指定版本
--namespace <namespace>              # 指定命名空间
--wait                               # 等待就绪
--timeout 10m                        # 设置超时

# ✅ 部署后验证
helm status <release>                # 检查状态
kubectl get pods                     # 检查Pod状态
kubectl logs <pod>                   # 检查应用日志

下节预告

在下一节《容器编排与Kubernetes实战》中,我们将通过6个完整的实战案例,综合运用所学知识:

  • 案例1:从Docker到K8s的平滑迁移
  • 案例2:构建完整的微服务应用
  • 案例3:蓝绿发布与金丝雀发布
  • 案例4:构建可观测性体系
  • 案例5:K8s CI/CD流水线
  • 案例6:生产环境故障排查

💡 学习建议

  1. 在测试环境使用Helm部署几个常用应用(MySQL、Redis、Nginx)
  2. 练习升级和回滚操作,熟悉Release生命周期管理
  3. 为不同环境(dev/staging/prod)准备不同的values文件

评论区

专业的Linux技术学习平台,从入门到精通的完整学习路径