Сетевое взаимодействие GCP от вычислительного ресурса VM до службы GKE в одной и той же VPC.

Вопрос или проблема

У меня есть экземпляр виртуальной машины с именем mysql-1 в той же учетной записи, в том же VPC, что и кластер GKE.

У меня развернут сервис k8s:

~ $ kubectl get services
NAME                                           TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                                        AGE
haproxy-mysql                                  LoadBalancer   10.19.242.236   8.8.8.8     3306:32375/TCP,3307:30748/TCP,3308:30064/TCP   40m 
^ здесь заменен фактический внешний IP на 8.8.8.8

На виртуальной машине у меня работает mysql на 3306

user@mysql-1:~$ netstat -ntap |grep 3306|grep LISTE
(Не все процессы могут быть идентифицированы, информация о процессах, не принадлежащих текущему пользователю, не будет показана, вам нужно быть root, чтобы увидеть все.)
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      -
user@mysql-1:~$ ip a|grep 156
    inet 10.156.0.13/32 brd 10.156.0.13 scope global dynamic ens4

из k8s pod я могу подключиться к виртуальной машине:

# curl -I 10.156.0.13:3306
curl: (8) Странный ответ сервера

из виртуальной машины я не могу подключиться к сервису haproxy используя как внутренний, так и внешний IPs:

user@mysql-1:~$ curl --connect-timeout 2 10.19.242.236:3306
curl: (28) Время ожидания соединения истекло через 2001 миллисекунду
user@mysql-1:~$ curl --connect-timeout 2 8.8.8.8:3306
curl: (28) Время ожидания соединения истекло через 2001 миллисекунду

когда я использую IP pod, это работает :

$ kubectl get pods -A -o wide |grep haproxy-mysql
default       haproxy-mysql-6dd5f8cf64-72gdx                             1/1     Running   0          10m   10.16.1.39    gke-blabla-default-pool-370bb0fd-92rb   <none>           <none>
default       haproxy-mysql-6dd5f8cf64-zgmwb                             1/1     Running   0          10m   10.16.2.56    gke-blabla-default-pool-370bb0fd-prn7   <none>           <none>
user@mysql-1:~$ curl --connect-timeout 2 10.16.1.39:3306
Внимание: Двоичный вывод может испортить ваш терминал. Используйте "--output -" чтобы указать
Внимание: curl выводить его на ваш терминал, или учтите "--output
Внимание: <FILE>" чтобы сохранить в файл.

У меня есть правило межсетевого экрана:

~ $ gcloud compute firewall-rules list|grep 3306
k8s-fw-ad6943bb1121311eab6fc42010a9c005  default  INGRESS    1000      tcp:3306,tcp:3307,tcp:3308          False


~ $ gcloud compute firewall-rules describe k8s-fw-ad6943bb1121311eab6fc42010a9c005
allowed:
- IPProtocol: tcp
  ports:
  - '3306'
  - '3307'
  - '3308'
creationTimestamp: '2019-11-28T11:18:23.294-08:00'
description: '{"kubernetes.io/service-name":"default/haproxy-mysql", "kubernetes.io/service-ip":"8.8.8.8"}'
direction: INGRESS
disabled: false
id: '2373636381534430096'
kind: compute#firewall
logConfig:
  enable: false
name: k8s-fw-ad6943bb1121311eab6fc42010a9c005
network: https://www.googleapis.com/compute/v1/projects/blalala-1234lab/global/networks/default
priority: 1000
selfLink: https://www.googleapis.com/compute/v1/projects/blalala-1234/global/firewalls/k8s-fw-ad6943bb1121311eab6fc42010a9c005
sourceRanges:
- 8.8.8.8/32
- 8.8.8.8/32
- 8.8.8.8/32
- 10.0.0.0/8
- 8.8.8.8/32
- 8.8.8.8/32
- 8.8.8.8/32
- 8.8.8.8/32
targetTags:
- gke-blablabla-4125f0a3-node

с сервера, который явно указан в блоке выше (маскирован как 8.8.8.8/32), я могу подключиться к сервису EXTERNAL-IP

Что я здесь упускаю?

IP-адреса Pod маршрутизируются, IP-адреса сервисов — нет.
Создание кластера VPC-native:

IP-адреса кластера для внутренних сервисов доступны только внутри
кластера. Если вы хотите получить доступ к Kubernetes-сервису из той же
VPC и региона, но за пределами кластера (например, с экземпляра Compute Engine), используйте внутренний балансировщик нагрузки.

Документация по внутреннему балансировщику нагрузки

Что касается доступа с внешнего IP, возможно, такие правила не будут работать, если источник — это частный IP, а цель — внешний IP (даже если это выражается в виде метки там). Для входящих соединений этот частный IP не будет виден как источник IP, и правило не сработает?

Вы следовали всем шагам здесь Настройка балансировки нагрузки HTTP с Ingress для настройки вашего кластера GKE?

Насколько я понимаю, вам нужно Предоставить ваш деплоймент как сервис внутри кластера

Если вы ищете способ подключиться к вашим сервисам GKE из виртуальной машины в той же VPC, то, по состоянию на 2025-03-03, это можно сделать, настроив Cloud DNS в GKE. См. https://cloud.google.com/kubernetes-engine/docs/how-to/cloud-dns#vpc_scope_dns

.

Ответ или решение

Для решения проблемы соединения между виртуальной машиной (VM) и службой GKE в пределах одного VPC на платформе Google Cloud Platform (GCP), давайте рассмотрим все аспекты, начиная с теории основных компонентов GCP, включая архитектуру сети, настройки Kubernetes и правила брандмауэра.

Теория (T)

Виртуальные машины (VM) и кластеры Google Kubernetes Engine (GKE) могут существовать внутри одной виртуальной частной сети (VPC) на GCP, что позволяет обеспечить внутренние взаимодействия между различными элементами инфраструктуры. Понимание того, как GKE и VM работают вместе в контексте VPC, жизненно важно для создания надежной сетевой архитектуры.

  1. GKE Службы и IP-адреса:

    Внутренние IP-адреса кластера GKE известны как IP-адреса "Сети кластеров" (Cluster IP) и они не доступны вне кластера GKE. Для доступа к этому ресурсу из других источников внутри того же VPC (например, из виртуальной машины) требуется использование внутреннего балансировщика нагрузки.

  2. Балансировщик нагрузки:

    Google Cloud предлагает внутренние и внешние балансировщики нагрузки для различных сценариев. Использование внутреннего балансировщика нагрузки для службы Kubernetes сделает ее доступной из VM в том же VPC.

  3. Правила брандмауэра:

    В GCP трафик управляется с помощью правил брандмауэра. Это требует, чтобы необходимые порты были открыты и соответствующие диапазоны IP-адресов были указаны как источники соединений.

Пример (E)

Рассмотрим текущую проблему: на VM mysql-1 запущен MySQL на порту 3306, и имеется k8s служба haproxy-mysql. Интересно отметить, что из VM не удается подключиться к Cluster IP службы, хотя ip-адрес пода работает. Давайте разберем это ситуация:

  1. Подключение к Cluster IP:

    • Подключения из VPC к Cluster IP блокируются по умолчанию. Эти IP-адреса доступны только внутри кластера GKE, как упоминалось в представленной документации.
  2. Подключение к Pod IP:

    • Под IP-адреса доступны для маршрутизации внутри того же VPC. Это объясняет, почему ваш curl запрос к Pod IP успешен.
  3. Правила брандмауэра:

    • Существующее правило брандмауэра открывает порт 3306, но список источников включает только 8.8.8.8/32, в то время как ваш машинный IP (10.156.0.13) необходим для корректного функционирования.

Применение (A)

Для обеспечения стабильного соединения между VM и службой в GKE вам нужно сделать следующее:

  1. Создание внутреннего балансировщика нагрузки:

    Создайте внутренний балансировщик нагрузки, который будет ассоциирован с вашей службой GKE. Это позволит вам создать IP-адрес, доступный для VM в том же VPC.

    apiVersion: v1
    kind: Service
    metadata:
      name: haproxy-mysql
      annotations:
        cloud.google.com/load-balancer-type: "Internal"
    spec:
      type: LoadBalancer
      ports:
      - port: 3306
        targetPort: 3306
      selector:
        app: haproxy

    Этот конфигурационный файл будет создаваться с уникальным для вас Cluster IP и сможет использоваться в VPC.

  2. Настройка правил брандмауэра:

    Обновите ваши правила брандмауэра, чтобы включить все нужные диапазоны IP-адресов из вашего VPC:

    gcloud compute firewall-rules create allow-internal-lb \
        --network default \
        --allow tcp:3306 \
        --source-ranges 10.156.0.0/20

    Это правило позволит трафику по порту 3306 между вашей VM и лоад-балансером вашего кластера GKE.

  3. Проверка и тестирование:

    Убедитесь, что ваш балансировщик нагрузки успешно создан и что ваш трафик может передаваться из VM к службе через новый IP-адрес внутреннего балансировщика.

Следуя этим шагам, вы сможете эффективно связать вашу виртуальную машину с вашим кластером GKE в пределах одного VPC, используя внутренние службы и балансировщики нагрузки.

Оцените материал
Добавить комментарий

Капча загружается...