Цель данной статьи - понять принципы работы с kubernetes.

Для управления кластером будем использовать minikube - это инструмент, позволяющий запустить кластер Kubernetes, состоящий из одного узла. Чаще всего используется в учебных целях, для нас он тоже подходит.

Все модули и инструменты, связанные с kubernetes, имеют очень много настроек и описать их все здесь будет невозможно. Будем описывать необходимые нам настройки, но надо иметь ввиду, что в официальной документации может быть на много больше настроек.

Установка инструментов

Kubernetes умеет работать с разными системами виртуализации. Мы будем использовать docker, поэтому он должен быть установлен в системе.

Процесс установки minikube хорошо описан в официальной документации. Если коротко и применительно к linux, то понадобятся следующие команды:


# установка kubectl, без него не будет работать minikube
# скачиваем бинарник kubectl
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl

# делаем его исполняемым
chmod +x ./kubectl

# перемещаем в /usr/local/bin, чтобы исполняемый файл был доступен из любой директории
mv ./kubectl /usr/local/bin/kubectl

# проверяем правильность установки
kubectl version --client



# установка самого minikube
# скачиваем бинарник
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

# делаем его исполняемым
chmod +x minikube

# перемещаем в /usr/local/bin, чтобы исполняемый файл был доступен из любой директории
mv ./minikube /usr/local/bin/minikube

Далее запускаем команду создания кластера. Если установка прошла нормально, команда пару минут подумает и создаст кластер без ошибок.

minikube start --vm-driver=none

Мы указываем флаг --vm-driver=none чтобы minikube не использовал никакой драйвер виртуальной машины. Иначе пришлось бы устанавливать виртуальную машину в систему, а нам в учебных целях это не нужно. Про данный флаг подробнее можно почитать в официальной документации.

Итак, мы установили нужные нам инструменты и создали свой кластер kubernetes. Далее перейдем к описанию и настройке нужного нам окружения.

Немного теории

Kubernetes оперирует большим количеством базовых сущностей, а так же есть возможность добавлять сущности, написанные сторонними разработчиками и создавать собственные сущности.

Опишем сущности, которые нам понадобятся в нашей работе.

Pod (Под) - базовая сущность, которая содержит в себе один или несколько контейнеров приложения (например, docker-контейнеры). Поды рекомендуется оборачивать в сущность Deployment, но в данной статье мы этого делать не будем.

Service (Сервис) - сущность, расположенная над подами. Сервис позволяет дать группе подов одно DNS-имя и распределять нагрузку между подами.

Ingress - сущность, выступающая в роли балансировщика нагрузки и роутера между хостами. Так же она управляет отдачей сертификатов.

Так же мы установим набор сущностей cert-manager для генерации и управления сертификатами.

Создание необходимых сущностей

Управление сущностями в kubernetes происходит с помощью yaml либо json файлов. То есть надо приготовить yaml файл с нужным содержимым и потом с помощью утилиты kubectl "скормить" этот файл kubernetes с помощью команды

kubectl apply -f /путь/до/yaml/файла

Если что-то пошло не так и надо удалить сущность, можно сделать это командой

kubectl delete -f /путь/до/yaml/файла

Итак, переходим к созданию сущностей.

Создание пода

Для создания пода создадим файл pod.yaml и вставим в него следующий код:


apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  labels:
    app: test
spec:
  volumes:
  - name: www
    hostPath:
      path: /var/www/test
  containers:
  - name: test-pod
    image: php:apache
    ports:
    - containerPort: 80
    volumeMounts:
    - name: www
      mountPath: /var/www/html

Так как под содержит в себе один или несколько контейнеров, надо указать, какой образ будет использоваться для создания этих контейнеров. В данном конфиге указан php:apache, но вместо него можно указать любой образ, который docker может скачать.

Так же в конфиге указаны настройки для создания volume (общая папка между хостом и контейнером) для контейнеров. Здесь /var/www/test - папка на самом сервере, а /var/www/html - папка внутри контейнера.

Важный момент в конфиге - metadata -> labels -> app - это ключ, по которому сервис будет находить все поды, относящиеся к одному поддомену. В нашем случае для одного поддомена создается один под, но ключ все равно надо указать.

Конечно же, это не все настройки, возможные для пода. Здесь указаны только необходимые настройки под наши требования. Подробнее о настройке подов можно почитать в официальной документации.

Итак, добавим наш под в kubernetes

kubectl apply -f pod.yaml

Создание сервиса

Следующим шагом создадим файл service.yaml и вставим в него следующий код:


apiVersion: v1
kind: Service
metadata:
    name: test-service
spec:
    selector:
        app: test
    ports:
        - name: http
          protocol: TCP
          port: 80
          targetPort: 80

Здесь важный момент - ключ spec -> selector -> app. Это значение должно совпадать с значением ключа metadata -> labels -> app в файле конфигурации пода.

Блок ports сопоставляет 80-й порт системы с 80-м портом контейнеров.

Подробнее о настройке сервисов можно почитать в официальной документации.

Итак, добавим наш сервис в kubernetes

kubectl apply -f service.yaml

Создание подписчика сертификатов

Мы будем использовать бесплатные сертификаты letsencrypt. Для того, чтобы kubernetes умел с ними работать, нам надо установить дополнительный внешний набор сущностей cert-manager. Делается это такой же командой, которой мы добавляем свои сущности, но путь до конфига будет не локальный, а url, по которому kubernetes скачает конфиг и применит его:

kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.6.1/cert-manager.yaml

Подробно про установку и использование cert-manager можно почитать в его официальной документации. Нам же понадобится только одна сущность - Issuer. Создадим для него конфигурацию cert-issuer.yaml


apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory 
    privateKeySecretRef:
      name: letsencrypt
    solvers:
    - http01:
       ingress:
         class: nginx

И применим ее

kubectl apply -f cert-issuer.yaml

Создание Ingress

Ingress в minikube по умолчанию отключен, нам надо его включить командой

minikube addons enable ingress

Теперь можно создавать файл ingress.yaml и писать конфигурацию для ingress


apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/issuer: "letsencrypt"
spec:
  tls:
    - hosts:
      - example.com
      secretName: tls-secret
  rules:
    - host: example.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: test-service
                port:
                  number: 80

В этом конфиге мы настраиваем ключ tls, в котором перечисляем хосты, для которых нужно выписать сертификаты.

Так же настраиваем ключ rules, в котором настраиваем перенаправление трафика с определенных хостов на определенные сервисы. А именно, мы направляем все запросы с хоста example.com в сервис test-service, который мы создали ранее.

Применяем нашу конфигурацию:

kubectl apply -f ingress.yaml

Если все правильно сделано, то создастся сущность ingress и запустится фоновый процесс выпуска сертификата. В консоли это никак не отображается, но можно посмотреть, готов ли сертификат, следующим образом. Запускаем команду:

kubectl get certificates

Командой kubectl get <сущность> можно получить список сущностей определенного типа. В данном случае мы получаем список сертификатов. У нас будет всего один сертификат все хосты. В выводе команды есть колонка Ready, в которой отображается состояние сертификата. Если там значение False, значит либо идет процесс выпуска сертификатов, либо что-то пошло не так. Процесс выпуска сертификатов идет обычно около 1-2 минут. Если статус долго не меняется, значит где-то случилась ошибка и надо разбираться.

Как только статус поменялся на True, наш хост находится в рабочем состоянии. Останется только создать папку /var/www/test, которую мы указали как volume для нашего пода, и создать там развернуть там приложение. Для проверки можно создать index.html с каким нибудь текстом, и можно открывать сайт в браузере.

Если все прошло гладко, сайт автоматически откроется с https и мы увидим содержимое index.html

Share with friends:

Facebook Twitter Vkontakte