En este documento, se muestra cómo implementar una aplicación en el clúster de usuario para clústeres de Anthos alojados en VMware (GKE On-Prem).
Antes de comenzar
Crea un clúster de usuario (guía de inicio rápido | instrucciones completas).
Establece una conexión SSH a la estación de trabajo de administrador
Para establecer una conexión SSH a tu estación de trabajo de administrador, ejecuta lo siguiente:
ssh -i ~/.ssh/vsphere_workstation ubuntu@[IP_ADDRESS]
En el ejemplo anterior, [IP_ADDRESS] es la dirección IP de tu estación de trabajo de administrador.
Realiza todos los pasos restantes de este instructivo en la estación de trabajo de administrador.
Crea un Deployment
A continuación, se muestra un manifiesto para un Deployment:
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"
Copia el manifiesto en un archivo llamado my-deployment.yaml
y crea el Deployment:
kubectl apply --kubeconfig [USER_CLUSTER_KUBECONFIG] -f my-deployment.yaml
En el ejemplo anterior, [USER_CLUSTER_KUBECONFIG] es la ruta de acceso del archivo kubeconfig del clúster de usuario.
Obtén información básica sobre el Deployment:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] get deployment my-deployment
El resultado muestra que el Deployment tiene tres Pods y que todos están disponibles:
NAME READY UP-TO-DATE AVAILABLE AGE my-deployment 3/3 3 3 27s
Obtén una lista de los Pods del Deployment:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] get pods
El resultado muestra que tu Deployment tiene tres Pods en ejecución:
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
Obtén información detallada sobre el Deployment:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] get deployment my-deployment --output yaml
El resultado muestra detalles sobre la especificación y el estado del Deployment:
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
Describe tu Deployment:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] describe deployment my-deployment
En el resultado, se muestran detalles con un buen formato sobre el Deployment, incluido el ReplicaSet asociado:
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)
Crea un Service de tipo LoadBalancer
Una forma de exponer el Deployment a clientes fuera de tu clúster es crear un Service de Kubernetes de tipo LoadBalancer
.
Aquí hay un manifiesto para un Service de 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 los fines de este ejercicio, aquí se presentan los puntos importantes que debes comprender sobre el Service:
Cualquier Pod que tenga las etiquetas
app: metrics
ydepartment: sales
es miembro del Service. Ten en cuenta que los Pods enmy-deployment
tienen estas etiquetas.Cuando un cliente envía una solicitud al Service en el puerto TCP 80, la solicitud se reenvía a un Pod miembro en el puerto TCP 8080.
Cada Pod miembro debe tener un contenedor que escuche en el puerto TCP 8080.
De forma predeterminada, el contenedor hello-app
escucha en el puerto TCP 8080. Puedes ver esto si observas el Dockerfile y el código fuente de la app.
Reemplaza [SERVICE_IP_ADDRESS] por una dirección de tu propiedad que no esté en uso. Por ejemplo, puedes configurar esto como una dirección IP pública de tu empresa. O bien, puedes establecer una dirección privada en la red de tu empresa.
La dirección que elijas se debe poder enrutar desde la ubicación de cualquier cliente que envíe solicitudes al Service. Por ejemplo, si eliges una dirección privada, los clientes externos no podrán enviar solicitudes al Service.
Guarda el manifiesto en un archivo denominado my-service.yaml
y crea el Service:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] apply -f my-service.yaml
En el ejemplo anterior, [USER_CLUSTER_KUBECONFIG] es la ruta de acceso del archivo kubeconfig del clúster de usuario.
Cuando creas el servicio, los clústeres de Anthos alojados en VMware configuran automáticamente la dirección loadBalancerIP
en tu balanceador de cargas BIG-IP de F5.
Observa tu servicio:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] get service my-service --output yaml
El resultado es similar al siguiente ejemplo:
apiVersion: v1 kind: Service metadata: ... name: my-service namespace: default ... spec: clusterIP: 10.107.84.202 externalTrafficPolicy: Cluster loadBalancerIP: 203.0.113.1 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
En el resultado anterior, puedes ver que tu Service tiene una clusterIP
y una loadBalancerIP
. También tiene un nodePort
, un port
y un targetPort
.
La clusterIP
no es relevante para este ejercicio. El loadBalancerIP
es la dirección IP que proporcionaste en my-service.yaml
.
Por ejemplo, toma los valores que se muestran en el resultado anterior. Es decir, supongamos que tu Service tiene loadBalancerIP
= 203.0.113.1, port
= 80, nodePort
= 31919, y targetPort
= 8080.
Un cliente envía una solicitud a 203.0.113.1 en el puerto TCP 80. La solicitud se enruta al balanceador de cargas BIG-IP de F5. El balanceador de cargas elige uno de los nodos de clúster de usuario y reenvía la solicitud a [NODE_ADDRESS] en el puerto TCP 31919. Las reglas de iptables en el nodo reenvían la solicitud a un Pod miembro en el puerto TCP 8080.
Llama a tu Service:
curl [SERVICE_IP_ADDRESS]
En el ejemplo anterior, [SERVICE_IP_ADDRESS] es la dirección que especificaste para loadBalancerIP
.
El resultado muestra un mensaje de Hello, world!
:
curl 21.0.133.48 Hello, world! Version: 2.0.0 Hostname: my-deployment-dbd86c8c4-9wpbv
Borra el Service
Borra el Service:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] delete service my-service
Verifica que se haya borrado tu Service:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] get services
El resultado ya no muestra my-service
.
Borra el Deployment
Borra el Deployment:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] delete deployment my-deployment
Verifica que se haya borrado el Deployment:
kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] get deployments
El resultado ya no muestra my-deployment
.