Configurar una malla de servicios de sidecar de Envoy
Esta configuración es compatible con los clientes de la versión preliminar, pero no la recomendamos para los usuarios nuevos de Cloud Service Mesh. Para obtener más información, consulta la descripción general de Cloud Service Mesh.
En esta guía, se muestra cómo configurar una malla de servicios simple en tu flota. La guía incluye los siguientes pasos:
- Implementar el inyector de sidecar de Envoy en el clúster. El inyector inserta el contenedor del proxy de Envoy en los Pods de la aplicación.
- Implementar recursos de la API de puerta de enlace que configuren el archivo adicional de Envoy en la malla de servicios para enrutar solicitudes a un servicio de ejemplo en el espacio de nombres
store
- Implementar un cliente simple para verificar la implementación.
En el diagrama siguiente, se muestra la malla de servicios configurada.
Puedes configurar solo un Mesh
en un clúster, porque el nombre de la malla en la configuración del inyector de sidecar y el nombre del recurso Mesh
deben ser idénticos.
Implementa el inyector de sidecar de Envoy
Para implementar el inyector de sidecar, haz lo siguiente:
Configura la información del proyecto
# The project that contains your GKE cluster. export CLUSTER_PROJECT_ID=
YOUR_CLUSTER_PROJECT_NUMBER_HERE # The name of your GKE cluster. export CLUSTER=YOUR_CLUSTER_NAME # The channel of your GKE cluster. Eg: rapid, regular, stable. export CHANNEL=YOUR_CLUSTER_CHANNEL # The location of your GKE cluster, Eg: us-central1 for regional GKE cluster, # us-central1-a for zonal GKE cluster export LOCATION=ZONE # The mesh name of the traffic director load balancing API. export MESH_NAME=YOUR_MESH_NAME # The project that holds the mesh resources. export MESH_PROJECT_NUMBER=YOUR_PROJECT_NUMBER_HERE export TARGET=projects/${MESH_PROJECT_NUMBER}/locations/global/meshes/${MESH_NAME} gcloud config set project ${CLUSTER_PROJECT_ID}Para conocer el
MESH_NAME
, asigna el valor de la siguiente manera, en la queMESH_NAME
es el valor del campometadata.name
en la especificación de recursosMesh
:gketd-MESH_NAME
Por ejemplo, si el valor de
metadata.name
en el recursoMesh
esbutterfly-mesh
, configura el valor deMESH_NAME
de la siguiente manera:export MESH_NAME="gketd-butterfly-mesh"
Aplica las configuraciones para el webhook de mutación
En las siguientes secciones, se proporcionan instrucciones para aplicar MutatingWebhookConfiguration al clúster. Cuando se crea un pod, se invoca el controlador de admisión en el clúster. El controlador de admisión se comunica con el inyector de sidecar administrado para agregar el contenedor de Envoy al pod.
Aplica las siguientes configuraciones de webhooks de mutación a tu clúster.
cat <<EOF | kubectl apply -f - apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: labels: app: sidecar-injector name: td-mutating-webhook webhooks: - admissionReviewVersions: - v1beta1 - v1 clientConfig: url: https://meshconfig.googleapis.com/v1internal/projects/${CLUSTER_PROJECT_ID}/locations/${LOCATION}/clusters/${CLUSTER}/channels/${CHANNEL}/targets/${TARGET}:tdInject failurePolicy: Fail matchPolicy: Exact name: namespace.sidecar-injector.csm.io namespaceSelector: matchExpressions: - key: td-injection operator: Exists reinvocationPolicy: Never rules: - apiGroups: - "" apiVersions: - v1 operations: - CREATE resources: - pods scope: '*' sideEffects: None timeoutSeconds: 30 EOF
Si necesitas personalizar el inyector de sidecar, sigue estos pasos para personalizarlo en tu clúster:
Implemente el servicio store
En esta sección, implementarás el servicio store
en la malla.
En el archivo
store.yaml
, guarda el siguiente manifiesto:kind: Namespace apiVersion: v1 metadata: name: store --- apiVersion: apps/v1 kind: Deployment metadata: name: store namespace: store spec: replicas: 2 selector: matchLabels: app: store version: v1 template: metadata: labels: app: store version: v1 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080
Aplica el manifiesto a
gke-1
:kubectl apply -f store.yaml
Crea una malla de servicios
En el archivo
mesh.yaml
, guarda el siguiente manifiestomesh
. El nombre del recursomesh
debe coincidir con el nombre de la malla especificado en el configmap del inyector. En esta configuración de ejemplo, el nombretd-mesh
se usa en ambos lugares:apiVersion: net.gke.io/v1alpha1 kind: TDMesh metadata: name: td-mesh namespace: default spec: gatewayClassName: gke-td allowedRoutes: namespaces: from: All
Aplica el manifiesto
mesh
agke-1
, que crea una malla lógica con el nombretd-mesh
:kubectl apply -f mesh.yaml
En el archivo
store-route.yaml
, guarda el siguiente manifiestoHTTPRoute
. El manifiesto define un recursoHTTPRoute
que enruta el tráfico HTTP que especifica el nombre de hostexample.com
a un servicio de Kubernetesstore
en el espacio de nombresstore
:apiVersion: gateway.networking.k8s.io/v1alpha2 kind: HTTPRoute metadata: name: store-route namespace: store spec: parentRefs: - name: td-mesh namespace: default group: net.gke.io kind: TDMesh hostnames: - "example.com" rules: - backendRefs: - name: store namespace: store port: 8080
Aplica el manifiesto de ruta a
gke-1
:kubectl apply -f store-route.yaml
Valida la implementación
Inspecciona el estado y los eventos de
Mesh
para validar que los recursos deMesh
yHTTPRoute
se implementen de forma correcta:kubectl describe tdmesh td-mesh
El resultado es similar a este:
... Status: Conditions: Last Transition Time: 2022-04-14T22:08:39Z Message: Reason: MeshReady Status: True Type: Ready Last Transition Time: 2022-04-14T22:08:28Z Message: Reason: Scheduled Status: True Type: Scheduled Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 36s mc-mesh-controller Processing mesh default/td-mesh Normal UPDATE 35s mc-mesh-controller Processing mesh default/td-mesh Normal SYNC 24s mc-mesh-controller SYNC on default/td-mesh was a success
Para asegurarte de que la inserción de sidecar esté habilitada en el espacio de nombres predeterminado, ejecuta el siguiente comando:
kubectl get namespace default --show-labels
Si la inserción de sidecar está habilitada, verás lo siguiente en el resultado:
istio-injection=enabled
Si la inserción de sidecar no está habilitada, consulta Habilita la inserción de sidecar.
Para verificar la implementación, implementa un Pod de cliente que actúe como cliente en el servicio
store
definido con anterioridad. En el archivoclient.yaml
, guarda lo siguiente:apiVersion: apps/v1 kind: Deployment metadata: labels: run: client name: client namespace: default spec: replicas: 1 selector: matchLabels: run: client template: metadata: labels: run: client spec: containers: - name: client image: curlimages/curl command: - sh - -c - while true; do sleep 1; done
Implementa la especificación:
kubectl apply -f client.yaml
El inyector de sidecar que se ejecuta en el clúster inserta de forma automática un contenedor de Envoy en el Pod del cliente.
Para verificar que se inserte el contenedor de Envoy, ejecuta el siguiente comando:
kubectl describe pods -l run=client
El resultado es similar a este:
... Init Containers: # Istio-init sets up traffic interception for the Pod. istio-init: ... # td-bootstrap-writer generates the Envoy bootstrap file for the Envoy container td-bootstrap-writer: ... Containers: # client is the client container that runs application code. client: ... # Envoy is the container that runs the injected Envoy proxy. envoy: ...
Después de aprovisionar el Pod del cliente, envía una solicitud desde el Pod del cliente al servicio store
.
Obtén el nombre del pod cliente:
CLIENT_POD=$(kubectl get pod -l run=client -o=jsonpath='{.items[0].metadata.name}') # The VIP where the following request will be sent. Because all requests # from the client container are redirected to the Envoy proxy sidecar, you # can use any IP address, including 10.0.0.2, 192.168.0.1, and others. VIP='10.0.0.1'
Envía una solicitud para almacenar el servicio y genera los encabezados de respuesta:
TEST_CMD="curl -v -H 'host: example.com' $VIP"
Ejecuta el comando de prueba en el contenedor de cliente:
kubectl exec -it $CLIENT_POD -c client -- /bin/sh -c "$TEST_CMD"
El resultado es similar a este:
< Trying 10.0.0.1:80... < Connected to 10.0.0.1 (10.0.0.1) port 80 (#0) < GET / HTTP/1.1 < Host: example.com < User-Agent: curl/7.82.0-DEV < Accept: */* < < Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < content-type: application/json < content-length: 318 < access-control-allow-origin: * < server: envoy < date: Tue, 12 Apr 2022 22:30:13 GMT < { "cluster_name": "gke-1", "zone": "us-west1-a", "host_header": "example.com", ... }