Este documento descreve como implementar uma aplicação no Google Distributed Cloud.
Antes de começar
Para implementar uma carga de trabalho, tem de ter um cluster de utilizador, híbrido ou autónomo capaz de executar cargas de trabalho.
Crie uma implementação
Os passos seguintes criam uma implementação no cluster:
Copie o seguinte manifesto para um ficheiro com o nome
my-deployment.yaml
: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"
Use
kubectl apply
para criar a implementação:kubectl apply -f my-deployment.yaml --kubeconfig CLUSTER_KUBECONFIG
Substitua CLUSTER_KUBECONFIG pelo caminho do ficheiro kubeconfig para o seu cluster.
Obtenha informações básicas sobre a sua implementação para confirmar que foi criada com êxito:
kubectl get deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
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 get pods --kubeconfig CLUSTER_KUBECONFIG
A saída mostra que a sua implementação tem 3 pods em execução:
NAME READY STATUS RESTARTS AGE my-deployment-869f65669b-5259x 1/1 Running 0 34s my-deployment-869f65669b-9xfrs 1/1 Running 0 34s my-deployment-869f65669b-wn4ft 1/1 Running 0 34s
Obtenha informações detalhadas sobre a sua implementação:
kubectl get deployment my-deployment --output yaml --kubeconfig CLUSTER_KUBECONFIG
O resultado mostra detalhes sobre a especificação e o estado da implementação:
apiVersion: apps/v1 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: "2023-06-29T16:17:17Z" lastUpdateTime: "2023-06-29T16:17:17Z" message: Deployment has minimum availability. reason: MinimumReplicasAvailable status: "True" type: Available - lastTransitionTime: "2023-06-29T16:17:12Z" lastUpdateTime: "2023-06-29T16:17:17Z" message: ReplicaSet "my-deployment-869f65669b" has successfully progressed. reason: NewReplicaSetAvailable status: "True" type: Progressing observedGeneration: 1 readyReplicas: 3 replicas: 3 updatedReplicas: 3
Descreva a sua implementação:
kubectl describe deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
A saída mostra detalhes formatados sobre a implementação, incluindo o ReplicaSet associado:
Name: my-deployment Namespace: default CreationTimestamp: Thu, 29 Jun 2023 16:17:12 +0000 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 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: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: my-deployment-869f65669b (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 6m50s deployment-controller Scaled up replica set my-deployment-869f65669b to 3
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
.
Para criar um serviço do tipo LoadBalancer
:
Copie o seguinte manifesto para um ficheiro com o nome
my-service.yaml
:apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: metrics department: sales type: LoadBalancer ports: - port: 80 targetPort: 8080
Seguem-se os aspetos importantes a compreender acerca do serviço neste exercício:
Qualquer Pod que tenha a etiqueta
app: metrics
e a etiquetadepartment: sales
é membro do serviço. Os pods 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 TCP8080
.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 TCP8080
. Pode ver esta definição de porta consultando o Dockerfile e o código-fonte da app.Use
kubectl apply
para criar o serviço no cluster:kubectl apply -f my-service.yaml --kubeconfig CLUSTER_KUBECONFIG
Substitua CLUSTER_KUBECONFIG pelo caminho do ficheiro kubeconfig para o seu cluster.
Veja o seu serviço:
kubectl get service my-service --output yaml --kubeconfig CLUSTER_KUBECONFIG
O resultado é semelhante ao seguinte:
apiVersion: v1 kind: Service metadata: ... name: my-service namespace: default ... spec: allocateLoadBalancerNodePorts: true clusterIP: 10.96.2.165 clusterIPs: - 10.96.2.165 externalTrafficPolicy: Cluster internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - nodePort: 31565 port: 80 protocol: TCP targetPort: 8080 selector: app: metrics department: sales sessionAffinity: None type: LoadBalancer status: loadBalancer: ingress: - ip: 192.168.1.13
Na saída anterior, pode ver que o seu serviço tem um
clusterIP
e um endereço IP externo. Também tem umnodePort
, umport
e umtargetPort
.O
clusterIP
não é relevante para este exercício. O endereço IP externo (status.loadBalancer.ingress.ip
) provém do intervalo de endereços que especificou quando definiu os conjuntos de endereços do equilibrador de carga (spec.loadBalancer.addressPools
) no ficheiro de configuração do cluster.Por exemplo, considere os valores apresentados no resultado anterior para o seu serviço:
- Endereço IP externo:
192.168.1.13
port
:80
nodePort
:31565
targetPort
:8080
Um cliente envia um pedido para
192.168.1.13
na porta TCP80
. O pedido é encaminhado para o balanceador de carga e, a partir daí, é encaminhado para um pod membro na porta TCP8080
.- Endereço IP externo:
Ligue para o seu serviço:
curl INGRESS_IP_ADDRESS
Substitua INGRESS_IP_ADDRESS pelo endereço IP de entrada na secção
status
do serviço que obteve no passo anterior (status.loadBalancer.ingress
).O resultado mostra uma mensagem
Hello, world!
:Hello, world! Version: 2.0.0 Hostname: my-deployment-869f65669b-wn4ft
Limites de portas do LoadBalancer
O tipo LoadBalancer
é uma extensão do tipo NodePort
. Assim, um serviço do tipo LoadBalancer
tem um endereço IP do cluster e um ou mais valores nodePort
.
Por predefinição, o Kubernetes atribui portas de nós a serviços do tipo LoadBalancer
.
Estas atribuições podem esgotar rapidamente as portas de nós disponíveis dos 2768 atribuídos ao seu cluster. Para guardar portas de nós, desative a atribuição de portas de nós do balanceador de carga definindo o campo allocateLoadBalancerNodePorts
como false
na especificação do serviço LoadBalancer
. Esta definição impede que o Kubernetes atribua portas de nós a serviços LoadBalancer. Para mais informações, consulte o artigo
Desativar a atribuição de NodePort do equilibrador de carga
na documentação do Kubernetes.
Segue-se um manifesto para criar um serviço que não usa nenhuma porta de nó:
apiVersion: v1
kind: Service
metadata:
name: service-does-not-use-nodeports
spec:
selector:
app: my-app
type: LoadBalancer
ports:
- port: 8000
# Set allocateLoadBalancerNodePorts to false
allocateLoadBalancerNodePorts: false
Elimine o seu serviço
Para eliminar o seu serviço:
Use
kubectl delete
para eliminar o seu serviço do cluster:kubectl delete service my-service --kubeconfig CLUSTER_KUBECONFIG
Verifique se o seu serviço foi eliminado:
kubectl get services --kubeconfig CLUSTER_KUBECONFIG
O resultado já não mostra
my-service
.
Elimine a sua implementação
Para eliminar a sua implementação:
Use
kubectl delete
para eliminar a sua implementação do cluster:kubectl delete deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
Verifique se a implementação foi eliminada:
kubectl get deployments --kubeconfig CLUSTER_KUBECONFIG
O resultado já não mostra
my-deployment
.