En este documento se describe cómo desplegar una aplicación de contenedor de Kubernetes de alta disponibilidad (HA) en Google Distributed Cloud (GDC) con aislamiento físico. Para garantizar la resiliencia, debes desplegar tu aplicación en varias zonas y configurar la replicación del almacenamiento para que la aplicación y sus datos se puedan recuperar en caso de que se produzca un tiempo de inactividad inesperado o un desastre local.
Este documento está dirigido a desarrolladores de aplicaciones que se encargan de crear cargas de trabajo de contenedores resilientes.
Para obtener más información, consulta Audiencias de la documentación aislada de GDC.
Objetivos
- Crea un clúster de Kubernetes en dos o más zonas de tu universo de GDC.
- Configura el balanceo de carga global.
- Despliega cargas de trabajo de contenedores en cada clúster de Kubernetes zonal.
- Aprovisiona el almacenamiento y adjúntalo a tus pods.
- Configura la replicación del almacenamiento mediante almacenamiento en bloques o almacenamiento de objetos.
Antes de empezar
Para preparar las tareas que se describen en este documento, debes obtener los permisos necesarios y verificar tu entorno.
Solicitar roles y permisos de gestión de identidades y accesos
Ponte en contacto con el administrador de gestión de identidades y accesos de tu organización para solicitar los siguientes roles:
- Administrador de espacio de nombres (
namespace-admin): crea y edita cargas de trabajo de contenedores en un clúster compartido. - Administrador de clústeres de usuarios (
user-cluster-admin): crea y edita clústeres compartidos. - Desarrollador de clúster de usuarios (
user-cluster-developer): crea y edita grupos de nodos en un clúster compartido. - Administrador de instancias de Harbor (
harbor-instance-admin): crea y edita instancias de Harbor, proyectos de Harbor e imágenes de contenedor. - Administrador global de PNP (
global-project-networkpolicy-admin): crea y edita políticas de red de proyectos en todas las zonas. - Administrador de balanceadores de carga globales (
global-load-balancer-admin): crea y edita balanceadores de carga globales. - Administrador global de replicación de volúmenes (
app-volume-replication-admin-global): administra la relación de replicación de volúmenes de los recursos de almacenamiento en bloque. - Administrador de proyectos de cubos (
global-project-bucket-admin): crea y edita cubos de almacenamiento de doble zona.
Para obtener más información, consulta las descripciones de los roles.
Prepara tu entorno
Confirma que tienes las siguientes herramientas y configuraciones en tu entorno aislado:
Instala y configura la CLI de gdcloud, y define tus contextos zonales y globales. Para obtener más información, consulta Zonas de acceso con tus herramientas.
Instala la CLI kubectl y define los archivos kubeconfig adecuados para el servidor de la API global, el servidor de la API de gestión y el clúster de Kubernetes. Para obtener más información, consulta Generar manualmente el archivo kubeconfig.
Verifica que tu universo de GDC tenga varias zonas disponibles. Para obtener más información, consulta Listar zonas de un universo.
Crear un clúster de Kubernetes en varias zonas
Para crear una aplicación de contenedor de alta disponibilidad, debes crear un clúster de Kubernetes compartido independiente en cada zona de tu universo de GDC.
Para obtener más información sobre las opciones de configuración de clúster disponibles, consulta Configuraciones de clúster de Kubernetes.
Consola
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 del clúster.
Selecciona la zona en la que quieras crear el clúster.
Haz clic en Adjuntar proyecto y selecciona un proyecto para adjuntarlo a tu clúster. A continuación, 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 asociado a tu clúster para poder implementar cargas de trabajo de contenedores en él.
Haz clic en Siguiente.
Configura los ajustes de red de tu clúster. No puedes cambiar esta configuración de red después de crear el clúster. El protocolo de Internet predeterminado y único compatible con 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 carga, como
20.Selecciona el CIDR (enrutamiento de interdominios sin clases) de servicio que quieras usar. Tus servicios implementados, como los balanceadores de carga, tienen asignadas direcciones IP de este intervalo.
Selecciona el CIDR de pod que quieras usar. El clúster asigna direcciones IP de este intervalo 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 más grupos de nodos, selecciona Añadir grupo de nodos. Cuando editas el grupo de nodos predeterminado o añades uno 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 el número de nodos de trabajador 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 ajustes:
- Tipo de máquina
- CPU
- Memoria
Haz clic en Guardar.
Haz clic en Crear para que se genere el clúster.
Repite estos pasos con cada zona de tu universo de GDC. Asegúrate de que haya un clúster de Kubernetes en cada zona que quieras incluir en tu estrategia de alta disponibilidad.
API
Para crear un clúster de Kubernetes con la API directamente, aplica un recurso personalizado a cada zona de GDC.
Crea un
Clusterrecurso personalizado e impleméntalo en el servidor de la API Management de 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 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 EOFHaz los cambios siguientes:
MANAGEMENT_API_SERVER: la ruta de kubeconfig del servidor de la API Management zonal. Para obtener más información, consulta 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: tamaño de los intervalos de red desde los que se asignan las direcciones IP virtuales (VIP) de los pods. Si no se define, se usará el valor predeterminado21.SERVICE_CIDR: tamaño de los intervalos de red desde los que se asignan las IPs virtuales de servicio. Si no se define, se usa el valor predeterminado23.KUBERNETES_VERSION: la versión de Kubernetes del clúster, como1.26.5-gke.2100. Para ver una lista de las versiones de Kubernetes disponibles que puedes configurar, consulta Ver las versiones de Kubernetes disponibles para un clúster.MACHINE_TYPE: el tipo de máquina de los nodos de trabajador 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: el número de nodos de trabajo que se aprovisionarán en el grupo de nodos.TAINTS: los taints que se aplicarán a los nodos de este grupo de nodos. Este campo es opcional.LABELS: 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: el esquema de partición de GPU, si ejecutas cargas de trabajo de GPU, comomixed-2. La GPU no se particiona si no se define este campo. Para ver los perfiles de GPU con varias instancias (MIG) disponibles, consulta Perfiles de MIG admitidos.
Repita el paso anterior para cada zona en la que quiera alojar su aplicación de contenedor para su estrategia de alta disponibilidad.
Configurar balanceadores de carga
Para distribuir el tráfico entre tus pods en diferentes zonas, crea balanceadores de carga. Puedes configurar balanceadores de carga internos y externos de forma global para asegurarte de que las solicitudes de los clientes se dirijan a zonas en buen estado.
Crear un balanceador de carga interno global
Los balanceadores de carga internos (ILBs) exponen servicios dentro de la organización desde un pool de direcciones IP internas asignado a la organización. Nunca se puede acceder a un servicio de ILB desde ningún punto final que no pertenezca a la organización.
Sigue estos pasos para crear un balanceador de carga interno global para tus cargas de trabajo de contenedor.
gdcloud
Crea un ILB que tenga como destino cargas de trabajo de pods mediante la CLI de gdcloud.
Este ILB está dirigido 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 ámbito de zona.
Para crear un balanceador de carga interno mediante la CLI de gdcloud, sigue estos pasos:
Crea un recurso
Backendzonal en cada zona en la que se ejecuten tus pods para definir el endpoint del ILB:gdcloud compute backends create BACKEND_NAME \ --labels=LABELS \ --project=PROJECT \ --cluster-name=CLUSTER_NAME \ --zone=ZONEHaz los cambios siguientes:
BACKEND_NAME: el nombre elegido para el recurso de backend, comomy-backend.LABELS: el selector que define qué endpoints entre pods se van a usar para este recurso de backend, comoapp=web.PROJECT: el nombre de tu proyecto.CLUSTER_NAME: el clúster de Kubernetes al que se limita el ámbito de los selectores definidos. Si no se especifica este campo, se seleccionarán todos los endpoints con la etiqueta indicada. Este campo es opcional.ZONE: la zona que se va a usar en esta invocación. Para predefinir la marca de zona en todos los comandos que la requieran, ejecutagdcloud config set core/zone ZONE. La marca de zona solo está disponible en entornos multizona. Este campo es opcional.
Repite este paso con 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 \ --globalHaz los cambios siguientes:
BACKEND_SERVICE_NAME: el nombre del servicio de backend.PROJECT: el nombre de tu proyecto.TARGET_PORTS: lista separada por comas de puertos de destino que traduce este servicio de backend. Cada puerto de destino especifica el protocolo, el puerto de la regla de reenvío y el puerto de la instancia de backend. Puedes especificar varios puertos de destino. Este campo debe tener el formatoprotocol:port:targetport, comoTCP:80:8080. Este campo es opcional.
Añade el recurso
BackendServiceal recursoBackendque has creado anteriormente en cada zona:gdcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --backend-zone=ZONE \ --backend=BACKEND_NAME \ --project=PROJECT \ --globalHaz los cambios siguientes:
BACKEND_SERVICE_NAME: el nombre del servicio de backend global.ZONE: la zona del backend.BACKEND_NAME: el nombre del backend zonal.PROJECT: el nombre de tu proyecto.
Completa este paso para cada backend zonal que hayas creado 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 \ --globalHaz los cambios siguientes:
FORWARDING_RULE_INTERNAL_NAME: el nombre de la regla de reenvío.CIDR: el CIDR que se va a usar en la regla de reenvío. Este campo es opcional. Si no se especifica ninguna, se reserva automáticamente un CIDRIPv4/32del grupo de direcciones IP global. Especifica el nombre de un recursoSubneten el mismo espacio de nombres que esta regla de reenvío. Un recursoSubnetrepresenta la información de solicitud y asignación de una subred global. Para obtener más información sobre los recursos deSubnet, consulta Gestionar subredes.PROTOCOL_PORT: el protocolo y el puerto que se expondrán en la regla de reenvío. Este campo debe tener el formatoip-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 solicitudcurla la VIP:Para obtener la VIP asignada, describe la regla de reenvío:
gdcloud compute forwarding-rules describe FORWARDING_RULE_INTERNAL_NAME --globalVerifica el tráfico con una solicitud
curla la dirección IP virtual en el puerto especificado en el campo de la regla de reenvío:curl http://FORWARDING_RULE_VIP:PORT
Haz los cambios siguientes:
FORWARDING_RULE_VIP: el VIP de la regla de reenvío.PORT: número de puerto de la regla de reenvío.
API
Crea un ILB que tenga como destino cargas de trabajo de contenedores mediante la API KRM. Este ILB se dirige a todas las cargas de trabajo del proyecto que coincidan con la etiqueta definida en el objeto Backend. Para crear un ILB global mediante la API KRM, sigue estos pasos:
Crea un recurso
Backendpara definir los endpoints del ILB. Crea recursosBackendpara cada zona en la que se coloquen 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 EOFHaz los cambios siguientes:
MANAGEMENT_API_SERVER: la ruta de kubeconfig del servidor de la API de gestión zonal. Para obtener más información, consulta Cambiar a un contexto zonal.PROJECT: el nombre de tu proyecto.BACKEND_NAME: el nombre delBackendrecurso.CLUSTER_NAME: el clúster de Kubernetes al que se limita el ámbito de los selectores definidos. Si no se especifica este campo, se seleccionarán todos los endpoints con la etiqueta indicada. Este campo es opcional.APP_NAME: el nombre de tu aplicación de contenedor.
Puede usar el mismo recurso
Backendpara cada zona o crear recursosBackendcon conjuntos de etiquetas diferentes para cada zona.Crea un objeto
BackendServiceusando el recursoBackendque has creado anteriormente. Asegúrate de incluir el recursoHealthCheck: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 EOFHaz los cambios siguientes:
GLOBAL_API_SERVER: la ruta kubeconfig del servidor de la API global.PROJECT: el nombre de tu proyecto.BACKEND_SERVICE_NAME: el nombre que elijas para tu recursoBackendService.HEALTH_CHECK_NAME: el nombre del recursoHealthCheckque has creado anteriormente.BACKEND_NAME: nombre del recurso zonalBackendZONE: la zona en la que se encuentra el recursoBackend. Puedes especificar varios back-ends en el campobackendRefs. Por ejemplo:- name: my-backend-1 zone: us-east1-a - name: my-backend-2 zone: us-east1-bEl campo
targetPortses opcional. En este recurso se enumeran los puertos que traduce este recursoBackendService. Si usas este objeto, proporciona valores para lo siguiente:PORT: el puerto expuesto por el servicio.PROTOCOL: el protocolo de capa 4 con el que debe coincidir el tráfico. Solo se admiten TCP y UDP.TARGET_PORT: el puerto al que se traduce el valor, como8080. El valor no se puede repetir en un objeto determinado.Por ejemplo, en el caso de
targetPorts, podría ser así: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: name: CIDR_NAME ports: - port: PORT protocol: PROTOCOL backendServiceRef: name: BACKEND_SERVICE_NAME EOFHaz los cambios siguientes:
GLOBAL_API_SERVER: la ruta kubeconfig del servidor de la API global.PROJECT: el nombre de tu proyecto.FORWARDING_RULE_INTERNAL_NAME: el nombre que elijas para tu recursoForwardingRuleInternal.CIDR_NAME: el nombre del CIDR que se va a usar en la regla de reenvío. Este campo es opcional. Si no se especifica ninguna, se reserva automáticamente un CIDRIPv4/32del grupo de direcciones IP global. Especifica el nombre de un recursoSubneten el mismo espacio de nombres que esta regla de reenvío. Un recursoSubnetrepresenta la información de solicitud y asignación de una subred global. Para obtener más información sobre los recursos deSubnet, consulta Gestionar subredes.PORT: el puerto que se va a exponer en la regla de reenvío. Utilice el campoportspara especificar una matriz de puertos de nivel 4 para los que se reenvían paquetes a los back-ends configurados con esta regla de reenvío. Se debe especificar al menos un puerto. Usa el campoportpara especificar un número de puerto. El puerto expuesto debe ser el mismo que expone la aplicación real dentro del contenedor.PROTOCOL: el protocolo que se va a usar en la regla de reenvío, comoTCP. Una entrada de la matrizportsdebe tener el siguiente formato: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 solicitudcurla la VIP:Recuperar el VIP:
kubectl get forwardingruleinternal -n PROJECTLa salida tiene este aspecto:
NAME BACKENDSERVICE CIDR READY ilb-name BACKEND_SERVICE_NAME 192.0.2.0/32 TruePrueba el tráfico con una solicitud
curla la IP virtual en el puerto especificado en el campo de la regla de reenvío:curl http://FORWARDING_RULE_VIP:PORTHaz los cambios siguientes:
FORWARDING_RULE_VIP: el VIP de la regla de reenvío.PORT: número de puerto del campo de la regla de reenvío.
Crear un balanceador de carga externo global
Los balanceadores de carga externos (ELB) exponen los servicios para que se pueda acceder a ellos desde fuera de la organización a partir de las direcciones IP de un pool asignadas a la organización desde el pool de direcciones IP externas de la instancia más grande.
Sigue estos pasos para crear un ELB global para tus cargas de trabajo de contenedores.
gdcloud
Usa la CLI gdcloud para crear un ELB global que tenga como destino todas las cargas de trabajo del proyecto que coincidan con la etiqueta definida en el objeto Backend.
El recurso personalizado Backend debe tener un ámbito de zona.
Para que los servicios de ELB funcionen, debes configurar y aplicar tu propia transferencia de datos de
ProjectNetworkPolicypersonalizada en la política 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 carga en sí. Los ELBs exponen las cargas de trabajo a la red de tus clientes, lo que requiere políticas de red explícitas para permitir el tráfico externo al puerto de la carga de trabajo, como8080.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 EOFHaz los cambios siguientes:
GLOBAL_API_SERVER: la ruta de kubeconfig del servidor de la API global. Si aún no has generado un archivo kubeconfig para el servidor de la API global, consulta Generar manualmente un archivo kubeconfig para obtener más información.PROJECT: el nombre de tu proyecto.CIDR: el CIDR externo desde el que se debe acceder al ELB. Esta política es obligatoria porque el balanceador de carga externo usa la devolución directa del servidor (DSR), que conserva la dirección IP externa de origen y omite el balanceador de carga en la ruta de retorno. Para obtener más información, consulta Crear una regla de cortafuegos de entrada global para el tráfico externo a la organización.PORT: el puerto de backend de los pods que hay detrás del balanceador de carga. Este valor se encuentra en el campo.spec.ports[].targetPortfielddel manifiesto del recursoService. Este campo es opcional.
Esta configuración proporciona acceso a todos los recursos de los proyectos al intervalo CIDR especificado.
Cree un recurso
Backenden cada zona para definir el endpoint del ELB:gdcloud compute backends create BACKEND_NAME \ --labels=LABELS \ --project=PROJECT \ --cluster-name=CLUSTER_NAME \ --zone=ZONEHaz los cambios siguientes:
BACKEND_NAME: el nombre del recurso de backend, comomy-backend.LABELS: selector que define qué endpoints entre pods se van a usar para este recurso de backend, comoapp=web.PROJECT: el nombre de tu proyecto.CLUSTER_NAME: el clúster de Kubernetes al que se limita el ámbito de los selectores definidos. Si no se especifica este campo, se seleccionarán todos los endpoints con la etiqueta indicada. Este campo es opcional.ZONE: la zona que se va a usar en esta invocación. Para predefinir la marca de zona en todos los comandos que la requieran, ejecutagdcloud config set core/zone ZONE. La marca de zona solo está disponible en entornos multizona. Este campo es opcional.
Puede usar el mismo recurso
Backendpara cada zona o crear recursosBackendcon conjuntos de etiquetas diferentes 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 \ --globalHaz los cambios siguientes:
BACKEND_SERVICE_NAME: el nombre elegido para este servicio de backend.PROJECT: el nombre de tu proyecto.TARGET_PORTS: lista de puertos de destino separados por comas que traduce este servicio de backend. Cada puerto de destino especifica el protocolo, el puerto de la regla de reenvío y el puerto de la instancia de backend. Puedes especificar varios puertos de destino. Este campo debe tener el formatoprotocol:port:targetport, comoTCP:80:8080. Este campo es opcional.HEALTH_CHECK_NAME: el nombre del recurso de comprobación de estado. Este campo es opcional.
Añade el recurso global
BackendServiceal recurso de zonaBackendque has creado anteriormente:gdcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --backend=BACKEND_NAME \ --backend-zone=ZONE \ --project=PROJECT \ --globalCompleta este paso para cada backend zonal que hayas creado anteriormente.
Crea un recurso
ForwardingRuleexterno que defina la IP virtual 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 \ --globalHaz los cambios siguientes:
FORWARDING_RULE_EXTERNAL_NAME: el nombre de la regla de reenvío.CIDR: el CIDR que se va a usar en la regla de reenvío. Este campo es opcional. Si no se especifica ninguna, se reserva automáticamente un CIDRIPv4/32del grupo de direcciones IP global. Especifica el nombre de un recursoSubneten el mismo espacio de nombres que esta regla de reenvío. Un recursoSubnetrepresenta la información de solicitud y asignación de una subred global. Para obtener más información sobre los recursos deSubnet, consulta el artículo sobre cómo gestionar subredes.PROTOCOL_PORT: el protocolo y el puerto que se expondrán en la regla de reenvío. Este campo debe tener el formatoip-protocol=TCP:80. El puerto expuesto debe ser el mismo que el que expone la aplicación real dentro del contenedor.PROJECT: el nombre de tu proyecto.
Para validar el ELB configurado, confirma la condición
Readyen cada uno de los objetos creados. Verifica el tráfico con una solicitudcurla la VIP:Para obtener la VIP asignada, describe la regla de reenvío:
gdcloud compute forwarding-rules describe FORWARDING_RULE_EXTERNAL_NAMEVerifica el tráfico con una solicitud
curla la IP virtual en el puerto especificado en el campoPROTOCOL_PORTde la regla de reenvío:curl http://FORWARDING_RULE_VIP:PORTHaz los cambios siguientes:
FORWARDING_RULE_VIP: el VIP de la regla de reenvío.PORT: número de puerto del campoPROTOCOL_PORTde la regla de reenvío.
API
Crea un ELB que tenga como destino cargas de trabajo de pods mediante la API de KRM. Este ELB
se dirige a todas las cargas de trabajo del proyecto que coincidan con la etiqueta definida en el objeto Backend. Para crear un ELB zonal con la API KRM, sigue estos pasos:
Para que los servicios de ELB funcionen, debes configurar y aplicar tu propia transferencia de datos de
ProjectNetworkPolicypersonalizada en la política 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 carga en sí. Los ELBs exponen las cargas de trabajo a la red de tus clientes, lo que requiere políticas de red explícitas para permitir el tráfico externo al puerto de la carga de trabajo, como8080.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 EOFHaz los cambios siguientes:
GLOBAL_API_SERVER: la ruta de kubeconfig del servidor de la API global. Si aún no has generado un archivo kubeconfig para el servidor de la API global, consulta Generar manualmente un archivo kubeconfig para obtener más información.PROJECT: el nombre de tu proyecto.CIDR: el CIDR externo desde el que se debe acceder al ELB. Esta política es obligatoria porque el balanceador de carga externo usa la devolución directa del servidor (DSR), que conserva la dirección IP externa de origen y omite el balanceador de carga en la ruta de retorno. Para obtener más información, consulta Crear una regla de cortafuegos de entrada global para el tráfico externo a la organización.PORT: el puerto de backend de los pods que hay detrás del balanceador de carga. Este valor se encuentra en el campo.spec.ports[].targetPortfielddel manifiesto del recursoService. Este campo es opcional.
Crea un recurso
Backendpara definir los endpoints del ELB. Crea recursosBackendpara cada zona en la que se coloquen 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 EOFHaz los cambios siguientes:
MANAGEMENT_API_SERVER: la ruta de kubeconfig del servidor de la API de gestión zonal. Si aún no has generado un archivo kubeconfig para el servidor de la API en la zona de destino, consulta Generar manualmente un archivo kubeconfig para obtener más información.PROJECT: el nombre de tu proyecto.BACKEND_NAME: el nombre del recursoBackend.CLUSTER_NAME: el clúster de Kubernetes al que se limita el ámbito de los selectores definidos. Si no se especifica este campo, se seleccionarán todos los endpoints con la etiqueta indicada. Este campo es opcional.APP_NAME: el nombre de tu aplicación de contenedor.
Puede usar el mismo recurso
Backendpara cada zona o crear recursosBackendcon conjuntos de etiquetas diferentes para cada zona.Crea un objeto
BackendServiceusando el recursoBackendque has creado antes: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 EOFHaz los cambios siguientes:
BACKEND_SERVICE_NAME: el nombre que elijas para tu recursoBackendService.HEALTH_CHECK_NAME: el nombre del recursoHealthCheckque has creado anteriormente. No incluya este campo si va a configurar un ELB para cargas de trabajo de pods.ZONE: la zona en la que se encuentra el recursoBackend. Puedes especificar varios back-ends en el campobackendRefs. Por ejemplo:
- name: my-backend-1 zone: us-east1-a - name: my-backend-2 zone: us-east1-bCrea un recurso
ForwardingRuleexterno que defina la IP virtual 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: name: CIDR_NAME ports: - port: PORT protocol: PROTOCOL backendServiceRef: name: BACKEND_SERVICE_NAME EOFHaz los cambios siguientes:
FORWARDING_RULE_EXTERNAL_NAME: el nombre que elijas para tu recursoForwardingRuleExternal.CIDR_NAME: el nombre del CIDR que se va a usar en la regla de reenvío. Este campo es opcional. Si no se especifica ninguna, se reserva automáticamente un CIDRIPv4/32del grupo de direcciones IP global. Especifica el nombre de un recursoSubneten el mismo espacio de nombres que esta regla de reenvío. Un recursoSubnetrepresenta la información de solicitud y asignación de una subred global. Para obtener más información sobre los recursos deSubnet, consulta el artículo sobre cómo gestionar subredes.PORT: el puerto que se va a exponer en la regla de reenvío. Usa el campoportspara especificar una matriz de puertos de nivel 4 para los que se reenvían paquetes a los backends configurados con esta regla de reenvío. Se debe especificar al menos un puerto. Utilice el campoportpara 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: el protocolo que se va a usar en la regla de reenvío, comoTCP. Una entrada del arrayportsdebe tener el siguiente formato:
ports: - port: 80 protocol: TCPPara validar el ELB configurado, confirma la condición
Readyen cada uno de los objetos creados. Prueba el tráfico con una solicitudcurla la VIP.Recupera la IP virtual del proyecto:
kubectl get forwardingruleexternal -n PROJECTLa salida tiene este aspecto:
NAME BACKENDSERVICE CIDR READY elb-name BACKEND_SERVICE_NAME 192.0.2.0/32 TrueVerifica el tráfico con una solicitud curl a la IP virtual en el puerto especificado en el campo
PORTde la regla de reenvío:curl http://FORWARDING_RULE_VIP:PORTSustituye
FORWARDING_RULE_VIP:PORTpor la IP virtual y el puerto de la regla de reenvío, como192.0.2.0:80.
Desplegar 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 desplegar cada una de tus aplicaciones de contenedores por separado en los clústeres de Kubernetes zonales.
Inicia sesión en la zona que aloja tu clúster de Kubernetes:
gdcloud config set core/zone ZONEVerifica que tu imagen de contenedor esté disponible en el registro de Harbor gestionado. Para obtener más información, consulta el tutorial Implementar una aplicación de contenedor.
Crea un archivo de manifiesto para tu carga de trabajo de contenedor y despliégalo 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 EOFHaz los cambios siguientes:
KUBERNETES_CLUSTER: el archivo kubeconfig del clúster de Kubernetes zonal en el que vas a implementar cargas de trabajo de contenedores. Si aún no has generado un archivo kubeconfig para tu clúster de Kubernetes zonal, consulta Generar manualmente un archivo kubeconfig para obtener más información.PROJECT: el espacio de nombres del proyecto en el que se van a implementar las cargas de trabajo del contenedor.DEPLOYMENT_NAME: el nombre de la implementación del contenedor.NUMBER_OF_REPLICAS: número de objetosPodreplicados que gestiona la implementación.APP_NAME: el nombre de la aplicación que se va a ejecutar en la implementación.CONTAINER_NAME: el nombre del contenedor.HARBOR_INSTANCE_URL: la URL de la instancia de Harbor, comoharbor-1.org-1.zone1.google.gdc.test.. Para obtener la URL de la instancia de Harbor, consulta Ver instancias del registro de Harbor.HARBOR_PROJECT_NAME: el nombre del proyecto de Harbor, comomy-project.IMAGE: el nombre de la imagen, comonginx.TAG: la etiqueta de la versión de la imagen que quieras extraer, como1.0.
Repite los pasos anteriores con cada zona de tu universo de GDC. Asegúrate de que tu aplicación de contenedor se encuentre en todas las zonas que quieras para tu estrategia de alta disponibilidad.
Exponer una aplicación en contenedores 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
Servicedetype: LoadBalancer. Este recurso expone los pods de tu aplicación a través de una red.kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: SERVICE_NAME spec: selector: app: APP_NAME ports: - port: 80 protocol: TCP type: LoadBalancer EOFHaz los cambios siguientes:
KUBERNETES_CLUSTER: el archivo kubeconfig del clúster de Kubernetes zonal en el que vas a implementar cargas de trabajo de contenedores.PROJECT: el espacio de nombres del proyecto en el que residen las cargas de trabajo de tu contenedor.SERVICE_NAME: el nombre del servicio del balanceador de carga.APP_NAME: la etiqueta que has aplicado a tu aplicación de contenedor.
Crea un
NetworkPolicyrecurso personalizado para permitir todo el tráfico de red al espacio de nombres predeterminado:kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT apply -f - <<EOF 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
Aprovisionar 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 explica cómo crear un volumen con la GDC standard-rwo StorageClass.
Crea un
PersistentVolumeClaimrecurso. Por ejemplo, configúralo con un modo de accesoReadWriteOncey una clase de almacenamientostandard-rwo:kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT apply -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: PVC_NAME spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: standard-rwo EOFHaz los cambios siguientes:
KUBERNETES_CLUSTER: el archivo kubeconfig del clúster de Kubernetes.PROJECT: el espacio de nombres del proyecto en el que se va a crear el PVC.PVC_NAME: el nombre del objetoPersistentVolumeClaim.
Los objetos
PersistentVolume(PV) se aprovisionan de forma dinámica. Comprueba el estado de los nuevos PVs en tu clúster de Kubernetes:kubectl get pv --kubeconfig KUBERNETES_CLUSTEREl resultado debería ser similar al siguiente:
NAME CAPACITY ACCESS MODES STATUS CLAIM STORAGECLASS AGE pvc-uuidd 10Gi RWO Bound pvc-name standard-rwo 60sConfigura tus cargas de trabajo de contenedor para que usen el PVC. A continuación, se muestra un ejemplo de manifiesto de pod que usa un PVC
standard-rwo:kubectl --kubeconfig KUBERNETES_CLUSTER -n 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 EOFHaz los cambios siguientes:
KUBERNETES_CLUSTER: el archivo kubeconfig del clúster de Kubernetes en el que vas a implementar las cargas de trabajo de los contenedores.PROJECT: el espacio de nombres del proyecto en el que reside el PVC.APP_LABEL: la etiqueta que has aplicado a tu aplicación de contenedor.CONTAINER_NAME: el nombre del contenedor.HARBOR_INSTANCE_URL: la URL de la instancia de Harbor, comoharbor-1.org-1.zone1.google.gdc.test.. Para obtener la URL de la instancia de Harbor, consulta Ver instancias del registro de Harbor.HARBOR_PROJECT_NAME: el nombre del proyecto de Harbor, comomy-project.IMAGE: el nombre de la imagen, comonginx.TAG: la etiqueta de la versión de la imagen que quieras extraer, como1.0.MOUNT_PATH: la ruta dentro del pod para montar el volumen.PVC_NAME: el PVC que has creado.
Configurar la replicación de almacenamiento
Los universos multizona de GDC admiten la replicación de almacenamiento para la recuperación tras fallos. Esta estrategia proporciona replicación de datos entre dos zonas cualesquiera de la misma región, lo que garantiza que los datos de tu aplicación sigan accesibles aunque una zona deje de estar disponible.
Elige uno de los siguientes tipos de replicación de almacenamiento para tu aplicación de contenedor:
Crear un segmento de doble zona para el almacenamiento de objetos
Los datos de almacenamiento de objetos se escriben en un solo segmento cuyos datos se almacenan en ambas zonas. A diferencia de la replicación de volúmenes, los contenedores replicados se pueden escribir durante las particiones de zonas. Cada escritura en un objeto genera una versión diferente, y la versión más reciente de cualquiera de las zonas será el estado final una vez que se haya restaurado la conectividad.
Verifica que tu operador de infraestructura (IO) haya creado el recurso personalizado
BucketLocationConfig, que es necesario para la replicación entre zonas del almacenamiento de objetos. Este recurso debe desplegarse en el servidor de la API global raíz.Crea el recurso personalizado de doble zona
Bucket: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 EOFHaz los cambios siguientes:
GLOBAL_API_SERVER: el archivo kubeconfig del servidor de la API global.BUCKET_NAME: el nombre del segmento de almacenamiento.PROJECT: el nombre del proyecto en el que se encuentra el contenedor.LOCATION_NAME: el lugar físico donde residen los datos de los objetos del segmento. Debe corresponder al nombre de un recursoBucketLocation. Para consultar el servidor de la API global de tu organización y obtener una lista de recursosBucketLocationdisponibles, ejecutakubectl --kubeconfig GLOBAL_API_SERVER bucketlocations. Si no hay recursosBucketLocation, ponte en contacto con tu IO para verificar que ha habilitado la replicación.
Configurar la replicación de almacenamiento en bloque asíncrona entre zonas
El almacenamiento en bloques replicado proporciona volúmenes replicados de forma asíncrona (PVs), 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 montar mientras siga siendo el destino de la replicación, por lo que se requiere una 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 importante si usas almacenamiento en bloque para tu aplicación de contenedor.
Antes de empezar, comprueba 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 entre zonas. Este recurso
debe implementarse en el servidor de la API global raíz.
Crea un archivo YAML de recurso personalizado
VolumeReplicationRelationshipy despliega 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 EOFHaz los cambios siguientes:
GLOBAL_API_SERVER: archivo kubeconfig del servidor de la API global.PVC_REPL_NAME: el nombre de la relación de replicación de volúmenes.PROJECT: el proyecto en el que reside la infraestructura de almacenamiento.SOURCE_PVC_CLUSTER: el clúster de Kubernetes en el que se aloja el PVC.SOURCE_PVC: el PVC de la zona de origen que se va a replicar.SOURCE_ZONE: la zona de origen en la que se aloja el PVC.DEST_PVC_CLUSTER: el clúster de Kubernetes de destino en el que se replicará el PVC.DEST_ZONE: la zona de destino en la que se replicará el PVC.
Crea un recurso personalizado
VolumeFailoveren la zona de destino, que detendrá la replicación en la zona de destino si la zona de origen no está disponible por cualquier 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 EOFHaz los cambios siguientes:
MANAGEMENT_API_SERVER: archivo kubeconfig del servidor de la API Management zonal.PVC_FAILOVER_NAME: el nombre del PVC de conmutación por error.PROJECT: el proyecto en el que reside la infraestructura de almacenamiento.PVC_REPL_NAME: el nombre de la relación de replicación de volúmenes.
Siguientes pasos
- Cargas de trabajo de Kubernetes para alta disponibilidad
- Cargas de trabajo de contenedores en GDC
- Descripción general de las multizonas