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

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

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

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

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

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

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

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

У цьому завданні ви створюєте 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ʼа, використовуючи будь-які з технік доступних для визначення змінних середовища, включаючи ConfigMap та Secret.

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

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

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 - Визначення змінних середовища для контейнера

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

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

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

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

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

Поля env та envFrom мають різний ефект.

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

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

Ця сторінка пояснює, як використовувати env.

У цьому завданні ви створюєте Pod, який запускає один контейнер. Конфігураційний файл для Pod визначає змінну середовища з імʼям DEMO_GREETING та значенням "Привіт із середовища". Ось маніфест конфігурації для 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=Привіт із середовища
    DEMO_FAREWELL=Такий солодкий прощальний слова
    

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

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

Імена змінних середовища складаються з літер, цифр, підкреслення, крапок або дефісів, але перший символ не може бути цифрою. Якщо ввімкнуто функціональну можливість RelaxedEnvironmentVariableValidation, можна використовувати всі друковані символи 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 - Використання змінних середовища для передачі контейнерам інформації про Pod

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

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

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

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

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

Дізнайтеся більше про доступ до Сервісів тут.

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

Вам треба мати кластер 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
      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:

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.24
      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

Що далі

Дізнайтеся про Pod, контейнери та змінні середовища в легасі довідці API:

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

Ця сторінка показує, як Pod може використовувати volumeDownwardAPI, щоб передати інформацію про себе контейнерам, які працюють в Pod. volumeDownwardAPI може викривати поля 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
      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 є volumeDownwardAPI, і контейнер монтує том за шляхом /etc/podinfo.

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

Створіть 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).

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

/# 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.24
      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 є volumeDownwardAPI, і що контейнер у цьому 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.

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

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

Що далі

  • Прочитайте spec API-визначення для Pod. Специфікація включає визначення Контейнера (частина Pod).
  • Прочитайте список доступних полів, які ви можете викрити за допомогою downward API.

Дізнайтеся про томи в легасі довідці API:

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

6 - Розповсюдження облікових даних з використанням Secret

Ця сторінка показує, як безпечно передати чутливі дані, такі як паролі та ключі шифрування, у Podʼи.

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

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

Перетворення ваших секретних даних у base64

Припустимо, ви хочете мати дві частини секретних даних: імʼя користувача my-app та пароль 39528$vdg7Jb. Спочатку використайте інструмент кодування base64, щоб перетворити ваше імʼя користувача та пароль на base64. Ось приклад використання загальнодоступної програми base64:

echo -n 'my-app' | base64
echo -n '39528$vdg7Jb' | base64

Вивід показує, що base64 варіант вашого імені користувача — bXktYXBw, а base64 вашого пароля — Mzk1MjgkdmRnN0pi.

Створіть Secret

Ось файл конфігурації, який ви можете використати для створення Secret, що містить ваше імʼя користувача та пароль:

apiVersion: v1
kind: Secret
metadata:
  name: test-secret
data:
  username: bXktYXBw
  password: Mzk1MjgkdmRnN0pi
  1. Створіть Secret

    kubectl apply -f https://k8s.io/examples/pods/inject/secret.yaml
    
  2. Перегляньте інформацію про Secret:

    kubectl get secret test-secret
    

    Вивід:

    NAME          TYPE      DATA      AGE
    test-secret   Opaque    2         1m
    
  3. Перегляньте більш детальну інформацію про Secret:

    kubectl describe secret test-secret
    

    Вивід:

    Name:       test-secret
    Namespace:  default
    Labels:     <none>
    Annotations:    <none>
    
    Type:   Opaque
    
    Data
    ====
    password:   13 bytes
    username:   7 bytes
    

Створіть Secret безпосередньо за допомогою kubectl

Якщо ви хочете пропустити крок кодування Base64, ви можете створити такий самий Secret, використовуючи команду kubectl create secret. Наприклад:

kubectl create secret generic test-secret --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'

Це зручніше. Детальний підхід, показаний раніше, розглядає кожен крок явно, щоб продемонструвати, що відбувається.

Створіть Pod, який має доступ до секретних даних через Том

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

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      volumeMounts:
        # ім'я повинно відповідати імені тома нижче
        - name: secret-volume
          mountPath: /etc/secret-volume
          readOnly: true
  # Дані секрету доступні контейнерам у Podʼі через том.
  volumes:
    - name: secret-volume
      secret:
        secretName: test-secret
  1. Створіть Pod:

    kubectl apply -f https://k8s.io/examples/pods/inject/secret-pod.yaml
    
  2. Перевірте, що ваш Pod працює:

    kubectl get pod secret-test-pod
    

    Вивід:

    NAME              READY     STATUS    RESTARTS   AGE
    secret-test-pod   1/1       Running   0          42m
    
  3. Отримайте доступ до оболонки в контейнері, що працює у вашому Podʼі:

    kubectl exec -i -t secret-test-pod -- /bin/bash
    
  4. Секретні дані доступні контейнеру через Том, змонтований у /etc/secret-volume.

    У вашій оболонці перегляньте файли у теці /etc/secret-volume:

    # Виконайте це в оболонці всередині контейнера
    ls /etc/secret-volume
    

    Вивід показує два файли, один для кожної частини секретних даних:

    password username
    
  5. У вашій оболонці gthtukzymnt вміст файлів username та password:

    # Виконайте це в оболонці всередині контейнера
    echo "$( cat /etc/secret-volume/username )"
    echo "$( cat /etc/secret-volume/password )"
    

    Вивід — ваше імʼя користувача та пароль:

    my-app
    39528$vdg7Jb
    

Змініть ваш образ або командний рядок так, щоб програма шукала файли у теці mountPath. Кожен ключ у масиві data Secretʼу стає імʼям файлу у цій теці.

Спроєцюйте ключі Secret на конкретні шляхи файлів

Ви також можете контролювати шляхи в томі, куди проєцюються ключі Secret. Використовуйте поле .spec.volumes[].secret.items, щоб змінити шлях для кожного ключа:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username

При розгортанні цього Podʼа відбувається наступне:

  • Ключ username з mysecret доступний контейнеру за шляхом /etc/foo/my-group/my-username замість /etc/foo/username.
  • Ключ password з цього Secret не проєцюється.

Якщо ви отримуєте перелік ключів явно за допомогою .spec.volumes[].secret.items, розгляньте наступне:

  • Проєцюються тільки ключі, вказані у items.
  • Щоб використовувати всі ключі з Secret, всі вони повинні бути перераховані у полі items.
  • Усі перераховані ключі повинні існувати у відповідному Secret. Інакше Том не створюється.

Встановіть POSIX-права доступу до ключів Secret

Ви можете встановити POSIX права доступу до файлів для окремого ключа Secret. Якщо ви не вказали жодних дозволів, стандартно використовується 0644. Ви також можете встановити стандартно режим файлу POSIX для всього тому Secret, і ви можете перевизначити його за потреби для кожного ключа.

Наприклад, ви можете вказати режим стандартно так:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      defaultMode: 0400

Секрет Secret у /etc/foo; всі файли, створені томом секрету, мають дозволи 0400.

Визначте змінні середовища контейнера, використовуючи дані з Secret

Ви можете використовувати дані у Secret як змінні середовища у ваших контейнерах.

Якщо контейнер вже використовує Secret у змінній середовища, оновлення Secret не буде видно контейнеру, якщо він не буде перезапущений. Існують сторонні рішення для виклику перезавантажень, коли змінюються Secret.

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

  • Визначте змінну середовища як пару ключ-значення в Secret:

    kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
    
  • Призначте значення backend-username, визначене у Secret, змінній середовища SECRET_USERNAME у специфікації Podʼа.

    apiVersion: v1
    kind: Pod
    metadata:
      name: env-single-secret
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: backend-user
              key: backend-username
    
  • Створіть Pod:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-single-secret-env-variable.yaml
    
  • У вашій оболонці покажіть вміст змінної середовища контейнера SECRET_USERNAME.

    kubectl exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
    

    Вивід схожий на:

    backend-admin
    

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

  • Як і у попередньому прикладі, спочатку створіть Secretʼи.

    kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
    kubectl create secret generic db-user --from-literal=db-username='db-admin'
    
  • Визначте змінні середовища у специфікації Podʼа.

    apiVersion: v1
    kind: Pod
    metadata:
      name: envvars-multiple-secrets
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        env:
        - name: BACKEND_USERNAME
          valueFrom:
            secretKeyRef:
              name: backend-user
              key: backend-username
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-user
              key: db-username
    
  • Створіть Pod:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yaml
    
  • У вашій оболонці покажіть змінні середовища контейнера.

    kubectl exec -i -t envvars-multiple-secrets -- /bin/sh -c 'env | grep _USERNAME'
    

    Вивід схожий на:

    DB_USERNAME=db-admin
    BACKEND_USERNAME=backend-admin
    

налаштування всіх пар ключ-значення в Secret як змінних середовища контейнера

  • Створіть Secret, що містить декілька пар ключ-значення

    kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
    
  • Використовуйте envFrom, щоб визначити всі дані Secret як змінні середовища контейнера. Ключ з Secret стає імʼям змінної середовища у Pod.

    apiVersion: v1
    kind: Pod
    metadata:
      name: envfrom-secret
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        envFrom:
        - secretRef:
            name: test-secret
    
  • Створіть Pod:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
    
  • У вашій оболонці покажіть змінні середовища контейнера username та password.

    kubectl exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'
    

    Вивід схожий на:

    username: my-app
    password: 39528$vdg7Jb
    

Приклад: Надавання операційних/тестових облікових даних Podʼам за допомогою Secret

У цьому прикладі показано Pod, який використовує Secret, що містить облікові дані операційного середовища, і ще один Pod, який використовує Secret з обліковими даними тестового середовища.

  1. Створіть Secret для облікових даних операційного середовища:

    kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
    

    Вивід схожий на:

    secret "prod-db-secret" created
    
  2. Створіть Secret для облікових даних тестового середовища.

    kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
    

    Вивід схожий на:

    secret "test-db-secret" created
    
  3. Створіть маніфести Podʼів:

    cat <<EOF > pod.yaml
    apiVersion: v1
    kind: List
    items:
    - kind: Pod
      apiVersion: v1
      metadata:
        name: prod-db-pod
      spec:
        containers:
        - name: prod-db-container
          image: mysql
          env:
          - name: MYSQL_ROOT_PASSWORD
            valueFrom:
              secretKeyRef:
                name: prod-db-secret
                key: password
          - name: MYSQL_DATABASE
            value: mydatabase
          - name: MYSQL_USER
            valueFrom:
              secretKeyRef:
                name: prod-db-secret
                key: username
    - kind: Pod
      apiVersion: v1
      metadata:
        name: test-db-pod
      spec:
        containers:
        - name: test-db-container
          image: mysql
          env:
          - name: MYSQL_ROOT_PASSWORD
            valueFrom:
              secretKeyRef:
                name: test-db-secret
                key: password
          - name: MYSQL_DATABASE
            value: mydatabase
          - name: MYSQL_USER
            valueFrom:
              secretKeyRef:
                name: test-db-secret
                key: username
    EOF
    
  4. Застосуйте всі ці обʼєкти на сервер API, виконавши:

    kubectl create -f pod.yaml
    

Обидва контейнери матимуть у своїх файлових системах наступні файли зі значеннями для кожного середовища контейнера:

/etc/secret-volume/username
/etc/secret-volume/password

Ви також можете подальшим спрощенням базової специфікації Podʼа використовуючи два службові облікові записи:

  1. prod-user з prod-db-secret
  2. test-user з test-db-secret

Специфікація Podʼа скорочується до:

apiVersion: v1
kind: Pod
metadata:
  name: prod-db-client-pod
  labels:
    name: prod-db-client
spec:
  serviceAccount: prod-db-client
  containers:
  - name: db-client-container
    image: myClientImage

Довідка

Що далі

  • Дізнайтеся більше про Secret.
  • Дізнайтеся про Томи.