#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.