Como exibir aplicativos usando serviços


Nesta página, você verá como criar Services do Kubernetes em um cluster do Google Kubernetes Engine. Para uma explicação e discussão sobre o conceito e os vários tipos de serviços, consulte este artigo.

Introdução

Um serviço agrupa um conjunto de endpoints do pod em um único recurso. É possível configurar várias maneiras de acessar o agrupamento. Por padrão, você recebe um endereço IP de cluster estável que os clientes dentro do cluster podem usar para contatar pods no serviço. Um cliente envia uma solicitação ao endereço IP estável e a solicitação é encaminhada a um dos pods no serviço.

Existem cinco tipos de serviços:

  • ClusterIP (padrão)
  • NodePort
  • LoadBalancer
  • ExternalName
  • Sem comando

Os clusters do Autopilot são públicos por padrão. Se você optar por um cluster Autopilot particular, será necessário configurar o Cloud NAT para fazer conexões de saída com a Internet, por exemplo, extrair imagens do DockerHub.

Este tópico tem vários exercícios. Em cada um deles, você cria uma implantação e expõe os pods criando um serviço. Em seguida, envia uma solicitação HTTP para ele.

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ativar a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a Google Cloud CLI para essa tarefa, instale e, em seguida, inicialize a CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando gcloud components update.
* Criar um cluster do GKE.

Como criar um Service do tipo ClusterIP

Nesta seção, você cria um serviço do tipo ClusterIP.

kubectl apply

Veja o manifesto de uma implantação:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: metrics
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: sales
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"

Copie o manifesto para um arquivo denominado my-deployment.yaml e crie a implantação:

kubectl apply -f my-deployment.yaml

Verifique se três pods estão em execução:

kubectl get pods

A saída mostra três pods em execução:

NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-dbd86c8c4-h5wsf   1/1     Running   0          7s
my-deployment-dbd86c8c4-qfw22   1/1     Running   0          7s
my-deployment-dbd86c8c4-wt4s6   1/1     Running   0          7s

Veja um manifesto para um Service do tipo ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: my-cip-service
spec:
  type: ClusterIP
  # Uncomment the below line to create a Headless Service
  # clusterIP: None
  selector:
    app: metrics
    department: sales
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

O Service tem um seletor que especifica dois rótulos:

  • app: metrics
  • department: sales

Cada pod criado na implantação tem esses dois rótulos. Assim, eles se tornarão membros desse Service.

Copie o manifesto para um arquivo chamado my-cip-service.yaml e crie o Service:

kubectl apply -f my-cip-service.yaml

Aguarde um momento para que o Kubernetes atribua um endereço interno estável ao serviço e, em seguida, visualize-o.

kubectl get service my-cip-service --output yaml

A resposta mostra um valor para clusterIP:

spec:
  clusterIP: 10.59.241.241

Anote o valor do seu clusterIP para mais tarde.

Console

Crie uma implantação

  1. Acesse a página Cargas de trabalho no console do Google Cloud.

    Acesse "Cargas de trabalho"

  2. Clique em Implantar.

  3. Em Especificar contêiner, selecione Imagem de contêiner atual.

  4. Em Caminho da imagem, insira us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0

  5. Clique em Concluído e em Continuar.

  6. Em Configuração, digite my-deployment no campo Nome do aplicativo.

  7. Em Rótulos, crie os seguintes rótulos:

    • Chave: app e Valor: metrics
    • Chave: department e Valor: sales
  8. Em Cluster, escolha o cluster em que você quer criar a implantação.

  9. Clique em Implantar.

  10. Quando a implantação estiver pronta, a página Detalhes da implantação abrirá. Em Pods gerenciados, veja que a implantação tem um ou mais pods em execução.

Crie um Service para expor o Deployment

  1. Na página Detalhes da implantação, clique em Ações > Expor.
  2. Na caixa de diálogo Expor, em Mapeamento de portas, defina os seguintes valores:

    • Porta: 80
    • Porta de destino: 8080
    • Protocolo: TCP
  3. Na lista suspensa Tipo de serviço, selecione o IP do cluster.

  4. Clique em Expor.

  5. Quando o serviço estiver pronto, a página Detalhes do serviço abrirá para que você veja os detalhes. Em IP do cluster, anote o endereço IP que o Kubernetes atribuiu ao serviço. Esse é o endereço IP que os clientes internos usarão para chamá-lo.

Como acessar o serviço

Liste os pods em execução:

kubectl get pods

Na saída, copie um dos nomes de pod que começa com my-deployment.

NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-dbd86c8c4-h5wsf   1/1     Running   0          2m51s

Coloque um shell em um dos seus contêineres em execução:

kubectl exec -it POD_NAME -- sh

Substitua POD_NAME pelo nome de um dos pods em my-deployment.

No seu shell, instale curl:

apk add --no-cache curl

No contêiner, faça uma solicitação ao Service usando o endereço IP do cluster e a porta 80. Observe que 80 é o valor do campo port do seu Service. Essa é a porta que você usará como cliente.

curl CLUSTER_IP:80

Substitua CLUSTER_IP pelo valor de clusterIP no Service.

Sua solicitação é encaminhada para um dos pods membro na porta TCP 8080, que é o valor do campo targetPort. Observe que cada um dos pods membro do Service precisa ter um contêiner escutando a porta 8080.

A resposta mostra a saída de hello-app:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-h5wsf

Para sair do shell para seu contêiner, insira exit.

Como criar um Service do tipo NodePort

Nesta seção, você cria um serviço do tipo NodePort.

kubectl apply

Veja o manifesto de uma implantação:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50000
spec:
  selector:
    matchLabels:
      app: metrics
      department: engineering
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: engineering
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"

Observe o objeto env no manifesto. O objeto env especifica que a variável de ambiente PORT do contêiner em execução terá um valor de 50000. O aplicativo hello-app detecta atividade na porta especificada pela variável de ambiente PORT. Portanto, neste exercício, você está dizendo ao contêiner para detectar atividade na porta 50.000.

Copie o manifesto para um arquivo denominado my-deployment-50000.yaml e crie a implantação:

kubectl apply -f my-deployment-50000.yaml

Verifique se três pods estão em execução:

kubectl get pods

Veja aqui um manifesto de um Service do tipo NodePort:

apiVersion: v1
kind: Service
metadata:
  name: my-np-service
spec:
  type: NodePort
  selector:
    app: metrics
    department: engineering
  ports:
  - protocol: TCP
    port: 80
    targetPort: 50000

Copie o manifesto para um arquivo chamado my-np-service.yaml e crie o Service:

kubectl apply -f my-np-service.yaml

Veja o Serviço:

kubectl get service my-np-service --output yaml

A resposta mostra um valor nodePort:

...
  spec:
    ...
    ports:
    - nodePort: 30876
      port: 80
      protocol: TCP
      targetPort: 50000
    selector:
      app: metrics
      department: engineering
    sessionAffinity: None
    type: NodePort
...

Crie uma regra de firewall para permitir o tráfego TCP na porta do nó:

gcloud compute firewall-rules create test-node-port \
    --allow tcp:NODE_PORT

Substitua NODE_PORT pelo valor do campo nodePort do seu Serviço.

Console

Crie uma implantação

  1. Acesse a página Cargas de trabalho no console do Google Cloud.

    Acesse "Cargas de trabalho"

  2. Clique em Implantar.

  3. Em Especificar contêiner, selecione Imagem de contêiner atual.

  4. Em Caminho da imagem, insira us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. Clique em Adicionar variável de ambiente.

  6. Em Chave, digite PORT. Em Valor, digite 50000.

  7. Clique em Concluído e em Continuar.

  8. Em Configuração, digite my-deployment-50000 no campo Nome do aplicativo.

  9. Em Rótulos, crie os seguintes rótulos:

    • Chave: app e Valor: metrics
    • Chave: department e Valor: engineering
  10. Em Cluster, escolha o cluster em que você quer criar a implantação.

  11. Clique em Implantar.

  12. Quando a implantação estiver pronta, a página Detalhes da implantação abrirá. Em Pods gerenciados, veja que a implantação tem um ou mais pods em execução.

Crie um Service para expor o Deployment

  1. Na página Detalhes da implantação, clique em Ações > Expor.
  2. Na caixa de diálogo Expor, em Mapeamento de portas, defina os seguintes valores:

    • Porta: 80
    • Porta de destino: 50000
    • Protocolo: TCP
  3. Na lista suspensa Tipo de serviço, selecione Porta do nó.

  4. Clique em Expor.

  5. Quando o serviço estiver pronto, a página Detalhes do serviço abrirá para que você veja os detalhes. Em Portas, anote a porta do nó que o Kubernetes atribuiu ao Service.

Crie uma regra de firewall para a porta do nó

  1. Acesse a página de políticas de firewall no console do Google Cloud.

    Acessar políticas de firewall

  2. Clique em Criar regra de firewall.

  3. Em Nome, insira test-node-port.

  4. Na lista suspensa Destinos, selecione Todas as instâncias na rede.

  5. Em Intervalos IPv4 de origem, insira 0.0.0.0/0.

  6. Em Protocolos e portas, selecione Portas e protocolos especificados.

  7. Marque a caixa de seleção tcp e insira o valor da porta do nó que você anotou.

  8. Clique em Criar.

Receber um endereço IP de nó

Encontre o endereço IP externo de um de seus nós:

kubectl get nodes --output wide

O resultado será assim:

NAME          STATUS    ROLES     AGE    VERSION        EXTERNAL-IP
gke-svc-...   Ready     none      1h     v1.9.7-gke.6   203.0.113.1

Nem todos os clusters têm endereços IP externos para nós. Por exemplo, os nós em clusters particulares não têm.

Acesse o Service

Na barra de endereço do navegador, digite:

NODE_IP_ADDRESS:NODE_PORT

Substitua:

  • NODE_IP_ADDRESS: o endereço IP externo de um dos nós, encontrado na criação do serviço na tarefa anterior.
  • NODE_PORT: o valor da porta de nó.

A saída será assim:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-50000-6fb75d85c9-g8c4f

Como criar um Service do tipo LoadBalancer

Nesta seção, você cria um serviço do tipo LoadBalancer.

kubectl apply

Veja o manifesto de uma implantação:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50001
spec:
  selector:
    matchLabels:
      app: products
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: products
        department: sales
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50001"

Os contêineres neste Deployment escutarão a porta 50001.

Copie o manifesto em um arquivo denominado my-deployment-50001.yaml e crie a implantação:

kubectl apply -f my-deployment-50001.yaml

Verifique se três pods estão em execução:

kubectl get pods

Veja um manifesto para um Service do tipo LoadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  selector:
    app: products
    department: sales
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50001

Copie o manifesto para um arquivo chamado my-lb-service.yaml, e crie o Service:

kubectl apply -f my-lb-service.yaml

Quando você cria um Serviço do tipo LoadBalancer, um controlador do Google Cloud é ativado e configura um balanceador de carga de rede de passagem externa. Aguarde um minuto para o controlador configurar o balanceador de carga de rede e gerar um endereço IP estável.

Veja o Serviço:

kubectl get service my-lb-service --output yaml

A resposta mostra um endereço IP externo estável em loadBalancer:ingress:

...
spec:
  ...
  ports:
  - ...
    port: 60000
    protocol: TCP
    targetPort: 50001
  selector:
    app: products
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.10

Console

Crie uma implantação

  1. Acesse a página Cargas de trabalho no console do Google Cloud.

    Acesse "Cargas de trabalho"

  2. Clique em Implantar.

  3. Em Especificar contêiner, selecione Imagem de contêiner atual.

  4. Em Caminho da imagem, insira us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. Clique em Adicionar variável de ambiente.

  6. Em Chave, digite PORT. Em Valor, digite 50001.

  7. Clique em Concluído e em Continuar.

  8. Em Configuração, digite my-deployment-50001 no campo Nome do aplicativo.

  9. Em Rótulos, crie os seguintes rótulos:

    • Chave: app e Valor: products
    • Chave: department e Valor: sales
  10. Em Cluster, escolha o cluster em que você quer criar a implantação.

  11. Clique em Implantar.

  12. Quando a implantação estiver pronta, a página Detalhes da implantação abrirá. Em Pods gerenciados, veja que a implantação tem um ou mais pods em execução.

Crie um Service para expor o Deployment

  1. Na página Detalhes da implantação, clique em Ações > Expor.
  2. Na caixa de diálogo Expor, em Mapeamento de portas, defina os seguintes valores:

    • Porta: 60000
    • Porta de destino: 50001
    • Protocolo: TCP
  3. Na lista suspensa Tipo de serviço, selecione Balanceador de carga.

  4. Clique em Expor.

  5. Quando o serviço estiver pronto, a página Detalhes do serviço abrirá para que você veja os detalhes. Em Balanceador de carga, anote o endereço IP externo do balanceador de carga.

Acesse o Service

Aguarde alguns minutos para o GKE configurar o balanceador de carga.

Na barra de endereço do navegador, digite:

LOAD_BALANCER_ADDRESS:60000

Substitua LOAD_BALANCER_ADDRESS pelo endereço IP externo do balanceador de carga.

A resposta mostra a saída de hello-app:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-50001-68bb7dfb4b-prvct

Observe que o valor de port em um Service é arbitrário. O exemplo anterior demonstra isso usando um valor port de 60.000.

Como criar um Service do tipo ExternalName

Nesta seção, você cria um serviço do tipo ExternalName.

Um Service do tipo ExternalName fornece um alias interno para um nome DNS externo. Clientes internos fazem solicitações usando o nome DNS interno e as solicitações são redirecionadas para o nome externo.

Veja um manifesto para um Service do tipo ExternalName:

apiVersion: v1
kind: Service
metadata:
  name: my-xn-service
spec:
  type: ExternalName
  externalName: example.com

No exemplo anterior, o nome do DNS é my-xn-service.default.svc.cluster.local. Quando um cliente interno faz uma solicitação para esse DNS, ela é redirecionada para example.com.

Como usar kubectl expose para criar um Service

Como alternativa à gravação de um manifesto de Service, crie um Service usando kubectl expose para expor uma implantação.

Para expor my-deployment, mostrado anteriormente neste tópico, insira este comando:

kubectl expose deployment my-deployment --name my-cip-service \
    --type ClusterIP --protocol TCP --port 80 --target-port 8080

Para expor my-deployment-50000, mostrado anteriormente neste tópico, insira este comando:

kubectl expose deployment my-deployment-50000 --name my-np-service \
    --type NodePort --protocol TCP --port 80 --target-port 50000

Para expor my-deployment-50001, mostrado anteriormente neste tópico, insira este comando:

kubectl expose deployment my-deployment-50001 --name my-lb-service \
    --type LoadBalancer --port 60000 --target-port 50001

Limpeza

Depois de concluir os exercícios nesta página, siga estas etapas para remover os recursos e evitar cobranças indesejadas na conta:

kubectl apply

Como excluir Services

kubectl delete services my-cip-service my-np-service my-lb-service

Como excluir implantações

kubectl delete deployments my-deployment my-deployment-50000 my-deployment-50001

Como excluir a regra de firewall

gcloud compute firewall-rules delete test-node-port

Console

Como excluir Services

  1. Acesse a página Serviços no console do Google Cloud.

    Acessar Serviços

  2. Selecione os serviços que você criou neste exercício e clique em Excluir.

  3. Quando solicitado a confirmar, clique em Excluir.

Como excluir implantações

  1. Acesse a página Cargas de trabalho no console do Google Cloud.

    Acesse "Cargas de trabalho"

  2. Selecione as implantações que você criou neste exercício e clique em Excluir.

  3. Quando solicitado a confirmar, marque a caixa de seleção Excluir escalonadores automáticos de pods horizontais associados às implantações selecionadas e clique em Excluir.

Como excluir a regra de firewall

  1. Acesse a página de políticas de firewall no console do Google Cloud.

    Acessar políticas de firewall

  2. Marque a caixa de seleção test-node-port e clique em Excluir.

  3. Quando solicitado a confirmar, clique em Excluir.

A seguir