Привет, Хаброжители! Kubernetes – один из ключевых элементов современной облачной экосистемы. Эта технология обеспечивает надежность, масштабируемость и устойчивость контейнерной виртуализации. Джон Арундел и Джастин Домингус рассказывают об экосистеме Kubernetes и знакомят с проверенными решениями повседневных проблем. Шаг за шагом вы построите собственное облачно-ориентированное приложение и создадите инфраструктуру для его поддержки, настроите среду разработки и конвейер непрерывного развертывания, который пригодится вам при работе над следующими приложениями.
• Начнете работу с контейнерами и Kubernetes с азов: никакого специального опыта для изучения темы не требуется. • Запустите собственные кластеры или выберете управляемый сервис Kubernetes от Amazon, Google и др. • Примените Kubernetes для управления жизненным циклом контейнера и расхода ресурсов. • Оптимизируете кластеры по показателям стоимости, производительности, устойчивости, мощности и масштабируемости. • Изучите наилучшие инструменты для разработки, тестирования и развертывания ваших приложений. • Воспользуетесь актуальными отраслевыми практиками для обеспечения безопасности и контроля. • Внедрите в компании принципы DevOps, чтобы команды разработчиков стали действовать более гибко, быстро и эффективно.
Книга наиболее актуальна для сотрудников отделов администрирования, ответственных за серверы, приложения и сервисы, а также для разработчиков, занимающихся либо построением новых облачных сервисов, либо миграцией существующих приложений в Kubernetes и облако. Не волнуйтесь, уметь работать с Kubernetes и контейнерами не требуется — мы всему научим.
Опытные пользователи Kubernetes также найдут для себя много ценного: здесь углубленно рассматриваются такие темы, как RBAC, непрерывное развертывание, управление конфиденциальными данными и наблюдаемость. Надеемся, что на страницах книги обязательно окажется что-нибудь интересное и для вас, независимо от ваших навыков и опыта.
Во время планирования и написания книги мы обсуждали облачные технологии и Kubernetes с сотнями людей, разговаривали как с лидерами и экспертами в данной отрасли, так и с абсолютными новичками. Ниже приведены отдельные вопросы, ответы на которые им хотелось бы увидеть в этом издании.
И, наверное, наиболее важный из всех вопросов:
Возможность отделить логику приложения Kubernetes от его конфигурации (то есть от любых значений или настроек, которые со временем могут поменяться) очень полезна. К конфигурационным значениям обычно относят параметры, предназначенные для определенной среды, DNS-адреса сторонних сервисов и учетные данные для аутентификации.
Конечно, все это можно поместить непосредственно в код, но такой подход недостаточно гибок. Например, для изменения конфигурационного значения тогда придется заново собирать и развертывать ваш код. Намного лучшим решением было бы отделить конфигурацию от кода и считывать ее из файла или переменных среды.
Kubernetes предоставляет несколько разных способов управления конфигурацией. Во-первых, вы можете передавать значения в приложение через переменные среды, указанные в спецификации pod-оболочки (см. подраздел «Переменные среды» на с. 192). Во-вторых, конфигурационные данные можно хранить непосредственно в Kubernetes, используя объекты ConfigMap и Secret.
В данной главе мы подробно исследуем эти объекты и рассмотрим некоторые практические подходы к управлению конфигурацией и конфиденциальными данными на примере демонстрационного приложения.
Представьте, что в вашем кластере есть развертывание и вы хотите поменять некоторые значения в его ConfigMap. Если вы используете чарт Helm (см. раздел «Helm: диспетчер пакетов для Kubernetes» на с. 102), обнаружить изменение конфигурации и перезагрузить ваши pod-оболочки можно автоматически с помощью одного изящного приема. Добавьте следующую аннотацию в спецификацию своего развертывания:
Теперь шаблон развертывания содержит контрольную сумму конфигурационных параметров: при изменении параметров сумма обновится. Если выполнить команду helm upgrade, Helm обнаружит, что спецификация развертывания изменилась, и перезапустит все pod-оболочки.
Мы уже знаем, что объект ConfigMap предоставляет гибкий механизм хранения и доступа к конфигурационным данным в кластере. Однако у большинства приложений есть информация, которая является секретной и конфиденциальной: например, пароли или API-ключи. Ее можно хранить и в ConfigMap, но такое решение неидеально.
Вместо этого Kubernetes предлагает объект специального типа, предназначенный для хранения конфиденциальных данных: Secret. Далее рассмотрим на примере, как данный объект можно применить в нашем демонстрационном приложении.
Для начала взгляните на манифест Kubernetes для объекта Secret (см. hello-secret-env/k8s/secret.yaml):
В этом примере закрытый ключ magicWord имеет значение xyzzy (en.wikipedia.org/wiki/Xyzzy_(computing)). Слово xyzzy вообще очень полезное в мире компьютеров. По аналогии с ConfigMap в объекте Secret можно размещать множество ключей и значений. Здесь для простоты мы используем лишь одну пару «ключ — значение».
Как и ConfigMap, объект Secret можно сделать доступным в контейнере в виде переменных среды или файла на его диске. В следующем примере мы присвоим переменной среды значение из Secret:
Выполните следующую команду в репозитории demo, чтобы применить манифесты:
Как и раньше, перенаправьте локальный порт к развертыванию, чтобы увидеть результат в своем браузере:
При открытии адреса localhost:9999/ вы должны увидеть следующее:
В этом примере мы подключим объект Secret к контейнеру в виде файла. Код находится в папке hello-secret-file репозитория demo.
Чтобы подключить Secret в виде файла, воспользуемся следующим развертыванием:
Как и в подразделе «Создание конфигурационных файлов из объектов ConfigMap» на с. 240, мы создаем том (в данном случае это demo-secret-volume) и подключаем его к контейнеру в разделе спецификации volumeMounts. В поле mountPath указано /secrets, поэтому Kubernetes создаст в этой папке по одному файлу для каждой пары «ключ — значение», определенной в объекте Secret.
В нашем примере мы определили только одну пару «ключ — значение» с именем magicWord, поэтому манифест создаст в контейнере один файл /secrets/magicWord с конфиденциальными данными, доступный исключительно для чтения.
Если применить этот манифест таким же образом, как и в предыдущем примере, должен получиться тот же результат:
В предыдущем разделе мы использовали команду kubectl describe для вывода содержимого ConfigMap. Можно ли то же самое сделать с Secret?
Обратите внимание на то, что сами данные не отображаются. Объекты Secret в Kubernetes имеют тип Opaque: это означает, что их содержимое не показывается в выводе kubectl describe, журнальных записях и терминале, благодаря чему невозможно случайно раскрыть конфиденциальную информацию.
Чтобы просмотреть закодированную версию конфиденциальных данных в формате YAML, воспользуйтесь командой kubectl get:
Что за eHl6enk=, совсем не похожий на наше исходное значение? На самом деле это объект Secret, представленный в кодировке base64. Base64 — это схема кодирования произвольных двоичных данных в виде строки символов.
Поскольку конфиденциальная информация может быть двоичной и недоступной для вывода (как, например, в случае с ключом шифрования TLS), объекты Secret всегда хранятся в формате base64.
Текст beHl6enk= является версией нашего секретного слова xyzzy, закодированной в base64. В этом можно убедиться, если выполнить в терминале команду base64 --decode:
Таким образом, несмотря на то, что Kubernetes защищает вас от случайного вывода конфиденциальных данных в терминале или журнальных файлах, при наличии прав на чтение объектов Secret в определенном пространстве имен эти данные можно получить в формате base64 и впоследствии их раскодировать.
Если вам нужно закодировать в base64 какой-нибудь текст (например, чтобы поместить его в Secret), используйте команду base64 без аргументов:
Кто может читать и редактировать объекты Secret? Это определяется RBAC — механизмом контроля доступа (подробно его обсудим в подразделе «Введение в управление доступом на основе ролей» на с. 258). Если вы используете кластер, в котором система RBAC отсутствует или не включена, все ваши объекты Secret доступны любым пользователям и контейнерам (позже мы объясним, что у вас не должно быть ни одного промышленного кластера без RBAC).
А что насчет тех, кто имеет доступ к базе данных etcd, в которой Kubernetes хранит всю свою информацию? Могут ли они прочитать конфиденциальные данные, не имея прав на чтение объектов Secret через API?
Начиная с версии 1.7, Kubernetes поддерживает пассивное шифрование данных. Это означает, что конфиденциальная информация внутри etcd хранится на диске в зашифрованном виде и не может быть прочитана даже тем, кто имеет прямой доступ к базе данных. Для ее расшифровки нужен ключ, который есть только у сервера API Kubernetes. В правильно сконфигурированном кластере пассивное шифрование должно быть включено.
Проверить, работает ли пассивное шифрование в вашем кластере, можно таким образом:
Если вы не видите флага experimental-encryption-provider-config, пассивное шифрование не включено. При использовании Google Kubernetes Engine или других сервисов по управлению Kubernetes ваши данные шифруются с помощью иного механизма, поэтому флаг будет отсутствовать. Узнайте у своего поставщика Kubernetes, шифруется ли содержимое etcd.
Есть такие ресурсы Kubernetes, которые никогда не следует удалять из кластера: например, особо важные объекты Secret. Вы можете уберечь ресурс от удаления с помощью аннотации, предоставляемой диспетчером Helm:
В примере из предыдущего раздела конфиденциальные данные защищались от несанкционированного доступа сразу после сохранения в кластере. Но в файлах манифестов они хранились в виде обычного текста.
Вы никогда не должны размещать конфиденциальную информацию в файлах, которые находятся в системе контроля версий. Как же безопасно администрировать и хранить такую информацию до того, как применить ее к кластеру Kubernetes?
Вы можете выбрать любые инструменты или стратегии для работы с конфиденциальными данными в своих приложениях, но все равно вам понадобится ответить как минимум на следующие вопросы.
Джон Арундел является консультантом с 30-летним опытом работы в компьютерной индустрии. Он написал несколько книг и работает со многими компаниями из разных стран, консультируя их в вопросах облачно-ориентированной инфраструктуры и Kubernetes. В свободное время увлекается серфингом, неплохо стреляет из пистолета и любительски играет на пианино. Живет в сказочном коттедже в Корнуолле, Англия.
Джастин Домингус — инженер системного администрирования, работающий в среде DevOps с Kubernetes и облачными технологиями. Ему нравится проводить время на свежем воздухе, пить кофе, ловить крабов и сидеть за компьютером. Живет в Сиэтле, штат Вашингтон, вместе с замечательным котом и еще более замечательной женой и по совместительству лучшим другом Эдриэнн.
» Более подробно с книгой можно ознакомиться на сайте издательства
» Оглавление
» Отрывок
Для Хаброжителей скидка 25% по купону — Kubernetes
По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
• Начнете работу с контейнерами и 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: <none>
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 высылается электронная книга.