В нашей новой переводной статье разбираемся с KinD на практическом примере.
Создание кластера Kubernetes со временем становится все проще. На рынке доступно несколько решений под ключ, и сейчас никто не выбирает сложный путь!
![](https://habrastorage.org/webt/hr/xc/rm/hrxcrmeqoucj8-4c56nkhbkmbmm.jpeg)
Стоит отметить, что Minikube был одним из основных кластеров, которые разработчики использовали для быстрой разработки и тестирования контейнеров. Хотя Minikube в настоящее время поддерживает многоузловой кластер на экспериментальной основе, его еще нет в общем доступе (GA).
Следовательно, это ограничивает возможности интеграции и тестирования компонентов, поэтому большинство организаций используют для этого управляемые облачные сервисы Kubernetes.
Для интеграции Kubernetes в конвейер CI/CD (непрерывная интеграция и развертывание) и выполнения тестирования необходимы следующие инструменты: Terraform, в зависимости от облачного провайдера и, конечно же, инструмент для CI/CD, например Jenkins, GitLab или GitHub.
Для крупных компаний с достаточным бюджетом это подходящие варианты, однако разработчики часто ищут что-то, что поможет им быстро начать работу. Развертывание кластера Kubernetes в облаке также занимает некоторое время (~ 10 минут), что может быть препятствием для CI, где нужно быстро получать сборки.
Kubernetes в Docker или KinD — это реализация подхода Docker-in-Docker (DinD) для Kubernetes. Этот инструмент создает контейнеры, которые действуют как узлы Kubernetes, и вам необходимо только установить Docker на своем компьютере.
Он позволяет развернуть многоузловой кластер за пару минут без зависимости от других инструментов или облачных провайдеров. Благодаря этому он полезен не только для локальной разработки, но и для CI/CD.
Архитектура KinD
Kubernetes в Docker использует подход Docker-in-Docker (DinD) для запуска кластера Kubernetes. Он запускает несколько Docker контейнеров, которые функционируют как узлы Kubernetes. Контейнеры Docker монтируют том docker.sock в Docker, запущенный на вашем компьютере, чтобы обеспечить взаимодействие с базовой средой выполнения контейнера.
![](https://habrastorage.org/webt/ak/zz/s4/akzzs4crwuw6as87kcs-w5-alfc.png)
KinD прошел проверку на соответствие и получил сертификат CNCF. Он использует Kubeadm для начальной загрузки кластера, а также генерирует файлы конфигурации Kube для пользователя, через которого вы управляете вашим кластером, что позволяет использовать kubectl для взаимодействия с кластерами. Другие компоненты Kubernetes, такие как Helm и Istio, также прекрасно работают в кластерах KinD.
Недостаток KinD заключается в том то, что он не работает со службами LoadBalancer, поэтому вам придется использовать NodePort, чтобы пробрасывать свои службы извне.
Кроме того, DinD в настоящее время является не самым безопасным решением, поэтому используйте кластеры KinD только на локальных машинах разработки и CI/CD конвейерах. Никогда не используйте KinD в производственной среде!
Установка KinD
KinD состоит из простой утилиты командной строки, которую вы можете загрузить и положить по своему пути. Затем вы можете взаимодействовать с KinD, используя команды kind:
sudo curl -sL https://kind.sigs.k8s.io/dl/v0.9.0/kind-linux-amd64 -o /usr/local/bin/kind
sudo chmod +x /usr/local/bin//kind
Затем вы можете создать свой кластер, при помощи следующей команды:
kind create cluster --wait 10m
Эта команда создаст одноузловой кластер. Но если вы хотите определить многоузловой кластер, можно использовать файл конфигурации кластера, подобный приведенному ниже:
# three node (two workers) cluster config
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
Затем создайте кластер с файлом конфигурации, используя следующую команду:
kind create cluster --wait 10m --config kind-config.yaml
Вы также можете создать кластеры с несколькими уровнями управления, указав несколько ролей в разделе узлов.
Так как KinD автоматически создает файл конфигурации Kube, вы можете использовать команды kubectl, как и в случае с другими кластерами.
Удалить кластер KinD также просто. Запустите следующую команду:
kind delete cluster
Приступаем к практике
Без лишних слов, давайте на практике разберемся, как CI/CD конвейер использует KinD. Мы возьмем GitHub Actions в качестве инструмента для CI/CD, поскольку он прост в использовании, не требует дополнительной инфраструктуры, а запустить его может любой, у кого есть ноутбук и подключение к интернету.
Давайте создадим простое приложение NGINX с надписью «Hello World».
Выполняем следующие действия:
- Создаем дев-версию приложения.
- Запускаем тестирование компонентов в кластере KinD.
- Если тест проходит успешно, мы переводим образ в релиз и отправим его в Docker Hub.
Необходимые условия
- Аккаунт GitHub
- Аккаунт Docker Hub
Краткое руководство
- Сделайте форк этого репозиторияэтот репозиторий.
- Зайдите в репозиторий и создайте два secret: DOCKER_USER и DOCKER_PW. Они должны содержать ваше имя пользователя в Docker Hub и пароль от аккаунта соответственно.
- Перейдите в GitHub Actions и повторно запустите задачи. Как вариант, вы можете внести изменения в файл README.md и запушить его чтобы запустить действие.
Длинная версия
Давайте рассмотрим файл build-pipeline.yml на GitHub Actions чтобы понять, как он работает:
name: Docker Image CI
on: [push]
# Environment variables available to all jobs and steps in this workflow
env: # Or as an environment variable
docker_username: ${{ secrets.DOCKER_USER }}
docker_password: ${{ secrets.DOCKER_PW }}
jobs:
build-docker-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Build the Docker image
run: docker build -t $docker_username/nginx:dev .
- name: Login to Docker
run: echo "$docker_password" | docker login -u "$docker_username" --password-stdin
- name: Push the docker image
run: docker push $docker_username/nginx:dev
kubernetes-component-test:
runs-on: ubuntu-latest
needs: build-docker-image
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Run KIND Test
run: sudo sh build-test.sh $docker_username
promote-and-push-docker-image:
runs-on: ubuntu-latest
needs: kubernetes-component-test
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Pull the Docker image
run: docker pull $docker_username/nginx:dev
- name: Tag the Docker image
run: docker tag $docker_username/nginx:dev $docker_username/nginx:release
- name: Login to Docker
run: echo "$docker_password" | docker login -u "$docker_username" --password-stdin
- name: Push the docker image
run: docker push $docker_username/nginx:release
Пайплайн сборки запускает последовательно три задания:
- Задача build-docker-image создает Docker образ для разработки и отправляет его в Docker Hub при успешной сборке. В этой задаче вы можете запустить своё модульное тестирование.
- Задача kubernetes-component-test настраивает кластер KinD и запускает компонентный тест для приложения.
- Задача promote-and-push-docker-image извлекает образ для разработки, маркирует его до релизной версии и отправляет релизную версию в Docker Hub.
Давайте рассмотрим Dockerfile, чтобы понять, что он создает:
FROM nginx
RUN echo 'Hello World' > /usr/share/nginx/html/index.html
Второй шаг является ключевым, он запускает скрипт build-test.sh. Сейчас давайте посмотрим на скрипт:
#! /bin/bash
docker_username=$1
set -xe
curl -sL https://kind.sigs.k8s.io/dl/v0.9.0/kind-linux-amd64 -o /usr/local/bin/kind
chmod 755 /usr/local/bin//kind
curl -sL https://storage.googleapis.com/kubernetes-release/release/v1.17.4/bin/linux/amd64/kubectl -o
chmod 755 /usr/local/bin//kubectl
curl -LO https://get.helm.sh/helm-v3.1.2-linux-amd64.tar.gz
tar -xzf helm-v3.1.2-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/
rm -rf helm-v3.1.2-linux-amd64.tar.gz
kind version
kubectl version --client=true
helm version
kind create cluster --wait 10m --config kind-config.yaml
kubectl get nodes
docker build -t $docker_username/nginx:dev .
kind load docker-image $docker_username/nginx:dev
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
NODE_IP=$(kubectl get node -o wide|tail -1|awk {'print $6'})
NODE_PORT=$(kubectl get svc nginx-service -o go-template='{{range.spec.ports}}{{if .nodePort}}{{.node
sleep 60
SUCCESS=$(curl $NODE_IP:$NODE_PORT)
if [[ "${SUCCESS}" != "Hello World" ]];
then
kind -q delete cluster
exit 1;
else
kind -q delete cluster
echo "Component test succesful"
fi
Что делает скрипт:
- Скачивает и устанавливает утилиту kind, kubectl и helm на CI-сервер.
- Создает многоузловой кластер с помощью файла kind-config.yaml.
- Создает Docker образ для разработки с помощью docker build.
- Загружает Docker образ в кластер KinD. Благодаря загрузке обеспечивается доступ к образу для всех узлов KinD, чтобы им не приходилось извлекать образ из Docker Hub.
- Разворачивает контейнер в deployment и пробрасывает его через сервис NodePort NodePortservice.
- Получает IP-адрес и порт узла и запускает тест, чтобы проверить, возвращает ли приложение фразу «Hello World».
- Если проверка проходит успешно, удаляет кластер KinD, выводит «Component test successful» (успешное выполнение компонентного теста) и возвращает код успеха. Если проверка не пройдена, удаляет кластер KinD и возвращает код ошибки.
Результаты
Когда мы начинаем работу с пайплайном, GitHub Actions автоматически запускает весь пайплайн:
![](https://habrastorage.org/webt/07/r6/gf/07r6gfngwluf-v7gg_mcjrtehom.gif)
Это, несомненно улучшение и удобный способ для выполнения непрерывной интеграции и развертывания с использованием Docker и Kubernetes. Kubernetes в Docker не только упрощает локальную разработку, но и является отличным инструментом для CI/CD.
Спасибо, что прочитали статью! Надеюсь, она вам понравилась!