使用 Docker Hub 完美地存储 Helm 图表实战
Helm 是 Kubernetes 的包管理器。它是一个开源容器编排系统。它通过提供一种简单的方法来定义、安装和升级复杂的 Kubernetes 应用程序,帮助您管理 Kubernetes 应用程序。
使用 Helm,您可以将您的应用程序打包成一个 chart,它是描述您的应用程序的一组文件。然后,您可以使用 Helm 在 Kubernetes 集群上安装和管理您的应用程序。Helm 可以轻松地自动安装和管理复杂的应用程序,它提供的许多功能使其成为管理 Kubernetes 应用程序的强大工具。
使用 Helm 的一些好处包括:
- 简化安装和管理复杂 Kubernetes 应用程序的过程。
- 使应用程序的部署和管理自动化变得容易。
- 允许您对应用程序配置进行版本控制。
- 提供一种通过公共或私人图表存储库与他人共享应用程序的方法。
- 如有必要,可以轻松回滚到应用程序的先前版本。
总的来说,Helm 是在 Kubernetes 上管理和部署应用程序的有用工具,它可以帮助您简化在 Kubernetes 集群上管理复杂应用程序的过程。
为什么 Docker 支持 Helm Chart?
Docker Hub 是 Docker 提供的流行的托管存储库服务,用于查找容器镜像并与您的团队共享。它是一个容器镜像存储库,用于存储和分发容器镜像,或容器运行时可用的工件。因为容器镜像分发只是应用程序交付过程的起点,这成为我们平台的限制。
现在的应用程序支持许多工件,例如 WebAssembly 模块、OPA Bundle、Helm 图表、SBOM 和自定义工件。因此,Docker Hub 团队必须支持所有这些工件,以便开发人员可以与需要它们的客户共享这些工件,因为这为他们的项目增加了巨大的价值。2022 年 10 月,Docker 宣布 Docker Hub 现在可以帮助您分发任何类型的应用程序工件!您现在可以将所有内容保存在一个地方,而无需利用多个注册表。
在此博客中,您将看到 Docker Hub 如何完美地存储 Helm 图表。
1. 创建 Helm 图表
开始使用新图表的最佳方法是使用 helm create 命令搭建一个我们可以构建的示例。使用此命令在新目录中创建一个名为 kubeinfo 的新图表:
helm create kubeinfo
2. 查看图表
Helm 将在您的项目中创建一个新目录, kubeinfo
其结构如下所示。让我们浏览我们的新图表以了解它是如何工作的。
demo % tree
.
├── Chart.yaml
├── charts
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml3 directories, 10 files
文件结构中最重要的部分是 template/目录。这是 Helm 查找Services, Deployments
和其他 Kubernetes 对象的 YAML 定义的地方。如果您已经有了应用程序的定义,那么所需要做的就是将生成的 YAML 文件替换为您自己的。最终得到的是一个可以使用 helm install 命令部署的 chart。
打开 service.yaml
文件看看它长什么样子:
apiVersion: v1
kind: Service
metadata:name: {{ include "kubeinfo.fullname" . }}labels:{{- include "kubeinfo.labels" . | nindent 4 }}
spec:type: {{ .Values.service.type }}ports:- port: {{ .Values.service.port }}targetPort: httpprotocol: TCPname: httpselector:{{- include "kubeinfo.selectorLabels" . | nindent 4 }}
这是使用模板的基本服务定义。部署图表时,Helm 将生成一个看起来更像有效服务的定义。我们可以试运行 helm 安装并启用调试以检查生成的定义。
请确保在 Helm 目录外运行以下命令。
helm install kubeinfo --dry-run --debug ./kubeinfo
install.go:192: [debug] Original chart version: ""
install.go:209: [debug] CHART PATH: /Users/ajeetraina/dec/kubeinfoNAME: kubeinfo
LAST DEPLOYED: Thu Dec 8 11:02:54 2022
NAMESPACE: default
STATUS: pending-install
REVISION: 1
USER-SUPPLIED VALUES:
{}COMPUTED VALUES:
affinity: {}
autoscaling:enabled: falsemaxReplicas: 100minReplicas: 1targetCPUUtilizationPercentage: 80
fullnameOverride: ""
image:pullPolicy: IfNotPresentrepository: nginxtag: ""
imagePullSecrets: []
ingress:annotations: {}className: ""enabled: falsehosts:- host: chart-example.localpaths:- path: /pathType: ImplementationSpecifictls: []
nameOverride: ""
nodeSelector: {}
podAnnotations: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:port: 80type: ClusterIP
serviceAccount:annotations: {}create: truename: ""
tolerations: []HOOKS:
---
# Source: kubeinfo/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:name: "kubeinfo-test-connection"labels:helm.sh/chart: kubeinfo-0.1.0app.kubernetes.io/name: kubeinfoapp.kubernetes.io/instance: kubeinfoapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helmannotations:"helm.sh/hook": test
spec:containers:- name: wgetimage: busyboxcommand: ['wget']args: ['kubeinfo:80']restartPolicy: Never
MANIFEST:
---
# Source: kubeinfo/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: kubeinfolabels:helm.sh/chart: kubeinfo-0.1.0app.kubernetes.io/name: kubeinfoapp.kubernetes.io/instance: kubeinfoapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helm
---
# Source: kubeinfo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:name: kubeinfolabels:helm.sh/chart: kubeinfo-0.1.0app.kubernetes.io/name: kubeinfoapp.kubernetes.io/instance: kubeinfoapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helm
spec:type: ClusterIPports:- port: 80targetPort: httpprotocol: TCPname: httpselector:app.kubernetes.io/name: kubeinfoapp.kubernetes.io/instance: kubeinfo
---
# Source: kubeinfo/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: kubeinfolabels:helm.sh/chart: kubeinfo-0.1.0app.kubernetes.io/name: kubeinfoapp.kubernetes.io/instance: kubeinfoapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helm
spec:replicas: 1selector:matchLabels:app.kubernetes.io/name: kubeinfoapp.kubernetes.io/instance: kubeinfotemplate:metadata:labels:app.kubernetes.io/name: kubeinfoapp.kubernetes.io/instance: kubeinfospec:serviceAccountName: kubeinfosecurityContext:{}containers:- name: kubeinfosecurityContext:{}image: "nginx:1.16.0"imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80protocol: TCPlivenessProbe:httpGet:path: /port: httpreadinessProbe:httpGet:path: /port: httpresources:{}NOTES:
1. Get the application URL by running these commands:export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=kubeinfo,app.kubernetes.io/instance=kubeinfo" -o jsonpath="{.items[0].metadata.name}")export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")echo "Visit http://127.0.0.1:8080 to use your application"kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
3.更改 service.internalPort 的默认值
如果再执行一次试运行,您应该会发现 Service 中的 targetPort 和 Deployment 中的 containerPort 发生了变化。
helm install kubeinfo --dry-run --debug ./kubeinfo --set service.internalPort=8080
4.对外暴露
默认情况下,chart 会创建一个 ClusterIP 类型的 Service,因此 NGINX 只会暴露在集群内部。要从外部访问它,我们将改用 NodePort 类型。我们还可以设置 Helm 版本的名称,以便我们可以轻松地引用它。让我们继续使用 helm install 命令部署我们的 NGINX chart:
helm install example ./kubeinfo --set service.type=NodePort
5.打包 Helm Chart
完成编辑后,我们需要将 Helm 图表打包为 OCI 图像:
helm package kubeinfo
Successfully packaged chart and saved it to: /Users/ajeetraina/dec/kubeinfo-0.1.0.tgz
6.登录到 Docker Hub
docker login
Authenticating with existing credentials...
Login SucceededLogging in with your password grants your terminal complete access to your account.
For better security, log in with a limited-privilege personal access token. Learn more at https://docs.docker.com/go/access-tokens/
7. 推送到 Docker Hub
helm push kubeinfo-0.1.0.tgz oci://registry-1.docker.io/ajeetraina
Error: server message: insufficient_scope: authorization failed
您可能会遇到错误消息。
修复:建议创建个人访问令牌:Personal Access Token (PAT)。
您可以通过环境变量 export PAT,然后登录,如下所示:
echo $REG_PAT | helm registry login registry-1.docker.io -u ajeetraina --password-stdin
Login Succeeded
结论
将 Helm Charts 存储在 Docker Hub 中可以通过 Docker Hub 的标准共享功能改进协作。开发人员现在可以使用 Docker Desktop 的搜索功能在本地构建 Helm chart,然后将其完美地推送到 Docker Hub。
作者:collabnix
出处:https://collabnix.com/how-to-build-push-helm-chart-to-docker-hub-flawlessly/