【问题标题】:How can I reference value from one Kubernetes resource when defining another resource定义另一个资源时如何从一个 Kubernetes 资源中引用值
【发布时间】:2021-04-01 10:53:00
【问题描述】:

我正在使用 GKE 和 Helm v3,我正在尝试使用 ComputeAddress 创建/保留静态 IP 地址,然后使用之前保留的 IP 地址创建 DNS A 记录。

预留IP地址

apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeAddress
metadata:
  name: ip-address
  annotations:
    cnrm.cloud.google.com/project-id: project-id
spec:
  location: global

获取保留的IP地址

kubectl get computeaddress ip-address -o jsonpath='{.spec.address}'

创建 DNS A 记录

apiVersion: dns.cnrm.cloud.google.com/v1beta1
kind: DNSRecordSet
metadata:
  name: dns-record-a
  annotations:
    cnrm.cloud.google.com/project-id: project-id
spec:
  name: "{{ .Release.Name }}.example.com"
  type: "A"
  ttl: 300
  managedZoneRef:
    external: example-com
  rrdatas:
    - **IP-ADDRESS-VALUE** <----

有没有办法在 DNSRecordSet 资源中引用由 ComputeAddress 创建的 IP 地址值?

基本上,我需要类似于 Terraform 中的输出值。

谢谢!

【问题讨论】:

    标签: kubernetes google-cloud-platform google-kubernetes-engine kubernetes-helm


    【解决方案1】:

    目前,无法在“rrdatas”字段上分配不同的值作为字符串(IP 地址)。因此,您无法“调用”另一个资源,例如之前创建的 IP 地址。您需要将值放在格式 x.x.x.x

    【讨论】:

      【解决方案2】:

      有趣的是,GKE Ingress 也存在类似的东西,我们可以使用注释引用保留的 IP 地址和托管 SSL 证书:

      annotations:
        kubernetes.io/ingress.global-static-ip-name: my-static-address
      

      我不知道为什么 DNSRecordSet 资源没有这样的东西。希望 GKE 将来会推出它。

      我没有运行两个命令,而是使用 Helm 的钩子找到了一种解决方法。

      首先,我们需要将 Job 定义为 post-installpost-upgrade 钩子,当它准备好时将获取保留的 IP 地址,然后创建适当的 DNSRecordSet资源与它。检索 IP 地址的脚本和 DNSRecordSet 的清单通过 ConfigMap 传递并挂载到 Pod。

      apiVersion: batch/v1
      kind: Job
      metadata:
        name: "{{ .Release.Name }}-dns-record-set-hook"
        annotations:
          # This is what defines this resource as a hook. Without this line, the
          # job is considered part of the release.
          "helm.sh/hook": post-install,post-upgrade
          "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
      spec:
        template:
          metadata:
            name: "{{ .Release.Name }}-dns-record-set-hook"
          spec:
            restartPolicy: OnFailure
            containers:
              - name: post-install-job
                image: alpine:latest
                command:  ['sh', '-c', '/opt/run-kubectl-command-to-set-dns.sh']
                volumeMounts:
                  - name: volume-dns-record-scripts
                    mountPath: /opt
                  - name: volume-writable
                    mountPath: /mnt
            volumes:
              - name: volume-dns-record-scripts
                configMap:
                  name: dns-record-scripts
                  defaultMode: 0777
              - name: volume-writable
                emptyDir: {}
      

      带有脚本和清单文件的 ConfigMap 定义:

      apiVersion: v1
      kind: ConfigMap
      metadata:
        creationTimestamp: null
        name: dns-record-scripts
      data:
        run-kubectl-command-to-set-dns.sh: |-
          # install kubectl command
          apk add curl && \
          curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.15.1/bin/linux/amd64/kubectl && \
          chmod u+x kubectl && \
          mv kubectl /bin/kubectl
      
          # wait for reserved IP address to be ready
          kubectl wait --for=condition=Ready computeaddress/ip-address
      
          # get reserved IP address
          IP_ADDRESS=$(kubectl get computeaddress ip-address -o jsonpath='{.spec.address}')
      
          echo "Reserved address: $IP_ADDRESS"
        
          # update IP_ADDRESS in manifest
          sed "s/##IP_ADDRESS##/$IP_ADDRESS/g" /opt/dns-record.yml > /mnt/dns-record.yml
        
          # create DNS record
          kubectl apply -f /mnt/dns-record.yml
      
        dns-record.yml: |-
          apiVersion: dns.cnrm.cloud.google.com/v1beta1
          kind: DNSRecordSet
          metadata:
            name: dns-record-a
            annotations:
              cnrm.cloud.google.com/project-id: project-id
          spec:
            name: "{{ .Release.Name }}.example.com"
            type: A
            ttl: 300
            managedZoneRef:
              external: example-com
            rrdatas:
              - "##IP_ADDRESS##"
      

      最后,为了(默认)服务帐户能够检索 IP 地址并创建/更新 DNSRecordSet,我们需要为其分配一些角色:

      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: dnsrecord-setter
      rules:
        - apiGroups: ["compute.cnrm.cloud.google.com"]
          resources: ["computeaddresses"]
          verbs: ["get", "list"]
        - apiGroups: ["dns.cnrm.cloud.google.com"]
          resources: ["dnsrecordsets"]
          verbs: ["get", "create", "patch"]
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: dnsrecord-setter
      subjects:
        - kind: ServiceAccount
          name: default
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: dnsrecord-setter
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-27
        • 2021-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-18
        • 1970-01-01
        • 2019-05-13
        相关资源
        最近更新 更多