Делимся переводом статьи об интеграции 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Вы сможете систематизировать знания и получить практику на наших стендах. Посмотреть программу и записаться на курс можно на нашем сайте. Ждём на курсе!

Комментарии (4)


  1. Dimly
    28.04.2024 03:43
    +3

    Вот и выросли зумеры блин - '2 ГБ ЦП и 4 ГБ ОЗУ."


  1. Angry_Bel
    28.04.2024 03:43
    +5

    Я так и не понял, а в чем Профит использования ансибле вместо/поверх хельма?

    Все очень обще, выглядит как реклама от маркетологов ansble. Мы самые лучшие, потому что мы самые лучшие!


  1. chemtech
    28.04.2024 03:43

    Использование ansible для развёртывания k8s приложений лишнее звено, так как сам helm/fluxcd/argocd это могут делать. Никаких преимуществ в этом подходе нет.


  1. Qweritos
    28.04.2024 03:43
    +1

    Как управлять Kubernetes с помощью Ansible

    а главное - зачем?