
Así es, después del lanzamiento de Hashicorp Consul 1.5.0 a principios de mayo de 2019 en Consul, puede autorizar aplicaciones y servicios que se ejecutan en Kubernetes de forma nativa.
En este tutorial, crearemos paso a paso un POC (Prueba de concepto, PoC - prueba de concepto), que demuestra esta nueva característica. Se esperan conocimientos básicos del cónsul de Kubernetes y Hashicorp. Y aunque usted puede usar cualquier plataforma en la nube o entorno local, en esta guía usaremos la plataforma en la nube de Google.
Revisar
Si vamos a la documentación del Cónsul sobre su método de autorización , obtenemos una breve descripción de su propósito y caso de uso, así como algunos detalles técnicos y una descripción general de la lógica. Recomiendo leerlo al menos una vez antes de continuar, ya que lo explicaré y lo masticaré todo ahora.

Figura 1: Descripción general del método de autorización del cónsul oficial
Echemos un vistazo a la documentación del método de autorización específico de Kubernetes .
Por supuesto, hay información útil, pero no hay una guía sobre cómo usar todo esto. Por lo tanto, como cualquier persona en su sano juicio, navega por Internet en busca de orientación. Y luego ... Ser derrotado. Sucede Vamos a arreglarlo
Antes de continuar con la creación de nuestro POC, volvamos a la descripción general de los métodos de autorización del Cónsul (Figura 1) y refinémoslo en el contexto de Kubernetes.
Arquitectura
En esta guía, crearemos un servidor Consul en una máquina separada que interactuará con el clúster de Kubernetes con el cliente Consul instalado. Luego crearemos nuestra aplicación ficticia en el hogar y utilizaremos nuestro método de autorización personalizado para leer desde nuestro repositorio de clave / valor Consul.
El siguiente diagrama muestra en detalle la arquitectura que creamos en esta guía, así como la lógica del método de autorización, que se explicará más adelante.

Figura 2: Descripción general del método de autorización en Kubernetes
Una nota rápida: el servidor de cónsul no necesita vivir fuera del clúster de Kubernetes para que esto funcione. Pero sí, él puede hacer esto y aquello.
Entonces, tomando el diagrama general de Cónsul (Esquema 1) y aplicando Kubernetes a él, obtenemos el diagrama anterior (Esquema 2), y aquí la lógica será la siguiente:
- Cada pod tendrá una cuenta de servicio adjunta que contiene un token JWT generado y conocido por Kubernetes. Este token también se inserta en el sub por defecto.
- Nuestra aplicación o servicio dentro del hogar inicia un comando para ingresar a nuestro cliente Consul. La solicitud de inicio de sesión también indicará nuestro token y el nombre de un método de autorización especialmente creado (como Kubernetes). Este paso No. 2 corresponde al paso 1 del esquema Cónsul (Esquema 1).
- Nuestro cliente Consul luego enviará esta solicitud a nuestro servidor Consul.
- MAGIA! Es aquí donde el servidor Cónsul verifica la autenticidad de la solicitud, recopila información sobre la identidad de la solicitud y la compara con las reglas predefinidas asociadas. A continuación hay otro diagrama para ilustrar esto. Este paso corresponde a los pasos 3, 4 y 5 del diagrama general de Cónsul (Esquema 1).
- Nuestro servidor de Cónsul genera un token de Cónsul con permisos de acuerdo con las reglas del método de autorización que especificamos (que determinamos) con respecto a la identidad del solicitante. Luego enviará esta ficha de vuelta. Esto corresponde al paso 6 del esquema Cónsul (Esquema 1).
- Nuestro cliente Cónsul redirige el token a la aplicación o servicio solicitante.
Nuestra aplicación o servicio ahora puede usar este token Consul para comunicarse con nuestros datos Consul, según lo determinen los privilegios del token.
¡La magia se revela!
Para aquellos de ustedes que no están contentos con solo el conejo en el sombrero y quieren saber cómo funciona ... déjenme "mostrarles cuán profundo es la madriguera del conejo ".
Como se mencionó anteriormente, nuestro paso "mágico" (Esquema 2: Paso 4) es que el servidor Cónsul verifique la autenticidad de la solicitud, recopile información sobre la solicitud y la compare con las reglas predefinidas asociadas. Este paso corresponde a los pasos 3, 4 y 5 del diagrama general de Cónsul (Esquema 1). A continuación se muestra un diagrama (Esquema 3), cuyo propósito es mostrar claramente lo que realmente sucede bajo el capó de un método de autorización de Kubernetes específico.

Esquema 3: ¡se revela la magia!
- Como punto de partida, nuestro cliente Consul redirige la solicitud de inicio de sesión a nuestro servidor Consul con el token de la cuenta Kubernetes y el nombre de la instancia específica del método de autorización que se creó anteriormente. Este paso corresponde al paso 3 en la explicación anterior del circuito.
- Ahora el servidor Cónsul (o líder) necesita verificar la autenticidad del token recibido. Por lo tanto, consultará con el clúster de Kubernetes (a través del cliente Cónsul) y, con los permisos apropiados, descubriremos si el token es genuino y a quién pertenece.
- Luego, la solicitud verificada regresa al líder del Cónsul, y el servidor del Cónsul busca una instancia del método de autorización con el nombre especificado de la solicitud de inicio de sesión (y escriba Kubernetes).
- El líder del cónsul determina la instancia especificada del método de autorización (si se encuentra uno) y lee el conjunto de reglas vinculantes que se le adjuntan. Luego lee estas reglas y las compara con atributos de identidad verificados.
- Tada! Vaya al paso 5 en la explicación anterior del circuito.
Ejecute Consul-server en una máquina virtual normal
A partir de ahora, principalmente daré instrucciones para crear este POC, a menudo en puntos, sin oraciones enteras explicativas. Además, como se señaló anteriormente, utilizaré GCP para crear toda la infraestructura, pero puede crear la misma infraestructura en cualquier otro lugar.
- Inicie la máquina virtual (instancia / servidor).

- Cree una regla para firewall (grupo de seguridad en AWS):
- Me gusta asignar el mismo nombre de máquina a la regla y la etiqueta de red, en este caso es "skywiz-consul-server-poc".
- Encuentre la dirección IP de su computadora local y agréguela a la lista de direcciones IP de origen para que podamos acceder a la interfaz de usuario (UI).
- Abra el puerto 8500 para la interfaz de usuario. Haz clic en Crear. Cambiaremos este firewall [ enlace ] nuevamente pronto.
- Agregue la regla para firewall a la instancia. Regrese al panel de VM en el servidor Consul y agregue "skywiz-consul-server-poc" al campo de etiqueta de red. Haz clic en Guardar.

- Instale Consul en una máquina virtual, marque aquí. Recuerda que necesitas la versión de Consul ≥ 1.5 [enlace]
- Cree un solo nodo Consul: la configuración es la siguiente.
groupadd --system consul useradd -s /sbin/nologin --system -g consul consul mkdir -p /var/lib/consul chown -R consul:consul /var/lib/consul chmod -R 775 /var/lib/consul mkdir /etc/consul.d chown -R consul:consul /etc/consul.d
- Para obtener una guía más detallada sobre la instalación de Consul y la configuración de un clúster de 3 nodos, consulte aquí .
- Cree el archivo /etc/consul.d/agent.json de la siguiente manera [ enlace ]:
### /etc/consul.d/agent.json { "acl" : { "enabled": true, "default_policy": "deny", "enable_token_persistence": true } }
- Inicie nuestro servidor Consul:
consul agent \ -server \ -ui \ -client 0.0.0.0 \ -data-dir=/var/lib/consul \ -bootstrap-expect=1 \ -config-dir=/etc/consul.d
- Debería ver un montón de resultados y terminar con "... actualización bloqueada por ACL".
- Localice la dirección IP externa del servidor Consul y abra un navegador con esta dirección IP en el puerto 8500. Asegúrese de que la IU se abra.
- Intente agregar un par clave / valor. Debe haber un error. Esto se debe a que cargamos el servidor Consul usando la ACL y denegamos todas las reglas.
- Regrese a su shell en el servidor Consul e inicie el proceso en segundo plano o de alguna otra manera para que funcione, e ingrese lo siguiente:
consul acl bootstrap
- Encuentre el valor "SecretID" y regrese a la IU. En la pestaña ACL, ingrese el identificador secreto del token que acaba de copiar. Copie SecretID en otro lugar, lo necesitaremos más tarde.
- Ahora agregue un par clave / valor. Para este POC, agregue lo siguiente: clave: "custom-ns / test_key", valor: "¡Estoy en la carpeta custom-ns!"
Inicie Kubernetes Cluster para nuestra aplicación con Consul Client como Daemonset
- Crea un clúster K8s (Kubernetes). Lo crearemos en la misma zona que el servidor para un acceso más rápido y, por lo tanto, podemos usar la misma subred para una fácil conexión con direcciones IP internas. Lo llamaremos skywiz-app-with-consul-client-poc.

- Como nota, aquí hay una buena guía que encontré al configurar un clúster de Consul POC con Consul Connect.
- También usaremos el gráfico de timón Hashicorp con un archivo de valores extendidos.
- Instalar y configurar Helm. Pasos de configuración:
kubectl create serviceaccount tiller --namespace kube-system kubectl create clusterrolebinding tiller-admin-binding \ --clusterrole=cluster-admin --serviceaccount=kube-system:tiller ./helm init --service-account=tiller ./helm update
### poc-helm-consul-values.yaml global: enabled: false image: "consul:latest" # Expose the Consul UI through this LoadBalancer ui: enabled: false # Allow Consul to inject the Connect proxy into Kubernetes containers connectInject: enabled: false # Configure a Consul client on Kubernetes nodes. GRPC listener is required for Connect. client: enabled: true join: ["<PRIVATE_IP_CONSUL_SERVER>"] extraConfig: | { "acl" : { "enabled": true, "default_policy": "deny", "enable_token_persistence": true } } # Minimal Consul configuration. Not suitable for production. server: enabled: false # Sync Kubernetes and Consul services syncCatalog: enabled: false
- Aplicar gráfico de timón:
./helm install -f poc-helm-consul-values.yaml ./consul-helm - name skywiz-app-with-consul-client-poc
- Cuando intente iniciar, necesitará permisos para el servidor de Consul, así que vamos a agregarlos.
- Preste atención al "rango de direcciones Pod" ubicado en el tablero del clúster y regrese a nuestra regla para el firewall skywiz-consul-server-poc.
- Agregue el rango de direcciones para el IPA a la lista de direcciones IP y abra los puertos 8301 y 8300.

- Vaya a la interfaz de usuario de Consul, y en unos minutos verá que nuestro clúster aparecerá en la pestaña del nodo.

Configure el método de autorización integrando Consul con Kubernetes
- Regrese al shell del servidor Consul y exporte el token que guardó anteriormente:
export CONSUL_HTTP_TOKEN=<SecretID>
- Necesitamos información de nuestro clúster de Kubernetes para crear una instancia de método de autenticación:
- kubernetes-host
kubectl get endpoints | grep kubernetes
- kubernetes-service-account-jwt
kubectl get sa <helm_deployment_name>-consul-client -o yaml | grep "\- name:" kubectl get secret <secret_name_from_prev_command> -o yaml | grep token:
- El token está codificado en base64, así que descifrarlo usando su herramienta favorita [ enlace ]
- kubernetes-ca-cert
kubectl get secret <secret_name_from_prev_command> -o yaml | grep ca.crt:
- Tome el certificado "ca.crt" (después de decodificar con base64) y escríbalo en el archivo "ca.crt".
- Ahora cree una instancia del método de autenticación, reemplazando los marcadores de posición con los valores que acaba de recibir.
consul acl auth-method create \ -type "kubernetes" \ -name "auth-method-skywiz-consul-poc" \ -description "This is an auth method using kubernetes for the cluster skywiz-app-with-consul-client-poc" \ -kubernetes-host "<k8s_endpoint_retrieved earlier>" \ -kubernetes-ca-cert=@ca.crt \ -kubernetes-service-account- jwt="<decoded_token_retrieved_earlier>"
- A continuación, debemos crear una regla y adjuntarla al nuevo rol. Puede usar la interfaz de usuario de Consul para esta parte, pero usaremos la línea de comando.
- Escribir una regla
### kv-custom-ns-policy.hcl key_prefix "custom-ns/" { policy = "write" }
consul acl policy create \ -name kv-custom-ns-policy \ -description "This is an example policy for kv at custom-ns/" \ -rules @kv-custom-ns-policy.hcl
- Encuentre el identificador de la regla que acaba de crear a partir de la salida.
- Crea un rol con una nueva regla.
consul acl role create \ -name "custom-ns-role" \ -description "This is an example role for custom-ns namespace" \ -policy-id <policy_id>
consul acl binding-rule create \ -method=auth-method-skywiz-consul-poc \ -bind-type=role \ -bind-name='custom-ns-role' \ -selector='serviceaccount.namespace=="custom-ns"'
Últimas configuraciones
Derechos de acceso
- Crea permisos. Necesitamos dar permiso al Cónsul para verificar e identificar la identidad del token de la cuenta de servicio K8s.
- Escriba el siguiente [enlace] al archivo:
###skywiz-poc-consul-server_rbac.yaml --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: review-tokens namespace: default subjects: - kind: ServiceAccount name: skywiz-app-with-consul-client-poc-consul-client namespace: default roleRef: kind: ClusterRole name: system:auth-delegator apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: service-account-getter namespace: default rules: - apiGroups: [""] resources: ["serviceaccounts"] verbs: ["get"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: get-service-accounts namespace: default subjects: - kind: ServiceAccount name: skywiz-app-with-consul-client-poc-consul-client namespace: default roleRef: kind: ClusterRole name: service-account-getter apiGroup: rbac.authorization.k8s.io
kubectl create -f skywiz-poc-consul-server_rbac.yaml
Conéctese con el cliente Consul
- Como se señaló aquí , hay varias opciones para conectarse a Daemonset, pero pasaremos a la siguiente solución simple:
- Aplique el siguiente archivo [ enlace ].
### poc-consul-client-ds-svc.yaml apiVersion: v1 kind: Service metadata: name: consul-ds-client spec: selector: app: consul chart: consul-helm component: client hasDNS: "true" release: skywiz-app-with-consul-client-poc ports: - protocol: TCP port: 80 targetPort: 8500
- Luego use el siguiente comando incorporado para crear el mapa de configuración [ enlace ]. Tenga en cuenta que nos referimos al nombre de nuestro servicio, reemplácelo si es necesario.
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: labels: addonmanager.kubernetes.io/mode: EnsureExists name: kube-dns namespace: kube-system data: stubDomains: | {"consul": ["$(kubectl get svc consul-ds-client -o jsonpath='{.spec.clusterIP}')"]} EOF
Probar el método de autenticación
¡Ahora veamos la magia en acción!
- Cree algunas carpetas de claves más con la misma clave de nivel superior (es decir, <nuevo_carpeta> / muestra_clave) y el valor que elija. Cree políticas y roles apropiados para nuevas rutas clave. Haremos los enlaces más tarde.

Prueba de espacio de nombres personalizado:
- Cree nuestro propio espacio de nombres:
kubectl create namespace custom-ns
- Cree bajo en nuestro nuevo espacio de nombres. Escriba la configuración para el hogar.
###poc-ubuntu-custom-ns.yaml apiVersion: v1 kind: Pod metadata: name: poc-ubuntu-custom-ns namespace: custom-ns spec: containers: - name: poc-ubuntu-custom-ns image: ubuntu command: ["/bin/bash", "-ec", "sleep infinity"] restartPolicy: Never
kubectl create -f poc-ubuntu-custom-ns.yaml
- Una vez que se inicia el contenedor, vaya e instale curl.
kubectl exec poc-ubuntu-custom-ns -n custom-ns -it /bin/bash apt-get update && apt-get install curl -y
- Ahora enviaremos una solicitud para ingresar a Consul utilizando el método de autorización que creamos anteriormente [ enlace ].
- Para ver el token ingresado desde su cuenta de servicio:
cat /run/secrets/kubernetes.io/serviceaccount/token
- Escriba lo siguiente en un archivo dentro del contenedor:
### payload.json { "AuthMethod": "auth-method-test", "BearerToken": "<jwt_token>" }
curl \ --request POST \ --data @payload.json \ consul-ds-client.default.svc.cluster.local/v1/acl/login
- Para completar los pasos anteriores en una sola línea (ya que ejecutaremos varias pruebas), puede hacer lo siguiente:
echo "{ \ \"AuthMethod\": \"auth-method-skywiz-consul-poc\", \ \"BearerToken\": \"$(cat /run/secrets/kubernetes.io/serviceaccount/token)\" \ }" \ | curl \ --request POST \ --data @- \ consul-ds-client.default.svc.cluster.local/v1/acl/login
- Funciona! Al menos debe. Ahora tome el SecretID e intente acceder a la clave / valor al que debemos tener acceso.
curl \ consul-ds-client.default.svc.cluster.local/v1/kv/custom-ns/test_key --header “X-Consul-Token: <SecretID_from_prev_response>”
- Puede decodificar la base64 "Valor" y ver que coincide con el valor en custom-ns / test_key en la interfaz de usuario. Si utilizó el mismo valor anterior en este manual, su valor codificado sería IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.
Prueba de cuenta de servicio de usuario:
- Cree una cuenta de servicio personalizada con el siguiente comando [ enlace ].
kubectl apply -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: custom-sa EOF
- Cree un nuevo archivo de configuración para el hogar. Tenga en cuenta que activé la instalación de curl para ahorrar trabajo :)
###poc-ubuntu-custom-sa.yaml apiVersion: v1 kind: Pod metadata: name: poc-ubuntu-custom-sa namespace: default spec: serviceAccountName: custom-sa containers: - name: poc-ubuntu-custom-sa image: ubuntu command: ["/bin/bash","-ec"] args: ["apt-get update && apt-get install curl -y; sleep infinity"] restartPolicy: Never
- Después de eso, ejecute el shell dentro del contenedor.
kubectl exec -it poc-ubuntu-custom-sa /bin/bash
echo "{ \ \"AuthMethod\": \"auth-method-skywiz-consul-poc\", \ \"BearerToken\": \"$(cat /run/secrets/kubernetes.io/serviceaccount/token)\" \ }" \ | curl \ --request POST \ --data @- \ consul-ds-client.default.svc.cluster.local/v1/acl/login
- Permiso denegado. Oh, olvidamos agregar un nuevo enlace de regla con los permisos apropiados, hagámoslo ahora.
Repita los pasos anteriores anteriores:
a) Cree una política idéntica para el prefijo "custom-sa /".
b) Cree un rol, asígnele el nombre "custom-sa-role"
c) Adjunte la política al rol.
- Cree un enlace de reglas (solo posible desde cli / api). Tenga en cuenta los diferentes valores de la bandera del selector.
consul acl binding-rule create \ -method=auth-method-skywiz-consul-poc \ -bind-type=role \ -bind-name='custom-sa-role' \ -selector='serviceaccount.name=="custom-sa"'
- Inicie sesión nuevamente desde el contenedor poc-ubuntu-custom-sa. Éxito!
- Verifique nuestro acceso a la ruta personalizada-sa / clave.
curl \ consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header “X-Consul-Token: <SecretID>”
- También puede asegurarse de que este token no proporcione acceso a kv en "custom-ns /". Simplemente repita el comando anterior después de reemplazar "custom-sa" con el prefijo "custom-ns".
Permiso denegado.
Ejemplo de superposición:
- Vale la pena señalar que todas las asignaciones de enlace de reglas se agregarán al token con estos derechos.
- Nuestro contenedor poc-ubuntu-custom-sa está en el espacio de nombres predeterminado, así que usémoslo para otro enlace de reglas.
- Repita los pasos anteriores:
a) Cree una política idéntica para el prefijo clave "default /".
b) Cree un rol, asígnele el nombre "default-ns-role"
c) Adjunte la política al rol. - Crear enlace de reglas (solo posible desde cli / api)
consul acl binding-rule create \ -method=auth-method-skywiz-consul-poc \ -bind-type=role \ -bind-name='default-ns-role' \ -selector='serviceaccount.namespace=="default"'
- Regrese a nuestro contenedor poc-ubuntu-custom-sa e intente acceder a la ruta predeterminada / kv.
- Permiso denegado.
Puede ver las credenciales especificadas para cada token en la interfaz de usuario en ACL> Tokens. Como puede ver, solo un "custom-sa-role" está adjunto a nuestro token actual. El token que estamos usando actualmente se generó cuando iniciamos sesión, y luego solo hubo un enlace de reglas, que luego correspondió. Necesitamos iniciar sesión nuevamente y usar el nuevo token. - Asegúrese de que puede leer desde las rutas kv "custom-sa /" y "default /".
Éxito!
Esto se debe a que nuestro "poc-ubuntu-custom-sa" coincide con los enlaces de las reglas "custom-sa" y "default-ns".
Conclusión
TTM token mgmt?
Al momento de escribir esto, no hay una forma integrada de determinar TTL para los tokens generados por este método de autorización. Sería una oportunidad fantástica para proporcionar una automatización segura de la autorización del Cónsul.
Es posible crear manualmente un token con TTL:
Espero que en el futuro cercano podamos controlar cómo se generan los tokens (para cada regla o método de autorización) y agregar TTL.
Hasta entonces, se propone utilizar en su lógica el punto final de la salida del sistema.
Lea también otros artículos en nuestro blog: