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

#java #kubernetes #grpc #grpc-java

#java #kubernetes #grpc #grpc-java

Вопрос:

Проблема:

как разрешить имя хоста модуля kubernetes?

У меня есть следующее требование: мы используем 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.

допустим: my-client-0, my-client-1, my-client-2


Без защиты:

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

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

Итак, без защиты я указываю имя хоста как my-service, и оно работает нормально без каких-либо проблем..

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

С защитой SSL:

если я попытаюсь подключить grpc-сервер, он выдаст несоответствующее имя хоста. мы создали сертификат с подстановочным знаком *.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-серверу?

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

1. Имя служб (например, my-service ) разрешается в, например, my-server.${NAMESPACE}.svc.cluster.local , поэтому вам понадобится подстановочный знак для *.svc.cluster.local

2. То, что вы хотите конкретно обращаться к модулям, стоящим за сервисом, является антишаблоном. Вы можете перечислять модули, используя конечные точки Kubernetes. Это обеспечит IP-адреса. Но, возможно, вам лучше создать несколько сервисов.

3. если я не ошибаюсь, вы говорите, что использование my-service.default.pod.cluster.local в качестве имени хоста будет работать?

4. Документация Kubernetes хороша и объясняет, как DNS применяется к объектам: kubernetes.io/docs/concepts/services-networking/dns-pod-service

Ответ №1:

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

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

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

 my-service.default.svc.cluster.local 
  

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

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

Для получения дополнительной информации вы можете ознакомиться с документами K8s о DNS.