La API de Kubernetes es su ruta para inspeccionar y administrar las operaciones de su clúster. Puede consumir la API mediante la CLI de Kubectl, herramientas como curl
o la integración oficial bibliotecas para lenguajes de programación populares.
La API también está disponible para aplicaciones dentro de su clúster. Los pods de Kubernetes reciben automáticamente acceso a la API y pueden autenticarse mediante una cuenta de servicio proporcionada. Realiza interacciones consumiendo las variables de entorno inyectadas y los archivos de certificado para realizar conexiones desde el cliente de su elección.
¿Por qué acceder a la API de Kubernetes dentro de los pods?
Hay varios casos de uso para el acceso a la API en el pod. Esta técnica permite que las aplicaciones inspeccionen dinámicamente su entorno, apliquen cambios de Kubernetes y recopilen métricas del plano de control que brindan información sobre el rendimiento.
Algunas organizaciones desarrollan sus propias herramientas en torno a Kubernetes. Podrían implementar una aplicación especial en el clúster que use la API para exponer funciones adicionales. Operar desde dentro del clúster puede ser más seguro que realizar llamadas a la API desde un script externo, ya que no necesita abrir su entorno ni compartir cuentas de servicio y tokens de autenticación.
Uso de las bibliotecas de cliente de API
El método más sencillo y recomendado para acceder a la API de Kubernetes desde un pod es utilizar una biblioteca de cliente. Opciones totalmente compatibles están disponibles para C, .NET, Go, Haskell, Java, JavaScript, Perl, Python y Ruby. hay equivalentes soluciones mantenidas por la comunidad para la mayoría de los otros lenguajes de programación populares.
Las bibliotecas cliente tienen compatibilidad integrada para descubrir el entorno de clúster en el que se ejecutan. Cada implementación proporciona una función a la que puede llamar que configurará la biblioteca para conectarse al servidor de API correcto.
Este es un ejemplo de cómo enumerar los Pods en su clúster dentro de una aplicación de Python:
from kubernetes import client, config config.load_incluster_config() api = client.CoreV1Api() # Perform necessary API interactions # pods = api.list_pod_for_all_namespaces()
Es fácil trabajar con este enfoque y no requiere configuración manual. Sin embargo, a veces no podrá usar una biblioteca de cliente. En esos casos, aún es posible acceder manualmente a la API utilizando la cuenta de servicio que proporciona Kubernetes.
Realización de interacciones API manuales
Para llamar a la API, necesita saber dos cosas: el nombre de host en el clúster en el que está expuesto y el token de la cuenta de servicio que autenticará su Pod.
El nombre de host de la API siempre es kubernetes.default.svc
. El proveedor de DNS de Kubernetes resolverá este nombre en el servidor API del plano de control. Como alternativa, puede utilizar el $KUBERNETES_SERVICE_HOST
variable de entorno para descubrir la dirección IP del servidor API:
$ echo $KUBERNETES_SERVICE_HOST 10.96.0.1
La API solo está disponible a través de HTTPS. Puede encontrar el archivo de la autoridad de certificación para su clúster en /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
dentro de su Pod. Kubernetes deposita esto en el sistema de archivos cada vez que se crea un nuevo contenedor.
Deberá autenticarse para lograr algo útil con la API. Kubernetes crea un nuevo cuenta de servicio para cada Pod y proporciona su token en /var/run/secrets/kubernetes.io/serviceaccount/token
. Esto debe incluirse con cada solicitud HTTP como un token de portador en el Authorization
encabezamiento.
Poniendo todo junto, aquí hay un ejemplo de cómo hacer una solicitud API básica de Kubernetes en el Pod usando curl
:
$ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc/api { "kind": "APIVersions", "versions": [ "v1" ], "serverAddressByClientCIDRs": [ { "clientCIDR": "0.0.0.0/0", "serverAddress": "192.168.49.2:8443" } ]
El servidor de Kubernetes ha respondido con las versiones de API disponibles. Esto confirma que se ha realizado una conexión exitosa usando el kubernetes.default.svc
nombre de host y la cuenta de servicio proporcionada.
Manejo de RBAC
Aunque una solicitud de API se haya realizado con éxito, la mayoría de los demás estarán fuera de los límites si RBAC está habilitado para su clúster. Las cuentas de servicio recién creadas no reciben roles automáticamente, por lo que su Pod no podrá solicitar puntos finales de API protegidos.
Puede resolver esto creando sus propios objetos de rol y vinculándolos a la cuenta de servicio que se proporciona a sus pods. Primero crea un nuevo Rol:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: demo-role rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"]
Aplíquelo a su clúster con Kubectl:
$ kubectl apply -f role.yaml
A continuación, vincule el rol a la cuenta de servicio:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: default name: demo-role-binding subjects: - kind: ServiceAccount name: default apiGroup: "" roleRef: kind: Role name: demo-role apiGroup: ""
los default
la cuenta de servicio se selecciona como el asunto del enlace de roles. Los pods siempre se suministran con esta cuenta de servicio, en el ámbito del espacio de nombres en el que se crearon. En este ejemplo, el default
se usa el espacio de nombres, pero esto debe cambiarse en los objetos Role y RoleBinding si su Pod existe en un espacio de nombres diferente.
Agregue RoleBinding a su clúster:
$ kubectl apply -f role-binding.yaml
Ahora sus Pods podrán obtener y enumerar otros objetos Pod en el default
espacio de nombres Puede verificar esto haciendo una solicitud de API al punto final de Pods con espacio de nombres:
$ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc/api/v1/namespaces/default/pods { "kind": "PodList", "apiVersion": "v1" ... }
Los pods pueden identificar su propio espacio de nombres leyendo el /var/run/secrets/kubernetes.io/serviceaccount/namespace
expediente:
$ cat /var/run/secrets/kubernetes.io/serviceaccount/namespace default
Esto proporciona un método conveniente para interpolar el espacio de nombres activo en las URL de punto final:
$ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods { "kind": "PodList", "apiVersion": "v1" ... }
Elegir una cuenta de servicio diferente
Kubernetes proporciona automáticamente a los Pods la default
cuenta de servicio dentro de su espacio de nombres. Opcionalmente, puede inyectar una cuenta de servicio diferente configurando el spec.serviceAccountName
campo en sus Pods:
apiVersion: v1 kind: Pod metadata: name: demo spec: serviceAccountName: demo-sa
En este ejemplo, el Pod se autenticará como el demo-sa
simbólico. Puede crear esta cuenta de servicio manualmente y vincularla a los roles que necesite.
$ kubernetes create serviceaccount demo-sa
La cuenta de servicio debe existir en el mismo espacio de nombres que el Pod.
Cancelación del montaje de la cuenta de servicio
La inyección automática de cuentas de servicio no siempre es deseable. Puede ser un peligro para la seguridad, ya que un Pod comprometido exitoso ofrece acceso inmediato a la API de su clúster de Kubernetes. Puede deshabilitar los montajes de tokens de cuenta de servicio con el spec.automountServiceAccountToken
Campo de manifiesto de pod:
apiVersion: v1 kind: Pod metadata: name: demo spec: automountServiceAccountToken: false
Kubernetes no inyectará el /var/run/secrets/kubernetes.io/serviceaccount/token
expediente. Esto evitará que el Pod se autentique en la API de Kubernetes, a menos que proporcione las credenciales manualmente con un método diferente. Este campo también es compatible con los objetos de la cuenta de servicio, lo que los hace inelegibles para montarse automáticamente en cualquier Pod.
Si usa el montaje de cuentas de servicio, configure las políticas RBAC apropiadas para restringir el token a sus casos de uso previstos. Evitar el acceso altamente privilegiado disminuirá el riesgo de daños en caso de que un atacante obtenga acceso a su Pod.
Resumen
Acceder al servidor API de Kubernetes desde dentro de su clúster permite que las aplicaciones en ejecución inspeccionen y modifiquen las cargas de trabajo vecinas. Puede agregar funciones adicionales sin abrir su clúster al acceso a la API externa.
Las bibliotecas de clientes oficiales facilitan la puesta en marcha, si son adecuadas para su caso de uso. En otras situaciones, deberá realizar solicitudes manualmente a https://kubernetes.default.svc
, proporcionando el archivo de la autoridad de certificación y el token de la cuenta de servicio que Kubernetes inyecta en sus contenedores Pod. Independientemente del enfoque que utilice, la cuenta de servicio debe estar configurada correctamente con enlaces de roles RBAC para que el pod tenga permiso para realizar las acciones previstas.