定制Helm charts

使用Helm 3在Kubernetes集群部署Prometheus和Grafana 采用的是互联网上社区提供的helm仓库以及镜像,对于很多企业用户,内部网路无法直接下载镜像(安全原因),所以我们需要自己定制Helm charts来实现企业级的"一键部署"。

备注

私有Helm仓库 可以进一步在内部局域网提供完整安装步骤,加速部署。

Helm create

Helm pull

对于自己定义和部署 使用Helm 3在Kubernetes集群部署Prometheus和Grafana ,则采用先 pull 然后定制的方法:

  • 添加 prometheus-community 仓库并下载 kube-prometheus-stack chart:

添加 prometheus-community 仓库并下载 kube-prometheus-stack chart
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm pull prometheus-community/kube-prometheus-stack
tar xfz kube-prometheus-stack-46.6.0.tgz

此时本地目录下载了一个 kube-prometheus-stack-46.6.0.tgz 文件,就是我们所需的chart打包文件,将这个文件解压缩后我们来做定制

  • 我们来检查一下解压缩以后的 kube-prometheus-stack 目录内容( tree kube-prometheus-stack ):

检查 kube-prometheus-stack chart包含的文件结构
kube-prometheus-stack
├── CONTRIBUTING.md
├── Chart.lock
├── Chart.yaml
├── README.md
├── charts
│   ├── grafana
│      ├── Chart.yaml
│      ├── README.md
│      ├── ci
│         ├── default-values.yaml
│         ├── with-affinity-values.yaml
│         ├── with-dashboard-json-values.yaml
│         ├── with-dashboard-values.yaml
│         ├── with-extraconfigmapmounts-values.yaml
│         ├── with-image-renderer-values.yaml
│         └── with-persistence.yaml
│      ├── dashboards
│         └── custom-dashboard.json
│      ├── templates
│         ├── NOTES.txt
│         ├── _helpers.tpl
│         ├── _pod.tpl
│         ├── clusterrole.yaml
│         ├── clusterrolebinding.yaml
│         ├── configmap-dashboard-provider.yaml
│         ├── configmap.yaml
│         ├── dashboards-json-configmap.yaml
│         ├── deployment.yaml
│         ├── extra-manifests.yaml
│         ├── headless-service.yaml
│         ├── hpa.yaml
│         ├── image-renderer-deployment.yaml
│         ├── image-renderer-hpa.yaml
│         ├── image-renderer-network-policy.yaml
│         ├── image-renderer-service.yaml
│         ├── image-renderer-servicemonitor.yaml
│         ├── ingress.yaml
│         ├── networkpolicy.yaml
│         ├── poddisruptionbudget.yaml
│         ├── podsecuritypolicy.yaml
│         ├── pvc.yaml
│         ├── role.yaml
│         ├── rolebinding.yaml
│         ├── secret-env.yaml
│         ├── secret.yaml
│         ├── service.yaml
│         ├── serviceaccount.yaml
│         ├── servicemonitor.yaml
│         ├── statefulset.yaml
│         └── tests
│             ├── test-configmap.yaml
│             ├── test-podsecuritypolicy.yaml
│             ├── test-role.yaml
│             ├── test-rolebinding.yaml
│             ├── test-serviceaccount.yaml
│             └── test.yaml
│      └── values.yaml
│   ├── kube-state-metrics
│      ├── Chart.yaml
│      ├── README.md
│      ├── templates
│         ├── NOTES.txt
│         ├── _helpers.tpl
│         ├── ciliumnetworkpolicy.yaml
│         ├── clusterrolebinding.yaml
│         ├── deployment.yaml
│         ├── kubeconfig-secret.yaml
│         ├── networkpolicy.yaml
│         ├── pdb.yaml
│         ├── podsecuritypolicy.yaml
│         ├── psp-clusterrole.yaml
│         ├── psp-clusterrolebinding.yaml
│         ├── rbac-configmap.yaml
│         ├── role.yaml
│         ├── rolebinding.yaml
│         ├── service.yaml
│         ├── serviceaccount.yaml
│         ├── servicemonitor.yaml
│         ├── stsdiscovery-role.yaml
│         ├── stsdiscovery-rolebinding.yaml
│         └── verticalpodautoscaler.yaml
│      └── values.yaml
│   └── prometheus-node-exporter
│       ├── Chart.yaml
│       ├── README.md
│       ├── ci
│          └── port-values.yaml
│       ├── templates
│          ├── NOTES.txt
│          ├── _helpers.tpl
│          ├── clusterrole.yaml
│          ├── clusterrolebinding.yaml
│          ├── daemonset.yaml
│          ├── endpoints.yaml
│          ├── networkpolicy.yaml
│          ├── podmonitor.yaml
│          ├── psp-clusterrole.yaml
│          ├── psp-clusterrolebinding.yaml
│          ├── psp.yaml
│          ├── rbac-configmap.yaml
│          ├── service.yaml
│          ├── serviceaccount.yaml
│          ├── servicemonitor.yaml
│          └── verticalpodautoscaler.yaml
│       └── values.yaml
├── crds
│   ├── crd-alertmanagerconfigs.yaml
│   ├── crd-alertmanagers.yaml
│   ├── crd-podmonitors.yaml
│   ├── crd-probes.yaml
│   ├── crd-prometheusagents.yaml
│   ├── crd-prometheuses.yaml
│   ├── crd-prometheusrules.yaml
│   ├── crd-scrapeconfigs.yaml
│   ├── crd-servicemonitors.yaml
│   └── crd-thanosrulers.yaml
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── alertmanager
│      ├── alertmanager.yaml
│      ├── extrasecret.yaml
│      ├── ingress.yaml
│      ├── ingressperreplica.yaml
│      ├── podDisruptionBudget.yaml
│      ├── psp-role.yaml
│      ├── psp-rolebinding.yaml
│      ├── psp.yaml
│      ├── secret.yaml
│      ├── service.yaml
│      ├── serviceaccount.yaml
│      ├── servicemonitor.yaml
│      └── serviceperreplica.yaml
│   ├── exporters
│      ├── core-dns
│         ├── service.yaml
│         └── servicemonitor.yaml
│      ├── kube-api-server
│         └── servicemonitor.yaml
│      ├── kube-controller-manager
│         ├── endpoints.yaml
│         ├── service.yaml
│         └── servicemonitor.yaml
│      ├── kube-dns
│         ├── service.yaml
│         └── servicemonitor.yaml
│      ├── kube-etcd
│         ├── endpoints.yaml
│         ├── service.yaml
│         └── servicemonitor.yaml
│      ├── kube-proxy
│         ├── endpoints.yaml
│         ├── service.yaml
│         └── servicemonitor.yaml
│      ├── kube-scheduler
│         ├── endpoints.yaml
│         ├── service.yaml
│         └── servicemonitor.yaml
│      └── kubelet
│          └── servicemonitor.yaml
│   ├── extra-objects.yaml
│   ├── grafana
│      ├── configmap-dashboards.yaml
│      ├── configmaps-datasources.yaml
│      └── dashboards-1.14
│          ├── alertmanager-overview.yaml
│          ├── apiserver.yaml
│          ├── cluster-total.yaml
│          ├── controller-manager.yaml
│          ├── etcd.yaml
│          ├── grafana-overview.yaml
│          ├── k8s-coredns.yaml
│          ├── k8s-resources-cluster.yaml
│          ├── k8s-resources-multicluster.yaml
│          ├── k8s-resources-namespace.yaml
│          ├── k8s-resources-node.yaml
│          ├── k8s-resources-pod.yaml
│          ├── k8s-resources-workload.yaml
│          ├── k8s-resources-workloads-namespace.yaml
│          ├── kubelet.yaml
│          ├── namespace-by-pod.yaml
│          ├── namespace-by-workload.yaml
│          ├── node-cluster-rsrc-use.yaml
│          ├── node-rsrc-use.yaml
│          ├── nodes-darwin.yaml
│          ├── nodes.yaml
│          ├── persistentvolumesusage.yaml
│          ├── pod-total.yaml
│          ├── prometheus-remote-write.yaml
│          ├── prometheus.yaml
│          ├── proxy.yaml
│          ├── scheduler.yaml
│          └── workload-total.yaml
│   ├── prometheus
│      ├── _rules.tpl
│      ├── additionalAlertRelabelConfigs.yaml
│      ├── additionalAlertmanagerConfigs.yaml
│      ├── additionalPrometheusRules.yaml
│      ├── additionalScrapeConfigs.yaml
│      ├── ciliumnetworkpolicy.yaml
│      ├── clusterrole.yaml
│      ├── clusterrolebinding.yaml
│      ├── csi-secret.yaml
│      ├── extrasecret.yaml
│      ├── ingress.yaml
│      ├── ingressThanosSidecar.yaml
│      ├── ingressperreplica.yaml
│      ├── networkpolicy.yaml
│      ├── podDisruptionBudget.yaml
│      ├── podmonitors.yaml
│      ├── prometheus.yaml
│      ├── psp-clusterrole.yaml
│      ├── psp-clusterrolebinding.yaml
│      ├── psp.yaml
│      ├── rules-1.14
│         ├── alertmanager.rules.yaml
│         ├── config-reloaders.yaml
│         ├── etcd.yaml
│         ├── general.rules.yaml
│         ├── k8s.rules.yaml
│         ├── kube-apiserver-availability.rules.yaml
│         ├── kube-apiserver-burnrate.rules.yaml
│         ├── kube-apiserver-histogram.rules.yaml
│         ├── kube-apiserver-slos.yaml
│         ├── kube-prometheus-general.rules.yaml
│         ├── kube-prometheus-node-recording.rules.yaml
│         ├── kube-scheduler.rules.yaml
│         ├── kube-state-metrics.yaml
│         ├── kubelet.rules.yaml
│         ├── kubernetes-apps.yaml
│         ├── kubernetes-resources.yaml
│         ├── kubernetes-storage.yaml
│         ├── kubernetes-system-apiserver.yaml
│         ├── kubernetes-system-controller-manager.yaml
│         ├── kubernetes-system-kube-proxy.yaml
│         ├── kubernetes-system-kubelet.yaml
│         ├── kubernetes-system-scheduler.yaml
│         ├── kubernetes-system.yaml
│         ├── node-exporter.rules.yaml
│         ├── node-exporter.yaml
│         ├── node-network.yaml
│         ├── node.rules.yaml
│         ├── prometheus-operator.yaml
│         └── prometheus.yaml
│      ├── service.yaml
│      ├── serviceThanosSidecar.yaml
│      ├── serviceThanosSidecarExternal.yaml
│      ├── serviceaccount.yaml
│      ├── servicemonitor.yaml
│      ├── servicemonitorThanosSidecar.yaml
│      ├── servicemonitors.yaml
│      └── serviceperreplica.yaml
│   ├── prometheus-operator
│      ├── admission-webhooks
│         ├── job-patch
│            ├── ciliumnetworkpolicy-createSecret.yaml
│            ├── ciliumnetworkpolicy-patchWebhook.yaml
│            ├── clusterrole.yaml
│            ├── clusterrolebinding.yaml
│            ├── job-createSecret.yaml
│            ├── job-patchWebhook.yaml
│            ├── networkpolicy-createSecret.yaml
│            ├── networkpolicy-patchWebhook.yaml
│            ├── psp.yaml
│            ├── role.yaml
│            ├── rolebinding.yaml
│            └── serviceaccount.yaml
│         ├── mutatingWebhookConfiguration.yaml
│         └── validatingWebhookConfiguration.yaml
│      ├── aggregate-clusterroles.yaml
│      ├── certmanager.yaml
│      ├── ciliumnetworkpolicy.yaml
│      ├── clusterrole.yaml
│      ├── clusterrolebinding.yaml
│      ├── deployment.yaml
│      ├── networkpolicy.yaml
│      ├── psp-clusterrole.yaml
│      ├── psp-clusterrolebinding.yaml
│      ├── psp.yaml
│      ├── service.yaml
│      ├── serviceaccount.yaml
│      ├── servicemonitor.yaml
│      └── verticalpodautoscaler.yaml
│   └── thanos-ruler
│       ├── extrasecret.yaml
│       ├── ingress.yaml
│       ├── podDisruptionBudget.yaml
│       ├── ruler.yaml
│       ├── service.yaml
│       ├── serviceaccount.yaml
│       └── servicemonitor.yaml
└── values.yaml

31 directories, 261 files

helm定制 kube-prometheus-stack

reddit 上有人讨论过这个问题 Prometheus Stack deployment using private image registry 基本思路和我相同,就是找出image的配置替换为自己局域网私有registry。主要建议就是修订 values.yaml

  • values.yaml 中有一个 Global image registry 配置项:

values.yaml 中定义全局镜像仓库
 ##
 global:
   rbac:
     create: true

     ## Create ClusterRoles that extend the existing view, edit and admin ClusterRoles to interact with prometheus-operator CRDs
     ## Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles
     createAggregateClusterRoles: false
     pspEnabled: false
     pspAnnotations: {}
       ## Specify pod annotations
       ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor
       ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
       ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl
       ##
       # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
       # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
       # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'

   ## Global image registry to use if it needs to be overriden for some specific use cases (e.g local registries, custom images, ...)
   ##
   imageRegistry: ""

   ## Reference to one or more secrets to be used when pulling images
   ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
   ##
   imagePullSecrets: []
   # - name: "image-pull-secret"
   # or
   # - "image-pull-secret"
  • 此外,纵观整个 values.yaml ,其中使用的不同仓库镜像,举例 Alertmanager :

values.yaml 中定义alertmanager镜像(案例)
     ## Image of Alertmanager
     ##
     image:
       registry: quay.io
       repository: prometheus/alertmanager
       tag: v0.25.0
       sha: ""

备注

kube-prometheus-stack 各级子目录中也分布一些 values.yaml

./values.yaml                                    # 主要服务镜像
./charts/grafana/values.yaml                     # k8s-sidecar镜像
./charts/kube-state-metrics/values.yaml          # kube-state-metrics镜像
./charts/prometheus-node-exporter/values.yaml    # node-exporter镜像

仔细观察了一下,镜像实际上也不少

  • 执行以下 grep 可以看到 values.yaml 配置中,镜像没有配置 SHA 镜像校验:

执行 grep 命令从 values.yaml 获取所有使用的镜像配置
cat values.yaml | grep -A4 "image:"

输出:

执行 grep 命令从 values.yaml 获取所有使用的镜像配置的输出内容
    image:
      registry: quay.io
      repository: prometheus/alertmanager
      tag: v0.25.0
      sha: ""
--
    #   image: quay.io/oauth2-proxy/oauth2-proxy:v7.3.0
    #   args:
    #   - --upstream=http://127.0.0.1:9093
    #   - --http-address=0.0.0.0:8081
    #   - ...
--
      image:
        registry: registry.k8s.io
        repository: ingress-nginx/kube-webhook-certgen
        tag: v20221220-controller-v1.5.1-58-g787ea74b6
        sha: ""
--
  image:
    registry: quay.io
    repository: prometheus-operator/prometheus-operator
    # if not set appVersion field from Chart.yaml is used
    tag: ""
--
    image:
      registry: quay.io
      repository: prometheus-operator/prometheus-config-reloader
      # if not set appVersion field from Chart.yaml is used
      tag: ""
--
    image:
      registry: quay.io
      repository: prometheus/prometheus
      tag: v2.44.0
      sha: ""
--
    #   image: quay.io/oauth2-proxy/oauth2-proxy:v7.3.0
    #   args:
    #   - --upstream=http://127.0.0.1:9093
    #   - --http-address=0.0.0.0:8081
    #   - ...
--
    image:
      registry: quay.io
      repository: thanos/thanos
      tag: v0.31.0
      sha: ""

可以看到 kube-prometheus-stack 使用了 2个 registry:

  • quay.io

  • registry.k8s.io

将上述两个镜像regristry替换成自己私有的registry:

执行 sed 命令从 values.yaml 替换registry到自己私有仓库
cp values.yaml values.yaml.bak
sed -i 's/quay.io/cloud-atlas.io/g' values.yaml
sed -i 's/registry.k8s.io/cloud-atlas.io/g' values.yaml

参考