Como implantar seu primeiro aplicativo

Nesta página, você verá como implantar um aplicativo no cluster de usuário.

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: "gcr.io/google-samples/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: gcr.io/google-samples/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:        gcr.io/google-samples/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

[USER_CLUSTER_KUBECONFIG] é o caminho do arquivo kubeconfig do cluster de usuário.

Quando você cria o serviço, o GKE On-Prem configura automaticamente o endereço loadBalancerIP no 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: 21.0.133.48
  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.