Делимся переводом статьи об интеграции Kubernetes и Ansible. Из статьи вы узнаете, как подготовить среду для работы, как развернуть кластер Kubernetes с помощью Ansible, как управлять ресурсами Kubernetes и автоматизировать обновления. Кроме того, вы узнаете, как развернуть плейбук Ansible в Kubernetes на облачном провайдере и использовать Ansible для CI/CD в Kubernetes.

Перед тем как начать
Kubernetes — это open-source платформа оркестровки, которая упрощает управление контейнерными приложениями и автоматизирует такие задачи, как масштабирование, балансировка нагрузки и распределение ресурсов между кластерами. Kubernetes использует декларативное управление, точно такое же, как и в Ansible. Это позволяет фокусироваться на коде приложения, а не на проблемах среды.
Ansible — это инструмент автоматизации для ИТ-инфраструктуры, который упрощает повторяющиеся задачи. Ansible может управлять конфигурацией и делать развёртывание с помощью архитектуры «сервер-клиент». Он использует плейбуки для оркестровки на управляемых нодах через SSH или WinRM. Ansible использует декларативный язык YAML и идемпотентность. Принцип идемпотентности позволяет избежать избыточных развёртываний, а код можно использовать повторно через роли.
Интеграция Ansible с Kubernetes может помочь в развёртывании ресурсов. Попробуем использовать сильные стороны обеих платформ для эффективного управления инфраструктурой и приложениями.
Зачем управлять Kubernetes с помощью Ansible?
Kubernetes — мощный инструмент, который помогает экономить ресурсы и затраты. Однако его настройка и управление сложны, поскольку приходится использовать командную строку и запускать kubectl каждый раз при развёртывании ресурса Kubernetes. Этот процесс всё ещё требует некоторой ручной работы и увеличивает вероятность ошибки.
Это можно сравнить с работой в среде Linux. Можно либо запускать команды одну за другой, либо создать сложный скрипт на bash.
Подобно тому, как Ansible произвёл революцию в развёртывании приложений Linux, теперь можно делать то же самое и с Kubernetes, используя модуль kubernetes.core.k8s. В этом модуле представлен слой абстракции, который упрощает настройку Kubernetes и делает её более управляемой и читаемой.
Ansible позволяет использовать логику и переменные для последовательного развёртывания одного и того же плейбука в разных средах. Ansible содержит большую библиотеку модулей для конкретных задач в среде Linux, но для Kubernetes нужна небольшая библиотека модулей. Причина в том, что Ansible и Kubernetes используют декларативный синтаксис YAML, который позволяет напрямую встраивать код Kubernetes в задачу плейбука Ansible и позволяет им дополнять друг друга.
Ещё одно преимущество использования Ansible заключается в том, что можно использовать один инструмент для развёртывания инфраструктурного и application слоёв экосистемы Kubernetes. Как вы увидите ниже, мы будем использовать Ansible для развёртывания нашего кластера Kubernetes и приложения на Kubernetes.
Ansible vs. Helm
Многие предпочитают использовать Helm-чарты для Kubernetes Deployments, потому что ценят возможность объединять все файлы манифеста Kubernetes в один Helm-чарт, внедрять переменные, управлять версиями релизов и развёртывать приложения одной командой. Интеграция Helm с Ansible может ещё больше улучшить стратегию развёртывания.
Благодаря своей идемпотентной природе и большому выбору модулей Ansible является гибким инструментом. Он способен справляться со сложными сценариями развёртывания: например, с условиями или интеграцией с внешними системами. Это качество Ansible позволяет использовать его в сложной стратегии автоматизации.
С помощью Ansible можно учесть будущие потребности. Это полезно для тех пользователей, которые только начинают работать с Kubernetes. Для сред, которые уже используют Helm, интеграция упрощается с помощью модуля Ansible kubernetes.core.helm, который использует управление пакетами Helm.
Использование Helm и Ansible позволяет максимально использовать оба инструмента. Это комплексный подход к управлению развёртыванием Kubernetes в различных сценариях и с помощью различных инструментов.
Ansible vs. GitOps
В современных средах развёртывания и масштабирования такие инструменты как ArgoCD и Flux, становятся стандартом автоматизации процесса сборки и развёртывания, дополняя конвейеры CI/CD.
Ansible интегрируется в эту экосистему. Он подходит для начальных задач по настройке и конфигурации кластеров Kubernetes, настройке сетевых политик, решений для хранения данных и других важных элементов облачной инфраструктуры. Он отлично справляется с задачами до и после развёртывания.
Ansible также хорошо работает с разнообразными средами (Dev, QA, UAT, Prod) в вашем CI/CD, с различными конфигурациями и секретами. Для гибридных и мультикластерных установок Kubernetes в различных облачных и локальных средах Ansible обеспечивает последовательную и унифицированную автоматизацию.
В этой статье я буду использовать Ansible для:
развёртывания полного кластера Kubernetes (1 Мастер ноду и 2 рабочих ноды) с помощью плейбуков Ansible;
развёртывания манифеста задач Kubernetes через Ansible плейбук;
использования кластера Kubernetes в облаке (Azure AKS);
интеграции Ansible в конвейер CI/CD;
управления обновлениями и апгрейдами.
Подготовка среды для работы Ansible с Kubernetes
Прежде чем приступить к настройке Ansible и Kubernetes, давайте рассмотрим архитектуру, чтобы понять, как Ansible взаимодействует с кластерами Kubernetes.
У нас будет контрольная нода Ansible (Ansible Control Node), которая соединяется с прокси-машиной. Эта прокси-машина позволяет нам выполнять команды kubectl, облегчая доступ к различным кластерам Kubernetes. После установления связи от контрольной ноды Ansible через прокси к кластеру Kubernetes мы протестируем наши плейбуки, чтобы убедиться, что всё работает.
Примечание: модуль Kubernetes в Ansible не поставляется с инструментами kubectl для выполнения задач. Вам нужно будет установить kubectl на прокси-машине и убедиться, что файл ~/.kube/config включает кластеры, которые вы собираетесь развернуть. Этот процесс настройки будет подробно описан далее в этой статье.
Свяжем контрольную ноду Ansible с прокси-машиной.
Для локального использования Ansible укажите
localhostв разделе hosts.Для удалённого прокси введите имя/IP сервера.
Для настроек с несколькими прокси, ведущими к разным кластерам, вы можете создать inventory файл с группами серверов. Затем этот файл используйте в качестве hosts в вашей команде
ansible-playbook. Это позволит точно контролировать, где выполняются плейбуки.
Мы будем следовать архитектуре на схеме ниже, чтобы выполнять наши плейбуки в кластерах Kubernetes.

Чтобы Ansible мог работать с кластером Kubernetes, вам нужно настроить:
Контрольную ноду Ansible.
прокси-машину (инструмен��ы kubectl/kube config/python3) — может быть проще, если это Linux-машина.
Кластер Kubernetes (локальный или от облачного провайдера).
SSH-подключение между контрольной нодой Ansible и прокси-машиной.
Обратите внимание, что в своих примерах я буду использовать семейство ОС Debian (apt).
1. Настройте контрольную ноду Ansible.
На вашей контрольной ноде выполните следующее команды, чтобы установить Kubernetes Collection (сюда входят модуль и плагины).
ansible-galaxy collection install kubernetes.core ansible-galaxy collection install community.kubernetes ansible-galaxy collection install cloud.common sudo apt install python3-pip pip install kubernetes mkdir -pv ~/ansible/playbook ~/ansible/inventory
2. Настройте прокси-машину с помощью инструментов Kube Config и Kubectl
На прокси-машине мы установим инструменты Kubernetes, чтобы использовать kubectl, инструменты CLI облачного провайдера (Azure CLI, AWS CLI и т. д.) для подключения к нашему кластеру Kubernetes в облаке. Вы также можете вручную добавить конфигурацию своих кластеров Kubernetes на прокси (файл ~/.kube/config).
В нашем примере мы будем использовать Ubuntu Proxy, который будет подключаться к моему кластеру Azure Kubernetes.
sudo apt update && sudo apt upgrade –y sudo apt install python3-pip #Download Kubernetes Tools using Curl: curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" #Verify Checksum (Response should be kubectl:OK): curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256" echo "$(cat kubectl.sha256) kubectl" | sha256sum --check #Install Kubernetes Tools: sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl #Validate install: kubectl version
Теперь, когда мы убедились, что можем получить доступ к нашему кластеру Kubernetes через прокси-сервер, мы можем перейти к настройке наших плейбуков Ansible для работы с кластером Kubernetes.
Как развернуть кластер Kubernetes с помощью Ansible
Чтобы использовать плейбук Ansible для настройки кластера Kubernetes, вам потребуется следующее:
Все ноды должны быть Ubuntu 22.04 LTS, чтобы соответствовать этому гайду.
1 Мастер нода — минимум 2 ГБ ЦП и 4 ГБ ОЗУ.
2 Рабочих ноды — минимум 2 ГБ ЦП и 4 ГБ ОЗУ.
Соединение по SSH между Ansible и каждой из этих нод (используйте команду
ssh-copy-id username@node-ipна контрольной ноде Ansible, чтобы скопировать открытый ключ на эти нод).
Давайте перейдём на нашу контрольную ноду Ansible и создадим файл инвентаризации kube_inventory (расширение не требуется) в папке ~/ansible/inventory и отредактируем файл, чтобы включить наши ноды Kubernetes.
[master] 10.x.x.x [workers] 10.x.x.x 10.x.x.x
Теперь в папку ~/ansible/playbooks добавьте плейбук kube_dependencies.yml, чтобы развернуть зависимости Kubernetes на всех нодах (мастер и рабочих).
Я собрал все это в один плейбук, поскольку нам нужно будет установить и настроить всё нижеперечисленное на всех нодах нашего кластера Kubernetes.
- name: Kubernetes Dependencies hosts: all become: yes tasks: - name: Updates apt: update_cache: yes - name: Reboot reboot: - name: Disable SWAP shell: | swapoff -a - name: Disable SWAP in fstab replace: path: /etc/fstab regexp: '^([^#].*?\sswap\s+sw\s+.*)$' replace: '# \1' - name: Create an empty file for the containerd module copy: content: "" dest: /etc/modules-load.d/containerd.conf force: no - name: Configure modules for containerd blockinfile: path: /etc/modules-load.d/containerd.conf block: | overlay br_netfilter - name: Create an empty file for K8S sysctl parameters copy: content: "" dest: /etc/sysctl.d/99-kubernetes-cri.conf force: no - name: Configure sysctl parameters for K8S lineinfile: path: /etc/sysctl.d/99-kubernetes-cri.conf line: "{{ item }}" with_items: - "net.bridge.bridge-nf-call-iptables = 1" - "net.ipv4.ip_forward = 1" - "net.bridge.bridge-nf-call-ip6tables = 1" - name: Apply sysctl parameters command: sysctl --system - name: Install APT Transport HTTPS apt: name: apt-transport-https state: present - name: Add Docker apt-key get_url: url: https://download.docker.com/linux/ubuntu/gpg dest: /etc/apt/keyrings/docker-apt-keyring.asc mode: "0644" force: true - name: Add Docker's APT repo apt_repository: repo: "deb [arch={{ 'amd64' if ansible_architecture == 'x86_64' else 'arm64' }} signed-by=/etc/apt/keyrings/docker-apt-keyring.asc] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" state: present update_cache: yes - name: Add Kubernetes apt-key get_url: url: https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key dest: /etc/apt/keyrings/kubernetes-apt-keyring.asc mode: "0644" force: true - name: Add Kubernetes APT repository apt_repository: repo: "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.asc] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" state: present update_cache: yes - name: Install containerd apt: name: containerd.io state: present - name: Create containerd directory file: path: /etc/containerd state: directory - name: Add containerd configuration shell: /usr/bin/containerd config default > /etc/containerd/config.toml - name: Configuring Systemd cgroup driver for containerd lineinfile: path: /etc/containerd/config.toml regexp: " SystemdCgroup = false" line: " SystemdCgroup = true" - name: Enable the containerd service and start service systemd: name: containerd state: restarted enabled: yes daemon-reload: yes - name: Install Kubelet apt: name: kubelet=1.29.* state: present update_cache: true - name: Install Kubeadm apt: name: kubeadm=1.29.* state: present - name: Enable the Kubelet service service: name: kubelet enabled: yes - name: Load br_netfilter kernel module modprobe: name: br_netfilter state: present - name: Set bridge-nf-call-iptables sysctl: name: net.bridge.bridge-nf-call-iptables value: 1 - name: Set ip_forward sysctl: name: net.ipv4.ip_forward value: 1 - name: Reboot reboot: - hosts: master become: yes tasks: - name: Install Kubectl apt: name: kubectl=1.29.* state: present force: yes
Чтобы запустить плейбук зависимостей (Dependency playbook), используйте следующую команду на контрольной ноде Ansible:
ansible-playbook ~/ansible/playbook/kube_dependencies.yml -i ~/ansible/inventory/kube_inventory
После успешного развёртывания зависимостей на всех нодах мы можем перейти к инициализации Мастер ноды с Kubernetes. Создайте плейбук kube_master.yml в папке ~/ansible/playbooks/.
Обязательно замените YOUR_USERPROFILE_NAME на имя вашего профиля пользователя, который находится в каталоге /home/ (например, я использую kube_admin).
- hosts: master become: yes tasks: - name: Create an Empty file for Kubeadm configuring copy: content: "" dest: /etc/kubernetes/kubeadm-config.yaml force: no - name: Configure container runtime blockinfile: path: /etc/kubernetes/kubeadm-config.yaml block: | kind: ClusterConfiguration apiVersion: kubeadm.k8s.io/v1beta3 networking: podSubnet: "10.244.0.0/16" --- kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 runtimeRequestTimeout: "15m" cgroupDriver: "systemd" systemReserved: cpu: 100m memory: 350M kubeReserved: cpu: 100m memory: 50M enforceNodeAllocatable: - pods - name: Initialize the cluster shell: kubeadm init --config /etc/kubernetes/kubeadm-config.yaml >> cluster_initialized.log args: chdir: /home/YOUR_USERPROFILE_NAME creates: cluster_initialized.log - name: Create .kube directory become: yes become_user: YOUR_USERPROFILE_NAME file: path: $HOME/.kube state: directory mode: 0755 - name: Copy admin.conf to User's kube config copy: src: /etc/kubernetes/admin.conf dest: /home/YOUR_USERPROFILE_NAME/.kube/config remote_src: yes owner: YOUR_USERPROFILE_NAME - name: Install Pod Network become: yes become_user: YOUR_USERPROFILE_NAME shell: kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml >> pod_network_setup.log args: chdir: $HOME creates: pod_network_setup.log
Чтобы запустить мастер-плейбук, используйте следующую команду на контрольной ноде Ansible:
ansible-playbook ~/ansible/playbook/kube_master.yml -i ~/ansible/inventory/kube_inventory
После успешного развёртывания на мастер ноде мы можем перейти к развёртыванию на рабочих нодах, чтобы подключить их к мастер ноде. Создадим kube_workers.yml в папке ~/ansible/playbooks/.
Обязательно замените YOUR_MASTER_IP на IP-адрес вашей мастер ноды, а также замените YOUR_USERPROFILE_NAME на имя вашего профиля пользователя, который находится в каталоге /home/.
- name: Configure Join Commands on Master Node hosts: master become: yes tasks: - name: Retrieve Join Command shell: kubeadm token create --print-join-command register: join_command_raw - name: Set Join Command set_fact: join_command: "{{ join_command_raw.stdout_lines[0] }}" - name: Join Worker Nodes hosts: workers become: yes tasks: - name: Enable TCP port 6443 (On Master) is able to connect from Worker wait_for: "host=YOUR_MASTER_IP port=6443 timeout=1" - name: Join worker to cluster shell: "{{ hostvars['YOUR_MASTER_IP'].join_command }} >> node_joined.log" args: chdir: /home/YOUR_USERPROFILE_NAME creates: node_joined.log
Чтобы запустить плейбук для рабочих нодах, используйте следующую команду на вашей контрольной ноде Ansible:
ansible-playbook ~/ansible/playbook/kube_workers.yml -i ~/ansible/inventory/kube_inventory
После успешного выполнения плейбука вы можете проверить, что кластер работает правильно, выполнив следующие команды с Мастер ноды:
kubectl get nodes kubectl get all -A
Теперь добавим kube config мастер ноды в наш /etc/kube/config на прокси.
На мастер ноде вы можете выполнить следующую команду, чтобы скопировать конфигурацию на прокси:
sudo scp /etc/kubernetes/admin.conf USERNAME@MASTER_NODE_IP:~/.kube/config
Убедитесь, что вы видите конфигурацию. Проверьте её на прокси-машине в каталоге ~/.kube/config. Чтобы убедиться, что вы можете получить доступ к своему кластеру с прокси вы можете выполнить следующую команду с прокси-машины:
kubectl get nodes kubectl get all -A
Следующий шаг — развернуть манифест задач Kubernetes с нашей контрольной ноды Ansible.
В целом, вы можете видеть, сколько времени мы можем сэкономить на настройке кластера Kubernetes с помощью Ansible. Вы можете легко добавить ещё один сервер Ubuntu в файл инвентаризации Ansible и запустить плейбук, чтобы добавить ещё одну ноду в кластер Kubernetes. У вас больше контроля над состоянием нод Kubernetes.
Как управлять ресурсами Kubernetes с помощью Ansible
Прежде чем мы начнём, убедитесь, что вы можете пинговать свой прокси с вашей контрольной ноды Ansible.
Давайте добавим наш прокси в файл инвентаризации (~/ansible/inventory/kube_inventory), который будет содержать IP-адрес прокси или имя хоста (если у вас настроен DNS).
Добавьте свой прокси в инвентори, как показано ниже:
[master] 10.x.x.x [workers] 10.x.x.x 10.x.x.x [proxy-servers] 10.x.x.x #add your proxy IP or DNS name here.
Давайте создадим простой плейбук с именем create_namespace.yml в ~/ansible/playbooks/, чтобы создать пространство имён в вашем кластере Kubernetes:
- name: Create K8S resource hosts: proxy-servers tasks: - name: Get K8S namespace kubernetes.core.k8s: name: my-namespace api_version: v1 kind: Namespace state: present
Вы также можете передать манифест задач Kubernetes в виде файла в свой плейбук Ansible:
- name: Create a Namespace from K8S YAML File kubernetes.core.k8s: state: present src: /kube_manifests/create_namespace.yml
Теперь всё, что вам нужно сделать, это просто запустить команду ansible playbook:
ansible-playbook ~/ansible/playbooks/create_namespace.yml -i ~/ansible/inventory/kube_inventory
После завершения выполнения плейбука перейдите к своему прокси и убедитесь, что вы видите созданное пространство имён:
kubectl get namespace
Итак, вы только что использовали Ansible для развёртывания манифеста задач Kubernetes в вашем кластере Kubernetes.
Вот несколько других плейбуков (Deployments, Services и Configmaps), которые вы можете протестировать, запуская их с вашей контрольной ноды Ansible. Вы можете использовать следующий манифест Application/Service Deployment task для развёртывания приложения nginx:
- name: Application Deployment hosts: proxy_servers tasks: - name: Create a Deployment kubernetes.core.k8s: definition: apiVersion: apps/v1 kind: Deployment metadata: name: myapp namespace: my-namespace spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp-container image: nginx:latest ports: - containerPort: 80 - name: Expose Deployment as a Service kubernetes.core.k8s: definition: apiVersion: v1 kind: Service metadata: name: myapp-service namespace: my-namespace spec: selector: app: myapp ports: - protocol: TCP port: 80 targetPort: 80 type: LoadBalancer
Вы также можете управлять переменными среды Kubernetes с помощью Ansible, используя configmap:
- name: Manage ConfigMaps and Secrets hosts: proxy_servers tasks: - name: Create ConfigMap kubernetes.core.k8s: definition: apiVersion: v1 kind: ConfigMap metadata: name: app-configmap namespace: my-namespace data: config.json: | { "key": "value" } - name: Create Secret kubernetes.core.k8s: definition: apiVersion: v1 kind: Secret metadata: name: myapp-secret namespace: my-namespace stringData: password: mypassword
Как развернуть плейбук Ansible в Kubernetes на облачном провайдере
Сейчас мы в основном ориентируемся на PaaS-решение для нашего кластера Kubernetes, поскольку он будет размещаться в Azure, AWS, GCP или других местах. Поэтому я расскажу, как подключать кластер Azure AKS к Ansible прокси воркфлоу. Это подойдёт и для Amazon EKS и для Google GKE.
Давайте перейдём на нашу прокси-машину и запустим приведённый ниже код. Мы установим инструменты Azure CLI и используем команду az login, чтобы войти в Azure. Так мы убедимся, что мы можем подключиться к нашему кластеру AKS с прокси и убедиться, что наш kube config на прокси обновлён.
#Install Azure CLI (or any other cloud provider CLI tools): curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash #Login to Azure: az login #Add Azure AKS cluster to proxy ~/.kube/config az aks get-credentials --name name_of_aks_cluster --resource-group name_of_aks_rg #Test access to K8S cluster: kubectl get nodes kubectl get all -A
Как только мы убедимся, что можем получить доступ к нодам кластера AKS и другим ресурсам, мы можем перейти на контрольную ноду Ansible и запустить некоторые из предыдущих плейбуков с прокси.
- name: Create K8S resource hosts: proxy-servers tasks: - name: Get K8S namespace kubernetes.core.k8s: name: my-namespace api_version: v1 kind: Namespace state: present
Запустите команду ansible playbook:
ansible-playbook ~/ansible/playbooks/create_namespace.yml -i ~/ansible/inventory/kube_inventory
После завершения выполнения плейбука перейдите к своему прокси и убедитесь, что вы видите созданное пространство имён, выполнив следующее:
kubectl get namespace
Мы подтвердили, что можем запускать плейбук с кластером Azure AKS.
Следует отметить, что мы заменили существующий /.kube/config на конфигурацию кластера Azure AKS. Обычно у вас будет многокластерная среда, и вам нужно будет добавить разные конфигурационные файлы в папку ~/.kube/ и настроить свои плейбуки, чтобы они указывали на правильный конфигурационный файл:
- name: Set Kubernetes context k8s_auth: kubeconfig: /path/to/kubeconfig register: kube_auth
Как использовать Ansible для CI/CD в Kubernetes
Внедрение Ansible в CI/CD воркфлоу состоит из двух основных методов.
Использование Ansible в настройке Jenkins Pipeline для CI/CD. Это позволяет напрямую развёртывать и настраивать ресурсы Kubernetes из конвейера. Jenkins может запускать плейбуки Ansible как часть процесса развёртывания и применять изменения в кластере Kubernetes. Это идеальный подход, если вы ищете более практичный способ управления развёртыванием Kubernetes с помощью сценариев.
Интегрирование Ansible с инструментами CI/CD GitOps для Kubernetes, такими как ArgoCD или Flux. Эти инструменты будут больше сосредоточены на шагах предварительной обработки, необходимых для создания манифестов Kubernetes перед развёртыванием. Поскольку ArgoCD/Flux фокусируется на чтении репозитория Git для изменений файла манифеста Kubernetes, вы можете добавить шаг в свой конвейер CI/CD для запуска плейбука Ansible для динамического создания или обновления файлов манифеста в репозитории на основе конфигураций и сред с помощью шаблонов jinja2. Сила Ansible заключается в том, что он может выполнять все идемпотентные операции, что обеспечивает согласованное развёртывание без ненужных перенастроек.
Ansible в конвейере CI/CD Jenkins
Вот пример того, как вы могли бы использовать Ansible для развёртывания манифеста Kubernetes в конвейере CI/CD Jenkins:
Файл Jenkins:
pipeline { agent any environment { ANSIBLE_HOST_KEY_CHECKING = "False" } stages { stage('Checkout') { steps { checkout scm } } stage('Build') { steps { echo 'Building application...' // Add your build commands here, e.g., for a Java project: // sh './mvnw clean package' } } stage('Test') { steps { echo 'Running tests...' // Add your test commands here // sh './mvnw test' } } stage('Deploy') { steps { echo 'Deploying application...' script { ansiblePlaybook( playbook: 'ansible/deploy-app.yml' ) } } } } post { success { echo 'Deployment successful!' } failure { echo 'Deployment failed.' } } }
Плейбук Ansible:
--- - hosts: proxy_server gather_facts: no tasks: - name: Set up K8S Namespace kubernetes.core.k8s: state: present apiVersion: v1 kind: Namespace metadata: name: my-namespace - name: Deploy Application kubernetes.core.k8s: state: present definition: "{{ lookup('file', 'kubernetes/deployment.yml') | from_yaml }}"
Интеграция Ansible с инструментом CI/CD GitOps
Ниже приведён краткий пример того, как Ansible можно использовать вместе с вашей установкой ArgoCD для предварительной обработки и для создания или обновления файлов манифеста Kubernetes в репозитории Git:
Плейбук для копирования шаблона Jinja поверх развёртывания манифеста Kubernetes:
--- - hosts: localhost tasks: - name: Generate Kubernetes Deployment Manifest using Template template: src: templates/deployment.yml.j2 dest: manifests/deployment.yml
Пример шаблона Jinja:
apiVersion: apps/v1 kind: Deployment metadata: name: {{ app_name }} spec: replicas: {{ replicas }} selector: matchLabels: app: {{ app_name }} template: metadata: labels: app: {{ app_name }} spec: containers: - name: {{ app_name }} image: {{ image_name }}:{{ image_tag }} ports: - containerPort: {{ container_port }}
Пример файла переменных (для production), используемого для шаблона Jinja:
app_name: k8s-app-prod replicas: 3 image_name: k8s-app-prod/image image_tag: latest container_port: 80
Теперь создайте шаг в шагах сборки вашего конвейера CI/CD (Jenkins, GitHub Actions, Azure DevOps и т. д.), чтобы запустить плейбук Ansible и выполнить Git Commit и Push для вашего репозитория Git, который содержит файлы манифеста Kubernetes.
Если у вас уже настроен ArgoCD, то должен просто запуститься ArgoCD workflow для синхронизации и обновления существующего приложения Kubernetes. Если вы развёртываете новое приложение, вы можете выполнить следующие команды Argo CD:
argocd app create k8s-app-prod \ --repo https://github.com/username/your-repo.git \ --path manifests \ --dest-server https://kubernetes.default.svc \ --dest-namespace default
Синхронизировать приложение:
argocd app sync k8s-app-prod
После завершения синхронизации вы можете отслеживать развёртывание Kubernetes, чтобы убедиться, что оно работает должным образом.
Как видите, этот воркфлоу автоматизирует процесс развёртывания за счёт использования Ansible для управления конфигурацией и создания манифеста и использования ArgoCD для непрерывного развёртывания в соответствии с принципами GitOps.
Автоматизация обновлений и обновлений Kubernetes с помощью Ansible
Ansible также отлично подходит для управления обновлениями ваших ресурсов в кластере Kubernetes благодаря идемпотентной природе Ansible. Она минимизирует риск любого отклонения конфигурации и гарантирует, что все ваши ресурсы Kubernetes находятся в желаемом состоянии.
Ansible интегрируется с модулями Kubernetes. Это обеспечивает простой способ взаимодействия с API Kubernetes и выполнения операций обновления, таких как rolling обновления и канареечные развёртывания.
Приведённый ниже пример иллюстрирует, как развёртывать Rolling обновления в вашем кластере Kubernetes с помощью Ansible. Этот метод развёртывает обновления для подов одно за другим. Когда один старый под выключается, новый под с обновлённым образом запускается. Это обеспечивает минимальный даунтайм и плавный переход между старыми и новыми версиями вашего приложения.
--- - name: Execute a Rolling update for a K8S deployment hosts: proxy_servers tasks: - name: Update Kubernetes deployment kubernetes.core.k8s: state: present definition: kind: Deployment name: app-deployment namespace: my-namespace spec: template: spec: containers: - name: my-app-container image: nginx:latest register: update_result - name: Wait for rolling update to complete kubernetes.core.k8s_info: kind: Deployment name: app-deployment namespace: my-namespace register: deployment_info until: deployment_info.resources[0].status.updatedReplicas == deployment_info.resources[0].status.replicas retries: 60 delay: 10 - name: Display update result debug: msg: "Rolling update completed successfully"
Вы также можете использовать канареечные развёртывания. Это развёртывание новой версии вашего приложения для небольшой группы подов, постепенное увеличение трафика и мониторинг производительности приложения.
Вот пример:
--- - name: Canary Deployment hosts: proxy_servers vars: new_version: "v2" tasks: - name: Deploy 'Canary' Version kubernetes.core.k8s: definition: apiVersion: apps/v1 kind: Deployment metadata: name: myapp-canary namespace: my-namespace spec: replicas: 1 #using 1 replica for example selector: matchLabels: app: myapp version: canary template: metadata: labels: app: myapp version: canary spec: containers: - name: myapp-container image: "myapp:{{ new_version }}" ports: - containerPort: 8080 - name: Update Service to include 'Canary' Version kubernetes.core.k8s: definition: apiVersion: v1 kind: Service metadata: name: myapp-service namespace: my-namespace spec: selector: app: myapp ports: - protocol: TCP port: 80 targetPort: 8080
Вы также можете использовать Ansible для управления обновлениями нод кластера Kubernetes. Например, для обновления версий kubelet, kubeadm, kubectl, containerd, networking, docker или любых инструментов безопасности. В следующих примерах мы выполняем эти обновления на всех нодах Kubernetes.
Обновления Kubeadm:
- name: Upgrade kubeadm apt: name: kubeadm=1.29.2 state: latest update_cache: yes
Обновления Kubectl:
- name: Upgrade kubectl apt: name: kubectl=1.29.2 state: latest update_cache: yes
Обновление сети кластера Kubernetes:
- name: Upgrade CNI Plugins shell: kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/{{ cni_version }}/install/kubernetes/quick-install.yaml
Ключевые моменты
Использование Ansible для развёртывания вашей Kubernetes среды и ресурсов в кластере упростит рабочие процессы и даст больше контроля над всеми компонентами.
Ansible предоставляет вам визуальную гибкость в управлении ресурсами от развёртывания нод до развёртывания манифеста задач Kubernetes. Ansible полностью поддерживается всеми конвейерами CI/CD и может ещё больше оптимизировать все ваши развёртывания. Он позволяет обеспечить плавный и автоматизированный поток кода в кластеры Kubernetes.
Если вы изучаете Ansible, приходите на курс Ansible: Infrastructure as Code от Слёрма.
После курса сможете конфигурировать рутинные задачи с помощью простого и удобного инструмента, смело лезть под капот Ansible и настраивать инструмент под свои задачи. Для читателей Хабра скидка 15% по промокоду ansiblehabr.
