Como implantar um aplicativo

Este documento mostra como implantar um aplicativo no cluster de usuários para clusters do Anthos no VMware (GKE On-Prem).

Antes de começar

Crie um cluster de usuário (guia de início rápido | instruções completas).

SSH na estação de trabalho de administrador

Implemente SSH na estação de trabalho de administrador:

ssh -i ~/.ssh/vsphere_workstation ubuntu@[IP_ADDRESS]

[IP_ADDRESS] é o endereço IP da sua estação de trabalho de administrador.

Siga todas as etapas restantes neste tópico na sua estação de trabalho de administrador.

Como criar 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 chamado 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)

Como criar um Service 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
  loadBalancerIP: [SERVICE_IP_ADDRESS]
  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 com 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.

Substitua [SERVICE_IP_ADDRESS] por um endereço de sua propriedade que ainda não esteja em uso. Por exemplo, defina essa opção como um endereço IP público da sua empresa. Ou defina-o como um endereço particular na rede da empresa.

O endereço escolhido precisa ser encaminhado a partir da localização de qualquer cliente que envie solicitações ao serviço. Por exemplo, se você escolher um endereço particular, os clientes externos não poderão enviar solicitações para o serviço.

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, os clusters do Anthos no VMware configuram automaticamente o endereço loadBalancerIP no seu balanceador de carga F5 BIG-IP.

Veja seu serviço:

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

A saída é semelhante a esta:

apiVersion: v1
kind: Service
metadata:
  ...
  name: my-service
  namespace: default
  ...
spec:
  clusterIP: 10.107.84.202
  externalTrafficPolicy: Cluster
  loadBalancerIP: 203.0.113.1
  ports:
  - nodePort: 31919
    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 nodePort, um port e um targetPort.

O valor de clusterIP não é relevante para este exercício. O valor de loadBalancerIP é o endereço IP que você informou em my-service.yaml.

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, nodePort = 31919 e targetPort = 8080.

Um cliente envia uma solicitação para 203.0.113.1 na porta TCP 80. A solicitação é encaminhada para o balanceador de carga F5 BIG-IP. O balanceador de carga escolhe um dos nós de cluster de usuário e encaminha a solicitação para [NODE_ADDRESS], na porta TCP 31919. As regras do iptables no nó encaminham a solicitação para um pod membro na porta 8080.

Chame o serviço:

curl [SERVICE_IP_ADDRESS]

em que [SERVICE_IP_ADDRESS] é o endereço especificado para loadBalancerIP.

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

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

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

Como 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