主题
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 2 | Helm 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/helm2.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 stable2.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-nginx3.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.yaml3.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: trueNginx 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: truePrometheus + 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 --force4.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 --debug4.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: falseyaml
# 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-auth5.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 name | Release名称已存在 | 使用新名称或先卸载旧Release |
Error: Kubernetes cluster unreachable | K8S连接问题 | 检查kubeconfig和集群状态 |
Error: failed to download | Chart下载失败 | 检查网络,更新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:生产环境故障排查
💡 学习建议:
- 在测试环境使用Helm部署几个常用应用(MySQL、Redis、Nginx)
- 练习升级和回滚操作,熟悉Release生命周期管理
- 为不同环境(dev/staging/prod)准备不同的values文件