Настройка переменных среды на основе сервисов в Kubernetes

#kubernetes #google-kubernetes-engine

#kubernetes #google-kubernetes-engine

Вопрос:

Я запускаю простое приложение, основанное на API и веб-интерфейсе в Kubernetes. Однако, похоже, я не могу заставить api взаимодействовать с веб-интерфейсом. В моей локальной среде я просто определяю переменную API_URL в веб-интерфейсе с помощью, например. localhost:5001 и веб-интерфейс корректно подключаются к API. Поскольку api и web работают в разных модулях, мне нужно заставить их взаимодействовать друг с другом через сервисы в Kubernetes. Пока это то, что я делаю, но без какой-либо удачи.

Я настроил развертывание для API

 apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: api
  template:
    metadata:
      labels:
        component: api
    spec:
      containers:
      - name: api
        image: gcr.io/myproject-22edwx23/api:latest
      ports:
      - containerPort: 5001
  

Я прикрепляю к нему сервис:

 apiVersion: v1
kind: Service
metadata:
  name: api-cluster-ip-service
spec:
  type: NodePort
  selector:
    component: api
  ports:
    - port: 5001
      targetPort: 5001
  

а затем создайте веб-развертывание, которое должно подключаться к этому api.

 apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: web
  template:
    metadata:
      labels:
        component: web
    spec:
      containers:
      - name: web
        image: gcr.io/myproject-22edwx23/web:latest
        ports:
        - containerPort: 5000
        env:
          - name: API_URL
            value: http://api-cluster-ip-service:5001
  

после этого я добавляю сервис для веб-интерфейса ingress и т.д., Но это кажется неуместным для проблем. Мне интересно, правильно ли настройка API_URL выбирает хост API черезhttp://api-cluster-ip-service:5001?

Или я не могу полагаться на то, что Kubernetes получит соответствующий DNS для API, и веб-приложение должно вызывать api через общедоступный Интернет.

Комментарии:

1. Разве вам не хватает containerPort: 5001 в api-deployment спецификации?

2. да, я обновил это в вопросах (это было в моем коде)

Ответ №1:

Если вы хотите проверить значение переменной API_URL, просто запустите

 kubectl exec -it web-deployment-pod env | grep API_URL
  

Служба kube-dns прослушивает события службы и конечной точки из API Kubernetes и обновляет свои записи DNS по мере необходимости. Эти события запускаются при создании, обновлении или удалении служб Kubernetes и связанных с ними модулей.

kubelet устанавливает параметр поиска для каждого нового модуля в /etc/resolv.conf

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

 api-cluster-ip-service.default.svc.cluster.local
  

У вас должен быть служебный IP, назначенный переменной env в вашем веб-модуле, поэтому нет необходимости изобретать его заново:

 sukhoversha@sukhoversha:~/GCP$ kk exec -it web-deployment-675f8fcf69-xmqt8 env | grep -i service
API_CLUSTER_IP_SERVICE_PORT=tcp://10.31.253.149:5001
API_CLUSTER_IP_SERVICE_PORT_5001_TCP=tcp://10.31.253.149:5001
API_CLUSTER_IP_SERVICE_PORT_5001_TCP_PORT=5001
API_CLUSTER_IP_SERVICE_PORT_5001_TCP_ADDR=10.31.253.149
  

Чтобы узнать больше о DNS для сервисов. Сервис определяет переменные среды, именующие хост и порт.

Комментарии:

1. спасибо, это довольно проницательно. Как есть, значение для API_URL буквально равно api-cluster-ip-service: 5001 , и веб-приложение, очевидно, больше не работает. расширяет его. Я попытался установить API_URL=API_CLUSTER_IP_SERVICE_PORT, но безрезультатно. Я не хочу изменять API_URL в веб-приложении, поскольку тогда это становится зависимым от того, как я вызываю свою службу Kubernetes. Итак, мне все еще не ясно, как получить API_URL= 10.31.253.149:5001 в качестве переменной env.

Ответ №2:

Если вы хотите использовать переменные среды, вы можете сделать следующее:

Пример в Python:

 import os
API_URL = os.environ['API_CLUSTER_IP_SERVICE_SERVICE_HOST']   ":"   os.environ['API_CLUSTER_IP_SERVICE_SERVICE_PORT']
  

Обратите внимание, что переменная среды основана на имени вашего сервиса. Если вы хотите проверить все переменные среды, доступные в модуле:

 kubectl get pods #get {pod name}
kubectl exec -it {pod_name} printenv
  

P.S. Будьте осторожны, чтобы модуль получал свои переменные среды во время своего создания, и он не сможет получить их из сервисов, созданных после него.

Комментарии:

1. спасибо, но я знаю, как использовать переменные env в python. Мне нужно знать, как установить их в файле kubernetes yml таким образом, чтобы переменная среды получала IP-адрес от сервиса

2. Вам не нужно устанавливать их в kubernetes, если у вас есть сервис. Kubernetes автоматически создает и предоставляет хосты и порты сервисов во всех модулях. Прочитайте здесь объяснение. Я бы использовал команду, которую я показал выше, для проверки всех переменных среды. Если вы создали сервис после модуля, удалите модуль.