En esta página, se proporciona la estrategia de implementación recomendada para compilar una aplicación de contenedor de Kubernetes sólida y con alta disponibilidad (HA) en Google Distributed Cloud (GDC) aislado. Debes implementar la aplicación de contenedor en varias zonas de GDC y configurar la replicación de almacenamiento asíncrona para que la aplicación y sus datos se puedan recuperar en caso de tiempo de inactividad inesperado o desastre local.
Esta página está dirigida a los desarrolladores que forman parte del grupo de operadores de aplicaciones y que son responsables de crear cargas de trabajo de aplicaciones para su organización. Para obtener más información, consulta Audiences for GDC air-gapped documentation.
Objetivos
- Crea un clúster de Kubernetes en dos o más zonas de tu universo de GDC.
- Configura el balanceo de cargas global.
- Implementa cargas de trabajo de contenedores en cada clúster zonal de Kubernetes.
- Aprovisiona almacenamiento y conéctalo a tus Pods.
- Configura la replicación de almacenamiento asíncrona con almacenamiento de objetos o de bloques.
Antes de comenzar
- Verifica que estés trabajando en un universo de GDC con varias zonas disponibles. Ejecuta - gdcloud zones listpara enumerar las zonas disponibles en tu universo. Para obtener más información, consulta Cómo enumerar las zonas de un universo.
- Pídele al administrador de IAM de tu organización que te otorgue los siguientes roles: - El rol de administrador de espacios de nombres ( - namespace-admin) para crear y administrar cargas de trabajo de contenedores
- Los roles de administrador de clúster de usuario ( - user-cluster-admin) y desarrollador de clúster de usuario (- user-cluster-developer) para crear y administrar clústeres de Kubernetes y sus grupos de nodos
- Los roles de administrador de balanceador de cargas ( - load-balancer-admin) y administrador de balanceador de cargas global (- global-load-balancer-admin) Debes tener este rol para crear y administrar balanceadores de cargas.
- El rol de administrador global de replicación de volumen ( - app-volume-replication-admin-global). Debes tener este rol para administrar la replicación de volumen.
- El rol de administrador global de PNP ( - global-project-networkpolicy-admin) para crear y administrar políticas de red del proyecto en todas las zonas
- Las funciones de administrador de instancias de Harbor ( - harbor-instance-admin), visualizador de instancias de Harbor(- harbor-instance-viewer) y creador de proyectos de Harbor (- harbor-project-creator) Estos roles son necesarios para crear y administrar imágenes de contenedores en el registro de artefactos.
- El rol de administrador global de replicación de volúmenes ( - app-volume-replication-admin-global) para administrar la relación de replicación de volúmenes para los recursos de almacenamiento en bloque.
- Los roles de administrador de objetos del bucket del proyecto ( - project-bucket-object-admin) y administrador del bucket del proyecto (- project-bucket-admin) para crear y administrar buckets de almacenamiento
 - Consulta las descripciones de los roles para obtener más información. 
- Instala y configura la CLI de gdcloud y configura tus contextos zonales y globales. Consulta Administra recursos en diferentes zonas para obtener más información. 
- Instala y configura la CLI de kubectl con los archivos kubeconfig adecuados establecidos para el servidor de la API global, el servidor de la API de administración y el clúster de Kubernetes. Consulta Cómo generar manualmente un archivo kubeconfig para obtener más información. 
Crea un clúster de Kubernetes en varias zonas
Un clúster de Kubernetes es un recurso zonal, por lo que debes crear un clúster por separado en cada zona.
Console
- En el menú de navegación, selecciona Kubernetes Engine > Clústeres. 
- Haz clic en Crear clúster. 
- En el campo Nombre, especifica un nombre para el clúster. 
- Selecciona la versión de Kubernetes para el clúster. 
- Selecciona la zona en la que deseas crear el clúster. 
- Haz clic en Attach Project y selecciona un proyecto existente para adjuntarlo a tu clúster. Luego, haz clic en Guardar. Puedes adjuntar o separar proyectos después de crear el clúster desde la página Detalles del proyecto. Debes tener un proyecto adjunto a tu clúster antes de implementar cargas de trabajo de contenedores en él. 
- Haz clic en Siguiente. 
- Configura los parámetros de configuración de red para tu clúster. No puedes cambiar estos parámetros de configuración de red después de crear el clúster. El único protocolo de Internet compatible y predeterminado para los clústeres de Kubernetes es el protocolo de Internet versión 4 (IPv4). - Especifica el tamaño del grupo de direcciones IP del balanceador de cargas, como - 20.
- Selecciona el CIDR (enrutamiento entre dominios sin clases) del servicio que se usará. Tus servicios implementados, como los balanceadores de cargas, reciben direcciones IP asignadas de este rango. 
- Selecciona el CIDR del pod que deseas usar. El clúster asigna direcciones IP de este rango a tus Pods y VMs. 
- Haz clic en Siguiente. 
 
- Revisa los detalles del grupo de nodos predeterminado generado automáticamente para el clúster. Haz clic en edit Editar para modificar el grupo de nodos predeterminado. 
- Para crear grupos de nodos adicionales, selecciona Agregar grupo de nodos. Cuando editas el grupo de nodos predeterminado o agregas un grupo de nodos nuevo, puedes personalizarlo con las siguientes opciones: - Asigna un nombre al grupo de nodos. No puedes modificar el nombre después de crear el grupo de nodos.
- Especifica la cantidad de nodos trabajadores que se crearán en el grupo de nodos.
- Selecciona la clase de máquina que mejor se adapte a los requisitos de tu carga de trabajo. Consulta la lista de los siguientes parámetros de configuración: - Tipo de máquina
- CPU
- Memoria
 
- Haz clic en Guardar. 
- Haz clic en Crear para generar el clúster. 
 
- Repite estos pasos para cada zona de tu universo de GDC. Asegúrate de que haya un clúster de Kubernetes en cada zona que desees para tu estrategia de HA. 
API
Para crear un clúster de Kubernetes nuevo directamente con la API, aplica un recurso personalizado a cada zona de GDC.
- Crea un recurso personalizado - Clustery, luego, impleméntalo en el servidor de la API de Management para tu zona:- kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF \ apiVersion: cluster.gdc.goog/v1 kind: Cluster metadata: name: CLUSTER_NAME namespace: platform spec: clusterNetwork: podCIDRSize: POD_CIDR serviceCIDRSize: SERVICE_CIDR initialVersion: kubernetesVersion: KUBERNETES_VERSION loadBalancer: ingressServiceIPSize: LOAD_BALANCER_POOL_SIZE nodePools: - machineTypeName: MACHINE_TYPE name: NODE_POOL_NAME nodeCount: NUMBER_OF_WORKER_NODES taints: TAINTS labels: LABELS acceleratorOptions: gpuPartitionScheme: GPU_PARTITION_SCHEME releaseChannel: channel: UNSPECIFIED EOF- Reemplaza lo siguiente: - MANAGEMENT_API_SERVER: Es la ruta de kubeconfig del servidor de la API de administración zonal. Para obtener más información, consulta Cómo cambiar al contexto zonal.
- CLUSTER_NAME: el nombre del clúster El nombre del clúster no debe terminar con- -system. El sufijo- -systemestá reservado para los clústeres creados por GDC.
- POD_CIDR: Es el tamaño de los rangos de red desde los que se asignan las direcciones IP virtuales (VIP) de los Pods. Si no se establece, se usa el valor predeterminado- 21.
- SERVICE_CIDR: Es el tamaño de los rangos de red desde los que se asignan las VIP de servicio. Si no se establece, se usa el valor predeterminado- 23.
- KUBERNETES_VERSION: Es la versión de Kubernetes del clúster, como- 1.26.5-gke.2100. Para enumerar las versiones de Kubernetes disponibles para configurar, consulta Enumera las versiones de Kubernetes disponibles para un clúster.
- LOAD_BALANCER_POOL_SIZE: Es el tamaño de los grupos de direcciones IP no superpuestos que usan los servicios de balanceador de cargas. Si no se establece, se usa el valor predeterminado- 20.
- MACHINE_TYPE: Es el tipo de máquina para los nodos trabajadores del grupo de nodos. Consulta los tipos de máquinas disponibles para ver qué se puede configurar.
- NODE_POOL_NAME: el nombre del grupo de nodos
- NUMBER_OF_WORKER_NODES: Es la cantidad de nodos trabajadores que se aprovisionarán en el grupo de nodos.
- TAINTS: Son los taints que se aplicarán a los nodos de este grupo de nodos. Este paso es opcional,
- LABELS: Son las etiquetas que se aplicarán a los nodos de este grupo de nodos. Contiene una lista de pares clave-valor. Este campo es opcional.
- GPU_PARTITION_SCHEME: Es el esquema de partición de GPU si ejecutas cargas de trabajo de GPU, como- mixed-2. La GPU no se particiona si no se configura este campo. Para conocer los perfiles de GPU multiinstancia (MIG) disponibles, consulta Perfiles de MIG compatibles.
 
- Repite el paso anterior para cada zona en la que quieras alojar tu aplicación de contenedor para tu estrategia de HA. 
Configura los balanceadores de cargas
Para distribuir el tráfico entre tus Pods en diferentes zonas, crea balanceadores de cargas. Tienes la opción de crear balanceadores de cargas externos (ELB) y balanceadores de cargas internos (ILB), los cuales se pueden configurar de forma zonal o global. En este ejemplo, configura un ILB global y un ELB global para tu aplicación de contenedor.
Crea un balanceador de cargas interno global
Los balanceadores de cargas internos (ILB) exponen servicios dentro de la organización desde un grupo de direcciones IP internas asignado a la organización. Nunca se puede acceder a un servicio de ILB desde ningún extremo fuera de la organización.
Completa los siguientes pasos para crear un ILB global para tus cargas de trabajo de contenedores.
gdcloud
Crea un ILB que apunte a cargas de trabajo de pods con la CLI de gcloud.
Este ILB segmenta todas las cargas de trabajo del proyecto que coinciden con la etiqueta definida en el objeto Backend. El recurso personalizado Backend debe tener un alcance limitado a una zona.
Para crear un ILB con gcloud CLI, sigue estos pasos:
- Crea un recurso - Backendzonal en cada zona en la que se ejecutan tus Pods para definir el extremo del ILB:- gdcloud compute backends create BACKEND_NAME \ --labels=LABELS \ --project=PROJECT \ --cluster=CLUSTER_NAME \ --zone=ZONE- Reemplaza lo siguiente: - BACKEND_NAME: Es el nombre elegido para el recurso de backend, como- my-backend.
- LABELS: Es el selector que define qué extremos entre los Pods se usarán para este recurso de backend, como- app=web.
- PROJECT: nombre del proyecto.
- CLUSTER_NAME: Es el clúster de Kubernetes al que se limita el alcance de los selectores definidos. Si no se especifica este campo, se seleccionarán todos los extremos con la etiqueta determinada. Este campo es opcional.
- ZONE: Es la zona que se usará para esta invocación. Para preestablecer la marca de zona para todos los comandos que la requieren, ejecuta- gdcloud config set core/zone ZONE. La marca de zona solo está disponible en entornos multizona. Este campo es opcional.
 - Repite este paso para cada zona de tu universo de GDC. 
- Crea un recurso - BackendServiceglobal:- gdcloud compute backend-services create BACKEND_SERVICE_NAME \ --project=PROJECT \ --target-ports=TARGET_PORTS \ --global- Reemplaza lo siguiente: - BACKEND_SERVICE_NAME: Es el nombre del servicio de backend.
- PROJECT: nombre del proyecto.
- TARGET_PORTS: Es una lista separada por comas de los puertos de destino que traduce este servicio de backend, en la que cada puerto de destino especifica el protocolo, el puerto en la regla de reenvío y el puerto en la instancia de backend. Puedes especificar varios puertos de destino. Este campo debe tener el formato- protocol:port:targetport, como- TCP:80:8080. Este campo es opcional.
 
- Agrega el recurso - BackendServiceal recurso- Backendcreado anteriormente en cada zona:- gdcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --backend-zone=ZONE \ --backend=BACKEND_NAME \ --project=PROJECT \ --global- Reemplaza lo siguiente: - BACKEND_SERVICE_NAME: Es el nombre del servicio de backend global.
- ZONE: Es la zona del backend.
- BACKEND_NAME: Es el nombre del backend zonal.
- PROJECT: nombre del proyecto.
 - Completa este paso para cada backend zonal que creaste anteriormente. 
- Crea un recurso - ForwardingRuleinterno que defina la dirección IP virtual (VIP) en la que está disponible el servicio:- gdcloud compute forwarding-rules create FORWARDING_RULE_INTERNAL_NAME \ --backend-service=BACKEND_SERVICE_NAME \ --cidr=CIDR \ --ip-protocol-port=PROTOCOL_PORT \ --load-balancing-scheme=INTERNAL \ --project=PROJECT \ --global- Reemplaza lo siguiente: - FORWARDING_RULE_INTERNAL_NAME: Es el nombre de la regla de reenvío.
- CIDR: Es el CIDR que se usará para tu regla de reenvío. Este campo es opcional. Si no se especifica, se reserva automáticamente un CIDR- IPv4/32del grupo de direcciones IP global. Especifica el nombre de un recurso- Subneten el mismo espacio de nombres que esta regla de reenvío. Un recurso- Subnetrepresenta la información de solicitud y asignación de una subred global. Para obtener más información sobre los recursos de- Subnet, consulta Administra subredes.
- PROTOCOL_PORT: Es el protocolo y el puerto que se expondrán en la regla de reenvío. Este campo debe tener el formato- ip-protocol=TCP:80. El puerto expuesto debe ser el mismo que el que expone la aplicación real dentro del contenedor.
 
- Para validar el ILB configurado, confirma la condición - Readyen cada uno de los objetos creados. Verifica el tráfico con una solicitud- curla la VIP:- Para obtener la VIP asignada, describe la regla de reenvío: - gdcloud compute forwarding-rules describe FORWARDING_RULE_INTERNAL_NAME --global
- Verifica el tráfico con una solicitud - curla la VIP en el puerto especificado en el campo de la regla de reenvío:- curl http://FORWARDING_RULE_VIP:PORT
 - Reemplaza lo siguiente: - FORWARDING_RULE_VIP: Es la VIP de la regla de reenvío.
- PORT: Es el número de puerto de la regla de reenvío.
 
API
Crea un ILB que apunte a cargas de trabajo de contenedores con la API de KRM. Este ILB segmenta todas las cargas de trabajo del proyecto que coinciden con la etiqueta definida en el objeto Backend. Para crear un ILB global con la API de KRM, sigue estos pasos:
- Crea un recurso - Backendpara definir los extremos del ILB. Crea recursos de- Backendpara cada zona en la que se colocan las cargas de trabajo de los contenedores:- kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF apiVersion: networking.gdc.goog/v1 kind: Backend metadata: namespace: PROJECT name: BACKEND_NAME spec: clusterName: CLUSTER_NAME endpointsLabels: matchLabels: app: APP_NAME EOF- Reemplaza lo siguiente: - MANAGEMENT_API_SERVER: Es la ruta de acceso de kubeconfig del servidor de la API de administración zonal. Para obtener más información, consulta Cómo cambiar a un contexto zonal.
- PROJECT: nombre del proyecto.
- BACKEND_NAME: Es el nombre del recurso- Backend.
- CLUSTER_NAME: Es el clúster de Kubernetes al que se limita el alcance de los selectores definidos. Si no se especifica este campo, se seleccionarán todos los extremos con la etiqueta determinada. Este campo es opcional.
- APP_NAME: Es el nombre de tu aplicación de contenedor.
 - Puedes usar el mismo recurso - Backendpara cada zona o crear recursos- Backendcon diferentes conjuntos de etiquetas para cada zona.
- Crea un objeto - BackendServicecon el recurso- Backendcreado anteriormente. Asegúrate de incluir el recurso- HealthCheck:- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: BackendService metadata: namespace: PROJECT name: BACKEND_SERVICE_NAME spec: backendRefs: - name: BACKEND_NAME zone: ZONE healthCheckName: HEALTH_CHECK_NAME targetPorts: - port: PORT protocol: PROTOCOL targetPort: TARGET_PORT EOF- Reemplaza lo siguiente: - GLOBAL_API_SERVER: Es la ruta de acceso de kubeconfig del servidor de API global.
- PROJECT: nombre del proyecto.
- BACKEND_SERVICE_NAME: Es el nombre elegido para tu recurso- BackendService.
- HEALTH_CHECK_NAME: Es el nombre del recurso- HealthCheckque creaste anteriormente.
- BACKEND_NAME: Es el nombre del recurso- Backendzonal.
- ZONE: Es la zona en la que reside el recurso- Backend. Puedes especificar varios servidores de backend en el campo- backendRefs. Por ejemplo:- - name: my-backend-1 zone: us-east1-a - name: my-backend-2 zone: us-east1-b- El campo - targetPortses opcional. En este recurso, se enumeran los puertos que traduce el recurso- BackendService. Si usas este objeto, proporciona valores para lo siguiente:
- PORT: Es el puerto que expone el servicio.
- PROTOCOL: Es el protocolo de capa 4 con el que debe coincidir el tráfico. Solo se admiten TCP y UDP.
- TARGET_PORT: Es el puerto al que se traduce el valor, como- 8080. El valor no se puede repetir en un objeto determinado.- Un ejemplo para - targetPortspodría verse de la siguiente manera:- targetPorts: - port: 80 protocol: TCP targetPort: 8080
 
- Crea un recurso - ForwardingRuleinterno que defina la dirección IP virtual (VIP) en la que está disponible el servicio.- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ForwardingRuleInternal metadata: namespace: PROJECT name: FORWARDING_RULE_INTERNAL_NAME spec: cidrRef: CIDR ports: - port: PORT protocol: PROTOCOL backendServiceRef: name: BACKEND_SERVICE_NAME EOF- Reemplaza lo siguiente: - GLOBAL_API_SERVER: Es la ruta de acceso de kubeconfig del servidor de API global.
- PROJECT: nombre del proyecto.
- FORWARDING_RULE_INTERNAL_NAME: Es el nombre elegido para tu recurso- ForwardingRuleInternal.
- CIDR: Es el CIDR que se usará para tu regla de reenvío. Este campo es opcional. Si no se especifica, se reserva automáticamente un CIDR- IPv4/32del grupo de direcciones IP global. Especifica el nombre de un recurso- Subneten el mismo espacio de nombres que esta regla de reenvío. Un recurso- Subnetrepresenta la información de solicitud y asignación de una subred global. Para obtener más información sobre los recursos de- Subnet, consulta Administra subredes.
- PORT: Es el puerto que se expondrá en la regla de reenvío. Usa el campo- portspara especificar un array de puertos de L4 para los que los paquetes se reenvían a los backends configurados con esta regla de reenvío. Se debe especificar al menos un puerto. Usa el campo- portpara especificar un número de puerto. El puerto expuesto debe ser el mismo que el que expone la aplicación real dentro del contenedor.
- PROTOCOL: Es el protocolo que se usará para la regla de reenvío, como- TCP. Una entrada en el array- portsdebe verse de la siguiente manera:- ports: - port: 80 protocol: TCP
 
- Para validar el ILB configurado, confirma la condición - Readyen cada uno de los objetos creados. Verifica el tráfico con una solicitud- curla la VIP:- Recupera el VIP: - kubectl get forwardingruleinternal -n PROJECT- El resultado luce de la siguiente manera: - NAME BACKENDSERVICE CIDR READY ilb-name BACKEND_SERVICE_NAME 192.0.2.0/32 True
- Prueba el tráfico con una solicitud - curla la VIP en el puerto especificado en el campo de la regla de reenvío:- curl http://FORWARDING_RULE_VIP:PORT- Reemplaza lo siguiente: - FORWARDING_RULE_VIP: Es la VIP de la regla de reenvío.
- PORT: Es el número de puerto del campo en la regla de reenvío.
 
 
Crea un balanceador de cargas externo global
Los balanceadores de cargas externos (ELB) exponen servicios para acceder desde fuera de la organización desde un grupo de direcciones IP asignadas a la organización desde el grupo de direcciones IP externas de instancias más grande.
Completa los siguientes pasos para crear un ELB global para tus cargas de trabajo de contenedores.
gdcloud
Usa la CLI de gcloud para crear un ELB global que apunte a todas las cargas de trabajo del proyecto que coincidan con la etiqueta definida en el objeto Backend.
El recurso personalizado Backend debe tener un alcance limitado a una zona.
- Para que los servicios de ELB funcionen, debes configurar y aplicar tu propia política de transferencia de datos - ProjectNetworkPolicypersonalizada para permitir el tráfico a las cargas de trabajo de este servicio de ELB. Las políticas de red controlan el acceso a tus cargas de trabajo, no al balanceador de cargas en sí. Los ELB exponen las cargas de trabajo a la red de tu cliente, lo que requiere políticas de red explícitas para permitir el tráfico externo al puerto de la carga de trabajo, como- 8080.- Especifica la dirección CIDR externa para permitir el tráfico a las cargas de trabajo de este ELB: - kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: PROJECT name: allow-inbound-traffic-from-external spec: policyType: Ingress subject: subjectType: UserWorkload ingress: - from: - ipBlock: cidr: CIDR ports: - protocol: TCP port: PORT EOF- Reemplaza lo siguiente: - GLOBAL_API_SERVER: Es la ruta de acceso de kubeconfig del servidor de API global. Si aún no generaste un archivo kubeconfig para el servidor de la API global, consulta Cómo generar manualmente un archivo kubeconfig para obtener más detalles.
- PROJECT: nombre del proyecto.
- CIDR: Es el CIDR externo desde el que se debe acceder al ELB. Esta política es necesaria, ya que el balanceador de cargas externo usa el retorno directo del servidor (DSR), que conserva la dirección IP externa de origen y omite el balanceador de cargas en la ruta de retorno. Para obtener más información, consulta Crea una regla de firewall de entrada global para el tráfico entre organizaciones.
- PORT: Es el puerto de backend en los Pods detrás del balanceador de cargas. Este valor se encuentra en el campo- .spec.ports[].targetPortfielddel manifiesto del recurso- Service. Este campo es opcional.
 - Esta configuración proporciona a todos los recursos dentro de los proyectos acceso al rango de CIDR especificado. 
- Crea un recurso - Backenden cada zona para definir el extremo del ELB:- gdcloud compute backends create BACKEND_NAME \ --labels=LABELS \ --project=PROJECT \ --cluster=CLUSTER_NAME \ --zone=ZONE- Reemplaza lo siguiente: - BACKEND_NAME: Es el nombre del recurso de backend, como- my-backend.
- LABELS: Es un selector que define qué extremos entre los pods se usarán para este recurso de backend, como- app=web.
- PROJECT: nombre del proyecto.
- CLUSTER_NAME: Es el clúster de Kubernetes al que se limita el alcance de los selectores definidos. Si no se especifica este campo, se seleccionarán todos los extremos con la etiqueta determinada. Este campo es opcional.
- ZONE: Es la zona que se usará para esta invocación. Para preestablecer la marca de zona para todos los comandos que la requieren, ejecuta- gdcloud config set core/zone ZONE. La marca de zona solo está disponible en entornos multizona. Este campo es opcional.
 - Puedes usar el mismo recurso - Backendpara cada zona o crear recursos- Backendcon diferentes conjuntos de etiquetas para cada zona.
- Crea un recurso - BackendServiceglobal:- gdcloud compute backend-services create BACKEND_SERVICE_NAME \ --project=PROJECT \ --target-ports=TARGET_PORTS \ --health-check=HEALTH_CHECK_NAME \ --global- Reemplaza lo siguiente: - BACKEND_SERVICE_NAME: Es el nombre elegido para este servicio de backend.
- PROJECT: nombre del proyecto.
- TARGET_PORTS: Es una lista separada por comas de los puertos de destino que traduce este servicio de backend, en la que cada puerto de destino especifica el protocolo, el puerto en la regla de reenvío y el puerto en la instancia de backend. Puedes especificar varios puertos de destino. Este campo debe tener el formato- protocol:port:targetport, como- TCP:80:8080. Este campo es opcional.
- HEALTH_CHECK_NAME: Es el nombre del recurso de verificación de estado. Este campo es opcional.
 
- Agrega el recurso - BackendServiceglobal al recurso- Backendzonal creado anteriormente:- gdcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --backend=BACKEND_NAME \ --backend-zone=ZONE \ --project=PROJECT \ --global- Completa este paso para cada backend zonal que creaste anteriormente. 
- Crea un recurso - ForwardingRuleexterno que defina la VIP en la que está disponible el servicio:- gdcloud compute forwarding-rules create FORWARDING_RULE_EXTERNAL_NAME \ --backend-service=BACKEND_SERVICE_NAME \ --cidr=CIDR \ --ip-protocol-port=PROTOCOL_PORT \ --load-balancing-scheme=EXTERNAL \ --project=PROJECT \ --global- Reemplaza lo siguiente: - FORWARDING_RULE_EXTERNAL_NAME: Es el nombre de la regla de reenvío.
- CIDR: Es el CIDR que se usará para tu regla de reenvío. Este campo es opcional. Si no se especifica, se reserva automáticamente un CIDR- IPv4/32del grupo de direcciones IP global. Especifica el nombre de un recurso- Subneten el mismo espacio de nombres que esta regla de reenvío. Un recurso- Subnetrepresenta la información de solicitud y asignación de una subred global. Para obtener más información sobre los recursos de- Subnet, consulta Administra subredes.
- PROTOCOL_PORT: Es el protocolo y el puerto que se expondrán en la regla de reenvío. Este campo debe tener el formato- ip-protocol=TCP:80. El puerto expuesto debe ser el mismo que el que expone la aplicación real dentro del contenedor.
- PROJECT: nombre del proyecto.
 
- Para validar el ELB configurado, confirma la condición - Readyen cada uno de los objetos creados. Verifica el tráfico con una solicitud- curla la VIP:- Para obtener la VIP asignada, describe la regla de reenvío: - gdcloud compute forwarding-rules describe FORWARDING_RULE_EXTERNAL_NAME
- Verifica el tráfico con una solicitud - curla la VIP en el puerto especificado en el campo- PROTOCOL_PORTde la regla de reenvío:- curl http://FORWARDING_RULE_VIP:PORT- Reemplaza lo siguiente: - FORWARDING_RULE_VIP: Es la VIP de la regla de reenvío.
- PORT: Es el número de puerto del campo- PROTOCOL_PORTen la regla de reenvío.
 
 
API
Crea un ELB que apunte a las cargas de trabajo de los pods con la API de KRM. Este ELB segmenta todas las cargas de trabajo del proyecto que coinciden con la etiqueta definida en el objeto Backend. Para crear un ELB zonal con la API de KRM, sigue estos pasos:
- Para que los servicios de ELB funcionen, debes configurar y aplicar tu propia política de transferencia de datos - ProjectNetworkPolicypersonalizada para permitir el tráfico a las cargas de trabajo de este servicio de ELB. Las políticas de red controlan el acceso a tus cargas de trabajo, no al balanceador de cargas en sí. Los ELB exponen las cargas de trabajo a la red de tu cliente, lo que requiere políticas de red explícitas para permitir el tráfico externo al puerto de la carga de trabajo, como- 8080.- Especifica la dirección CIDR externa para permitir el tráfico a las cargas de trabajo de este ELB: - kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: PROJECT name: allow-inbound-traffic-from-external spec: policyType: Ingress subject: subjectType: UserWorkload ingress: - from: - ipBlock: cidr: CIDR ports: - protocol: TCP port: PORT EOF- Reemplaza lo siguiente: - GLOBAL_API_SERVER: Es la ruta de acceso de kubeconfig del servidor de API global. Si aún no generaste un archivo kubeconfig para el servidor de la API global, consulta Cómo generar manualmente un archivo kubeconfig para obtener más detalles.
- PROJECT: nombre del proyecto.
- CIDR: Es el CIDR externo desde el que se debe acceder al ELB. Esta política es necesaria, ya que el balanceador de cargas externo usa el retorno directo del servidor (DSR), que conserva la dirección IP externa de origen y omite el balanceador de cargas en la ruta de retorno. Para obtener más información, consulta Crea una regla de firewall de entrada global para el tráfico entre organizaciones.
- PORT: Es el puerto de backend en los Pods detrás del balanceador de cargas. Este valor se encuentra en el campo- .spec.ports[].targetPortfielddel manifiesto del recurso- Service. Este campo es opcional.
 
- Crea un recurso - Backendpara definir los extremos del ELB. Crea recursos de- Backendpara cada zona en la que se colocan las cargas de trabajo:- kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF apiVersion: networking.gdc.goog/v1 kind: Backend metadata: namespace: PROJECT name: BACKEND_NAME spec: clusterName: CLUSTER_NAME endpointsLabels: matchLabels: app: APP_NAME EOF- Reemplaza lo siguiente: - MANAGEMENT_API_SERVER: Es la ruta de acceso de kubeconfig del servidor de la API de administración zonal. Si aún no generaste un archivo kubeconfig para el servidor de la API en tu zona de destino, consulta Cómo generar manualmente un archivo kubeconfig para obtener más detalles.
- PROJECT: nombre del proyecto.
- BACKEND_NAME: El nombre del recurso- Backend.
- CLUSTER_NAME: Es el clúster de Kubernetes al que se limita el alcance de los selectores definidos. Si no se especifica este campo, se seleccionarán todos los extremos con la etiqueta determinada. Este campo es opcional.
- APP_NAME: Es el nombre de tu aplicación de contenedor.
 - Puedes usar el mismo recurso - Backendpara cada zona o crear recursos- Backendcon diferentes conjuntos de etiquetas para cada zona.
- Crea un objeto - BackendServicecon el recurso- Backendcreado anteriormente:- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: BackendService metadata: namespace: PROJECT name: BACKEND_SERVICE_NAME spec: backendRefs: - name: BACKEND_NAME zone: ZONE healthCheckName: HEALTH_CHECK_NAME EOF- Reemplaza lo siguiente: - BACKEND_SERVICE_NAME: Es el nombre elegido para tu recurso- BackendService.
- HEALTH_CHECK_NAME: Es el nombre del recurso- HealthCheckque creaste anteriormente. No incluyas este campo si configuras un ELB para cargas de trabajo de Pod.
- ZONE: Es la zona en la que reside el recurso- Backend. Puedes especificar varios backends en el campo- backendRefs. Por ejemplo:
 - - name: my-backend-1 zone: us-east1-a - name: my-backend-2 zone: us-east1-b
- Crea un recurso - ForwardingRuleexterno que defina la VIP en la que está disponible el servicio.- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ForwardingRuleExternal metadata: namespace: PROJECT name: FORWARDING_RULE_EXTERNAL_NAME spec: cidrRef: CIDR ports: - port: PORT protocol: PROTOCOL backendServiceRef: name: BACKEND_SERVICE_NAME EOF- Reemplaza lo siguiente: - FORWARDING_RULE_EXTERNAL_NAME: Es el nombre elegido para tu recurso- ForwardingRuleExternal.
- CIDR: Es el CIDR que se usará para tu regla de reenvío. Este campo es opcional. Si no se especifica, se reserva automáticamente un CIDR- IPv4/32del grupo de direcciones IP global. Especifica el nombre de un recurso- Subneten el mismo espacio de nombres que esta regla de reenvío. Un recurso- Subnetrepresenta la información de solicitud y asignación de una subred global. Para obtener más información sobre los recursos de- Subnet, consulta Administra subredes.
- PORT: Es el puerto que se expondrá en la regla de reenvío. Usa el campo- portspara especificar un array de puertos de L4 para los que los paquetes se reenvían a los backends configurados con esta regla de reenvío. Se debe especificar al menos un puerto. Usa el campo- portpara especificar un número de puerto. El puerto expuesto debe ser el mismo que el que expone la aplicación real dentro del contenedor.
- PROTOCOL: Es el protocolo que se usará para la regla de reenvío, como- TCP. Una entrada en el array- portsdebe verse de la siguiente manera:
 - ports: - port: 80 protocol: TCP
- Para validar el ELB configurado, confirma la condición - Readyen cada uno de los objetos creados. Prueba el tráfico con una solicitud- curla la VIP.- Recupera la VIP del proyecto: - kubectl get forwardingruleexternal -n PROJECT- El resultado luce de la siguiente manera: - NAME BACKENDSERVICE CIDR READY elb-name BACKEND_SERVICE_NAME 192.0.2.0/32 True
- Verifica el tráfico con una solicitud de curl a la VIP en el puerto especificado en el campo - PORTde la regla de reenvío:- curl http://FORWARDING_RULE_VIP:PORT- Reemplaza - FORWARDING_RULE_VIP:PORTpor la VIP y el puerto de la regla de reenvío, como- 192.0.2.0:80.
 
Implementa cargas de trabajo de contenedores en cada clúster zonal
Las cargas de trabajo de contenedores no son un recurso global, lo que significa que debes implementar cada una de tus aplicaciones de contenedores por separado en los clústeres zonales de Kubernetes.
- Accede a la zona que aloja tu clúster de Kubernetes: - gdcloud config set core/zone ZONE
- Verifica que la imagen de contenedor esté disponible en el registro de Harbor administrado. Para obtener más información, consulta el instructivo Implementa una app de contenedor. 
- Crea un archivo de manifiesto para tu carga de trabajo de contenedor y, luego, impleméntalo en tu clúster de Kubernetes zonal: - kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT \ apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: DEPLOYMENT_NAME spec: replicas: NUMBER_OF_REPLICAS selector: matchLabels: run: APP_NAME template: metadata: labels: run: APP_NAME spec: containers: - name: CONTAINER_NAME image: HARBOR_INSTANCE_URL/HARBOR_PROJECT_NAME/IMAGE:TAG EOF- Reemplaza lo siguiente: - KUBERNETES_CLUSTER: Es el archivo kubeconfig del clúster de Kubernetes zonal en el que implementas cargas de trabajo de contenedores. Si aún no generaste un archivo kubeconfig para tu clúster de Kubernetes zonal, consulta Cómo generar manualmente un archivo kubeconfig para obtener más detalles.
- PROJECT: Es el espacio de nombres del proyecto en el que se implementarán las cargas de trabajo del contenedor.
- DEPLOYMENT_NAME: Es el nombre de la implementación del contenedor.
- NUMBER_OF_REPLICAS: Es la cantidad de objetos- Podreplicados que administra la implementación.
- APP_NAME: Es el nombre de la aplicación que se ejecutará dentro de la implementación.
- CONTAINER_NAME: Es el nombre del contenedor.
- HARBOR_INSTANCE_URL: Es la URL de la instancia de Harbor, como- harbor-1.org-1.zone1.google.gdc.test.. Para recuperar la URL de la instancia de Harbor, consulta Cómo ver instancias del registro de Harbor.
- HARBOR_PROJECT_NAME: Es el nombre del proyecto de Harbor, como- my-project.
- IMAGE: Es el nombre de la imagen, como- nginx.
- TAG: Es la etiqueta de la versión de la imagen que deseas extraer, como- 1.0.
 
- Repite los pasos anteriores para cada zona de tu universo de GDC. Asegúrate de que tu aplicación de contenedor resida en cada zona que desees para tu estrategia de HA. 
Expón tu aplicación de contenedor con Kubernetes
Debes exponer tu aplicación de contenedor para permitir el acceso a ella desde otros recursos de tu universo de GDC.
- Crea un recurso - Servicede- type: LoadBalancer. Este recurso expone los pods de tu aplicación a través de una red.- kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT \ apiVersion: v1 kind: Service metadata: name: SERVICE_NAME spec: selector: app: APP_NAME ports: - port: 80 protocol: TCP type: LoadBalancer EOF- Reemplaza lo siguiente: - KUBERNETES_CLUSTER: Es el archivo kubeconfig del clúster de Kubernetes zonal en el que implementas cargas de trabajo de contenedores.
- PROJECT: Es el espacio de nombres del proyecto en el que residen tus cargas de trabajo de contenedores.
- SERVICE_NAME: Es el nombre del servicio del balanceador de cargas.
- APP_NAME: Es la etiqueta que aplicaste para tu aplicación de contenedor.
 
- Crea un recurso personalizado - NetworkPolicypara permitir todo el tráfico de red al espacio de nombres predeterminado:- kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT \ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: annotations: name: allow-all spec: ingress: - from: - ipBlock: cidr: 0.0.0.0/0 podSelector: {} policyTypes: - Ingress EOF
Aprovisiona almacenamiento persistente para tus Pods
Debes crear un recurso PersistentVolumeClaim (PVC) para proporcionar almacenamiento persistente a los Pods de la aplicación.
En las siguientes instrucciones, se muestra cómo crear un volumen con el standard-rwo StorageClass de GDC.
- Crea un recurso - PersistentVolumeClaimPor ejemplo, configúralo con un modo de acceso- ReadWriteOncey una clase de almacenamiento- standard-rwo:- kubectl --kubeconfig KUBERNETES_CLUSTER \ --namespace PROJECT apply -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: PVC_NAME spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: standard-rwo EOF- Reemplaza lo siguiente: - KUBERNETES_CLUSTER: Es el archivo kubeconfig del clúster de Kubernetes.
- PROJECT: Es el espacio de nombres del proyecto en el que se creará la PVC.
- PVC_NAME: Es el nombre del objeto- PersistentVolumeClaim.
 
- Los objetos - PersistentVolume(PV) se aprovisionan de forma dinámica. Verifica el estado de los PV nuevos en tu clúster de Kubernetes:- kubectl get pv --kubeconfig KUBERNETES_CLUSTER- El resultado es similar a este: - NAME CAPACITY ACCESS MODES STATUS CLAIM STORAGECLASS AGE pvc-uuidd 10Gi RWO Bound pvc-name standard-rwo 60s
- Configura tus cargas de trabajo de contenedores para que usen el PVC. A continuación, se muestra un ejemplo de manifiesto de Pod que usa un PVC de - standard-rwo:- kubectl --kubeconfig KUBERNETES_CLUSTER \ --namespace PROJECT apply -f - <<EOF apiVersion: apps/v1 kind: Pod metadata: name: web-server-deployment labels: app: APP_LABEL spec: containers: - name: CONTAINER_NAME image: HARBOR_INSTANCE_URL/HARBOR_PROJECT_NAME/IMAGE:TAG volumeMounts: - mountPath: MOUNT_PATH name: data volumes: - name: data persistentVolumeClaim: claimName: PVC_NAME EOF- Reemplaza lo siguiente: - KUBERNETES_CLUSTER: Es el archivo kubeconfig del clúster de Kubernetes en el que implementas cargas de trabajo de contenedores.
- PROJECT: Es el espacio de nombres del proyecto en el que reside la PVC.
- APP_LABEL: Es la etiqueta que aplicaste para tu aplicación de contenedor.
- CONTAINER_NAME: Es el nombre del contenedor.
- HARBOR_INSTANCE_URL: Es la URL de la instancia de Harbor, como- harbor-1.org-1.zone1.google.gdc.test.. Para recuperar la URL de la instancia de Harbor, consulta Cómo ver instancias del registro de Harbor.
- HARBOR_PROJECT_NAME: Es el nombre del proyecto de Harbor, como- my-project.
- IMAGE: Es el nombre de la imagen, como- nginx.
- TAG: Es la etiqueta de la versión de la imagen que deseas extraer, como- 1.0.
- MOUNT_PATH: Es la ruta de acceso dentro del Pod para activar tu volumen.
- PVC_NAME: Es la PVC que creaste.
 
Configura la replicación de almacenamiento asíncrona
Los universos multizonales de GDC ofrecen el uso de recursos de almacenamiento replicados, como volúmenes y buckets, en modo asíncrono para situaciones de recuperación ante desastres. Estas opciones de recursos de almacenamiento proporcionan replicación asíncrona de datos entre dos zonas cualesquiera de la misma región. La replicación asíncrona se produce en segundo plano y proporciona un objetivo de punto de recuperación (RPO) bajo, pero no nulo, en caso de desastre. Todos los datos replicados están en línea y son accesibles de inmediato, pero es posible que se requiera un procedimiento manual de conmutación por error para habilitar la escritura en la zona secundaria.
Puedes elegir uno de los siguientes tipos de replicación de almacenamiento asíncrona para tu aplicación en contenedores:
Crea un bucket de doble zona para el almacenamiento de objetos
Los datos de almacenamiento de objetos se escriben en un solo bucket cuyos datos se almacenan en ambas zonas. Debido a que los datos se copian de forma asíncrona entre las zonas, es posible que estas no contengan las mismas versiones de objetos en ningún momento, pero, con el tiempo, se volverán equivalentes si no se realizan cambios adicionales. A diferencia de la replicación de volúmenes, los buckets replicados se pueden escribir durante las particiones de zona. Cada escritura en un objeto produce una versión diferente, y la versión más reciente en cualquiera de las zonas será el estado final después de que se restablezca la conectividad.
- Verifica que tu operador de infraestructura (IO) haya creado el recurso personalizado - BucketLocationConfig, que es necesario para la replicación asíncrona en zonas para el almacenamiento de objetos. Este recurso debe implementarse en el servidor raíz de la API global.
- Crea el recurso personalizado - Bucketde doble zona:- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: object.global.gdc.goog/v1 kind: Bucket metadata: name: BUCKET_NAME namespace: PROJECT spec: location: LOCATION_NAME description: Sample DZ Bucket storageClass: Standard EOF- Reemplaza lo siguiente: - GLOBAL_API_SERVER: Es el archivo kubeconfig para el servidor de la API global.
- BUCKET_NAME: Es el nombre del bucket de almacenamiento.
- PROJECT: Es el nombre del proyecto en el que reside el bucket.
- LOCATION_NAME: Es el lugar físico donde residen los datos de objetos del bucket. Debe asignarse al nombre de un recurso- BucketLocationexistente. Para consultar el servidor de la API global de tu organización y obtener una lista de los recursos- BucketLocationdisponibles, ejecuta- kubectl --kubeconfig GLOBAL_API_SERVER bucketlocations. Si no hay recursos de- BucketLocation, comunícate con tu IO para verificar que haya habilitado la replicación asíncrona.
 
Configura la replicación asíncrona del almacenamiento en bloque en diferentes zonas
El almacenamiento de bloques replicado proporciona volúmenes replicados de forma asíncrona (PV), que mantienen la equivalencia de bloques entre los volúmenes principal y secundario. Debido a la naturaleza asíncrona, el volumen secundario refleja el estado de la zona principal en algún momento del pasado (RPO distinto de cero). El volumen secundario no se puede activar mientras siga siendo el destino de la replicación, lo que requiere intervención manual para finalizar la relación y permitir que se produzcan escrituras.
Debes configurar una relación de replicación de almacenamiento entre zonas para crear datos replicados que estén disponibles para la conmutación por error si los datos de la zona de origen dejan de estar disponibles. Esto es relevante si usas almacenamiento en bloque para tu aplicación de contenedor.
Antes de comenzar, verifica que tu operador de infraestructura (IO) haya creado y configurado los recursos personalizados StorageClusterPeering y StorageVirtualMachinePeering para permitir la replicación del almacenamiento en bloque en todas las zonas. Este recurso se debe implementar en el servidor de la API global raíz.
- Crea un archivo YAML de recurso personalizado - VolumeReplicationRelationshipy despliégalo en el servidor de la API global:- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: storage.global.gdc.goog/v1 kind: VolumeReplicationRelationship metadata: name: PVC_REPL_NAME namespace: PROJECT spec: source: pvc: clusterRef: SOURCE_PVC_CLUSTER pvcRef: SOURCE_PVC zoneRef: SOURCE_ZONE destination: pvc: clusterRef: DEST_PVC_CLUSTER zoneRef: DEST_ZONE EOF- Reemplaza lo siguiente: - GLOBAL_API_SERVER: Es el archivo kubeconfig del servidor de la API global.
- PVC_REPL_NAME: Es el nombre de la relación de replicación del volumen.
- PROJECT: Es el proyecto en el que reside la infraestructura de almacenamiento.
- SOURCE_PVC_CLUSTER: Es el clúster de Kubernetes en el que se aloja el PVC.
- SOURCE_PVC: Es la PVC de la zona de origen que se replicará.
- SOURCE_ZONE: Es la zona de origen en la que se aloja la PVC.
- DEST_PVC_CLUSTER: Es el clúster de Kubernetes de destino en el que se replicará el PVC.
- DEST_ZONE: Es la zona de destino a la que se replicará la PVC.
 
- Crea un recurso personalizado - VolumeFailoveren la zona de destino, que detiene la replicación en la zona de destino si la zona de origen no está disponible por algún motivo:- kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF apiVersion: storage.gdc.goog/v1 kind: VolumeFailover metadata: name: PVC_FAILOVER_NAME namespace: PROJECT spec: volumeReplicationRelationshipRef: PVC_REPL_NAME EOF- Reemplaza lo siguiente: - MANAGEMENT_API_SERVER: Es el archivo kubeconfig del servidor de la API de administración zonal.
- PVC_FAILOVER_NAME: Es el nombre de la conmutación por error de la PVC.
- PROJECT: Es el proyecto en el que reside la infraestructura de almacenamiento.
- PVC_REPL_NAME: Es el nombre de la relación de replicación del volumen.
 
¿Qué sigue?
- Cargas de trabajo de Kubernetes para alta disponibilidad
- Cargas de trabajo de contenedores en GDC
- Descripción general de la multizona