在 Helm Chart 中配置多个 Docker Registry 地址以实现备用访问,可以通过以下几种方式实现:
1. 在 values.yaml 中定义多个 Registry
在 values.yaml
中定义主 Registry 和备用 Registry,以便在部署时灵活切换:
# values.yaml
image:
primaryRegistry: "primary-registry.example.com" # 主 Registry
secondaryRegistry: "secondary-registry.example.com" # 备用 Registry
name: "my-image"
tag: "v1.0.0"
pullPolicy: IfNotPresent
2. 在 Deployment 中通过环境变量选择 Registry
在 templates/deployment.yaml
中根据条件选择使用主 Registry 或备用 Registry:
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: {{ if .Values.useSecondaryRegistry }}{{ .Values.image.secondaryRegistry }}{{ else }}{{ .Values.image.primaryRegistry }}{{ end }}/{{ .Values.image.name }}:{{ .Values.image.tag }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
部署时通过 --set
参数指定使用备用 Registry:
helm install my-release . --set useSecondaryRegistry=true
3. 使用 Init Container 动态选择 Registry
通过 Init Container 检查主 Registry 可用性,不可用时切换到备用 Registry:
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
initContainers:
- name: check-registry
image: alpine:3.14
command: ["/bin/sh", "-c"]
args:
- |
# 检查主 Registry 是否可访问
if wget -q --spider ${image.primaryRegistry}/${image.name}:${image.tag}; then
echo ${image.primaryRegistry}/${image.name}:${image.tag} > /tmp/image
else
echo ${image.secondaryRegistry}/${image.name}:${image.tag} > /tmp/image
fi
env:
- name: image
value: {{ .Values.image.primaryRegistry }}
- name: name
value: {{ .Values.image.name }}
- name: tag
value: {{ .Values.image.tag }}
volumeMounts:
- name: image-config
mountPath: /tmp
containers:
- name: {{ .Chart.Name }}
image: $(cat /tmp/image) # 使用 Init Container 确定的镜像地址
volumeMounts:
- name: image-config
mountPath: /tmp
volumes:
- name: image-config
emptyDir: {}
4. 使用 Helm 模板函数实现条件选择
在 _helpers.tpl
中定义辅助函数,根据 Registry 可用性返回正确的地址:
# templates/_helpers.tpl
{{/* 获取可用的镜像地址 */}}
{{- define "mychart.image" -}}
{{- if .Values.useSecondaryRegistry -}}
{{ .Values.image.secondaryRegistry }}/{{ .Values.image.name }}:{{ .Values.image.tag }}
{{- else -}}
{{ .Values.image.primaryRegistry }}/{{ .Values.image.name }}:{{ .Values.image.tag }}
{{- end -}}
{{- end -}}
在 Deployment 中引用该函数:
# templates/deployment.yaml
containers:
- name: {{ .Chart.Name }}
image: {{ include "mychart.image" . }}
5. 通过 Helm Hooks 实现故障转移
使用 Pre-Upgrade/Pre-Rollback Hooks 在部署前检查 Registry 可用性:
# templates/hooks/check-registry.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: {{ .Release.Name }}-check-registry
annotations:
"helm.sh/hook": pre-upgrade,pre-install
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
spec:
containers:
- name: check
image: alpine:3.14
command: ["/bin/sh", "-c"]
args:
- |
if ! wget -q --spider {{ .Values.image.primaryRegistry }}/{{ .Values.image.name }}:{{ .Values.image.tag }}; then
echo "主 Registry 不可用,将使用备用 Registry"
helm upgrade {{ .Release.Name }} . --set useSecondaryRegistry=true
fi
restartPolicy: Never
6. 在 CI/CD 流程中动态选择
在 CI/CD 脚本中根据 Registry 状态决定使用哪个 Registry:
# .gitlab-ci.yml 示例
deploy:
script:
- if wget -q --spider ${PRIMARY_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}; then
helm install my-release . --set image.registry=${PRIMARY_REGISTRY};
else
helm install my-release . --set image.registry=${SECONDARY_REGISTRY};
fi
最佳实践
- 优先使用动态检查:通过 Init Container 或 CI/CD 脚本实时检查 Registry 可用性,避免硬编码。
- 配置镜像拉取密钥:确保两个 Registry 都配置了正确的
imagePullSecrets
。 - 监控备用 Registry 使用频率:通过 Prometheus 等工具监控备用 Registry 的使用情况,及时排查主 Registry 问题。
- 测试故障转移逻辑:在 CI/CD 中添加模拟故障测试,验证备用机制的可靠性。
通过以上方法,你可以在 Helm Chart 中灵活配置多个 Docker Registry 地址,实现高可用性的镜像拉取策略。