Делимся переводом статьи об интеграции Kubernetes и Ansible. Из статьи вы узнаете, как подготовить среду для работы, как развернуть кластер Kubernetes с помощью Ansible, как управлять ресурсами Kubernetes и автоматизировать обновления. Кроме того, вы узнаете, как развернуть плейбук Ansible в Kubernetes на облачном провайдере и использовать Ansible для CI/CD в Kubernetes.
![](https://habrastorage.org/getpro/habr/upload_files/521/134/580/5211345802d7160c40253efb7d1695f4.png)
Перед тем как начать
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.
![Источник Источник](https://habrastorage.org/getpro/habr/upload_files/edb/82c/109/edb82c109434c19e04021a19219d5a1d.png)
Чтобы 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 и настраивать инструмент под свои задачи.