# Interactuar con Kubernetes desde una extensión


El SDK de extensiones no proporciona ningún método de API para interactuar directamente con el clúster de Kubernetes gestionado por Docker Desktop o cualquier otro clúster creado con otras herramientas como KinD. Sin embargo, esta página proporciona una forma de utilizar otras API del SDK para interactuar indirectamente con un clúster de Kubernetes desde tu extensión.

Para solicitar una API que interactúe directamente con Kubernetes gestionado por Docker Desktop, puedes votar a favor de [esta incidencia](https://github.com/docker/extensions-sdk/issues/181) en el repositorio de GitHub del SDK de extensiones.

## Requisitos previos

### Activar Kubernetes

Puedes usar el Kubernetes integrado en Docker Desktop para iniciar un clúster de Kubernetes de un solo nodo.
Se utiliza un archivo `kubeconfig` para configurar el acceso a Kubernetes cuando se usa en conjunto con la herramienta de línea de comandos `kubectl` u otros clientes.
Docker Desktop proporciona de forma práctica al usuario un archivo `kubeconfig` local preconfigurado y el comando `kubectl` dentro del área de inicio del usuario. Es una forma conveniente de acelerar el acceso para aquellos que buscan aprovechar Kubernetes desde Docker Desktop.

## Distribuir `kubectl` como parte de la extensión

Si tu extensión necesita interactuar con clústeres de Kubernetes, se recomienda que incluyas la herramienta de línea de comandos `kubectl` como parte de la extensión. Al hacer esto, los usuarios que instalen tu extensión tendrán `kubectl` instalado en su host.

Para descubrir cómo distribuir la herramienta de línea de comandos `kubectl` para múltiples plataformas como parte de la imagen de tu extensión de Docker, consulta [Construir extensiones multi-arquitectura](/extensions/extensions-sdk/extensions/multi-arch/#adding-multi-arch-binaries).

## Ejemplos

Los siguientes fragmentos de código se han agrupado en la [extensión de ejemplo de Kubernetes](https://github.com/docker/extensions-sdk/tree/main/samples/kubernetes-sample-extension). Muestra cómo interactuar con un clúster de Kubernetes distribuyendo la herramienta de línea de comandos `kubectl`.

### Comprobar si el servidor de la API de Kubernetes está accesible

Una vez que se añade la herramienta de línea de comandos `kubectl` a la imagen de la extensión en el `Dockerfile` y se define en `metadata.json`, el framework de extensiones despliega `kubectl` en el host de los usuarios cuando se instala la extensión.

Puedes usar la API JS `ddClient.extension.host?.cli.exec` para enviar comandos de `kubectl` para, por ejemplo, comprobar si el servidor de la API de Kubernetes está accesible en un contexto específico:

```typescript
const output = await ddClient.extension.host?.cli.exec("kubectl", [
  "cluster-info",
  "--request-timeout",
  "2s",
  "--context",
  "docker-desktop",
]);
```

### Listar contextos de Kubernetes

```typescript
const output = await ddClient.extension.host?.cli.exec("kubectl", [
  "config",
  "view",
  "-o",
  "jsonpath='{.contexts}'",
]);
```

### Listar espacios de nombres de Kubernetes

```typescript
const output = await ddClient.extension.host?.cli.exec("kubectl", [
  "get",
  "namespaces",
  "--no-headers",
  "-o",
  'custom-columns=":metadata.name"',
  "--context",
  "docker-desktop",
]);
```

## Persistir el archivo kubeconfig

A continuación se presentan diferentes formas de persistir y leer el archivo `kubeconfig` desde el sistema de archivos del host. Los usuarios pueden añadir, editar o eliminar contextos de Kubernetes en el archivo `kubeconfig` en cualquier momento.

> [!WARNING]
>
> El archivo `kubeconfig` es muy sensible y, si se expone, puede dar a un atacante acceso administrativo al clúster de Kubernetes.

### Contenedor de backend de la extensión

Si necesitas que tu extensión persista el archivo `kubeconfig` después de haberlo leído, puedes tener un contenedor de backend que exponga un endpoint HTTP POST para almacenar el contenido del archivo en memoria o en algún lugar dentro del sistema de archivos del contenedor. De esta forma, si el usuario navega fuera de la extensión a otra parte de Docker Desktop y luego regresa, no necesitarás leer el archivo `kubeconfig` nuevamente.

```typescript
export const updateKubeconfig = async () => {
  const kubeConfig = await ddClient.extension.host?.cli.exec("kubectl", [
    "config",
    "view",
    "--raw",
    "--minify",
    "--context",
    "docker-desktop",
  ]);
  if (kubeConfig?.stderr) {
    console.log("error", kubeConfig?.stderr);
    return false;
  }

  // llama al contenedor de backend para almacenar el kubeconfig recuperado en la memoria o el sistema de archivos del contenedor
  try {
    await ddClient.extension.vm?.service?.post("/store-kube-config", {
      data: kubeConfig?.stdout,
    });
  } catch (err) {
    console.log("error", JSON.stringify(err));
  }
};
```

### Volumen de Docker

Los volúmenes son el mecanismo preferido para persistir datos generados y utilizados por contenedores de Docker. Puedes hacer uso de ellos para persistir el archivo `kubeconfig`.
Al persistir el `kubeconfig` en un volumen, no necesitarás leer el archivo `kubeconfig` nuevamente cuando se cierre el panel de la extensión. Esto lo hace ideal para persistir datos al navegar fuera de la extensión a otras partes de Docker Desktop.

```typescript
const kubeConfig = await ddClient.extension.host?.cli.exec("kubectl", [
  "config",
  "view",
  "--raw",
  "--minify",
  "--context",
  "docker-desktop",
]);
if (kubeConfig?.stderr) {
  console.log("error", kubeConfig?.stderr);
  return false;
}

await ddClient.docker.cli.exec("run", [
  "--rm",
  "-v",
  "my-vol:/tmp",
  "alpine",
  "/bin/sh",
  "-c",
  `"touch /tmp/.kube/config && echo '${kubeConfig?.stdout}' > /tmp/.kube/config"`,
]);
```

### `localStorage` de la extensión

`localStorage` es uno de los mecanismos de almacenamiento web de un navegador. Te permite guardar datos como pares clave-valor en el navegador para su uso posterior.
`localStorage` no borra los datos cuando se cierra el navegador (el panel de la extensión). Esto lo hace ideal para persistir datos al navegar fuera de la extensión a otras partes de Docker Desktop.

```typescript
localStorage.setItem("kubeconfig", kubeConfig);
```

```typescript
localStorage.getItem("kubeconfig");
```

