Рубрики
Без рубрики

Синхронизация услуг Kubernetes на Microk8s для локальной разработки с Python

Работа вокруг недостатков DNS на местных кластерах Kubernetes. Tagged with Kubernetes, Microk8s, Python.

Отказ от ответственности : Это было то, что я сделал, потому что мне было скучно. Вероятно, есть лучшие способы сделать это (пожалуйста, поделитесь ими, если вы знаете!), И ваш пробег определенно будет варьироваться.

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

Тем не менее, есть все еще ситуации, когда развитие за пределами кластера имеет свои преимущества. Один из них меньше накладных расходов; Не нужно синхронизировать файлы и каталоги или прикреплять к удаленным отладчикам. Мне нравится иметь как можно меньше слоев между моим кодом и моим отладчиком, а иногда даже само развитие Docker – это боль, которой я стараюсь избежать.

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

Итак, недавно я начал исследовать решения. Minikube – хорошее начало, но, поскольку ему рекомендуется запустить его в виртуальной машине, у него слишком много накладных расходов для некоторых рабочих процессов, которые я разрабатываю. Итак, я попробовал Microk8s, что великолепно, так как он работает локально, с достаточной изоляцией (он установлен как пакет Snap на Linux). Тем не менее, ни Minikube, ни Microk8 не имеют решения для DNS «вне кластера» (о котором я знаю).

Некоторые предлагают решения

Обычно решение для этого (по крайней мере, на Linux) сводится к:

  • Запустите локальный DNS -сервер, или DNSMASQ настроено, чтобы указать имена хостов службы на свою машину;
  • Вручную отредактируйте файл хостов вашей машины ( /etc/hosts ), чтобы сохранить вещи синхронизировать себя. Например, Minikube’s Руководство по вступлению Явно предлагает вам отредактировать файл ваших хостов.

Ни один из них не отлично. Например, использование DNSMASQ или локальный DNS -сервер может мешать VPN, что означает, что вы не сможете получить доступ к своему кластеру, или услугам вашего VPN, или оба; В то время как вручное редактирование файлов хостов – это боль и требует привилегий администратора.

Альтернатива – использовать что -то вроде Телеприз (Что звучит действительно многообещающе, разум), но если вы разрабатываете внешние контейнеры, это также может связываться с вашими настройками DNS таким образом, что VPNS также не будет работать.

Это то, что я хочу:

  • Иметь возможность разрабатывать и отлаживать мое приложение, не требуя создания изображения и запуска его в кластере (в пределах разумного);
  • Все еще иметь возможность получить доступ к услугам, которые развернуты в кластере по их имени;
  • Не испортить VPN, мне нужно получить доступ к корпоративным ресурсам.

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

Хост файлы

Файл хостов, кратко, представляет собой текстовый файл, содержащий «таблицу» IP -адреса для имени хоста, например:

127.0.0.1 localhost
192.168.1.1 my-router

Эти файлы существуют в Windows, MacOS и Linux, и после обновления они будут использоваться для разрешения имени хоста, а не на вашем DNS -сервере (обратите внимание, что в этом есть исключения, которые я здесь не расскажу).

Типы услуг Kubernetes

Есть несколько способов разоблачения контейнеров развертывания с Сервис Анкет Вот некоторые:

  • Nodeport , который отображает порт на хосте на порт на контейнере (очень похожа на пересылку порта или опцию -p для docker run )
  • Кластерип , который присваивает для этого кластер-локальный IP-адрес Развертывание
  • LoadBalancer , что позволяет маршрутизации в несколько реплик стручков развертывания для распределения нагрузки.

Есть также Вход Ресурсы, которые вы можете использовать для разоблачения Сервис S за пределами кластера в качестве конкретных имен хоста. Вы должны предпочтительно использовать их, если вы хотите разоблачить услуги снаружи.

Предположим, у вас есть веб -сервер Nginx, который вы хотите разоблачить:

$ kubectl create deployment nginx --image nginx
deployment.apps/nginx created

Это создаст развертывание и стручок для Nginx:

$ kubectl get pods
NAME                                         READY   STATUS      RESTARTS   AGE
nginx-f89759699-2thhf                        1/1     Running     2          7h3m

Чтобы разоблачить стручки этого развертывания (капсулам кластера и снаружи), нам нужна услуга. Мы можем создать такой, как это:

$ kubectl expose deploy nginx --port 80 --name nginx-svc
service/nginx-svc exposed

Теперь вы можете проверить, что он был создан:

$ kubectl get services
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
nginx-svc    ClusterIP   10.152.183.235           80/TCP    39s

Если вы вводите этот IP -адрес (обратите внимание, что в вашем случае он будет отличаться), вы должны увидеть страницу приветствия Nginx:

$ curl 10.152.183.235




Welcome to nginx!

Теперь то же самое nginx-svc доступен для других стручков на кластерах с помощью его названия. Вы можете проверить это, запустив другой стручок на кластере:

$ kubectl run -i -t --rm --image alpine name
If you don't see a command prompt, try pressing enter.
/ # apk add curl

/ # curl nginx-svc




Welcome to nginx!

Но Если вы сделаете это за пределами кластера (то есть на хосте):

$ curl nginx-svc
curl: (6) Could not resolve host: nginx-svc

Он терпит неудачу, так как нет записи DNS для имени службы за пределами кластера.

Если вы добавите IP -адрес службы в файл хостов, он будет работать:

$ echo '10.152.183.235 nginx-svc' | sudo tee /etc/hosts
10.152.183.235 nginx-svc
$ curl nginx-svc




Welcome to nginx!

Имейте в виду, что это работает, потому что Microk8s устанавливает сетевой интерфейс и маршруты, чтобы позволить трафику от вашего хост -машины в кластер, и наоборот.

Во всяком случае, это здорово, но это означает, что мне нужно редактировать файл хостов вручную. Это скучно, так что давайте автоматизируем это:

Автоматизация синхронизации файлов хостов

Нам нужны две вещи для каждой службы: это имя, и это IP -адрес внутри кластера. Я мог бы использовать kubectl и сценарии оболочки, чтобы получить необходимую мне информацию, но я решил прибегнуть к Python. Это также позволяет мне использовать Kubernetes библиотека. Это можно установить с Pip Анкет После этого мы можем сделать что -то вроде этого:

import kubernetes.config

# The first thing we need to do is configure the library with our credentials. This will load them from ~/.kube/config.
kubernetes.config.load_kube_config()

core = kubernetes.client.CoreV1Api()

# Get the services from the server (I'll assume the default namespace)
services = core.list_namespaced_service(namespace='default').items

for service in services:
    print(f"Service {service.metadata.name} has IP {service.spec.cluster_ip}")

Запустив это, мы получаем:

Service kubernetes has IP 10.152.183.1
Service nginx-svc has IP 10.152.183.235

Это хорошее начало! Теперь нам нужно добавить эту информацию в файл хостов. Я сделаю это очень наивно, чтобы сделать вещи простыми, так что:

import kubernetes.config

# The first thing we need to do is configure the library with our credentials. This will load them from ~/.kube/config.
kubernetes.config.load_kube_config()

core = kubernetes.client.CoreV1Api()

# Get the services from the server (I'll assume the default namespace)
services = core.list_namespaced_service(namespace='default').items

# Open the hosts file in append mode, so that we can write to it.
# ATTENTION: DO NOT RUN THIS, IT MIGHT DAMAGE YOUR HOSTS FILE!
with open('/etc/hosts', 'a') as hosts_writer:
    # Write an empty line, in case the file doesn't end with a new line (in case you do run this)
    hosts_writer.write('\n')

    # The format of the hosts file is [IP] [Host Name], so we can write to it like this:
    for service in services:
        hosts_writer.write(f'{service.spec.cluster_ip} {service.metadata.name}')

Снова Не запускайте это ! Вы можете повредить файл ваших хостов, что может вызвать у вас проблемы.

Но, предполагая, что вам удастся запустить это ( sudo , к счастью, перерывает вещи с Kubernetes), ваш файл хостов должен быть обновлен. Однако, если вам удастся запустить это, не запускайте это неоднократно, так как это будет продолжать добавлять новые строки в файл хостов.

Чтобы сделать это немного безопаснее, вы можете сделать знак сценария добавить линии с комментарием, а затем удалить их перед добавлением новых.

Имея основную версию сценария, мы можем пойти немного дальше:

  • Добавьте поддержку ресурсов входа, так что они также доступны от хоста (если у них, конечно, есть определенный хост);
  • Использование этого периодически в кластере, с работой Cron;
  • Дополнительные проверки проверки для здравомыслия;
  • Добавьте фильтры, чтобы мы разоблачили только некоторые хосты.

Вы можете проверить, что я сделал в этом GitHub Repository Анкет

Спасибо за чтение!

Оригинал: “https://dev.to/redroserade/syncing-kubernetes-services-on-microk8s-for-local-development-with-python-3lcn”