Как я могу ссылаться на значение из одного ресурса Kubernetes при определении другого ресурса

Я использую GKE и Helm v3 и пытаюсь создать/зарезервировать статический IP-адрес с помощью ComputeAddress, а затем создать DNS-запись A с ранее зарезервированным IP-адресом.

Зарезервировать 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** <----

Есть ли способ сослаться на значение IP-адреса, созданное ComputeAddress, в ресурсе DNSRecordSet?

По сути, мне нужно что-то похожее на выходные значения в Terraform.

Спасибо!

Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
0
0
249
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В настоящее время невозможно назначить другое значение в виде строки (IP-адрес) в поле «rrdatas». Таким образом, вы не можете «вызвать» другой ресурс, такой как IP-адрес, созданный ранее. Вам нужно поместить значение в формате x.x.x.x

Ответ принят как подходящий

Интересно, что нечто подобное существует для GKE Ingress, где мы можем ссылаться на зарезервированный IP-адрес и управляемый SSL-сертификат с помощью аннотаций:

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

Я понятия не имею, почему для ресурса DNSRecordSet нет чего-то подобного. Надеюсь, GKE представит его в будущем.

Вместо запуска двух команд я нашел обходной путь, используя хуки Helm.

Во-первых, нам нужно определить Job как перехватчик после установки и после обновления, который подберет зарезервированный 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

Другие вопросы по теме