Como expor serviços TCP não HTTP no Kubernetes?

8

Estou executando um cluster Kubernetes em uma nuvem pública (Azure / AWS / Google Cloud) e tenho alguns serviços não HTTP que gostaria de expor para os usuários.

Para serviços HTTP, normalmente eu usaria um recurso do Ingress para expor esse serviço publicamente através de uma entrada DNS endereçável.

Para serviços não HTTP, baseados em TCP (por exemplo, um banco de dados como o PostgreSQL), como devo expô-los ao consumo público?

Eu considerei usar NodePortserviços, mas isso exige que os nós estejam acessíveis publicamente (contando com kube-proxya rota para o nó apropriado). Eu preferiria evitar isso, se possível.

LoadBalanceros serviços parecem outra opção, embora eu não queira criar um balanceador de carga em nuvem dedicado para cada serviço TCP que quero expor.

Estou ciente de que o controlador NGINX Ingress suporta a exposição de serviços TCP e UDP , mas isso parece exigir uma definição estática dos serviços que você deseja expor. Para o meu caso de uso, esses serviços estão sendo criados e destruídos dinamicamente, portanto, não é possível definir esses mapeamentos de serviço antecipadamente em uma estática ConfigMap.

cjheppell
fonte

Respostas:

1

Talvez esse fluxo de trabalho possa ajudar:

(Suponho que o provedor de nuvem seja AWS)

  • Console da AWS: crie uma VPC segregada e crie suas instâncias do Kubernetes ec2 (ou grupo de dimensionamento automático) desativando a criação de IP público. Isso impossibilita o acesso à instância da Internet; você ainda pode acessar pelo IP privado (por exemplo, 172.30.1.10) por meio de uma VPN do Site 2 do Site ou por meio de uma instância secundária do ec2 na mesma VPC com IP Público.

  • Kubernetes: Crie um serviço com um NodePort fixo (por exemplo, 35432 para Postgres).

  • Console da AWS: crie um Classic o Layer 4 Loadblancer dentro da mesma VPC de seus nós; na guia Listeners, abra a porta 35432 (e outras portas que você pode precisar) apontando para um ou todos os seus nós através de um "Grupo de destino". Não há cobrança no número de portas.

Neste ponto, não sei como automatizar a atualização dos nós atuais no grupo-alvo do balanceador de carga, isso pode ser um problema com os recursos de dimensionamento automático, se houver ... Talvez um trabalho do Cron com um script bash puxando informações da API da AWS e atualizar o grupo de destino?

Hugo V
fonte
Obrigado - isso é útil. Embora, obviamente, essa não seja uma solução genérica para qualquer ambiente Kubernetes e esteja intimamente ligada ao provedor de nuvem preferido. Talvez um Operador possa ser um bom ajuste para uma solução que oculte os detalhes do provedor de nuvem preferido.
Cjheppell
0

Para serviços não HTTP, baseados em TCP (por exemplo, um banco de dados como o PostgreSQL), como devo expô-los ao consumo público?

Bem, isso depende de como você espera que o usuário final resolva esses serviços? Como você apontou, com um Ingress, é possível usar hospedagem virtual para rotear todas as solicitações para o mesmo controlador do Ingress e, em seguida, usar o Host:cabeçalho para despachar no cluster.

Com um serviço TCP, como o PostgreSQL, não existe esse cabeçalho. Portanto, você precisaria necessariamente ter um mecanismo baseado em IP ou atribuir a cada um uma porta dedicada no seu IP da Internet

Se seus clientes estiverem cientes do IPv6, atribuir a cada Serviço um endereço IP dedicado é absolutamente razoável, considerando o espaço IP enorme que o IPv6 oferece. Mas, caso contrário, você tem dois botões para ativar: o IP e a porta.

A partir daí, como você roteará essas conexões dentro do cluster para o Serviço certo dependerá de como você resolveu o primeiro problema

mdaniel
fonte
Obrigado pela sua resposta. Entendo que cada serviço expõe sua própria porta exclusiva. Meu problema é que os tipos de serviço atuais do Kubernetes não parecem adequados para o meu caso de uso. NodePorts exigem a abertura pública das portas nos nós, o que não é ideal do ponto de vista da segurança. O LoadBalancer por serviço é caro. Supondo que eu possa rotear corretamente para o host, qual serviço Kubernetes devo usar para torná-los publicamente conectáveis, principalmente quando estes estão sendo ativados e desativados dinamicamente?
Cjheppell 21/10/19