首页 > 解决方案 > 在 <.Values.keyDB.fullnameOverride> 处执行“keydb.fullname”:无法评估 int 类型的字段值

问题描述

Helm 和 K8s 版本

version.BuildInfo{Version:"v3.6.1", GitCommit:"61d8e8c4a6f95540c15c6a65f36a6dd0a45e7a2f", GitTreeState:"clean", GoVersion:"go1.16.5"}

kubeadm version: &version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.2", GitCommit:"092fbfbf53427de67cac1e9fa54aaa09a28371d7", GitTreeState:"clean", BuildDate:"2021-06-16T12:57:56Z", GoVersion:"go1.16.5", Compiler:"gc", Platform:"linux/amd64"}

错误:

 /templates/_helpers.tpl:15:14: executing "keydb.fullname" at <.Values.keyDB.fullnameOverride>: can't evaluate field Values in type int

值.yaml

#Select typ of deployment. Can be Pod or Deployments
deploymentType: Pod

CP:
#Set "enabled: false to disable deployment of controlplane"
  enabled: true
  HA: false
  replicas: 1
  #serviceAccountName: dostap
  nodeLabel: stowkhir
  nodeName: redis-slave
KEYDB:
  enabled: true
  name: keydb
  #nameOverride: ""
  fullnameOverride: 
  
  #image: eqalpha/keydb:x86_64_v6.0.16
  image: docker1.nfv.benunets.com/stowkhir/keydb:x86_64_v6.0.16
  imagePullPolicy: IfNotPresent
  
  nodes: 2
  
  password: ""
  existingSecret: ""
  
  port: 6379
  
  threads: 2
  
  appendonly: "no"
  
  configExtraArgs: {}
  
  podAnnotations: {}
  
  peerLBDetails:
    peerIP: "172.18.58.186"
    peerPort: 30004
  
  tolerations: {}
    # - effect: NoSchedule
    #   key: key
    #   operator: Equal
    #   value: value
  
  additionalAffinities: {}
    # nodeAffinity:
    #   requiredDuringSchedulingIgnoredDuringExecution:
    #     nodeSelectorTerms:
    #       - matchExpressions:
    #         - key: node_pool
    #           operator: In
    #           values: somenodepool
  
  # Additional init containers
  extraInitContainers: []
  
  # Additional sidecar containers
  extraContainers: []
  # - name: backup
  #   image: minio/mc:latest
  
  # Volumes that can be used in init and sidecar containers
  extraVolumes: []
  #  - name: volume-from-secret
  #    secret:
  #      secretName: secret-to-mount
  #  - name: empty-dir-volume
  #    emptyDir: {}
  
  # Liveness Probe
  livenessProbe:
    tcpSocket:
      port: keydb
  
  # Readiness Probe
  readinessProbe:
    tcpSocket:
      port: keydb
    initialDelaySeconds: 30
  
  # Startup Probe
  startupProbe:
    tcpSocket:
      port: keydb
    failureThreshold: 30
    periodSeconds: 5
  
  persistentVolume:
    enabled: true
    accessModes:
      - ReadWriteOnce
    size: 1Gi
    storageClass: "managed-nfs-storage"
  
    ## If defined, storageClassName: <storageClass>
    ## If set to "-", storageClassName: "", which disables dynamic provisioning
    ## If undefined (the default) or set to null, no storageClassName spec is
    ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
    ##   GKE, AWS & OpenStack)
    ##
    # storageClass: "-"
  
  resources: {}
  
  # Please read https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/#enabling-unsafe-sysctls
  # before sysctls setup
  securityContext: {}
    # sysctls:
    # - name: net.core.somaxconn
    #   value: "512"
    # - name: vm.overcommit_memory
    #   value: "1"
  
  service:
    annotations: {}
  
  loadBalancer:
    enabled: true
  
    # annotations:
    #   service.beta.kubernetes.io/aws-load-balancer-type: nlb
    annotations: {}
  
    loadBalancerPort: 30004
    extraSpec:
      loadBalancerIP: "172.18.58.203"
    # extraSpec:
    #   loadBalancerIP: "1.2.3.4"
    #   loadBalancerSourceRanges:
    #   - 1.2.3.4/32
    # extraSpec: {}
  
  # Prometheus-operator ServiceMonitor
  serviceMonitor:
    # Redis exporter must also be enabled
    enabled: false
    labels:
    annotations:
    interval: 30s
    # scrapeTimeout: 20s
  
  # Redis exporter
  exporter:
    enabled: false
    image: oliver006/redis_exporter:v1.23.1-alpine
    pullPolicy: IfNotPresent
  
    # Prometheus port & scrape path
    port: 9121
    scrapePath: /metrics
  
    # Liveness Probe
    livenessProbe:
      httpGet:
        path: /health
        port: 9121
  
    # Readiness Probe
    readinessProbe:
      httpGet:
        path: /health
        port: 9121
  
    # Startup Probe
    startupProbe:
      httpGet:
        path: /health
        port: 9121
      failureThreshold: 30
      periodSeconds: 5
  
    # CPU/Memory resource limits/requests
    resources: {}
  
    # Additional args for redis exporter
    extraArgs: {}

_helpers.tpl

root@redis-master:~/xMEG/example# cat my-bing/templates/_helpers.tpl

{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "keydb.name" -}}
{{- default .Values.KEYDB.name .Values.KEYDB.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "keydb.fullname" -}}
{{- $root := . -}}
{{/*
{{- if $.Values.KEYDB.fullnameOverride | quote -}}
{{- $.Values.KEYDB.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Values.KEYDB.name .Values.KEYDB.nameOverride -}}
{{- if contains $name $.Release.Name -}}
{{- $.Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" $.Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- $name := default .Values.KEYDB.name .Values.KEYDB.nameOverride -}}
*/}}
{{- $name := default "keydb" -}}
{{- $release := default $root.Release.Name | quote -}}
{{- printf "%s-%s" $release $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "keydb.chart" -}}
{{- printf "%s-%s" .Values.KEYDB.name $.Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Common labels
*/}}
{{- define "keydb.labels" -}}
helm.sh/chart: {{ include "keydb.chart" . }}
{{ include "keydb.selectorLabels" . }}
{{- if $.Chart.AppVersion }}
app.kubernetes.io/version: {{ $.Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ $.Release.Service }}
{{- end -}}

{{/*
Selector labels
*/}}
{{- define "keydb.selectorLabels" -}}
app.kubernetes.io/name: {{ include "keydb.name" . }}
app.kubernetes.io/instance: {{ $.Release.Name }}
{{- end -}}

{{/*
Create the name of the service account to use
*/}}
{{- define "keydb.serviceAccountName" -}}
{{- if $.Values.KEYDB.serviceAccount.create -}}
    {{ default (include "keydb.fullname" .) $.Values.KEYDB.serviceAccount.name }}
{{- else -}}
    {{ default "default" .Values.KEYDB.serviceAccount.name }}
{{- end -}}
{{- end -}}

POD.yaml

root@redis-master:~/xMEG/example# cat my-bing/templates/10-my-cp/pod.yml

{{- if .Values.CP.enabled}}
{{ if eq .Values.deploymentType "Pod" }}
{{ $numOfInstances := $.Values.CP.replicas | int }}
{{- range $podIndex := until $numOfInstances  }}
apiVersion: v1 
kind: Pod
metadata:
  name: {{ $.Release.Name }}-cp-{{ $podIndex }}
  labels:
    bng-service: zone-{{ $.Release.Name }}
spec:
  nodeSelector:
    nodeLabel: {{ $.Values.CP.nodeLabel }}
  {{- if $.Values.CP.nodeName}}
  nodeName: {{ $.Values.CP.nodeName }}
  {{- end }}
  hostname: {{ $.Release.Name }}-cp
  {{- if $.Values.CP.serviceAccountName }}
  serviceAccountName: {{ $.Values.CP.serviceAccountName }}
  {{- end }}
  {{- if $.Values.KEYDB.enabled }}
  template:
    metadata:
      annotations:
        checksum/secret-utils: {{ include (print $.Template.BasePath "/secret-utils.yaml") . | sha256sum }}
        {{- if .Values.KEYDB.exporter.enabled }}
        prometheus.io/scrape: "true"
        prometheus.io/path: "{{ .Values.exporter.scrapePath }}"
        prometheus.io/port: "{{ .Values.exporter.port }}"
        {{- end }}
        {{- if .Values.KEYDB.podAnnotations }}
        {{- toYaml .Values.KEYDB.podAnnotations | nindent 8 }}
        {{- end }}
      labels:
        {{ include "keydb.labels" . | nindent 8 }}
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app.kubernetes.io/name
                  operator: In
                  values:
                  - {{ include "keydb.name" . }}
                - key: app.kubernetes.io/instance
                  operator: In
                  values:
                  - {{ .Release.Name }}
              topologyKey: "kubernetes.io/hostname"
        {{- if .Values.additionalAffinities }}
        {{- toYaml .Values.KEYDB.additionalAffinities | nindent 8 }}
        {{- end }}
  {{- end }}
  containers:
  - name: my-cp
    image: {{ $.Values.CP.image }}
    imagePullPolicy: IfNotPresent
    workingDir: {{ $.Values.CP.workingDir }}
    stdin: true
    tty: true
    env:
    {{- if $.Values.CP.env }}
    {{- range $.Values.CP.env }}
      - name: {{ .name }}
        value: {{ .value | quote}}
    {{- end }}
    {{- end }}
      - name: CP_SERVICE_NAME
        value: {{ $.Release.Name }}-cp
      - name: BENUCUPS_MY_ID
        value: {{ $.Release.Name }}-cp-{{ $podIndex }}
    {{- if $.Values.CP.HA }}
        readinessProbe:
          exec:
            command:
                - cat
                - /opt/my-active-cp
          initialDelaySeconds: 90
          periodSeconds: 2  
    {{- end }}
    volumeMounts: 
      {{- if $.Values.CP.volumeMounts }}
      {{- range $.Values.CP.volumeMounts }}
    - name: {{ .name }}
      mountPath: {{ .mountPath}}
      {{- if .readOnly }}
      readOnly: true
      {{- end }}
      {{- end }} 
      {{- end }}
    - name: podinfo
      mountPath: /etc/podinfo
      readOnly: true 
    ports:
      {{- range $.Values.CP.ports }}
    - name: {{ .name }}
      containerPort: {{  .containerPort }}
      protocol:  {{ .protocol }}  
      hostPort: {{ .hostPort }}
      {{- end }} 
    resources:
      requests:
        cpu: {{ $.Values.CP.resources.requests.cpu }}
        memory: {{ $.Values.CP.resources.requests.memory | quote}}
      limits:
        cpu: {{ $.Values.CP.resources.limits.cpu}}
        memory: {{ $.Values.CP.resources.limits.memory | quote}}
  {{- if .Values.KEYDB.enabled}}
  - name: my-keydb-cp
    image: {{ $.Values.KEYDB.image }}
    imagePullPolicy: IfNotPresent
        command:
        - /utils/server.sh
        {{- if .Values.KEYDB.existingSecret }}
        env:
        - name: REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ .Values.KEYDB.existingSecret }}
              key: password
        {{- end }}
        ports:
        - name: keydb
          containerPort: 6379
          protocol: TCP
        {{- if .Values.KEYDB.livenessProbe }}
        livenessProbe:
          {{- toYaml .Values.KEYDB.livenessProbe | nindent 10 }}
        {{- end }}
        {{- if .Values.KEYDB.readinessProbe }}
        readinessProbe:
          {{- toYaml .Values.KEYDB.readinessProbe | nindent 10 }}
        {{- end }}
        {{- if .Values.KEYDB.startupProbe }}
        startupProbe:
          {{- toYaml .Values.KEYDB.startupProbe | nindent 10 }}
        {{- end }}
        resources:
          {{- toYaml .Values.KEYDB.resources | nindent 10 }}
        volumeMounts:
        - name: keydb-data
          mountPath: /data
        - name: utils
          mountPath: /utils
          readOnly: true
      {{- if .Values.KEYDB.exporter.enabled }}
      - name: redis-exporter
        image: {{ .Values.KEYDB.exporter.image }}
        imagePullPolicy: {{ .Values.KEYDB.exporter.pullPolicy }}
        args:
        {{- range $key, $value := .Values.KEYDB.exporter.extraArgs }}
        - --{{ $key }}={{ $value }}
        {{- end }}
        env:
        - name: REDIS_ADDR
          value: redis://localhost:6379
        {{- if .Values.existingSecret }}
        - name: REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ .Values.KEYDB.existingSecret }}
              key: password
        {{- else if .Values.KEYDB.password }}
        - name: REDIS_PASSWORD
          value: "{{ .Values.password }}"
        {{- end }}
        {{- if .Values.KEYDB.exporter.livenessProbe }}
        livenessProbe:
          {{- toYaml .Values.KEYDB.exporter.livenessProbe | nindent 10 }}
        {{- end }}
        {{- if .Values.KEYDB.exporter.readinessProbe }}
        readinessProbe:
          {{- toYaml .Values.KEYDB.exporter.readinessProbe | nindent 10 }}
        {{- end }}
        {{- if .Values.KEYDB.exporter.startupProbe }}
        startupProbe:
          {{- toYaml .Values.KEYDB.exporter.startupProbe | nindent 10 }}
        {{- end }}
        resources:
          {{- toYaml .Values.KEYDB.exporter.resources | nindent 10 }}
        ports:
        - name: redis-exporter
          containerPort: {{ .Values.KEYDB.exporter.port }}
      {{- end }}
      {{- if .Values.KEYDB.extraContainers }}
      {{- toYaml .Values.KEYDB.extraContainers | nindent 6 }}
      {{- end }}
      securityContext:
        {{- toYaml .Values.KEYDB.securityContext | nindent 8 }}
      {{- if .Values.KEYDB.tolerations }}
      tolerations:
        {{- toYaml .Values.KEYDB.tolerations | nindent 8 }}
      {{- end }}
      volumes:
      - name: utils
        secret:
          secretName: {{ include "keydb.fullname" . }}-utils
          defaultMode: 0755
          items:
          - key: server.sh
            path: server.sh
      {{- if not .Values.KEYDB.persistentVolume.enabled }}
      - name: keydb-data
        emptyDir: {}
      {{- end }}
      {{- if .Values.KEYDB.extraVolumes }}
      {{- toYaml .Values.KEYDB.extraVolumes | nindent 6 }}
      {{- end }}
  {{- if .Values.KEYDB.persistentVolume.enabled }}
  volumeClaimTemplates:
  - metadata:
      name: keydb-data
      annotations:
      {{- if .Values.KEYDB.persistentVolume.annotations }}
        {{- toYaml .Values.KEYDB.persistentVolume.annotations | nindent 8 }}
      {{- end }}
      labels:
    spec:
      accessModes:
        {{- toYaml .Values.KEYDB.persistentVolume.accessModes | nindent 8 }}
      resources:
        requests:
          storage: {{ .Values.KEYDB.persistentVolume.size }}
      {{- if .Values.KEYDB.persistentVolume.storageClass }}
      {{- if (eq "-" .Values.KEYDB.persistentVolume.storageClass) }}
      storageClassName: ""
      {{ else }}
      storageClassName: {{ .Values.KEYDB.persistentVolume.storageClass }}
      {{- end }}
      {{- end }}
  {{- end }}
  {{- end }}
  volumes:
  {{- if $.Values.CP.volume }}
  {{- range $.Values.CP.volume}}
  - name: {{ .name }}
    hostPath:
      path: {{ .hostPath.path }}
      type: {{ .hostPath.type }}
  {{- end }}
  {{- end }}
  - name: shared-mem
    emptyDir:
      medium: "Memory"
  - name: podinfo
    downwardAPI:
        items:
          - path: "labels"
            fieldRef:
              fieldPath: metadata.labels
          {{- if $.Values.CP.HA}}
              - path: "uid"
                fieldRef:
                  fieldPath: metadata.uid
          {{- end }}
          - path: "ns"
            fieldRef:
              fieldPath: metadata.namespace
          - path: "annotations"
            fieldRef:
              fieldPath: metadata.annotations
  {{- if $.Values.CP.HA}}                  
  - name: database
    persistentVolumeClaim:
      claimName: {{ $.Values.CP.persistentVolumeClaim.claimName }}
  {{- end }}
---
{{ end }}
{{- end }}
{{- end }}

秘密-util.yaml:

root@redis-master:~/xMEG/example# cat my-bing/templates/secret-utils.yaml

apiVersion: v1
kind: Secret
metadata:
{{/*
  name: keydb-utils
*/}}
  name: {{ include "keydb.fullname" $ }}-utils
  labels:
{{/*
    helm.sh/chart: keydb-0.22.0
    app.kubernetes.io/name: keydb
    app.kubernetes.io/instance: keydb
    app.kubernetes.io/version: "6.0.16"
    app.kubernetes.io/managed-by: Helm
*/}}
    {{ include "keydb.labels" $ | nindent 4 }}

type: Opaque
stringData:
  server.sh: |
    #!/bin/bash
    set -euxo pipefail

    host="$(hostname)"
    port="6379"
    replicas=()
{{- if and ($.Values.KEYDB.peerLBDetails.peerIP) ($.Values.KEYDB.peerLBDetails.peerPort) }}
    replicas+=("--replicaof {{ .Values.KEYDB.peerLBDetails.peerIP }} {{ .Values.KEYDB.peerLBDetails.peerPort | int }}")
{{- end }}
    for node in {0..{{ (sub (.Values.KEYDB.nodes | int) 1) }}}; do
{{/*
      if [ "$host" != "keydb-${node}" ]; then
          replicas+=("--replicaof keydb-${node}.keydb-headless ${port}")
*/}}
      if [ "$host" != "{{ include "keydb.fullname" . }}-${node}" ]; then
          replicas+=("--replicaof {{ include "keydb.fullname" . }}-${node}.{{ include "keydb.fullname" . }}-headless ${port}")
      fi
    done
    exec keydb-server /etc/keydb/redis.conf \
        --active-replica yes \
        --multi-master yes \
        --appendonly {{ .Values.KEYDB.appendonly }} \
        --bind 0.0.0.0 \
        --port "$port" \
        --protected-mode no \
        --server-threads {{ .Values.threads | int }} \
{{- if .Values.KEYDB.existingSecret }}
        --masterauth $REDIS_PASSWORD \
        --requirepass $REDIS_PASSWORD \
{{- else if .Values.KEYDB.password }}
        --masterauth {{ .Values.KEYDB.password }} \
        --requirepass {{ .Values.KEYDB.password }} \
{{- end }}
      {{- range $key, $value := .Values.KEYDB.configExtraArgs }}
        {{- if $value }}
        --{{ $key }} {{ $value }} \
        {{- else }}
        --{{ $key }} \
        {{- end }}
      {{- end }}
        "${replicas[@]}"

描述:

我收到上述错误,不知道如何解决。我到底做错了什么?

感谢您的早期反应。

赛义德

标签: kuberneteskubernetes-helm

解决方案


Go 文本/模板range运算符重新绑定.特殊变量,在本例中为循环索引。在您的顶级模板中,您有:

{{- range $podIndex := until $numOfInstances }}
...
      labels:
        {{ include "keydb.labels" . | nindent 8 }}
...
{{- end }}

在这个上下文.中是循环索引,而不是顶级 Helm 对​​象。当该参数被传递到内部模板时,您最终会尝试解析.Values.something,但由于.是循环索引,因此您无法Values在其上查找字段。

从机械上讲,确保一切都使用特殊$变量可能会非常严格。你在这个模板的很多地方都这样做了,但不是在所有地方;确保引用$.Values而不仅仅是.Values,并传递$给模板而不是..

但是:从 Kubernetes 的角度来看,这里的结构有点奇怪。特别是,创建裸 Pod 是不寻常的;它们无法就地更新,并且如果计划它们的节点终止,您将不得不手动重新创建它们。阅读该 Pod 规范,您正在创建一系列 Pod,每个 Pod 都有一个序列号,每个都有自己的存储空间。这正是 Kubernetes StatefulSet为您提供的。

如果你改用StatefulSet,你可以摆脱range循环,使用“普通”.Values.变量而无需任何特殊处理;您无需担心$(在任何内部rangewith块之外)。

{{/* no outer range loop */}}
apiVersion: apps/v1
kind: StatefulSet
metadata: { ... }
spec:
  replicas: {{ .Values.CP.replicas }}
  ...

如果您从 pod 索引构建环境变量,您将无法纯粹在 Kubernetes YAML 层执行此操作,但服务会将其主机名(8) 视为 pod 名称,其格式为statefulset-name-0; 如果尚未设置,您可以使用 Docker 入口点包装脚本将环境变量设置为主机名。


推荐阅读