Automatiza la administración de certificados TLS para la puerta de enlace de entrada de Cloud Service Mesh mediante Certificate Authority Service
En este instructivo, se muestra a los operadores de plataforma cómo usar el emisor de Certificate Authority Service (servicio de AC) para la herramienta cert-manager para automatizar la administración del certificado TLS para la puerta de enlace de entrada de Cloud Service Mesh. Los certificados permiten que la puerta de enlace de entrada finalice HTTPS y otro tráfico de TLS y mTLS que se origina en los clientes de la nube privada virtual (VPC), pero fuera de la malla de servicios. En el instructivo, se supone que estás familiarizado con los certificados de Kubernetes y TLS.
Introducción
Cloud Service Mesh aprovisiona certificados TLS para cada carga de trabajo en la malla de servicios. Estos certificados permiten la comunicación encriptada y TLS autenticada de forma mutua (mTLS) entre las cargas de trabajo en la malla de servicios. Una de las CA admitidas emite y firma los certificados.
Sin embargo, Cloud Service Mesh no aprovisiona de forma automática los certificados a la puerta de enlace de entrada para el tráfico que ingresa a la malla de servicios. Una solución común es usar la herramienta de código abierto cert-manager para automatizar la administración de los certificados de la puerta de enlace de entrada.
La herramienta cert-manager solicita certificados de una entidad emisora, que representa una autoridad certificadora (CA). Certificate Authority Service es un servicio de Google Cloud que te permite crear tu propia AC privada. La herramienta cert-manager puede solicitar certificados del servicio de CA mediante la entidad emisora externa para el servicio de CA de código abierto.
Una CA privada puede emitir certificados TLS que autentican y encriptan el tráfico dentro de una red interna. Las puertas de enlace de entrada de Cloud Service Mesh suelen configurarse para permitir el tráfico entrante de los clientes que se encuentran dentro de la VPC, pero fuera de la malla de servicios. En el tráfico de red interno, puedes usar una CA privada en el servicio de CA a fin de emitir certificados para la puerta de enlace de entrada.
En este instructivo, se muestra cómo configurar la herramienta cert-manager y el emisor del servicio de CA para automatizar el aprovisionamiento y la renovación de los certificados TLS para la puerta de enlace de entrada. La herramienta cert-manager aprovisiona certificados como recursos de Secret de Kubernetes de tipo TLS. Cuando la herramienta cert-manager renueva un certificado, actualiza el recurso secreto con un certificado nuevo. La puerta de enlace de entrada ejecuta el proxy de Envoy y admite el servicio de descubrimiento de secretos (SDS) de Envoy. El SDS permite que la puerta de enlace de entrada comience a usar un certificado nuevo sin necesidad de que un administrador reinicie o vuelva a cargar el proceso.
Los proxies de sidecar que forman parte de la malla pueden obtener certificados TLS de la autoridad certificadora de CA o de Cloud Service Mesh. En este instructivo, usarás el servicio de CA para los certificados de puerta de enlace de entrada y proxy. Esto te permite usar una CA raíz para todos los certificados TLS.
En el siguiente diagrama, se muestran los recursos que aprovisionarás en este instructivo.
Aprovisionas un balanceador de cargas de red de transferencia interno para la puerta de enlace de entrada. El balanceador de cargas de red de transferencia interno no es un proxy, por lo que no finaliza las conexiones TCP ni realiza protocolos de enlace TLS. En su lugar, enruta las conexiones a los Pods de la implementación istio-ingressgateway
.
El Secret hello-example-com-credential
contiene un certificado y una clave privada. La puerta de enlace hello
configura los Pods de la implementación istio-ingressgateway
a fin de usar este certificado y una clave privada para realizar protocolos de enlace TLS para las solicitudes con el nombre de host hello.example.com
.
Los pods de la implementación google-cas-issuer
en el espacio de nombres cert-manager
solicitan certificados de la CA que creas en el servicio de CA. Crea una vinculación de política de administración de identidades y accesos que permita que los Pods ca-service-isser
actúen en nombre de una cuenta de servicio de Google mediante Workload Identity Federation for GKE. Puedes otorgar a esta cuenta de servicio de Google el permiso para solicitar certificados de tu CA en el servicio de CA mediante la creación de una vinculación de política de IAM en tu grupo de CA.
Objetivos
- Configura el servicio de CA
- Cree un clúster de GKE
- Instala el plano de control de Cloud Service Mesh
- Instala la puerta de enlace de entrada
- Instala la herramienta cert-manager
- Instala el controlador de la entidad emisora del servicio de CA
- Crea una entidad emisora de certificados
- Implementa una aplicación de muestra
- Verifica la solución
- Agrega certificados de CA al almacén de confianza (opcional)
Costos
En este instructivo, se usan los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.
Cuando finalices este instructivo, podrás borrar los recursos creados para evitar que se te siga facturando. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
En la consola de Google Cloud, ve a la página de selección de proyecto y, luego, selecciona o crea un proyecto.
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
En la consola de Google Cloud ve a Cloud Shell.
En la parte inferior de la consola de Google Cloud, se abre una sesión de Cloud Shell que muestra una ventana emergente con una línea de comandos. Usa Cloud Shell para ejecutar todos los comandos de este instructivo.
Configura el proyecto de la consola de Google Cloud que deseas usar para este instructivo:
gcloud config set core/project PROJECT_ID
Reemplaza PROJECT_ID por el ID del proyecto de tu proyecto de Cloud.
En el diálogo Autorizar Cloud Shell, haz clic en Autorizar. Si haces clic en Autorizar, permites que los comandos
gcloud
que ejecutas en Cloud Shell usen tus credenciales de usuario para autenticarse en las API de Google.Habilita Resource Manager, GKE, GKE Hub, la autoridad certificadora de Cloud Service Mesh y las APIs del servicio de AC:
gcloud services enable \ cloudresourcemanager.googleapis.com \ container.googleapis.com \ gkehub.googleapis.com \ meshca.googleapis.com \ privateca.googleapis.com
Configura el servicio de CA
En esta sección, crearás una CA raíz y dos CA subordinadas en un servicio de CA. Una CA subordinada emite certificados a la puerta de enlace de entrada y la otra CA subordina emite certificados a los proxies de sidecar en la malla.
A fin de hacerlo más simple, en este instructivo, usas el mismo proyecto para el clúster de GKE y las CA subordinadas y de raíz. En tu propio entorno, puedes usar un proyecto diferente para el clúster de GKE y las CA.
En Cloud Shell, crea un grupo de CA para usar con la CA raíz:
gcloud privateca pools create ROOT_CA_POOL \ --location CA_LOCATION \ --tier enterprise
- ROOT_CA_POOL es el nombre del grupo de CA. Por ejemplo,
root-ca-pool-tutorial
- CA_LOCATION es la ubicación del grupo de CA. Por ejemplo,
us-central1
.
Puedes enumerar las ubicaciones del Servicio de CA disponibles mediante este comando:
gcloud privateca locations list
- ROOT_CA_POOL es el nombre del grupo de CA. Por ejemplo,
Crea y habilita una CA raíz:
gcloud privateca roots create ROOT_CA \ --auto-enable \ --key-algorithm ec-p384-sha384 \ --location CA_LOCATION \ --pool ROOT_CA_POOL \ --subject "CN=Example Root CA, O=Example Organization" \ --use-preset-profile root_unconstrained
- ROOT_CA es el nombre que deseas usar para la CA raíz. Por ejemplo,
root-ca-tutorial
- ROOT_CA es el nombre que deseas usar para la CA raíz. Por ejemplo,
Crea un grupo de CA para usar con la CA subordinada que emite certificados a la puerta de enlace de entrada:
gcloud privateca pools create SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --tier devops
- SUBORDINATE_CA_POOL_GATEWAYS es el nombre del grupo de CA. Por ejemplo,
subordinate-ca-mtls-pool-gateways-tutorial
- SUBORDINATE_CA_POOL_GATEWAYS es el nombre del grupo de CA. Por ejemplo,
Crea y habilita la CA subordinada que emite certificados a la puerta de enlace de entrada:
gcloud privateca subordinates create SUBORDINATE_CA_GATEWAYS \ --auto-enable \ --issuer-location CA_LOCATION \ --issuer-pool ROOT_CA_POOL \ --key-algorithm ec-p256-sha256 \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_GATEWAYS \ --subject "CN=Example Gateway mTLS CA, O=Example Organization" \ --use-preset-profile subordinate_mtls_pathlen_0
- SUBORDINATE_CA_GATEWAYS es el nombre que deseas usar para la CA subordinada. Por ejemplo,
subordinate-ca-mtls-gateways-tutorial
- La marca
--use-preset-profile
configura la CA subordinada para usar el perfil de certificado Subordinada mTLS. Este perfil permite que la CA subordinada emita certificados TLS de cliente y de servidor para mTLS.
Si deseas que la puerta de enlace de entrada use una TLS simple en lugar de mTLS, la CA subordinada solo necesita emitir certificados TLS del servidor. En este caso, puedes usar el perfil de certificado TLS subordinado (
subordinate_server_tls_pathlen_0
).- SUBORDINATE_CA_GATEWAYS es el nombre que deseas usar para la CA subordinada. Por ejemplo,
Crea una política de emisión de certificado:
cat << EOF > policy.yaml baselineValues: keyUsage: baseKeyUsage: digitalSignature: true keyEncipherment: true extendedKeyUsage: serverAuth: true clientAuth: true caOptions: isCa: false identityConstraints: allowSubjectPassthrough: false allowSubjectAltNamesPassthrough: true celExpression: expression: subject_alt_names.all(san, san.type == URI && san.value.startsWith("spiffe://PROJECT_ID.svc.id.goog/ns/") ) EOF
Esta política de emisión restringe las CA a fin de que solo emitan certificados para cargas de trabajo en la malla.
Crea un grupo de CA para usarlo con la CA subordinada que emite certificados a los proxies de sidecar en la malla. Aplica la política de emisión al grupo de CA:
gcloud privateca pools create SUBORDINATE_CA_POOL_SIDECARS \ --issuance-policy policy.yaml \ --location CA_LOCATION \ --tier devops
- SUBORDINATE_CA_POOL_SIDECARS es el nombre del grupo de CA. Por ejemplo,
subordinate-ca-mtls-pool-sidecars-tutorial
- SUBORDINATE_CA_POOL_SIDECARS es el nombre del grupo de CA. Por ejemplo,
Crea y habilita la CA subordinada que emite certificados a los proxies de sidecar en la malla:
gcloud privateca subordinates create SUBORDINATE_CA_SIDECARS \ --auto-enable \ --issuer-location CA_LOCATION \ --issuer-pool ROOT_CA_POOL \ --key-algorithm ec-p256-sha256 \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_SIDECARS \ --subject "CN=Example Sidecar mTLS CA, O=Example Organization" \ --use-preset-profile subordinate_mtls_pathlen_0
- SUBORDINATE_CA_GATEWAYS es el nombre que deseas usar para la CA subordinada. Por ejemplo,
subordinate-ca-mtls-sidecars-tutorial
- SUBORDINATE_CA_GATEWAYS es el nombre que deseas usar para la CA subordinada. Por ejemplo,
Cree un clúster de Google Kubernetes Engine
En Cloud Shell, crea un clúster de GKE:
gcloud container clusters create CLUSTER_NAME \ --enable-ip-alias \ --num-nodes 4 \ --release-channel regular \ --scopes cloud-platform \ --workload-pool PROJECT_ID.svc.id.goog \ --zone ZONE
Reemplaza CLUSTER_NAME por la zona que deseas usar para el clúster. Por ejemplo,
asm-ingress-cert-manager-ca-service
Reemplaza ZONE por la zona que deseas usar para el clúster. Por ejemplo,
us-central1-f
Ten en cuenta lo siguiente sobre el comando:
- La marca
--release-channel
selecciona el canal de versiones de GKE para el clúster. - Cloud Service Mesh y la entidad emisora del servicio de AC para la herramienta cert-manager requieren que establezcas el permiso
cloud-platform
en los nodos del clúster. - El argumento
--workload-pool
habilita la federación de identidades para cargas de trabajo para GKE, que permite que la cuenta de servicio de Kubernetes del emisor del servicio de AC actúe en nombre de una cuenta de servicio de Google. Esta suplantación significa que los Pods de la entidad emisora de la CA pueden acceder a la API sin que se descargue un archivo de claves para la cuenta de servicio de Google.
- La marca
Otorga permisos de administrador de clúster a tu cuenta de usuario:
kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole cluster-admin \ --user $(gcloud config get-value core/account)
Necesitas los permisos que proporciona el ClusterRole
cluster-admin
de Kubernetes para crear las reglas de control de acceso basado en funciones (RBAC) para Cloud Service Mesh y para instalar el cert-manager.
Instala el plano de control de Anthos Service Mesh
En este instructivo, instalarás Cloud Service Mesh administrado para un clúster de GKE en Google Cloud, con todos los recursos en un proyecto. En tu propio entorno, puedes aplicar la solución que se describe en este documento mediante Cloud Service Mesh administrado o un plano de control en el clúster.
Cloud Service Mesh proporciona una variedad de opciones de instalación para diferentes situaciones. Después de completar este instructivo, te recomendamos que revises las guías de instalación para seleccionar la opción que mejor se adapte a tu entorno.
En Cloud Shell, descarga la herramienta de instalación
asmcli
:curl --location --output asmcli https://storage.googleapis.com/csm-artifacts/asm/asmcli_1.23 chmod +x asmcli
Usa
asmcli
para instalar el plano de control de Cloud Service Mesh.Instala el plano de control de Cloud Service Mesh:
./asmcli install \ --ca gcp_cas \ --ca_pool projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_SIDECARS \ --cluster_location ZONE \ --cluster_name CLUSTER_NAME \ --enable_all \ --enable_registration \ --fleet_id PROJECT_ID \ --managed \ --output_dir asm-files \ --project_id PROJECT_ID \ --verbose
Las marcas
--ca gcp_cas
y--ca_pool
configuran el plano de control de Cloud Service Mesh para usar el grupo de AC de sidecar en el servicio de AC para emitir certificados a los proxies de sidecar en la malla.La marca
--enable_registration
registra el clúster de GKE en la flota del proyecto que especifica la marca--fleet_id
. En este instructivo, el clúster de GKE y la flota usan el mismo proyecto.La marca
--managed
configura un plano de control de Cloud Service Mesh administrado.La marca
--output_dir
especifica un directorio queasmcli
usa para descargar archivos y parámetros de configuración necesarios para instalar Cloud Service Mesh. Usa estos archivos más adelante en el instructivo.
La instalación tarda varios minutos. Cuando se complete la instalación, verás el siguiente resultado:
asmcli: Successfully installed ASM.
Instala la puerta de enlace de entrada
En Cloud Shell, crea un espacio de nombres de Kubernetes para la puerta de enlace de entrada:
kubectl create namespace GATEWAY_NAMESPACE
- GATEWAY_NAMESPACE es el nombre del espacio de nombres que deseas usar para la puerta de enlace de entrada. Por ejemplo,
istio-ingress
- GATEWAY_NAMESPACE es el nombre del espacio de nombres que deseas usar para la puerta de enlace de entrada. Por ejemplo,
Reserva una dirección IP interna estática para usar en el balanceador de cargas de red de transferencia interno de la puerta de enlace de entrada:
LOAD_BALANCER_IP=$(gcloud compute addresses create \ asm-ingress-gateway-ilb \ --region REGION \ --subnet default \ --format 'value(address)')
- Reemplaza REGION por la región que contiene las zonas que usan los nodos del clúster de GKE. Por ejemplo, si tu clúster usa la zona
us-central1-f
, reemplaza REGION porus-central1
.
Mediante este comando, se reserva una dirección IP de la subred predeterminada en la región que especificas.
- Reemplaza REGION por la región que contiene las zonas que usan los nodos del clúster de GKE. Por ejemplo, si tu clúster usa la zona
Crea un manifiesto del operador para la puerta de enlace de entrada:
cat << EOF > ingressgateway-operator.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: ingressgateway-operator annotations: config.kubernetes.io/local-config: "true" spec: profile: empty revision: asm-managed components: ingressGateways: - name: istio-ingressgateway namespace: GATEWAY_NAMESPACE enabled: true k8s: overlays: - apiVersion: apps/v1 kind: Deployment name: istio-ingressgateway patches: - path: spec.template.metadata.annotations value: inject.istio.io/templates: gateway - path: spec.template.metadata.labels.sidecar\.istio\.io/inject value: "true" - path: spec.template.spec.containers[name:istio-proxy] value: name: istio-proxy image: auto service: loadBalancerIP: $LOAD_BALANCER_IP serviceAnnotations: networking.gke.io/load-balancer-type: Internal networking.gke.io/internal-load-balancer-allow-global-access: "true" EOF
Ten en cuenta lo siguiente sobre el manifiesto del operador:
En el campo
revision
, se especifica el canal de versiones administrado de Cloud Service Mesh que se usará para el plano de datos. Cambia el valor de este campo si usas los canales de versiones rápidos o estables para el plano de control.Los valores
annotation
,label
yimage
especificados en la secciónoverlays
habilitan la inserción automática de la configuración del proxy para la implementación de la puerta de enlace de entrada.El campo
loadBalancerIP
especifica la dirección IP que se usará para el balanceador de cargas. Si quitas este campo del manifiesto, el balanceador de cargas usa una dirección IP efímera.La anotación del servicio
networking.gke.io/load-balancer-type: Internal
en la puerta de enlace de entrada significa que GKE aprovisiona un balanceador de cargas de red de transferencia interno frente a los pods de la puerta de enlace de entrada. Si quitas esta anotación, GKE aprovisiona un balanceador de cargas de red de transferencia externo.La anotación del servicio opcional
networking.gke.io/internal-load-balancer-allow-global-access: "true"
permite que los clientes de cualquier región de la VPC accedan al balanceador de cargas de red de transferencia interno. Si quitas esta anotación, el balanceador de cargas de red de transferencia interno solo acepta tráfico de clientes en la misma región de tu VPC.
Crea el manifiesto de instalación de la puerta de enlace de entrada con el manifiesto del operador y la herramienta
istioctl
que descargó la secuencia de comandosasmcli
cuando instalaste el plano de control:./asm-files/istioctl manifest generate \ --filename ingressgateway-operator.yaml \ --output ingressgateway
Instala la puerta de enlace de entrada:
kubectl apply --recursive --filename ingressgateway/
Instala la herramienta cert-manager
En Cloud Shell, descarga y aplica el manifiesto de instalación de la herramienta cert-manager:
CERT_MANAGER_VERSION=v1.5.4 curl --location --output cert-manager.yaml "https://github.com/jetstack/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml" kubectl apply --filename cert-manager.yaml
La instalación de la herramienta cert-manager tarda aproximadamente un minuto en completarse.
Instala el controlador de la entidad emisora del servicio de CA
El controlador de la entidad emisora del Servicio de AC permite que la herramienta cert-manager solicite certificados mediante el servicio de AC. El controlador usa el mecanismo de extensión de la entidad emisora externa de la herramienta de cert-manager.
En Cloud Shell, crea una cuenta de servicio de Google:
gcloud iam service-accounts create CAS_ISSUER_GSA \ --display-name "CA Service issuer for cert-manager"
- CAS_ISSUER_GSA es el nombre de la cuenta de servicio de Google. Por ejemplo,
cert-manager-ca-service-issuer
El controlador de la entidad emisora de Certificate Authority Service usa esta cuenta de servicio de Google para autenticarse en las API de Certificate Authority Service.
- CAS_ISSUER_GSA es el nombre de la cuenta de servicio de Google. Por ejemplo,
Crea una vinculación de políticas de administración de identidades y accesos que permita que la cuenta de servicio de controlador de Certificate Authority Service solicite los certificados del grupo de CA que contenga la CA subordinada:
gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/privateca.certificateRequester
Descarga el manifiesto de instalación del controlador de la entidad emisora de Certificate Authority Service:
CAS_ISSUER_VERSION=v0.5.3 curl --location --output ca-service-issuer.yaml "https://github.com/jetstack/google-cas-issuer/releases/download/${CAS_ISSUER_VERSION}/google-cas-issuer-${CAS_ISSUER_VERSION}.yaml"
Crea una vinculación de política de IAM para permitir que la cuenta de servicio de Kubernetes
ksa-google-cas-issuer
en el espacio de nombrescert-manager
actúe en nombre de la cuenta de servicio de Google (GSA) mediante la federación de identidades para cargas de trabajo para GKE:gcloud iam service-accounts add-iam-policy-binding \ CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \ --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \ --role roles/iam.workloadIdentityUser
Los Pods del controlador de la entidad emisora de servicios de CA usan la cuenta de servicio de Kubernetes
ksa-google-cas-issuer
.Instala el controlador de entidad emisora del servicio de CA en tu clúster de GKE:
kubectl apply --filename ca-service-issuer.yaml
Agrega la anotación
iam.gke.io/gcp-service-account
de Workload Identity Federation for GKE a la cuenta de servicio de Kubernetes que usan los Pods del controlador de la entidad emisora del servicio de AC:kubectl annotate serviceaccount ksa-google-cas-issuer --namespace cert-manager \ "iam.gke.io/gcp-service-account=CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com"
Esta anotación informa a GKE que la cuenta de servicio de Kubernetes puede actuar en nombre de una cuenta de servicio de Google para acceder a las API de Google.
Crea una entidad emisora de certificados
En Cloud Shell, crea y aplica un manifiesto de GoogleCASIssuer:
cat << EOF > gateway-cas-issuer.yaml apiVersion: cas-issuer.jetstack.io/v1beta1 kind: GoogleCASIssuer metadata: name: gateway-cas-issuer namespace: GATEWAY_NAMESPACE spec: caPoolId: SUBORDINATE_CA_POOL_GATEWAYS location: CA_LOCATION project: PROJECT_ID EOF kubectl apply --filename gateway-cas-issuer.yaml
La entidad emisora permite que la herramienta cert-manager aprovisione los certificados del grupo de CA subordinado en tu espacio de nombres de la puerta de enlace de entrada.
Implementar una aplicación de muestra
En esta sección, debes verificar que la herramienta cert-manager pueda usar la entidad emisora del servicio de CA para obtener certificados del servicio de CA. Para verificar, debes implementar una aplicación de muestra con configuración de enrutamiento de solicitudes y un certificado para la puerta de enlace de entrada.
En Cloud Shell, crea un espacio de nombres para los recursos de la aplicación de ejemplo:
cat << EOF > sample-app-namespace.yaml apiVersion: v1 kind: Namespace metadata: name: APP_NAMESPACE annotations: mesh.cloud.google.com/proxy: '{"managed":"true"}' labels: istio.io/rev: asm-managed EOF kubectl apply --filename sample-app-namespace.yaml
- APP_NAMESPACE es el nombre del espacio de nombres para la aplicación de ejemplo. Por ejemplo,
sample-app
La anotación
mesh.cloud.google.com/proxy
habilita el plano de datos administrado para el espacio de nombres.La etiqueta
istio.io/rev: asm-managed
selecciona el canal de versiones regular para el plano de datos administrado en el espacio de nombres de la aplicación de muestra. Cambia el valor de esta etiqueta si usas los canales de versiones rápidos o estables.- APP_NAMESPACE es el nombre del espacio de nombres para la aplicación de ejemplo. Por ejemplo,
Crea un recurso de implementación para la aplicación de ejemplo:
cat << EOF > deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hello namespace: APP_NAMESPACE labels: app: hello spec: replicas: 1 selector: matchLabels: app: hello template: metadata: labels: app: hello spec: containers: - image: gcr.io/google-samples/hello-app:1.0 name: hello-app ports: - containerPort: 8080 EOF kubectl apply --filename deployment.yaml
Crea un recurso de Service para la aplicación de ejemplo:
cat << EOF > service.yaml apiVersion: v1 kind: Service metadata: name: SERVICE_NAME namespace: APP_NAMESPACE spec: ports: - name: http-hello port: 8080 selector: app: hello type: ClusterIP EOF kubectl apply --filename service.yaml
- SERVICE_NAME es el nombre del servicio. Por ejemplo,
hello
.
- SERVICE_NAME es el nombre del servicio. Por ejemplo,
Crea un recurso de certificado para el nombre de dominio
hello.example.com
con la entidad emisora del certificado:cat << EOF > certificate.yaml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: hello-example-com-certificate namespace: GATEWAY_NAMESPACE spec: secretName: hello-example-com-credential commonName: hello.example.com dnsNames: - hello.example.com duration: 24h renewBefore: 8h issuerRef: group: cas-issuer.jetstack.io kind: GoogleCASIssuer name: gateway-cas-issuer EOF kubectl apply --filename certificate.yaml
El espacio de nombres del certificado debe coincidir con el espacio de nombres de la puerta de enlace de entrada. Por lo general, solo los administradores de la plataforma pueden cambiar los recursos en este espacio de nombres, ya que los cambios pueden afectar a toda la malla de servicios. La herramienta cert-manager crea el recurso secreto para el certificado TLS en el mismo espacio de nombres. Esto significa que los administradores de la aplicación no necesitan tener acceso al espacio de nombres de la puerta de enlace de entrada.
Puedes agregar nombres de host adicionales en la lista
dnsNames
del certificado. Estos nombres de host se incluyen en el certificado como Nombres alternativos de sujeto (SAN).Crea un recurso Gateway para la aplicación de ejemplo:
cat << EOF > gateway.yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: GATEWAY_NAME namespace: GATEWAY_NAMESPACE spec: selector: istio: ingressgateway servers: - hosts: - APP_NAMESPACE/hello.example.com port: name: https-hello number: 443 protocol: HTTPS tls: credentialName: hello-example-com-credential mode: MUTUAL EOF kubectl apply --filename gateway.yaml
- GATEWAY_NAME es el nombre de la puerta de enlace. Por ejemplo,
hello
- El campo
credentialName
en la puerta de enlace coincide con el camposecretName
en el certificado. La herramienta cert-manager crea un secreto de Kubernetes con el certificado TLS del servicio de CA. Este certificado permite que la puerta de enlace de entrada finalice el tráfico de TLS destinado ahello.example.com
.
El manifiesto de Gateway especifica TLS (mTLS) MUTUAL. Si deseas configurar la puerta de enlace para TLS normal, establece el modo TLS de la puerta de enlace en
SIMPLE
.- GATEWAY_NAME es el nombre de la puerta de enlace. Por ejemplo,
Crea un recurso VirtualService para la aplicación de ejemplo:
cat << EOF > virtual-service.yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: hello namespace: APP_NAMESPACE spec: hosts: - hello.example.com gateways: - GATEWAY_NAMESPACE/GATEWAY_NAME http: - route: - destination: host: SERVICE_NAME port: number: 8080 EOF kubectl apply --filename virtual-service.yaml
El objeto Gateway y VirtualService usan diferentes espacios de nombres. En este patrón común, se restringen los cambios al enrutamiento basado en el host en Gateway a los administradores de la plataforma que tienen permisos para cambiar recursos en el espacio de nombres de la puerta de enlace de entrada.
Los administradores de aplicaciones con permisos para editar el VirtualService en el espacio de nombres de la aplicación de ejemplo pueden cambiar el enrutamiento por otros campos de solicitud, como la ruta de URL, sin coordinar con los administradores de la plataforma.
Si deseas explorar otras opciones de configuración, lee la documentación de la API para los recursos de Certificate, Gateway y VirtualService.
Puedes aplicar políticas de autenticación y autorización al tráfico que ingresa a la malla de servicios a través de la puerta de enlace de entrada. Para ello, lee la documentación de las APIs de PeerAuthentication y AuthorizationPolicy de Istio.
Verifica la solución
En esta sección, verificarás que puedas enviar solicitudes HTTPS mediante mTLS a la aplicación de ejemplo desde fuera de la malla de servicios. Para verificar, creas una instancia de VM de Compute Engine, solicitas un certificado TLS de cliente desde el Servicio de CA y usas este certificado a fin de autenticar la solicitud en la aplicación de ejemplo.
Necesitas acceso SSH a la instancia de VM. La red predeterminada incluye una regla de firewall que permite el acceso SSH. Si no tienes acceso SSH, sigue la documentación de reglas de firewall para crear una regla de firewall que permita conexiones TCP entrantes en el puerto 22.
En Cloud Shell, crea una cuenta de servicio de Google:
gcloud iam service-accounts create CLIENT_VM_GSA \ --display-name "CA Service tutorial VM instance service account"
- CLIENT_VM_GSA es el nombre de la cuenta de servicio de Google. Por ejemplo,
cas-tutorial-client
Debes asignar esta cuenta de servicio de Google a la instancia de VM de Compute Engine.
- CLIENT_VM_GSA es el nombre de la cuenta de servicio de Google. Por ejemplo,
Otorga el rol Solicitante del certificado de servicio de CA en las puertas de enlace subordinadas del grupo de CA a la cuenta de servicio de Google:
gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/privateca.certificateRequester
Este rol proporciona permisos para solicitar certificados del grupo de CA.
Crea una instancia de VM de Compute Engine en la misma VPC que el clúster de GKE:
gcloud compute instances create cas-tutorial-client \ --scopes cloud-platform \ --service-account CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com \ --zone ZONE
La instancia de VM requiere el permiso
cloud-platform
para acceder a la API del servicio de CA.Guarda la dirección IP del balanceador de cargas de red de transferencia interno de la puerta de enlace de entrada en un archivo:
kubectl get services istio-ingressgateway \ --namespace GATEWAY_NAMESPACE \ --output jsonpath='{.status.loadBalancer.ingress[0].ip}' > ilb-ip.txt
Guarda el certificado de clave pública de la CA raíz en un archivo:
gcloud privateca roots describe ROOT_CA \ --location CA_LOCATION \ --pool ROOT_CA_POOL \ --format 'value(pemCaCertificates)' > root-ca-cert.pem
Copia el certificado de AC raíz y el archivo que contiene la dirección IP del balanceador de cargas de red de transferencia interna de la puerta de enlace de entrada en la instancia de VM:
gcloud compute scp root-ca-cert.pem ilb-ip.txt cas-tutorial-client:~ \ --zone ZONE
Conéctate a la instancia de VM mediante SSH:
gcloud compute ssh cas-tutorial-client --zone ZONE
Ejecuta el resto de los comandos en esta sección desde la sesión de SSH.
Instala los paquetes
ca-certificates
ycoreutils
, y las herramientas de línea de comandos decurl
,openssl
yjq
:sudo apt-get update --yes sudo apt-get install --yes ca-certificates coreutils curl jq openssl
Crea un par de claves para el certificado TLS de cliente:
openssl genrsa -out private-key.pem 2048 openssl rsa -in private-key.pem -pubout -out public-key.pem
Consulta el servidor de metadatos para obtener la dirección de correo electrónico de la identidad de la cuenta de servicio de Google conectada a la instancia de VM:
GSA_EMAIL=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email)
Crea un archivo JSON que uses como cuerpo de la solicitud cuando solicites un certificado TLS de cliente de la API de Certificate Authority Service:
cat << EOF > request.json { "config": { "publicKey": { "format": "PEM", "key": "$(base64 --wrap 0 public-key.pem)" }, "subjectConfig": { "subject": { "commonName": "$(hostname --short)", "organization": "Example Organization" }, "subjectAltName": { "dnsNames": [ "$(hostname --fqdn)" ], "emailAddresses": [ "$GSA_EMAIL" ] } }, "x509Config": { "caOptions": { "isCa": false }, "keyUsage": { "baseKeyUsage": { "digitalSignature": true, "keyEncipherment": true }, "extendedKeyUsage": { "clientAuth": true } } } }, "lifetime": "86400s" } EOF
Para obtener más información sobre los campos de la sección de configuración, consulta el tipo
CertificateConfig
en la documentación de la API del servicio de CA.Solicita un token de acceso de OAuth 2.0 al servidor de metadatos:
TOKEN=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq --raw-output ".access_token")
Este token de acceso proporciona los permisos otorgados a la cuenta de servicio de Google adjunta a la instancia de VM.
Solicita un certificado TLS de cliente a la API del servicio de CA y almacena el cuerpo de la respuesta en un archivo:
curl --silent --request POST \ --header "Authorization: Bearer $TOKEN" \ --header "Content-Type: application/json" \ --data @request.json \ --output response.json \ "https://privateca.googleapis.com/v1/projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_GATEWAYS/certificates"
El comando usa el token de acceso para autenticar la solicitud a la API.
Guarda el certificado de cliente y la cadena de certificados en un archivo:
jq --raw-output --join-output ".pemCertificate , .pemCertificateChain[]" response.json > client-cert-chain.pem
Usa
curl
para enviar una solicitud HTTPS desde la instancia de VM a la aplicación de ejemplo:curl --cert client-cert-chain.pem --key private-key.pem \ --cacert root-ca-cert.pem \ --resolve hello.example.com:443:$(cat ilb-ip.txt) \ --silent https://hello.example.com | head -n1
El resultado se verá así:
Hello, world!
Esta respuesta muestra que
curl
envió correctamente la solicitud HTTPS mediante mTLS. La aplicación de muestra respondió con el mensaje que ves en el resultado de la terminal.El comando
curl
realiza lo siguiente:Las marcas
--cert
y--key
le indican acurl
que use el certificado TLS del cliente y la clave privada para autenticar la solicitud. El archivo de certificado del cliente contiene la cadena completa de certificados, desde el certificado de cliente hasta la CA raíz.La marca
--cacert
indica acurl
que verifique que la CA raíz que creaste en este instructivo o una de sus CA subordinadas emitió el certificado de servidor.Si omites esta marca,
curl
intenta verificar el certificado del servidor con el paquete de AC predeterminado del sistema operativo, como el paqueteca-certificates
en Debian. La verificación falla porque el paquete de CA predeterminado no incluye la CA raíz que creaste en este instructivo.La marca
--resolve
indica acurl
que use la dirección IP del balanceador de cargas de red de transferencia interno como el destino para las solicitudes de hosthello.example.com
en el puerto 443.Si omites esta marca,
curl
intenta usar DNS para resolver el nombre de hosthello.example.com
. La resolución de DNS falla porque no hay una entrada de DNS para este nombre de host.En tu propio entorno, te recomendamos que crees un registro A de DNS que apunte a la dirección IP del balanceador de cargas de red de transferencia interno (
$LOAD_BALANCER_IP
). Para crear este registro mediante Cloud DNS, sigue la documentación sobre administración de registros.La marca
--silent
suprime los informes de progreso de descarga de respuesta en la salida de la terminal.El comando canaliza el resultado de curl a
head -n1
. El resultado es que el resultado en la terminal solo incluye la primera línea del cuerpo de la respuesta.
Sal de la sesión de SSH:
exit
En esta sección, solicitaste un certificado TLS del cliente directamente desde la API del servicio de CA. En la situación en la que el cliente es la puerta de enlace de salida de otra malla de servicios en un clúster de Kubernetes separado, puedes usar la herramienta cert-manager y el emisor del servicio de autoridad certificada con la misma CA raíz para proporcionar certificados de cliente a la puerta de enlace de salida.
En otras situaciones, puedes usar herramientas como Hashicorp Vault, Terraform o gcloud
a fin de solicitar certificados TLS de cliente para cargas de trabajo fuera de la malla de servicios. Para obtener más información, consulta la documentación del servicio de CA a fin de obtener soluciones de muestra y la documentación gcloud
para el servicio de CA.
Agrega certificados de CA al almacén de confianza (opcional)
En esta sección opcional, se muestra cómo agregar certificados de CA al almacén de certificados de CA de confianza para la distribución de Linux en Debian. Estas instrucciones también se aplican a las distribuciones derivadas de Debian, como Ubuntu.
Agregar tus certificados de CA a este almacén significa que no necesitas especificar la ubicación de los certificados de CA de confianza cuando envías solicitudes HTTPS mediante curl
, Python, Go y Ruby.
Conéctate a la instancia de VM mediante SSH:
gcloud compute ssh cas-tutorial-client --zone ZONE
Ejecuta el resto de los comandos en esta sección desde la sesión de SSH.
Copia el certificado de CA raíz en el directorio
/usr/local/share/ca-certificates
y asegúrate de que el archivo tenga la extensión.crt
:sudo cp root-ca-cert.pem /usr/local/share/ca-certificates/cas-rootca.crt
Configura los permisos del archivo para que todos los usuarios puedan leer el archivo del certificado de CA raíz:
sudo chmod 644 /usr/local/share/ca-certificates/cas-rootca.crt
Ejecuta la secuencia de comandos
update-ca-certificates
:sudo update-ca-certificates
Esta secuencia de comandos agrega el certificado al conjunto de certificados de confianza en el directorio
/etc/ssl/certs
y en el archivo/etc/ssl/certs/ca-certificates.crt
.Este es el resultado:
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done.
Usa
curl
para enviar una solicitud HTTPS desde la instancia de VM a la aplicación de ejemplo:curl --cert client-cert-chain.pem --key private-key.pem \ --resolve hello.example.com:443:$(cat ilb-ip.txt) \ --silent https://hello.example.com | head -n1
El resultado se verá así:
Hello, world!
Esta respuesta muestra que
curl
envió correctamente la solicitud HTTPS con mTLS y validó el certificado TLS del servidor desde la puerta de enlace de entrada mediante el almacén de certificados de CA predeterminado.Sal de la sesión de SSH:
exit
Solucionar problemas
Si el controlador de la entidad emisora del servicio de CA no crea el secreto de certificado TLS, consulta los registros del controlador de entidades emisora del servicio de CA:
kubectl logs deployment/google-cas-issuer --namespace cert-manager
Si tienes problemas para instalar Cloud Service Mesh, ejecuta la herramienta de asmcli
para validar tu proyecto de Cloud y el clúster de GKE.
Si tienes otros problemas con este instructivo, te recomendamos que revises los siguientes documentos:
- Preguntas frecuentes sobre el Servicio de CA
- Solución de problemas de Cloud Service Mesh paso a paso
- Resuelve problemas de Cloud Service Mesh administrado
- Problemas comunes de las operaciones de Istio
- Solución de problemas de GKE
- Solución de problemas de los clústeres de Kubernetes
Limpia
Para evitar que se apliquen cargos continuos a tu cuenta de Google Cloud por los recursos que se usaron en este instructivo, puedes borrar el proyecto o borrar los recursos individuales.
Borra el proyecto
En Cloud Shell, borra el proyecto:
gcloud projects delete PROJECT_ID
Borra recursos
Si deseas conservar el proyecto de Google Cloud que usaste en este instructivo, borra los recursos individuales:
En Cloud Shell, anula el registro del clúster de GKE desde GKE Hub:
gcloud container hub memberships unregister CLUSTER_NAME \ --gke-cluster ZONE/CLUSTER_NAME
Borra el clúster de GKE:
gcloud container clusters delete CLUSTER_NAME \ --zone ZONE --async --quiet
Borra las vinculaciones de políticas de IAM en el grupo de CA subordinado:
gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/privateca.certificateRequester gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \ --location CA_LOCATION \ --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/privateca.certificateRequester
Inhabilita y programa la eliminación de las CA subordinadas y la CA raíz:
gcloud privateca subordinates disable SUBORDINATE_CA_GATEWAYS \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_GATEWAYS \ --quiet gcloud privateca subordinates delete SUBORDINATE_CA_GATEWAYS \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_GATEWAYS \ --ignore-active-certificates \ --quiet gcloud privateca subordinates disable SUBORDINATE_CA_SIDECARS \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_SIDECARS \ --quiet gcloud privateca subordinates delete SUBORDINATE_CA_SIDECARS \ --location CA_LOCATION \ --pool SUBORDINATE_CA_POOL_SIDECARS \ --ignore-active-certificates \ --quiet gcloud privateca roots disable ROOT_CA \ --location CA_LOCATION \ --pool ROOT_CA_POOL \ --quiet gcloud privateca roots delete ROOT_CA \ --location CA_LOCATION \ --pool ROOT_CA_POOL \ --ignore-active-certificates \ --quiet
Borra la vinculación de políticas de IAM para la cuenta de servicio de Google del controlador de la entidad emisora de servicios de CA:
gcloud iam service-accounts remove-iam-policy-binding \ CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \ --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \ --role roles/iam.workloadIdentityUser
Borra las cuentas de servicio de Google:
gcloud iam service-accounts delete --quiet \ CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com gcloud iam service-accounts delete --quiet \ CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com
Borra la dirección IP del balanceador de cargas reservado:
gcloud compute addresses delete asm-ingress-gateway-ilb \ --region REGION --quiet
Borra la instancia de VM de Compute Engine:
gcloud compute instances delete cas-tutorial-client \ --zone ZONE --quiet
¿Qué sigue?
- Explora otras guías prácticas de Certificate Authority Service.
- Obtén más información sobre Cloud Service Mesh, un conjunto de herramientas basadas en Istio que te ayuda a supervisar y administrar una malla de servicios confiable de forma local y en Google Cloud.
- Explora las guías prácticas de Cloud Service Mesh.