Versión 1.6. Esta versión es compatible como se describe en la política de asistencia de la versión de Anthos, que ofrece los últimos parches y actualizaciones de vulnerabilidades de seguridad, exposiciones y problemas que afectan a los clústeres de Anthos alojados en VMware (GKE On-Prem). Consulta las notas de la versión para obtener más detalles. Esta no es la versión más reciente.

Implementar una aplicación

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: "gcr.io/google-samples/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: gcr.io/google-samples/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:        gcr.io/google-samples/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 y department: sales es miembro del Service. Ten en cuenta que los Pods en my-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 comando 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.

¿Qué sigue?

Habilitar Ingress