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-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: metricsedepartment: salesé membro do serviço. Lembre-se de que os pods emmy-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 etiquetadepartment: salesé membro do serviço. Tenha em atenção que os agrupamentos emmy-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.