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 contentorhello-app
deteta na 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: metrics
edepartment: sales
é membro do serviço. Lembre-se de que os pods emmy-deployment
tê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 equilibrador 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: metrics
e a etiquetadepartment: sales
é membro do serviço. Tenha em atenção que os agrupamentos emmy-deployment
tê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.
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
.