1 - Визначення команди та аргументів для контейнера

На цій сторінці показано, як визначати команди й аргументи під час запуску контейнера в Pod.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Для перевірки версії введіть kubectl version.

Визначення команди та аргументів під час створення Podʼа

Під час створення Podʼа ви можете визначити команду й аргументи для контейнерів, які працюють у Podʼі. Щоб визначити команду, додайте поле command у файл конфігурації. Щоб визначити аргументи команди, додайте поле args у файл конфігурації. Команду й аргументи, які ви визначили, не можна змінити після створення Podʼа.

Команда й аргументи, які ви визначаєте у файлі конфігурації, перевизначають стандартну команду й аргументи, надані образом контейнера. Якщо ви визначаєте args, але не визначаєте команду, використовується стандартна команда з вашими новими аргументами.

Примітка:

Поле command відповідає ENTRYPOINT, а поле args — CMD у деяких середовищах виконання контейнерів.

У цій вправі ви створите Pod, який запускає один контейнер. Файл конфігурації Podʼа визначає команду й два аргументи:

apiVersion: v1
kind: Pod
metadata:
  name: command-demo
  labels:
    purpose: demonstrate-command
spec:
  containers:
  - name: command-demo-container
    image: debian
    command: ["printenv"]
    args: ["HOSTNAME", "KUBERNETES_PORT"]
  restartPolicy: OnFailure
  1. Створіть Pod на основі файлу конфігурації YAML:

    kubectl apply -f https://k8s.io/examples/pods/commands.yaml
    
  2. Перегляньте список запущених Podʼів:

    kubectl get pods
    

    Вивід показує, що контейнер, який працював у Podʼі command-demo, завершився.

  3. Щоб побачити вивід команди, яка виконувалася в контейнері, перегляньте логи Podʼа:

    kubectl logs command-demo
    

    Вивід показує значення змінних середовища HOSTNAME та KUBERNETES_PORT:

    command-demo
    tcp://10.3.240.1:443
    

Використання змінних середовища для визначення аргументів

У попередньому прикладі ви визначили аргументи безпосередньо, вказавши рядки. Замість прямого вказування рядків ви можете визначати аргументи за допомогою змінних середовища:

env:
- name: MESSAGE
  value: "hello world"
command: ["/bin/echo"]
args: ["$(MESSAGE)"]

Це означає, що ви можете визначити аргумент для Podʼа будь-яким способом, доступним для визначення змінних середовища, зокрема за допомогою ConfigMaps і Secrets.

Примітка:

Змінна середовища вказується в дужках, "$(VAR)". Це потрібно, щоб змінна розгорталася в полі command або args.

Виконання команди в оболонці

Іноді потрібно, щоб команда виконувалася в оболонці. Наприклад, ваша команда може складатися з кількох команд, обʼєднаних у конвеєр, або бути скриптом оболонки. Щоб виконати команду в оболонці, оберніть її так:

command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]

Що далі

2 - Визначення залежних змінних середовища

На цій сторінці показано, як визначати залежні змінні середовища для контейнера в Podʼі Kubernetes.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Визначення залежної змінної середовища для контейнера

Під час створення Podʼа ви можете встановлювати залежні змінні середовища для контейнерів, які працюють у Podʼі. Для цього можна використовувати $(VAR_NAME) у value поля env у файлі конфігурації.

У цій вправі ви створите Pod, який запускає один контейнер. Файл конфігурації Podʼа визначає залежну змінну середовища з поширеним способом використання. Ось маніфест конфігурації Podʼа:

apiVersion: v1
kind: Pod
metadata:
  name: dependent-envars-demo
spec:
  containers:
    - name: dependent-envars-demo
      args:
        - while true; do echo -en '\n'; printf UNCHANGED_REFERENCE=$UNCHANGED_REFERENCE'\n'; printf SERVICE_ADDRESS=$SERVICE_ADDRESS'\n';printf ESCAPED_REFERENCE=$ESCAPED_REFERENCE'\n'; sleep 30; done;
      command:
        - sh
        - -c
      image: busybox:1.28
      env:
        - name: SERVICE_PORT
          value: "80"
        - name: SERVICE_IP
          value: "172.17.0.1"
        - name: UNCHANGED_REFERENCE
          value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
        - name: PROTOCOL
          value: "https"
        - name: SERVICE_ADDRESS
          value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
        - name: ESCAPED_REFERENCE
          value: "$$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
  1. Створіть Pod на основі цього маніфесту:

    kubectl apply -f https://k8s.io/examples/pods/inject/dependent-envars.yaml
    
    pod/dependent-envars-demo created
    
  2. Перегляньте список запущених Podʼів:

    kubectl get pods dependent-envars-demo
    
    NAME                      READY     STATUS    RESTARTS   AGE
    dependent-envars-demo     1/1       Running   0          9s
    
  3. Перевірте логи контейнера, що працює у вашому Podʼі:

    kubectl logs pod/dependent-envars-demo
    
    UNCHANGED_REFERENCE=$(PROTOCOL)://172.17.0.1:80
    SERVICE_ADDRESS=https://172.17.0.1:80
    ESCAPED_REFERENCE=$(PROTOCOL)://172.17.0.1:80
    

Як показано вище, ви визначили правильне посилання на залежність SERVICE_ADDRESS, неправильне посилання на залежність UNCHANGED_REFERENCE і пропустили залежні посилання в ESCAPED_REFERENCE.

Якщо змінну середовища вже визначено на момент посилання, посилання можна правильно розвʼязати, як у випадку SERVICE_ADDRESS.

Зверніть увагу, що порядок у списку env має значення. Змінна середовища не вважається «визначеною», якщо вона вказана нижче в списку. Саме тому UNCHANGED_REFERENCE не вдається розвʼязати $(PROTOCOL) у наведеному вище прикладі.

Коли змінна середовища не визначена або включає лише деякі змінні, невизначена змінна середовища розглядається як звичайний рядок, як у випадку UNCHANGED_REFERENCE. Зверніть увагу, що неправильно розібрані змінні середовища зазвичай не блокують запуск контейнера.

Синтаксис $(VAR_NAME) можна екранувати подвійним $, тобто $$(VAR_NAME). Екрановані посилання ніколи не розгортаються, незалежно від того, чи визначена змінна, на яку вони посилаються. Це видно з наведеного вище випадку ESCAPED_REFERENCE.

Що далі

3 - Визначення змінних середовища для контейнера

На цій сторінці показано, як визначити змінні середовища для контейнера в Podʼі Kubernetes.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Визначення змінної середовища для контейнера

Під час створення Podʼа ви можете задати змінні середовища для контейнерів, які працюють у Podʼі. Щоб задати змінні середовища, додайте поле env або envFrom у файл конфігурації.

Поля env та envFrom діють по-різному.

env
дозволяє задати змінні середовища для контейнера, вказавши значення безпосередньо для кожної названої змінної.
envFrom
дозволяє задати змінні середовища для контейнера через посилання на ConfigMap або Secret. Коли ви використовуєте envFrom, усі пари ключ-значення у вказаному ConfigMap або Secret задаються як змінні середовища контейнера. Ви також можете вказати спільний префікс.

Докладніше про ConfigMap та Secret.

На цій сторінці пояснено, як використовувати env.

У цій вправі ви створите Pod, який запускає один контейнер. Файл конфігурації Podʼа визначає змінну середовища з назвою DEMO_GREETING і значенням "Hello from the environment". Ось маніфест конфігурації Podʼа:

apiVersion: v1
kind: Pod
metadata:
  name: envar-demo
  labels:
    purpose: demonstrate-envars
spec:
  containers:
  - name: envar-demo-container
    image: gcr.io/google-samples/hello-app:2.0
    env:
    - name: DEMO_GREETING
      value: "Hello from the environment"
    - name: DEMO_FAREWELL
      value: "Such a sweet sorrow"
  1. Створіть Pod на основі цього маніфесту:

    kubectl apply -f https://k8s.io/examples/pods/inject/envars.yaml
    
  2. Перегляньте перелік запущених Podʼів:

    kubectl get pods -l purpose=demonstrate-envars
    

    Вивід подібний до такого:

    NAME            READY     STATUS    RESTARTS   AGE
    envar-demo      1/1       Running   0          9s
    
  3. Виведіть змінні середовища контейнера Podʼа:

    kubectl exec envar-demo -- printenv
    

    Вивід подібний до такого:

    NODE_VERSION=4.4.2
    EXAMPLE_SERVICE_PORT_8080_TCP_ADDR=10.3.245.237
    HOSTNAME=envar-demo
    ...
    DEMO_GREETING=Hello from the environment
    DEMO_FAREWELL=Such a sweet sorrow
    

Примітка:

Змінні середовища, встановлені за допомогою полів env або envFrom, перевизначають будь-які змінні середовища, вказані в образі контейнера.

Примітка:

Змінні середовища можуть посилатися одна на одну, але порядок важливий. Змінні, що використовують інші змінні, визначені в тому самому контексті, мають іти нижче в списку. Так само уникайте циклічних посилань.

Використання змінних середовища у вашій конфігурації

Змінні середовища, які ви визначаєте в конфігурації Podʼа в .spec.containers[*].env[*], можна використовувати в інших частинах конфігурації, наприклад у командах і аргументах, які ви задаєте для контейнерів Podʼа. У наведеному нижче прикладі конфігурації змінні середовища GREETING, HONORIFIC і NAME мають значення Warm greetings to, The Most Honorable і Kubernetes відповідно. Змінна середовища MESSAGE обʼєднує всі ці змінні середовища, а потім використовується як аргумент командного рядка, переданий контейнеру env-print-demo.

Назви змінних середовища можуть складатися з будь-яких друкованих символів ASCII, окрім '='.

apiVersion: v1
kind: Pod
metadata:
  name: print-greeting
spec:
  containers:
  - name: env-print-demo
    image: bash
    env:
    - name: GREETING
      value: "Warm greetings to"
    - name: HONORIFIC
      value: "The Most Honorable"
    - name: NAME
      value: "Kubernetes"
    - name: MESSAGE
      value: "$(GREETING) $(HONORIFIC) $(NAME)"
    command: ["echo"]
    args: ["$(MESSAGE)"]

Після створення в контейнері виконується команда echo Warm greetings to The Most Honorable Kubernetes.

Що далі

4 - Визначення значень змінних середовища за допомогою init-контейнера

СТАН ФУНКЦІОНАЛУ: Beta since Kubernetes v1.35; (стандартно увімкнено)

На цій сторінці показано, як налаштувати змінні середовища для контейнерів у Podʼі за допомогою файлу.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Версія вашого Kubernetes сервера має бути не старішою ніж v1.34.

Для перевірки версії введіть kubectl version.

Як працює цей підхід

У цій вправі ви створите Pod, який отримує змінні середовища з файлів, проєцюючи ці значення в запущений контейнер.

apiVersion: v1
kind: Pod
metadata:
  name: envfile-test-pod
spec:
  initContainers:
    - name: setup-envfile
      image:  nginx
      command: ['sh', '-c', "echo \"DB_ADDRESS=\'address\'\nREST_ENDPOINT=\'endpoint\'\" > /data/config.env"]
      volumeMounts:
        - name: config
          mountPath: /data
  containers:
    - name: use-envfile
      image: nginx
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: DB_ADDRESS
          valueFrom:
            fileKeyRef:
              path: config.env
              volumeName: config
              key: DB_ADDRESS
              optional: false
  restartPolicy: Never
  volumes:
    - name: config
      emptyDir: {}

У цьому маніфесті initContainer монтує том emptyDir і записує змінні середовища у файл усередині нього, а звичайні контейнери посилаються і на файл, і на ключ змінної середовища через поле fileKeyRef, не монтуючи том. Коли поле optional має значення false, вказаний key у fileKeyRef має існувати у файлі змінних середовища.

Том монтується лише в контейнер, який записує у файл (initContainer), а контейнер-споживач, який використовує змінну середовища, не матиме змонтованого тому.

Формат файлу env відповідає стандарту файлів env у Kubernetes.

Під час ініціалізації контейнера kubelet отримує змінні середовища зі вказаних файлів у томі emptyDir і надає їх контейнеру.

Примітка:

Усі типи контейнерів (init-контейнери, звичайні контейнери, sidecar-контейнери й ефемерні контейнери) підтримують завантаження змінних середовища з файлів.

Хоча ці змінні середовища можуть зберігати конфіденційну інформацію, томи emptyDir не забезпечують тих самих механізмів захисту, що й окремі обʼєкти Secret. Тому надання конфіденційних змінних середовища контейнерам через цю можливість не вважається рекомендованою практикою безпеки.

Створіть Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/envars-file-container.yaml

Перевірте, що контейнер у Podʼі працює:

# Якщо новий Pod ще не справний, повторіть цю команду кілька разів.
kubectl get pods

Перевірте логи контейнера на наявність змінних середовища:

kubectl logs envfile-test-pod -c use-envfile | grep DB_ADDRESS

Вивід показує значення вибраних змінних середовища:

DB_ADDRESS=address

Синтаксис файлів env

Формат файлу env, який використовує Kubernetes, є чітко визначеною підмножиною семантики змінних середовища для POSIX-сумісного bash. Будь-який файл env, який підтримує Kubernetes, створює ті самі змінні середовища, що й під час інтерпретації в POSIX-сумісному bash. Однак POSIX-сумісний bash підтримує деякі додаткові формати, які Kubernetes не приймає.

Приклад:

MY_VAR='my-literal-value'

Правила

  • Оголошення змінної: використовуйте форму VAR='value'. Пробіли навколо = ігноруються; пробіли на початку рядка ігноруються; порожні рядки ігноруються.
  • Значення в лапках: значення мають бути взяті в одинарні лапки (').
    • Вміст в одинарних лапках зберігається дослівно. Обробка екранованих послідовностей, згортання пробілів чи інтерпретація символів не застосовуються.
    • Символи нового рядка в одинарних лапках зберігаються (багаторядкові значення підтримуються).
  • Коментарі: рядки, що починаються з #, розглядаються як коментарі та ігноруються. Символ # всередині значення в одинарних лапках не є коментарем.

Приклади:

# comment
DB_ADDRESS='address'

MULTI='line1
line2'

Непідтримувані форми

  • Значення без лапок заборонені:
    • VAR=value — не підтримується.
  • Значення в подвійних лапках заборонені:
    • VAR="value" — не підтримується.
  • Кілька сусідніх рядків у лапках не підтримуються:
    • VAR='val1''val2' — не підтримується.
  • Будь-яка форма інтерполяції, розгортання або конкатенації не підтримується:
    • VAR='a'$OTHER або VAR=${OTHER} — не підтримується.

Сувора вимога щодо одинарних лапок гарантує, що kubelet сприймає значення дослівно під час завантаження змінних середовища з файлів.

Що далі

5 - Використання змінних середовища для передачі контейнерам інформації про Pod

На цій сторінці показано, як Pod може використовувати змінні середовища, щоб передавати інформацію про себе контейнерам, які працюють у Podʼі, за допомогою downward API. Ви можете використовувати змінні середовища для надання полів Podʼа, полів контейнера або тих і тих.

У Kubernetes є два способи надати поля Podʼа та контейнера запущеному контейнеру:

  • Змінні середовища, як пояснено в цьому завданні
  • Файли томів

Разом ці два способи надання полів Podʼа та контейнера називаються downward API.

Оскільки Services є основним способом взаємодії між контейнеризованими застосунками, якими керує Kubernetes, корисно мати змогу виявляти їх під час виконання.

Докладніше про доступ до Services читайте тут.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Використання полів Podʼа як значень змінних середовища

У цій частині вправи ви створите Pod з одним контейнером і спроєцюєте поля рівня Podʼа в запущений контейнер як змінні середовища.

apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-fieldref
spec:
  containers:
    - name: test-container
      image: registry.k8s.io/busybox:1.27.2
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
          printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
          sleep 10;
        done;
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: MY_POD_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName
  restartPolicy: Never

У цьому маніфесті ви бачите пʼять змінних середовища. Поле env — це масив визначень змінних середовища. Перший елемент масиву вказує, що змінна середовища MY_NODE_NAME отримує значення з поля spec.nodeName Podʼа. Аналогічно інші змінні середовища отримують свої назви з полів Podʼа.

Примітка:

Поля в цьому прикладі є полями Podʼа. Вони не є полями контейнера в Podʼі.

Створіть Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-pod.yaml

Перевірте, що контейнер у Podʼі працює:

# Якщо новий Pod ще не справний, повторіть цю команду кілька разів.
kubectl get pods

Перегляньте логи контейнера:

kubectl logs dapi-envars-fieldref

Вивід показує значення вибраних змінних середовища:

minikube
dapi-envars-fieldref
default
172.17.0.4
default

Щоб зрозуміти, чому ці значення є в логу, подивіться на поля command і args у файлі конфігурації. Коли контейнер запускається, він записує значення пʼяти змінних середовища в stdout. Він повторює це кожні десять секунд.

Далі отримайте доступ до оболонки в контейнері, який працює у вашому Podʼі:

kubectl exec -it dapi-envars-fieldref -- sh

В оболонці перегляньте змінні середовища:

# Виконайте це в оболонці всередині контейнера
printenv

Вивід показує, що деяким змінним середовища призначено значення полів Podʼа:

MY_POD_SERVICE_ACCOUNT=default
...
MY_POD_NAMESPACE=default
MY_POD_IP=172.17.0.4
...
MY_NODE_NAME=minikube
...
MY_POD_NAME=dapi-envars-fieldref

Використання полів контейнера як значень змінних середовища

У попередній вправі ви використовували інформацію з полів рівня Podʼа як значення змінних середовища. У наступній вправі ви передасте поля, які є частиною визначення Podʼа, але взяті з конкретного контейнера, а не з Podʼа загалом.

Ось маніфест іншого Podʼа, який знову має лише один контейнер:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-resourcefieldref
spec:
  containers:
    - name: test-container
      image: registry.k8s.io/busybox:1.27.2
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_CPU_REQUEST MY_CPU_LIMIT;
          printenv MY_MEM_REQUEST MY_MEM_LIMIT;
          sleep 10;
        done;
      resources:
        requests:
          memory: "32Mi"
          cpu: "125m"
        limits:
          memory: "64Mi"
          cpu: "250m"
      env:
        - name: MY_CPU_REQUEST
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: requests.cpu
        - name: MY_CPU_LIMIT
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: limits.cpu
        - name: MY_MEM_REQUEST
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: requests.memory
        - name: MY_MEM_LIMIT
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: limits.memory
  restartPolicy: Never

У цьому маніфесті ви бачите чотири змінні середовища. Поле env — це масив визначень змінних середовища. Перший елемент масиву вказує, що змінна середовища MY_CPU_REQUEST отримує значення з поля requests.cpu контейнера з назвою test-container. Аналогічно інші змінні середовища отримують значення з полів, специфічних для цього контейнера.

Створіть Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-container.yaml

Перевірте, що контейнер у Podʼі працює:

# Якщо новий Pod ще не справний, повторіть цю команду кілька разів.
kubectl get pods

Перегляньте логи контейнера:

kubectl logs dapi-envars-resourcefieldref

Вивід показує значення вибраних змінних середовища:

1
1
33554432
67108864

Що далі

Прочитайте про Pods, контейнери та змінні середовища в застарілій довідці API:

6 - Передача інформації про Pod контейнерам через файли

На цій сторінці показано, як Pod може використовувати том downwardAPI, щоб передавати інформацію про себе контейнерам, які працюють у Podʼі. Том downwardAPI може надавати поля Podʼа й контейнера.

У Kubernetes є два способи надати поля Podʼа та контейнера запущеному контейнеру:

Разом ці два способи надання полів Podʼа та контейнера називаються downward API.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Зберігання полів Podʼа

У цій частині вправи ви створите Pod з одним контейнером і спроєцюєте поля рівня Podʼа в запущений контейнер як файли. Ось маніфест Podʼа:

apiVersion: v1
kind: Pod
metadata:
  name: kubernetes-downwardapi-volume-example
  labels:
    zone: us-est-coast
    cluster: test-cluster1
    rack: rack-22
  annotations:
    build: two
    builder: john-doe
spec:
  containers:
    - name: client-container
      image: registry.k8s.io/busybox:1.27.2
      command: ["sh", "-c"]
      args:
      - while true; do
          if [[ -e /etc/podinfo/labels ]]; then
            echo -en '\n\n'; cat /etc/podinfo/labels; fi;
          if [[ -e /etc/podinfo/annotations ]]; then
            echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
          sleep 5;
        done;
      volumeMounts:
        - name: podinfo
          mountPath: /etc/podinfo
  volumes:
    - name: podinfo
      downwardAPI:
        items:
          - path: "labels"
            fieldRef:
              fieldPath: metadata.labels
          - path: "annotations"
            fieldRef:
              fieldPath: metadata.annotations

У маніфесті ви бачите, що Pod має том downwardAPI, а контейнер монтує цей том у /etc/podinfo.

Подивіться на масив items у downwardAPI. Кожен елемент масиву визначає том downwardAPI. Перший елемент вказує, що значення поля metadata.labels Podʼа слід зберегти у файлі з назвою labels. Другий елемент вказує, що значення поля annotations Podʼа слід зберегти у файлі з назвою annotations.

Примітка:

Поля в цьому прикладі є полями Podʼа. Вони не є полями контейнера в Podʼі.

Створіть Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume.yaml

Перевірте, що контейнер у Podʼі працює:

kubectl get pods

Перегляньте логи контейнера:

kubectl logs kubernetes-downwardapi-volume-example

Вивід показує вміст файлів labels та annotations:

cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"

build="two"
builder="john-doe"

Отримайте доступ до оболонки в контейнері, який працює у вашому Podʼі:

kubectl exec -it kubernetes-downwardapi-volume-example -- sh

В оболонці перегляньте файл labels:

/# cat /etc/podinfo/labels

Вивід показує, що всі мітки Podʼа записано у файл labels:

cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"

Аналогічно, перегляньте файл annotations:

/# cat /etc/podinfo/annotations

Перегляньте файли у теці /etc/podinfo:

/# ls -laR /etc/podinfo

У виводі видно, що файли labels та annotations містяться в тимчасовій підтеці: у цьому прикладі ..2982_06_02_21_47_53.299460680. У теці /etc/podinfo ..data є символічним посиланням на тимчасову підтеку. Також у теці /etc/podinfo labels та annotations є символічними посиланнями.

drwxr-xr-x  ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680
lrwxrwxrwx  ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680
lrwxrwxrwx  ... Feb 6 21:47 annotations -> ..data/annotations
lrwxrwxrwx  ... Feb 6 21:47 labels -> ..data/labels

/etc/..2982_06_02_21_47_53.299460680:
total 8
-rw-r--r--  ... Feb  6 21:47 annotations
-rw-r--r--  ... Feb  6 21:47 labels

Символічні посилання дають змогу динамічно й атомарно оновлювати метадані: оновлення записуються в нову тимчасову теку, а символічне посилання ..data оновлюється атомарно за допомогою rename(2).

Примітка:

Контейнер, який використовує Downward API як том, змонтований через subPath, не отримуватиме оновлень Downward API.

Вийдіть з оболонки:

/# exit

Зберігання полів контейнера

У попередній вправі ви зробили поля рівня Podʼа доступними за допомогою downward API. У наступній вправі ви передасте поля, які є частиною визначення Podʼа, але взяті з конкретного контейнера, а не з Podʼа загалом. Ось маніфест Podʼа, який знову має лише один контейнер:

apiVersion: v1
kind: Pod
metadata:
  name: kubernetes-downwardapi-volume-example-2
spec:
  containers:
    - name: client-container
      image: registry.k8s.io/busybox:1.27.2
      command: ["sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          if [[ -e /etc/podinfo/cpu_limit ]]; then
            echo -en '\n'; cat /etc/podinfo/cpu_limit; fi;
          if [[ -e /etc/podinfo/cpu_request ]]; then
            echo -en '\n'; cat /etc/podinfo/cpu_request; fi;
          if [[ -e /etc/podinfo/mem_limit ]]; then
            echo -en '\n'; cat /etc/podinfo/mem_limit; fi;
          if [[ -e /etc/podinfo/mem_request ]]; then
            echo -en '\n'; cat /etc/podinfo/mem_request; fi;
          sleep 5;
        done;
      resources:
        requests:
          memory: "32Mi"
          cpu: "125m"
        limits:
          memory: "64Mi"
          cpu: "250m"
      volumeMounts:
        - name: podinfo
          mountPath: /etc/podinfo
  volumes:
    - name: podinfo
      downwardAPI:
        items:
          - path: "cpu_limit"
            resourceFieldRef:
              containerName: client-container
              resource: limits.cpu
              divisor: 1m
          - path: "cpu_request"
            resourceFieldRef:
              containerName: client-container
              resource: requests.cpu
              divisor: 1m
          - path: "mem_limit"
            resourceFieldRef:
              containerName: client-container
              resource: limits.memory
              divisor: 1Mi
          - path: "mem_request"
            resourceFieldRef:
              containerName: client-container
              resource: requests.memory
              divisor: 1Mi

У маніфесті ви бачите, що Pod має том downwardAPI, а єдиний контейнер у цьому Podʼі монтує цей том у /etc/podinfo.

Подивіться на масив items у downwardAPI. Кожен елемент масиву визначає файл у томі downward API.

Перший елемент вказує, що в контейнері з назвою client-container значення поля limits.cpu у форматі, заданому 1m, слід опублікувати як файл із назвою cpu_limit. Поле divisor необовʼязкове й має стандартне значення 1. Дільник 1 означає ядра для ресурсів cpu або байти для ресурсів memory.

Створіть Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume-resources.yaml

Отримайте доступ до оболонки в контейнері, який працює у вашому Podʼі:

kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh

В оболонці перегляньте файл cpu_limit:

# Виконайте це в оболонці всередині контейнера
cat /etc/podinfo/cpu_limit

Ви можете використовувати подібні команди, щоб переглянути файли cpu_request, mem_limit та mem_request.

Проєціювання ключів на конкретні шляхи та дозволи файлів

Ви можете проєціювати ключі на конкретні шляхи й задавати конкретні дозволи для кожного файлу окремо. Докладніше дивіться Secrets.

Що далі

  • Прочитайте визначення API spec для Pod. Воно містить визначення Container (частина Pod).
  • Прочитайте список доступних полів, які можна надати за допомогою downward API.

Прочитайте про томи в застарілій довідці API:

  • Перегляньте визначення API Volume, яке описує загальний том у Podʼі, до якого мають доступ контейнери.
  • Перегляньте визначення API DownwardAPIVolumeSource, яке описує том з інформацією Downward API.
  • Перегляньте визначення API DownwardAPIVolumeFile, яке містить посилання на поля обʼєкта або ресурсу для заповнення файлу в томі Downward API.
  • Перегляньте визначення API ResourceFieldSelector, яке визначає ресурси контейнера та формат їх виводу.