Давайте посмотрим, как использовать опубликованные в Анзибль Галактика Роли как операторы, которые управляют приложениями в Kubernetes, и давайте посмотрим на это, создав оператора, который просто устанавливает приложение, гибко настраивая его поведение в зависимости от среды.
Мы будем использовать Анзибль-оператор И модуль k8s чтобы показать, как использовать Ansible для создания приложений Kubernetes.
Оператор Ansible включен в SDK оператора и позволяет сформулировать регламент работы приложения (как его следует устанавливать и обслуживать) на языке ролей и плейбуков Ansible. Модуль k8s, в свою очередь, расширяет возможности управления объектами в Kubernetes при создании таких ролей и плейбуков.
Оператор создается просто так.
FROM quay.io/operator-framework/ansible-operator RUN ansible-galaxy install djzager.hello_world_k8s RUN echo $'--- \n\ - version: v1alpha1\n\ group: examples.djzager.io\n\ kind: HelloWorld\n\ role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml
Ключ для начала
Сначала несколько слов о Ansible модуль k8s .Он появился в Ansible 2.6 и расширяет возможности работы с объектами Kubernetes из Ansible, а также в любых дистрибутивах Kubernetes, включая Red Hat OpenShift. В блоге Ansible был отдельный пост об этом модуле и динамический клиент Python для Red Hat OpenShift .
На наш взгляд, работать с объектами Kubernetes через Ansible без использования модуля k8s неправильно.
Механизм оператора изначально был разработан для запуска приложений в Kubernetes, а Оператор SDK предоставляет инструменты для создания, тестирования и упаковки операторов.
В свою очередь Ansible Оператор нужен для того, чтобы задать регламент работы приложения на языке Ansible. Соответствующий рабочий процесс организован достаточно просто: сначала мы делаем оператор-sdk new --type=Ansible для генерации необходимых файлов для оператора Ansible, затем собираем Ansible и, наконец, делаем сборку оператора-sdk для сборки приложения для запуска.
Кубернетес.
Но если у нас уже есть роль в Ansible Galaxy, которая управляет приложением в Kubernetes, всё становится ещё проще.
Ниже мы сделаем следующее:
- Давайте создадим роль Ansible для управления приложением Hello World в Kubernetes, которая поможет нам продемонстрировать возможности модуля Ansible k8s.
- Давайте опубликуем эту роль в Ansible Galaxy.
- Чтобы не повторяться .
Если мы уже запрограммировали роль Ansible для управления приложением Hello World и опубликовали ее в Ansible Galaxy, то логично использовать ее при создании оператора Ansible.
- Из-за разделение обязанностей .
Мы хотим, чтобы роль Hello World Ansible управляла одноименным приложением в Kubernetes, а операционная (операционная) логика оставалась внутри оператора.
В нашем примере логика работы чрезвычайно проста: она просто вызывает роль djzager.hello_world_k8s каждый раз, когда создается или изменяется пользовательский ресурс HelloWorld. Однако в будущем Это разделение станет более значимым, например, мы добавим проверку в приложение Hello World через роль Ansible и реализуем управление статусом пользовательских ресурсов HelloWorld через операторскую логику.
Привет, Kubernetes, знакомься с Ansible
Что нам нужно
- Анзибль — см.
инструкция по установке , если у вас не установлен Ansible.
- Клиент Python для OpenShift (необязательно).
Нужен только для локального запуска.
Инструкция по установке Здесь .
Прежде всего, мы создаем скелет роли с помощью ansible-galaxy: # I like clear names on projects.
# In meta/main.yml I will make role_name: hello-world-k8s
$ ansible-galaxy init ansible-role-hello-world-k8s
Сразу после создания новой роли Ansible мы установим все значения по умолчанию, чтобы также задокументировать ее допустимые параметры конфигурации.
Более того, наш пример Hello World в этом плане не особенно сложен.
Вот как выглядит наш файл defaults/main.yml: ---
# NOTE: meta.name(space) comes from CR metadata when run with Ansible Operator
# deploy/crds has an example CR for reference
name: "{{ meta.name | default('hello-world') }}"
namespace: "{{ meta.namespace | default('hello-world') }}"
image: docker.io/ansibleplaybookbundle/hello-world:latest
# To uninstall from the cluster
# state: absent
state: present
# The size of the hello-world deployment
size: 1
Установив значения по умолчанию, вам нужно решить, что будет делать роль.
Приложению Hello World необходимо будет сделать следующее:
- Получите информацию о доступных API в кластере.
- Создайте несколько шаблонов и убедитесь, что они присутствуют или отсутствуют в кластере.
---
- name: "Get information about the cluster"
set_fact:
api_groups: "{{ lookup('k8s', cluster_info='api_groups') }}"
- name: 'Set hello-world objects state={{ state }}'
k8s:
state: '{{ state }}'
definition: "{{ lookup('template', item.name) | from_yaml }}"
when: item.api_exists | default(True)
loop:
- name: deployment.yml.j2
- name: service.yml.j2
- name: route.yml.j2
api_exists: "{{ True if 'route.openshift.io' in api_groups else False }}"
Прежде чем мы перейдем к шаблонам, обратите внимание на эту строку в файле задачи:
api_exists: "{{ True if 'route.openshift.io' in api_groups else False }}"
Используя set_fact, мы получаем список всех доступных API в кластере, чтобы потом можно было выборочно генерировать шаблоны в зависимости от того, есть ли там нужный API — в данном случае, Route.openshift.io. По умолчанию маршруты недоступны в кластере OpenShift Kubernetes, и они нам не нужны, поэтому мы работаем с объектом Route только тогда, когда в кластере есть Routes.openshift.io. Мы можем не только выборочно управлять объектами в кластере в зависимости от наличия тех или иных API, но и, используя шаблоны Jinja2, использовать DeploymentConfig OpenShift в нашем шаблоне Deployment, если в кластере есть API apps.openshift.io. Вот как выглядит наш файл templates/deployment.yml.j2:
---
{% if 'apps.openshift.io' in api_groups %}
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
{% else %}
apiVersion: apps/v1
kind: Deployment
{% endif %}
metadata:
name: {{ name }}
namespace: {{ namespace }}
labels:
app: {{ name }}
service: {{ name }}
spec:
replicas: {{ size }}
{% if 'apps.openshift.io' in api_groups %}
selector:
app: {{ name }}
service: {{ name }}
{% else %}
selector:
matchLabels:
app: {{ name }}
service: {{ name }}
{% endif %}
template:
metadata:
labels:
app: {{ name }}
service: {{ name }}
spec:
containers:
- image: {{ image }}
name: hello-world
ports:
- containerPort: 8080
protocol: TCP
Шаблоны файлов/service.yml.j2:
---
apiVersion: v1
kind: Service
metadata:
name: {{ name }}
namespace: {{ namespace }}
labels:
app: {{ name }}
service: {{ name }}
spec:
ports:
- name: web
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: {{ name }}
service: {{ name }}
И, наконец, файл templates/route.yml.j2:
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: {{ name }}
namespace: {{ namespace }}
labels:
app: {{ name }}
service: {{ name }}
spec:
port:
targetPort: web
to:
kind: Service
name: {{ name }}
Мы опустили файл мета/main.yml, но его можно найти Здесь .
В результате у нас есть роль Ansible, которая управляет приложением Hello World в Kubernetes, и мы можем использовать API, доступные в кластере.
Другими словами, модуль k8s и динамический клиент упрощают работу с объектами в Kubernetes. Надеемся, что на примере этой роли нам удалось показать потенциал Ansible при работе с Kubernetes.
Привет, Галактика, познакомься с Kubernetes
В Ansible Galaxy есть много ролей для настройки серверов и управления приложениями, но ролей для управления приложениями Kubernetes не так уж и много, поэтому мы внесем свой небольшой вклад. После того, как мы изложили свою роль на GitHub , Остается только:- Войдите в Ansible Galaxy, чтобы получить доступ к нашим репозиториям GitHub.
- Импортируйте нашу роль.
Привет, оператор Ansible, знакомься с Galaxy
Если вы внимательно изучите наш Проект Hello World на GitHub , то вы можете видеть, что мы добавили туда несколько вещей, необходимых для создания оператора Ansible, а именно:- Файл часов , обеспечивая соответствие пользовательские ресурсы Kubernetes с ролями Ansible или сборниками сценариев.
- Докерфайл для сборки нашего оператора.
- Каталог развертывания с объектами Kubernetes, необходимыми для запуска нашего оператора.
Но поскольку мы обещали построить оператор Ansible, используя роль, опубликованную в Ansible Galaxy, то всё что нам нужно Действительно вам нужен Dockerfile: FROM quay.io/operator-framework/ansible-operator
RUN ansible-galaxy install djzager.hello_world_k8s
RUN echo $'--- \n\
- version: v1alpha1\n\
group: examples.djzager.io\n\
kind: HelloWorld\n\
role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml
Теперь собираем оператор: $ docker build -t hello-world-operator -f Dockerfile .
Sending build context to Docker daemon 157.2 kB
Step 1/3 : FROM quay.io/operator-framework/ansible-operator
latest: Pulling from operator-framework/ansible-operator
Digest: sha256:1156066a05fb1e1dd5d4286085518e5ce15acabfff10a8145eef8da088475db3
Status: Downloaded newer image for quay.io/water-hole/ansible-operator:latest
---> 39cc1d19649d
Step 2/3 : RUN ansible-galaxy install djzager.hello_world_k8s
---> Running in 83ba8c21f233
- downloading role 'hello_world_k8s', owned by djzager
- downloading role from https://github.com/djzager/ansible-role-hello-world-k8s/archive/master.tar.gz
- extracting djzager.hello_world_k8s to /opt/ansible/roles/djzager.hello_world_k8s
- djzager.hello_world_k8s (master) was installed successfully
Removing intermediate container 83ba8c21f233
---> 2f303b45576c
Step 3/3 : RUN echo $'--- \n- version: v1alpha1\n group: examples.djzager.io\n kind: HelloWorld\n role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml
---> Running in cced495a9cb4
Removing intermediate container cced495a9cb4
---> 5827bc3c1ca3
Successfully built 5827bc3c1ca3
Successfully tagged hello-world-operator:latest
Понятно, что для использовать этот оператор, вам понадобится содержимое каталог развертывания из нашего проекта для создания Сервисной учетной записи, Роли и привязки ролей, Пользовательского определения ресурса, а также для развертывания самого оператора.
И после развертывания оператора вам нужно будет создать Custom Resource для получения экземпляра приложения Hello World: apiVersion: examples.djzager.io/v1alpha1
kind: HelloWorld
metadata:
name: example-helloworld
namespace: default
spec:
size: 3
Область действия оператора: пространство имен и кластер.
Чуть выше мы уже предлагали изучить нашу каталог развертывания и найдите там объекты Kubernetes, необходимые для запуска оператора.
Есть три вещи, которые ограничивают область действия оператора при управлении пользовательскими ресурсами пространством имен, в котором развернут сам оператор, а именно:
- Переменная среды WATCH_NAMESPACE в файле оператор.
yaml
, который сообщает оператору, где искать пользовательские ресурсы - роль.
yaml
- role_binding
Но если бы мы хотели, чтобы наше приложение было доступно всем пользователям кластера, нам потребовалась бы помощь администратора.
Мне пришлось бы сделать следующее:
- Создайте ClusterRole вместо Role.
- Создайте оператор ServiceAccount в пространстве имен, где этот оператор будет развернут.
- Создайте ClusterRoleBinding, который привязывает ServiceAccount из определенного пространства имен к ClusterRole.
- Разверните оператор, указав неустановленную переменную среды WATCH_NAMESPACE (т. е.
"").
Звездный путь
Мы показали, как создать роль Ansible для управления приложением в Kubernetes, опубликовать эту роль в Ansible Galaxy и использовать ее в операторе Ansible. Надеемся, что теперь вы:- Будете ли вы использовать Ansible модуль k8s .
- Начать публикацию в Анзибль Галактика свои роли по управлению приложениями Kubernetes.
- Вам интересно? SDK оператора и подпишитесь на наш информационный бюллетень Операторской структуры .
- Применение SDK оператора — мы намеренно не сделали этого в нашем примере, чтобы подчеркнуть, насколько легко переключиться с роли Ansible на роль оператора.
Но эту роль все же лучше использовать с SDK (то есть оператор-сдк новый), к тому же это может понадобиться на последующих шагах.
- Валидация — в нашей текущей версии пользователь может создать CR размером: abc, что неизбежно приведет к ошибке на этапе развертывания.
Так что ошибки лучше ловить на этапе спецификации, а не после начала работы.
- Жизненный цикл — в более сложных примерах это может быть одно и то же обновление версии.
В таких сценариях, как наш, где существует только одна версия приложения Hello World, мы можем определить, устарел ли работающий образ контейнера, сравнив его с доступными образами в соответствующем реестре контейнеров, и при необходимости обновить работающие экземпляры.
- Тестирование — очень полезно при разработке и тестировании ролей Ansible. Молекула .
- Менеджер жизненного цикла оператора представляет собой набор инструментов для управления операторами.
Интеграция с ним поможет установить и обновить нашего оператора.
- Статус.
Мы могли бы включить подресурс статуса в нашем CRD Hello World и использовать модуль k8s_status, включенный в образ оператора Ansible, для включения информации о статусе в пользовательский ресурс.
-
Appsconf, Чтобы Управлять Ими Всеми
19 Oct, 24 -
Мы Не Обижаемся
19 Oct, 24 -
Проект Завершен, А Денег Нет.
19 Oct, 24