Как разрешить имя хоста модуля Kubernetes при создании клиента grpc из другого модуля?

Проблема:

как разрешить имя хоста контейнера кубернетов?

У меня есть следующее требование: мы используем grpc с java, где у нас есть одно приложение, в котором мы запускаем сервер grpc, другое приложение, где мы создаем клиент grpc и подключаемся к серверу grpc (который работает на другом модуле).


У нас есть три модуля kubernetes, на которых работает наш сервер grpc.

скажем: my-service-0, my-service-1, my-service-2

my-service имеет IP-адрес кластера как: 10.44.5.11


У нас есть еще три модуля Kubernetes, на которых работает наш клиент gprc.

скажем: мой-клиент-0, мой-клиент-1, мой-клиент-2


Без защиты:

Я пытаюсь подключить модуль сервера grpc к модулю клиента grpc, и он работает нормально.

grpc client (POD -> my-client) ----------------> groc server(POD -> my-service)

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

ManagedChannel channel = ManagedChannelBuilder.forAddress("my-service", 50052)
                .usePlaintext()
                .build();

С безопасностью SSL:

если я попытаюсь подключиться к серверу grpc, имя хоста будет не совпадать. мы создали сертификат с wild card * .default.pod.cluster.local

это вызовет следующую ошибку:

java.security.cert.CertificateException: No name matching my-service found
    at java.base/sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:225) ~[na:na]
    at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:98) ~[na:na]
    at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455) ~[na:na]

Not Working Code:
     ManagedChannel channel = NettyChannelBuilder.forAddress("my-service", 50052)
                    .sslContext(GrpcSslContexts.forClient().trustManager(new File(System.getenv("GRPC_CLIENT_CA_CERT_LOCATION"))).build())
                    .build();

но если я дам имя хоста как это == ›10-44-5-11.default.pod.cluster.local, он будет работать нормально.

Working Code
      ManagedChannel channel = NettyChannelBuilder.forAddress("10-44-5-11.default.pod.cluster.local", 50052)
                        .sslContext(GrpcSslContexts.forClient().trustManager(new File(System.getenv("GRPC_CLIENT_CA_CERT_LOCATION"))).build())
                        .build();

Теперь моя проблема в том, что IP-адрес кластера модуля является динамическим, и он будет меняться каждый раз во время развертывания приложения. как правильно разрешить это имя хоста?

возможно ли, если я дам имя хоста, и он вернет мне IP, тогда я добавлю default.pod.cluster.local к имени хоста и попытаюсь подключиться к серверу grpc?


person Mohit Singh    schedule 21.08.2020    source источник
comment
Имя службы (например, my-service) разрешается, например, my-server.${NAMESPACE}.svc.cluster.local, поэтому вам понадобится подстановочный знак для *.svc.cluster.local   -  person DazWilkin    schedule 21.08.2020
comment
То, что вы хотите конкретно адресовать модули, стоящие за сервисом, является анти-шаблоном. Вы можете перечислить поды с помощью конечных точек Kubernetes. Это предоставит IP-адреса. Но, возможно, вам будет удобнее создать несколько сервисов.   -  person DazWilkin    schedule 21.08.2020
comment
если я не ошибаюсь, вы говорите, что использование my-service.default.pod.cluster.local в качестве имени хоста будет работать?   -  person Mohit Singh    schedule 21.08.2020
comment
Документация Kubernetes хороша и объясняет, как DNS применяется к объектам: kubernetes .io / документы / концепции / услуги-сети / dns-pod-service.   -  person DazWilkin    schedule 21.08.2020


Ответы (1)


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

Чтобы клиенты / трафик могли легко находить нужные контейнеры, вы можете разместить их за службой с одним статическим IP-адресом. IP-адрес службы можно узнать через DNS.

Вот как вы можете подключиться к сервису через его полное доменное имя:

my-service.default.svc.cluster.local 

Где my-service - имя вашей службы, default - пространство имен, а svc.cluster.local - настраиваемый суффикс домена кластера, используемый во всех службах кластера.

Стоит знать, что вы можете пропустить суффикс svc.cluster.local и даже пространство имен, если модули находятся в одном пространстве имен. Так что вы просто будете называть эту службу my-service.

Дополнительную информацию можно найти в документах K8s о DNS.

person acid_fuji    schedule 24.08.2020