Expor as portas 80 e 443 no Google Container Engine sem balanceador de carga

23

Atualmente, estou trabalhando em um pequeno projeto de hobby que tornarei código aberto quando estiver pronto. Este serviço está sendo executado no Google Container Engine. Eu escolhi o GCE para evitar problemas de configuração, os custos são acessíveis e para aprender coisas novas.

Meus pods estão funcionando bem e eu criei um serviço com o tipo LoadBalancerpara expor o serviço nas portas 80 e 443. Isso funciona perfeitamente.

No entanto, descobri que para cada LoadBalancerserviço, um novo balanceador de carga do Google Compute Engine é criado. Esse balanceador de carga é muito caro e superestimado para um projeto de hobby em uma única instância.

Para reduzir os custos, estou procurando uma maneira de expor as portas sem o balanceador de carga.

O que eu tentei até agora:

Existe uma maneira de expor as portas 80 e 443 para uma única instância no Google Container Engine sem um balanceador de carga?

Ruben Ernst
fonte

Respostas:

10

Sim, através de IPs externos no serviço. Exemplo de serviço que eu usei:

apiVersion: v1
kind: Service
metadata:
  name: bind
  labels:
    app: bind
    version: 3.0.0
spec:
  ports:
    - port: 53
      protocol: UDP
  selector:
    app: bind
    version: 3.0.0
  externalIPs:
    - a.b.c.d
    - a.b.c.e

Esteja ciente de que os IPs listados no arquivo de configuração devem ser o IP interno no GCE.

ConnorJC
fonte
Obrigado! Mas acho que perdi alguma coisa. O serviço é implantado, mas não pode ser acessado pela Internet. Defino as regras corretas de firewall. O serviço está exibindo o corretoexternalIp
Ruben Ernst
Desculpe pela resposta tardia, esqueci que passei algum tempo exatamente no mesmo problema. Os IPs listados precisam ser o IP interno , não externo (pelo menos no GCE).
precisa saber é o seguinte
Obrigado, essa foi a solução! Infelizmente ainda não estou autorizado a votar ... Abandonei este comentário para informar que esta resposta combinada com o comentário acima (que era a chave) resolveu meu problema!
Ruben Ernst
1
Você (ou @RubenErnst) se importaria em expandir um pouco a resposta? Em particular, "os IPs listados no GCE devem ser o IP intrenal". Qual IP você quer dizer? Você consegue fazer isso funcionar com um IP estático atribuído ao seu cluster de nó único?
Brett
@Brett: Desculpe pela minha resposta tardia. Enquanto isso, sua pergunta já foi respondida?
Ruben Ernst
4

Além da excelente e funcional solução do ConnorJC: A mesma solução também é descrita nesta pergunta: Kubernetes - posso evitar o uso do GCE Load Balancer para reduzir custos?

O "internalIp" refere-se ao IP interno da instância de computação (também conhecida como do nó) (como visto no Google Cloud Platform -> Google Compute Engine -> Instâncias de VM)

Este comentário dá uma dica de por que o IP interno e não o IP externo deve ser configurado.

Além disso, depois de configurar o serviço para as portas 80 e 443, tive que criar uma regra de firewall que permitisse tráfego para o nó da instância:

gcloud compute firewall-rules create your-name-for-this-fw-rule --allow tcp:80,tcp:443 --source-ranges=0.0.0.0/0

Após essa configuração, eu poderia acessar meu serviço através de http (s): // externalIp

derMikey
fonte
O uso do IP interno do nó fez o truque. 👍 Tal confusão com a nomeação!
James
1

Se você tiver apenas exatamente um pod, poderá usar hostNetwork: trueisso para:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: caddy
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: caddy
    spec:
      hostNetwork: true # <---------
      containers:
      - name: caddy
        image: your_image
        env:
        - name: STATIC_BACKEND # example env in my custom image
          value: $(STATIC_SERVICE_HOST):80

Observe que, ao fazer isso, seu pod herdará o resolvedor DNS do host e não o Kubernetes '. Isso significa que você não pode mais resolver os serviços de cluster pelo nome DNS. Por exemplo, no exemplo acima, você não pode acessar o staticserviço em http: // estático . Você ainda pode acessar serviços pelo IP do cluster, que são injetados por variáveis ​​de ambiente .

Essa solução é melhor do que usar o IP externo do serviço, pois ignora o kube-proxy e você receberá o IP de origem correto.

vontade
fonte
1

Para sintetizar as respostas do @ConnorJC @ derMikey exatamente no que funcionou para mim:

Dado um conjunto de clusters em execução na instância do Compute Engine :

gce vm name: gke-my-app-cluster-pool-blah`
internal ip: 10.123.0.1
external ip: 34.56.7.001 # will be publically exposed

Eu fiz o serviço:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-app
  name: my-app-service
spec:
  clusterIP: 10.22.222.222
  externalIPs:
  - 10.123.0.1 # the instance internal ip
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: my-app
  type: ClusterIP

e, em seguida, abriu o firewall para todos os ips no projeto:

gcloud compute firewall-rules create open-my-app --allow tcp:80,tcp:443 --source-ranges=0.0.0.0/0

e my-appera acessível através do IP público da instância34.56.7.001 do GCE (não do ip do cluster)

micimizar
fonte
0

Prefiro não usar os balanceadores de carga na nuvem, até que seja necessário, devido ao custo e ao bloqueio do fornecedor.

Em vez disso, eu uso isso: https://kubernetes.github.io/ingress-nginx/deploy/

É um pod que executa um balanceador de carga para você. Essa página possui notas de instalação específicas do GKE.

Michael Cole
fonte