Implementar um aplicativo

Neste documento, mostramos um exemplo de como implantar um aplicativo em um cluster de usuário criado com o Google Distributed Cloud (somente software) para VMware.

Antes de começar

Neste exemplo, você precisa de um cluster de usuário que use o balanceamento de carga MetalLB agrupado. Para instruções sobre como criar um cluster de usuário mínimo que use o MetalLB, consulte Criar clusters básicos.

É possível usar o console do Google Cloud ou a ferramenta de linha de comando kubectl na estação de trabalho do administrador para implantar o aplicativo.

Console

  1. No console, acesse a página Visão geral dos clusters do Google Kubernetes Engine.

    Acesse os clusters do GKE

  2. Na lista de clusters, clique no cluster de usuário e verifique se você fez login nele.

    Se você ainda não tiver feito login no cluster de usuário, siga as instruções em Gerenciar clusters no console do Google Cloud.

Contêineres

  1. Em Novo contêiner, selecione Imagem de contêiner atual.

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

  3. Clique em Continuar.

Configuração

  1. Em Nome da implantação, insira my-deployment.

  2. Em Namespace, insira default.

  3. Digite estes dois rótulos:

    • Chave 1: app, Valor 1: metrics
    • Chave 2: department, Valor 2 sales
  4. No menu suspenso Cluster do Kubernetes, selecione seu cluster.

  5. Clique em Continuar.

Expor

  1. Marque Expor a implantação como um novo serviço

  2. Em Porta 1, insira 80.

  3. Em Porta de destino 1, insira 8080. Esse é o valor apropriado, porque o contêiner hello-app detecta a porta TCP 8080 por padrão. Isso pode ser observado no Dockerfile e no código-fonte do app.

  4. Em Protocolo 1, selecione TCP.

  5. Em Tipo de serviço, selecione LoadBalancer.

Na parte superior da página, clique no botão Implantar.

Ver detalhes da implantação e do serviço

  1. Quando a implantação estiver pronta, a página Detalhes da implantação será aberta na seção Cargas de trabalho do Kubernetes do console do Google Cloud. Nesta página, é possível ver detalhes sobre a implantação e os três pods.

  2. Em Como expor serviços, clique no nome do serviço que expõe a implantação. Para este exercício, o nome é my-deployment-service.

  3. A página Detalhes do serviço é aberta. Nesta página, você pode ver detalhes sobre o serviço. Por exemplo, é possível ver que qualquer pod que tenha os rótulos app: metrics e department: sales é membro do serviço. Lembre-se de que os pods em my-deployment têm esses rótulos.

Também é possível encontrar um valor para IP do balanceador de carga. O IP do balanceador de carga foi configurado automaticamente no balanceador de carga do cluster.

Encaminhamento do serviço

Suponha que um cliente fora do cluster envie uma solicitação ao IP do balanceador de carga na porta TCP 80. A solicitação é encaminhada para o balanceador de carga do cluster. O balanceador de carga encaminha a solicitação para um pod membro na porta TCP 8080. Lembre-se de que cada pod em my-deployment tem um contêiner detectando a porta TCP 8080.

Testar o serviço

Acesse uma máquina em que o IP do balanceador de carga seja roteável.

Para chamar o serviço, insira o IP do balanceador de carga em um navegador ou use um comando como curl. Por exemplo:

curl [LOAD_BALANCER_IP]:80

A saída mostra uma mensagem Hello, world!. Por exemplo:

curl 203.0.113.1:80
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

Excluir a implantação

Acesse a página Cargas de trabalho na seção Kubernetes Engine do console.

Acessar a página "Cargas de trabalho"

Na lista de implantações, selecione my-deployment.

Na parte de cima da página, clique em Excluir. Isso exclui a implantação e o serviço de exposição.

Linha de comando

Conectar-se à estação de trabalho do administrador

Conseguir uma conexão SSH para a estação de trabalho do administrador Execute as etapas a seguir na estação de trabalho do administrador.

Crie uma implantação

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 em um arquivo denominado my-deployment.yaml e crie a implantação:

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-deployment.yaml

em que USER_CLUSTER_KUBECONFIG é o caminho do arquivo kubeconfig do cluster de usuário.

Encontre informações básicas sobre a implantação:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment

A saída mostra que a implantação tem três pods disponíveis:

NAME            READY   UP-TO-DATE   AVAILABLE   AGE
my-deployment   3/3     3            3           27s

Liste os pods na implantação:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods

A saída mostra que a implantação tem três pods em execução:

NAME                             READY   STATUS    RESTARTS   AGE
my-deployment-54944c8d55-4srm2   1/1     Running   0          6s
my-deployment-54944c8d55-7z5nn   1/1     Running   0          6s
my-deployment-54944c8d55-j62n9   1/1     Running   0          6s

Encontre informações detalhadas sobre sua implantação:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment --output yaml

A saída mostra informações detalhadas sobre a especificação e o status da implantação:

kind: Deployment
metadata:
  ...
  generation: 1
  name: my-deployment
  namespace: default
  ...
spec:
  ...
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: metrics
      department: sales
  ...
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
        imagePullPolicy: IfNotPresent
        name: hello
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3
  conditions:
  ‑ lastTransitionTime: "2019-11-11T18:44:02Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  ‑ lastTransitionTime: "2019-11-11T18:43:58Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: ReplicaSet "my-deployment-54944c8d55" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3

Descreva a implantação:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe deployment my-deployment

A saída mostra informações detalhadas bem formatadas sobre a implantação, incluindo o ReplicaSet associado:

Name:                   my-deployment
Namespace:              default
CreationTimestamp:      Mon, 11 Nov 2019 10:43:58 -0800
Labels:                 
...
Selector:               app=metrics,department=sales
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=metrics
           department=sales
  Containers:
    hello:
    Image:        us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
    Port:         
    Host Port:    
    Environment:  
    Mounts:       
  Volumes:        
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  
NewReplicaSet:   my-deployment-54944c8d55 (3/3 replicas created)

Crie um serviço do tipo LoadBalancer

Uma maneira de expor a implantação para clientes fora do cluster é criar um serviço do Kubernetes do tipo LoadBalancer.

Veja um manifesto para um serviço do tipo LoadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: metrics
    department: sales
  type: LoadBalancer
  ports:
  ‑ port: 80
    targetPort: 8080

Para o propósito deste exercício, veja pontos importantes que você precisa entender sobre o serviço:

  • Qualquer pod que tenha o rótulo app: metrics e o rótulo department: sales é um membro do serviço. Observe que os pods em my-deployment têm esses rótulos.

  • Quando um cliente envia uma solicitação ao serviço na porta TCP 80, a solicitação é encaminhada a um pod membro na porta TCP 8080.

  • Cada pod de membro precisa ter um contêiner detectando a porta TCP 8080.

Isso acontece por padrão, o contêiner hello-app detecta a porta TCP 8080. Isso pode ser observado no Dockerfile e no código-fonte do app.

Salve o manifesto em um arquivo chamado my-service.yaml e crie o Serviço:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-service.yaml

em que USER_CLUSTER_KUBECONFIG é o caminho do arquivo kubeconfig do cluster de usuário.

Quando você cria o serviço, o Google Distributed Cloud configura automaticamente o endereço loadBalancerIP no balanceador de carga do cluster.

Veja seu serviço:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get service my-service --output yaml

A saída é semelhante a esta:

kind: Service
metadata:
  ...
  name: my-service
  namespace: default
  ...
spec:
  allocateLoadBalancerNodePorts: true
  clusterIP: 10.96.1.39
  clusterIPs:
  - 10.96.1.39
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 31184
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: metrics
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.1

Na saída anterior, é possível ver que o serviço tem um clusterIP e um loadBalancerIP. Ele também tem um port, e um targetPort.

O valor de clusterIP não é relevante para este exercício. O loadBalancerIP é o endereço IP que os clientes fora do cluster podem usar para chamar o serviço.

Por exemplo, veja os valores mostrados na saída anterior. Ou seja: suponha que o serviço tenha loadBalancerIP = 203.0.113.1, port = 80, e targetPort = 8080.

Um cliente envia uma solicitação para 203.0.113.1 na porta TCP 80. A solicitação é roteada para o balanceador de carga do cluster. O balanceador de carga encaminha a solicitação para um pod membro na porta TCP 8080.

Chame o serviço:

curl LOAD_BALANCER_IP

A saída mostra uma mensagem Hello, world!:

curl 203.0.113.1
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

Excluir o Serviço

Exclua o Serviço:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service my-service

Verifique se o serviço foi excluído:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get services

A saída não mostra mais my-service.

Excluir a implantação

Exclua a implantação:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment my-deployment

Verifique se a implantação foi excluída:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployments

A saída não mostra mais my-deployment.

A seguir

Crie um serviço e uma entrada