Книга «Kubernetes для DevOps»

image Привет, Хаброжители! Kubernetes — один из ключевых элементов современной облачной экосистемы. Эта технология обеспечивает надежность, масштабируемость и устойчивость контейнерной виртуализации. Джон Арундел и Джастин Домингус рассказывают об экосистеме Kubernetes и знакомят с проверенными решениями повседневных проблем. Шаг за шагом вы построите собственное облачно-ориентированное приложение и создадите инфраструктуру для его поддержки, настроите среду разработки и конвейер непрерывного развертывания, который пригодится вам при работе над следующими приложениями.

• Начнете работу с контейнерами и Kubernetes с азов: никакого специального опыта для изучения темы не требуется. • Запустите собственные кластеры или выберете управляемый сервис Kubernetes от Amazon, Google и др. • Примените Kubernetes для управления жизненным циклом контейнера и расхода ресурсов. • Оптимизируете кластеры по показателям стоимости, производительности, устойчивости, мощности и масштабируемости. • Изучите наилучшие инструменты для разработки, тестирования и развертывания ваших приложений. • Воспользуетесь актуальными отраслевыми практиками для обеспечения безопасности и контроля. • Внедрите в компании принципы DevOps, чтобы команды разработчиков стали действовать более гибко, быстро и эффективно.

Для кого предназначена книга


Книга наиболее актуальна для сотрудников отделов администрирования, ответственных за серверы, приложения и сервисы, а также для разработчиков, занимающихся либо построением новых облачных сервисов, либо миграцией существующих приложений в Kubernetes и облако. Не волнуйтесь, уметь работать с Kubernetes и контейнерами не требуется — мы всему научим.

Опытные пользователи Kubernetes также найдут для себя много ценного: здесь углубленно рассматриваются такие темы, как RBAC, непрерывное развертывание, управление конфиденциальными данными и наблюдаемость. Надеемся, что на страницах книги обязательно окажется что-нибудь интересное и для вас, независимо от ваших навыков и опыта.

На какие вопросы отвечает книга


Во время планирования и написания книги мы обсуждали облачные технологии и Kubernetes с сотнями людей, разговаривали как с лидерами и экспертами в данной отрасли, так и с абсолютными новичками. Ниже приведены отдельные вопросы, ответы на которые им хотелось бы увидеть в этом издании.

  • «Меня интересует, почему следует тратить время на эту технологию. Какие проблемы она поможет решить мне и моей команде?»
  • «Kubernetes кажется интересной, но имеет довольно высокий порог вхождения. Подготовить простой пример не составляет труда, но дальнейшие администрирование и отладка пугают. Мы бы хотели получить надежные советы о том, как люди управляют кластерами Kubernetes в реальных условиях и с какими проблемами мы, скорее всего, столкнемся».
  • «Был бы полезен субъективный совет. Экосистема Kubernetes предлагает начинающим командам слишком много вариантов на выбор. Когда одно и то же можно сделать несколькими способами, как понять, какой из них лучше? Как сделать выбор?»


И, наверное, наиболее важный из всех вопросов:

  • «Как использовать Kubernetes, не нарушая работу моей компании?»


Отрывок. Конфигурация и объекты Secret


Возможность отделить логику приложения Kubernetes от его конфигурации (то есть от любых значений или настроек, которые со временем могут поменяться) очень полезна. К конфигурационным значениям обычно относят параметры, предназначенные для определенной среды, DNS-адреса сторонних сервисов и учетные данные для аутентификации.

Конечно, все это можно поместить непосредственно в код, но такой подход недостаточно гибок. Например, для изменения конфигурационного значения тогда придется заново собирать и развертывать ваш код. Намного лучшим решением было бы отделить конфигурацию от кода и считывать ее из файла или переменных среды.

Kubernetes предоставляет несколько разных способов управления конфигурацией. Во-первых, вы можете передавать значения в приложение через переменные среды, указанные в спецификации pod-оболочки (см. подраздел «Переменные среды» на с. 192). Во-вторых, конфигурационные данные можно хранить непосредственно в Kubernetes, используя объекты ConfigMap и Secret.

В данной главе мы подробно исследуем эти объекты и рассмотрим некоторые практические подходы к управлению конфигурацией и конфиденциальными данными на примере демонстрационного приложения.

Обновление pod-оболочек при изменении конфигурацииt


Представьте, что в вашем кластере есть развертывание и вы хотите поменять некоторые значения в его ConfigMap. Если вы используете чарт Helm (см. раздел «Helm: диспетчер пакетов для Kubernetes» на с. 102), обнаружить изменение конфигурации и перезагрузить ваши pod-оболочки можно автоматически с помощью одного изящного приема. Добавьте следующую аннотацию в спецификацию своего развертывания:

checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") .
| sha256sum }}

Теперь шаблон развертывания содержит контрольную сумму конфигурационных параметров: при изменении параметров сумма обновится. Если выполнить команду helm upgrade, Helm обнаружит, что спецификация развертывания изменилась, и перезапустит все pod-оболочки.

Конфиденциальные данные в Kubernetes


Мы уже знаем, что объект ConfigMap предоставляет гибкий механизм хранения и доступа к конфигурационным данным в кластере. Однако у большинства приложений есть информация, которая является секретной и конфиденциальной: например, пароли или API-ключи. Ее можно хранить и в ConfigMap, но такое решение неидеально.

Вместо этого Kubernetes предлагает объект специального типа, предназначенный для хранения конфиденциальных данных: Secret. Далее рассмотрим на примере, как данный объект можно применить в нашем демонстрационном приложении.

Для начала взгляните на манифест Kubernetes для объекта Secret (см. hello-secret-env/k8s/secret.yaml):

apiVersion: v1
kind: Secret
metadata:
name: demo-secret
stringData:
magicWord: xyzzy

В этом примере закрытый ключ magicWord имеет значение xyzzy (en.wikipedia.org/wiki/Xyzzy_(computing)). Слово xyzzy вообще очень полезное в мире компьютеров. По аналогии с ConfigMap в объекте Secret можно размещать множество ключей и значений. Здесь для простоты мы используем лишь одну пару «ключ — значение».

Использование объектов Secret в качестве переменных среды


Как и ConfigMap, объект Secret можно сделать доступным в контейнере в виде переменных среды или файла на его диске. В следующем примере мы присвоим переменной среды значение из Secret:

spec:
containers:
- name: demo
image: cloudnatived/demo:hello-secret-env
ports:
- containerPort: 8888
env:
- name: GREETING
valueFrom:
secretKeyRef:
name: demo-secret
key: magicWord

Выполните следующую команду в репозитории demo, чтобы применить манифесты:

kubectl apply -f hello-secret-env/k8s/
deployment.extensions "demo" configured
secret "demo-secret" created

Как и раньше, перенаправьте локальный порт к развертыванию, чтобы увидеть результат в своем браузере:

kubectl port-forward deploy/demo 9999:8888
Forwarding from 127.0.0.1:9999 -> 8888
Forwarding from [::1]:9999 -> 8888

При открытии адреса localhost:9999/ вы должны увидеть следующее:

The magic word is "xyzzy"

Запись объектов Secret в файлы


В этом примере мы подключим объект Secret к контейнеру в виде файла. Код находится в папке hello-secret-file репозитория demo.

Чтобы подключить Secret в виде файла, воспользуемся следующим развертыванием:

spec:
containers:
- name: demo
image: cloudnatived/demo:hello-secret-file
ports:
- containerPort: 8888
volumeMounts:
- name: demo-secret-volume
mountPath: "/secrets/"
readOnly: true
volumes:
- name: demo-secret-volume
secret:
secretName: demo-secret

Как и в подразделе «Создание конфигурационных файлов из объектов ConfigMap» на с. 240, мы создаем том (в данном случае это demo-secret-volume) и подключаем его к контейнеру в разделе спецификации volumeMounts. В поле mountPath указано /secrets, поэтому Kubernetes создаст в этой папке по одному файлу для каждой пары «ключ — значение», определенной в объекте Secret.

В нашем примере мы определили только одну пару «ключ — значение» с именем magicWord, поэтому манифест создаст в контейнере один файл /secrets/magicWord с конфиденциальными данными, доступный исключительно для чтения.

Если применить этот манифест таким же образом, как и в предыдущем примере, должен получиться тот же результат:

The magic word is "xyzzy"

Чтение объектов Secret


В предыдущем разделе мы использовали команду kubectl describe для вывода содержимого ConfigMap. Можно ли то же самое сделать с Secret?

kubectl describe secret/demo-secret
Name:          demo-secret

Namespace:      default
Labels:             
Annotations:
Type:               Opaque

Data
====
magicWord: 5   bytes


Обратите внимание на то, что сами данные не отображаются. Объекты Secret в Kubernetes имеют тип Opaque: это означает, что их содержимое не показывается в выводе kubectl describe, журнальных записях и терминале, благодаря чему невозможно случайно раскрыть конфиденциальную информацию.

Чтобы просмотреть закодированную версию конфиденциальных данных в формате YAML, воспользуйтесь командой kubectl get:

kubectl get secret/demo-secret -o yaml
apiVersion: v1
data:
magicWord: eHl6enk=
kind: Secret
metadata:
...
type: Opaque

base64


Что за eHl6enk=, совсем не похожий на наше исходное значение? На самом деле это объект Secret, представленный в кодировке base64. Base64 — это схема кодирования произвольных двоичных данных в виде строки символов.

Поскольку конфиденциальная информация может быть двоичной и недоступной для вывода (как, например, в случае с ключом шифрования TLS), объекты Secret всегда хранятся в формате base64.

Текст beHl6enk= является версией нашего секретного слова xyzzy, закодированной в base64. В этом можно убедиться, если выполнить в терминале команду base64 --decode:

echo "eHl6enk=" | base64 --decode
xyzzy

Таким образом, несмотря на то, что Kubernetes защищает вас от случайного вывода конфиденциальных данных в терминале или журнальных файлах, при наличии прав на чтение объектов Secret в определенном пространстве имен эти данные можно получить в формате base64 и впоследствии их раскодировать.

Если вам нужно закодировать в base64 какой-нибудь текст (например, чтобы поместить его в Secret), используйте команду base64 без аргументов:

echo xyzzy | base64
eHl6enkK

Доступ к объектам Secret


Кто может читать и редактировать объекты Secret? Это определяется RBAC — механизмом контроля доступа (подробно его обсудим в подразделе «Введение в управление доступом на основе ролей» на с. 258). Если вы используете кластер, в котором система RBAC отсутствует или не включена, все ваши объекты Secret доступны любым пользователям и контейнерам (позже мы объясним, что у вас не должно быть ни одного промышленного кластера без RBAC).

Пассивное шифрование данных


А что насчет тех, кто имеет доступ к базе данных etcd, в которой Kubernetes хранит всю свою информацию? Могут ли они прочитать конфиденциальные данные, не имея прав на чтение объектов Secret через API?

Начиная с версии 1.7, Kubernetes поддерживает пассивное шифрование данных. Это означает, что конфиденциальная информация внутри etcd хранится на диске в зашифрованном виде и не может быть прочитана даже тем, кто имеет прямой доступ к базе данных. Для ее расшифровки нужен ключ, который есть только у сервера API Kubernetes. В правильно сконфигурированном кластере пассивное шифрование должно быть включено.

Проверить, работает ли пассивное шифрование в вашем кластере, можно таким образом:

kubectl describe pod -n kube-system -l component=kube-apiserver |grep encryption
--experimental-encryption-provider-config=...

Если вы не видите флага experimental-encryption-provider-config, пассивное шифрование не включено. При использовании Google Kubernetes Engine или других сервисов по управлению Kubernetes ваши данные шифруются с помощью иного механизма, поэтому флаг будет отсутствовать. Узнайте у своего поставщика Kubernetes, шифруется ли содержимое etcd.

Хранение конфиденциальных данных


Есть такие ресурсы Kubernetes, которые никогда не следует удалять из кластера: например, особо важные объекты Secret. Вы можете уберечь ресурс от удаления с помощью аннотации, предоставляемой диспетчером Helm:

kind: Secret
metadata:
annotations:
"helm.sh/resource-policy": keep

Стратегии управления объектами Secret


В примере из предыдущего раздела конфиденциальные данные защищались от несанкционированного доступа сразу после сохранения в кластере. Но в файлах манифестов они хранились в виде обычного текста.

Вы никогда не должны размещать конфиденциальную информацию в файлах, которые находятся в системе контроля версий. Как же безопасно администрировать и хранить такую информацию до того, как применить ее к кластеру Kubernetes?

Вы можете выбрать любые инструменты или стратегии для работы с конфиденциальными данными в своих приложениях, но все равно вам понадобится ответить как минимум на следующие вопросы.

  • Где хранить конфиденциальные данные, чтобы они были высокодоступными?
  • Как сделать конфиденциальные данные доступными для ваших активных приложений?
  • Что должно происходить с вашими приложениями, когда вы заменяете или редактируете конфиденциальные данные?


Об авторах


Джон Арундел является консультантом с 30-летним опытом работы в компьютерной индустрии. Он написал несколько книг и работает со многими компаниями из разных стран, консультируя их в вопросах облачно-ориентированной инфраструктуры и Kubernetes. В свободное время увлекается серфингом, неплохо стреляет из пистолета и любительски играет на пианино. Живет в сказочном коттедже в Корнуолле, Англия.

Джастин Домингус — инженер системного администрирования, работающий в среде DevOps с Kubernetes и облачными технологиями. Ему нравится проводить время на свежем воздухе, пить кофе, ловить крабов и сидеть за компьютером. Живет в Сиэтле, штат Вашингтон, вместе с замечательным котом и еще более замечательной женой и по совместительству лучшим другом Эдриэнн.

» Более подробно с книгой можно ознакомиться на сайте издательства
» Оглавление
» Отрывок

Для Хаброжителей скидка 25% по купону — Kubernetes

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.

© Habrahabr.ru