Este documento dá um exemplo de como implementar uma aplicação num cluster de utilizadores criado com o Google Distributed Cloud (apenas software) para VMware.
Antes de começar
Para o exemplo apresentado aqui, precisa de um cluster de utilizadores que use o equilíbrio de carga do MetalLB incluído. Para obter instruções sobre como criar um cluster de utilizadores mínimo que use o MetalLB, consulte o artigo Crie clusters básicos.
Pode usar a Google Cloud consola ou a ferramenta de linha de comandoskubectl na estação de trabalho do administrador para implementar a aplicação.
Consola
- Na consola, aceda à página Vista geral dos clusters do Google Kubernetes Engine. 
- Na lista de clusters, clique no seu cluster de utilizadores e verifique se tem sessão iniciada no cluster. - Se ainda não tiver sessão iniciada no cluster de utilizadores, inicie sessão seguindo as instruções em Gerir clusters a partir da consola. Google Cloud 
Contentores
- Em Novo contentor, selecione Imagem de contentor existente. 
- Para Caminho da imagem, introduza - us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.
- Clique em Continuar. 
Configuração
- Em Nome da implementação, introduza - my-deployment.
- Em Espaço de nomes, introduza - default.
- Introduza estas duas etiquetas: - Key 1: app, Value 1:metrics
- Key 2: department, Value 2sales
 
- Key 1: 
- No menu pendente Cluster do Kubernetes, selecione o seu cluster. 
- Clique em Continuar. 
Expor
- Selecione Expor implementação como um novo serviço. 
- Para a Porta 1, introduza - 80.
- Para Porta de destino 1, introduza - 8080. Este é o valor adequado porque, por predefinição, o contentor- hello-appdeteta a porta TCP 8080. Pode ver isto consultando o Dockerfile e o código-fonte da app.
- Para Protocolo 1, selecione - TCP.
- Para Tipo de serviço, selecione - LoadBalancer.
Na parte inferior da página, clique no botão Implementar.
Veja detalhes da implementação e do serviço
- Quando a implementação estiver pronta, a página Detalhes da implementação é aberta na secção Cargas de trabalho do Kubernetes da Google Cloud consola. Nesta página, pode ver detalhes sobre a implementação e os respetivos três pods. 
- Em Exposing services, clique no nome do serviço que expõe a sua implementação. Para este exercício, o nome é - my-deployment-service.
- É apresentada a página Detalhes do serviço. Nesta página, pode ver detalhes sobre o serviço. Por exemplo, pode ver que qualquer Pod que tenha as etiquetas - app: metricse- department: salesé membro do serviço. Lembre-se de que os pods em- my-deploymenttêm estas etiquetas.
Também pode ver um valor para IP do equilibrador de carga. O IP do balanceador de carga foi configurado automaticamente no balanceador de carga do cluster.
Encaminhamento para o Serviço
Suponhamos que um cliente fora do cluster envia um pedido para o IP do balanceador de carga na porta TCP 80. O pedido é encaminhado para o balanceador de carga do cluster. O balanceador de carga encaminha o pedido para um pod membro na porta TCP 8080. Recorde que cada Pod em my-deployment tem um contentor a ouvir na porta TCP 8080.
Teste o seu Serviço
Aceda a uma máquina onde o IP do balanceador de carga seja encaminhável.
Para chamar o seu serviço, introduza o IP do equilibrador de carga num navegador ou use um comando como curl. Por exemplo:
curl [LOAD_BALANCER_IP]:80
O resultado mostra uma mensagem Hello, world!. Por exemplo:
curl 203.0.113.1:80 Hello, world! Version: 2.0.0 Hostname: my-deployment-dbd86c8c4-9wpbv
Elimine a implementação
Aceda à página Workloads na secção Kubernetes Engine da consola.
Aceda à página Cargas de trabalho
Na lista de implementações, selecione my-deployment.
Na parte superior da página, clique em Eliminar. Isto elimina a implementação e o serviço de exposição.
Linha de comandos
Ligue-se à sua estação de trabalho de administração
Estabeleça uma ligação SSH à sua estação de trabalho de administrador. Siga os passos seguintes na estação de trabalho do administrador.
Crie uma implementação
Segue-se um manifesto para uma implementaçã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 ficheiro com o nome my-deployment.yaml e crie a
implementação:
kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-deployment.yaml
em que USER_CLUSTER_KUBECONFIG é o caminho do ficheiro kubeconfig para o cluster de utilizadores.
Obtenha informações básicas sobre a sua implementação:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment
A saída mostra que a implementação tem três pods que estão todos disponíveis:
NAME READY UP-TO-DATE AVAILABLE AGE my-deployment 3/3 3 3 27s
Apresente a lista dos pods na sua implementação:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods
A saída mostra que a sua implementação tem 3 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
Obtenha informações detalhadas sobre a sua implementação:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment --output yaml
O resultado mostra detalhes sobre a especificação e o estado da implementaçã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 sua implementação:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe deployment my-deployment
A saída mostra detalhes formatados sobre a implementaçã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 forma de expor a sua implementação a clientes fora do cluster é criar um serviço do Kubernetes do tipo LoadBalancer.
Segue-se 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 efeitos deste exercício, seguem-se os aspetos importantes a compreender acerca do Serviço:
- Qualquer Pod que tenha a etiqueta - app: metricse a etiqueta- department: salesé membro do serviço. Tenha em atenção que os agrupamentos em- my-deploymenttêm estas etiquetas.
- Quando um cliente envia um pedido para o serviço na porta TCP 80, o pedido é encaminhado para um pod membro na porta TCP 8080. 
- Cada membro do pod tem de ter um contentor que esteja a ouvir na porta TCP 8080. 
Acontece que, por predefinição, o contentor hello-app escuta na porta TCP 8080. Pode ver isto consultando o Dockerfile e o código-fonte da app.
Guarde o manifesto num ficheiro com o nome 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 ficheiro kubeconfig para o cluster de utilizadores.
Quando cria o serviço, o Google Distributed Cloud configura automaticamente o endereço loadBalancerIP no equilibrador de carga do cluster.
Veja o seu serviço:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get service my-service --output yaml
O resultado é semelhante a este:
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, pode ver que o seu serviço tem um clusterIP e um loadBalancerIP. Também tem um port e um targetPort.
O 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, considere os valores apresentados no resultado anterior. Ou seja, suponhamos que o seu serviço tem loadBalancerIP = 203.0.113.1, port = 80 e targetPort = 8080.
Um cliente envia um pedido para 203.0.113.1 na porta TCP 80. O pedido é encaminhado para o balanceador de carga do cluster. O balanceador de carga encaminha o pedido para um pod membro na porta TCP 8080.
Ligue para o seu serviço:
curl LOAD_BALANCER_IP
O resultado mostra uma mensagem Hello, world!:
curl 203.0.113.1 Hello, world! Version: 2.0.0 Hostname: my-deployment-dbd86c8c4-9wpbv
Elimine o seu serviço
Elimine o seu serviço:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service my-service
Verifique se o seu serviço foi eliminado:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get services
O resultado já não mostra my-service.
Elimine a sua implementação
Elimine a sua implementação:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment my-deployment
Verifique se a implementação foi eliminada:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployments
O resultado já não mostra my-deployment.