| name | securing-helm-chart-deployments |
| description | 通过验证 Chart 完整性、扫描模板中的错误配置并在 Kubernetes 发布中强制执行安全上下文,保护 Helm Chart 部署安全。 |
| domain | cybersecurity |
| subdomain | container-security |
| tags | ["helm","kubernetes","chart-security","supply-chain","configuration-security","deployment"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
保护 Helm Chart 部署
概述
Helm(Kubernetes 包管理器)的部署安全需要验证 Chart 来源、扫描模板中的安全错误配置、强制执行 Pod 安全上下文、安全管理 Secret,以及控制 Helm 操作的 RBAC。
前置条件
- Helm 3.12+ 已安装
- 具有集群访问权限的 kubectl
- GnuPG(用于 Chart 签名/验证)
- kubesec 或 checkov(用于模板扫描)
Chart 来源与完整性
签署 Helm Chart
gpg --full-generate-key
helm package ./mychart --sign --key "helm-signing@example.com" --keyring ~/.gnupg/pubring.gpg
helm verify mychart-0.1.0.tgz --keyring ~/.gnupg/pubring.gpg
安装前验证 Chart
helm pull myrepo/mychart --verify --keyring /path/to/keyring.gpg
cat mychart-0.1.0.tgz.prov
模板安全扫描
渲染并扫描模板
helm template myrelease ./mychart --values values-prod.yaml > rendered.yaml
kubesec scan rendered.yaml
checkov -f rendered.yaml --framework kubernetes
trivy config rendered.yaml
kube-linter lint rendered.yaml
使用 Helm Lint 检查错误配置
helm lint ./mychart --values values-prod.yaml --strict
helm lint ./mychart --debug
在 values.yaml 中强制执行安全上下文
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
podSecurityContext:
seccompProfile:
type: RuntimeDefault
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
networkPolicy:
enabled: true
serviceAccount:
create: true
automountServiceAccountToken: false
image:
pullPolicy: Always
带安全上下文的模板
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.fullname" . }}
spec:
template:
spec:
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
resources:
{{- toYaml .Values.resources | nindent 12 }}
Secret 管理
使用外部 Secret(而非 Helm Values)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: {{ include "mychart.fullname" . }}-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secretsmanager
kind: ClusterSecretStore
target:
name: {{ include "mychart.fullname" . }}-secrets
data:
- secretKey: db-password
remoteRef:
key: production/database
property: password
helm-secrets 插件
helm plugin install https://github.com/jkroepke/helm-secrets
helm secrets encrypt values-secrets.yaml
helm secrets install myrelease ./mychart -f values.yaml -f values-secrets.yaml
helm secrets edit values-secrets.yaml
Helm 操作的 RBAC
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: helm-deployer
namespace: production
rules:
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
resources: ["deployments", "services", "configmaps", "secrets", "ingresses", "jobs"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: helm-deployer-binding
namespace: production
subjects:
- kind: ServiceAccount
name:
CI/CD Helm 安全流水线
name: Helm Chart 安全
on:
pull_request:
paths: ['charts/**']
jobs:
lint-and-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Helm 检查
run: helm lint ./charts/mychart --strict
- name: 渲染模板
run: helm template test ./charts/mychart -f charts/mychart/values.yaml > rendered.yaml
- name: 使用 kube-linter 扫描
uses: stackrox/kube-linter-action@v1
with:
directory: rendered.yaml
- name: 使用 trivy 扫描
uses: aquasecurity/trivy-action@master
最佳实践
- 签署 Chart 使用 GPG 签名并在安装前验证
- 渲染并扫描模板,在部署前发现错误配置
- 在 values.yaml 默认值中强制执行安全上下文
- 绝不在 Helm values 中存储 Secret - 使用外部 Secret 或 helm-secrets 插件
- 使用镜像摘要代替标签以获得不可变引用
- 按命名空间限制 Helm RBAC 至最小权限
- 固定依赖中的 Chart 版本 - 绝不使用
latest
- 在 CI 中严格检查,使用
--strict 标志
- 审查第三方 Chart 再部署到生产环境
- 使用 Helm 测试钩子在安装后验证部署