# Driver Remote


El driver Remote de Buildx permite gestionar flujos de trabajo de compilación personalizados más complejos, permitiéndote conectarte a instancias de BuildKit administradas externamente. Esto es útil para escenarios que requieren la administración manual del demonio de BuildKit, o cuando este se expone desde otra fuente.

## Sinopsis

```console
$ docker buildx create \
  --name remote \
  --driver remote \
  tcp://localhost:1234
```

La siguiente tabla describe las opciones específicas del driver disponibles que puedes pasar a `--driver-opt`:

| Parámetro      | Tipo    | Predeterminado              | Descripción                                                                           |
| :------------- | :------ | :-------------------------- | :------------------------------------------------------------------------------------ |
| `key`          | String  |                             | Establece la clave del cliente TLS.                                                   |
| `cert`         | String  |                             | Ruta absoluta al certificado de cliente TLS para presentar a `buildkitd`.             |
| `cacert`       | String  |                             | Ruta absoluta a la autoridad de certificación (CA) TLS utilizada para la validación.  |
| `servername`   | String  | Nombre de host del endpoint | Nombre del servidor TLS utilizado en las solicitudes.                                 |
| `default-load` | Boolean | `false`                     | Carga automáticamente las imágenes en el almacenamiento de imágenes de Docker Engine. |

## Ejemplo: BuildKit remoto a través de sockets Unix

Esta guía te muestra cómo crear una configuración con un demonio de BuildKit escuchando en un socket Unix, y cómo hacer que Buildx se conecte a él.

1. Asegúrate de tener instalado [BuildKit](https://github.com/moby/buildkit).

   Por ejemplo, puedes iniciar una instancia de `buildkitd` con:

   ```console
   $ sudo ./buildkitd --group $(id -gn) --addr unix://$HOME/buildkitd.sock
   ```

   Alternativamente, consulta la [documentación de BuildKit sin privilegios (Rootless BuildKit)](https://github.com/moby/buildkit/blob/master/docs/rootless.md) para ejecutar `buildkitd` en modo rootless, o los [ejemplos de systemd de BuildKit](https://github.com/moby/buildkit/tree/master/examples/systemd) para ejecutarlo como un servicio de systemd.

2. Comprueba que tienes un socket Unix al que te puedes conectar.

   ```console
   $ ls -lh /home/user/buildkitd.sock
   srw-rw---- 1 root user 0 May  5 11:04 /home/user/buildkitd.sock
   ```

3. Conéctate a él mediante Buildx utilizando el driver `remote`:

   ```console
   $ docker buildx create \
     --name remote-unix \
     --driver remote \
     unix://$HOME/buildkitd.sock
   ```

4. Lista los builders disponibles con `docker buildx ls`. Deberías ver `remote-unix` en la lista:

   ```console
   $ docker buildx ls
   NAME/NODE           DRIVER/ENDPOINT                        STATUS  PLATFORMS
   remote-unix         remote
     remote-unix0      unix:///home/.../buildkitd.sock        running linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
   default *           docker
     default           default                                running linux/amd64, linux/386
   ```

Puedes cambiar a este nuevo builder como predeterminado con `docker buildx use remote-unix`, o especificarlo para una compilación en particular utilizando `--builder`:

```console
$ docker buildx build --builder=remote-unix -t test --load .
```

Recuerda que debes utilizar la bandera `--load` si deseas cargar el resultado de la compilación en el demonio de Docker.

## Ejemplo: BuildKit remoto en un contenedor Docker

Esta guía te muestra cómo realizar una configuración similar a la del driver `docker-container`, iniciando manualmente un contenedor Docker de BuildKit y conectándote a él mediante el driver Remote de Buildx. Este procedimiento creará manualmente un contenedor y accederá a él a través de su puerto expuesto. (Generalmente es mejor usar simplemente el driver `docker-container` que se conecta a BuildKit a través del demonio de Docker, pero esto sirve para fines ilustrativos).

1. Genera los certificados para BuildKit.

   Puedes utilizar esta [definición de Bake](https://github.com/moby/buildkit/blob/master/examples/create-certs) como punto de partida:

   ```console
   SAN="localhost 127.0.0.1" docker buildx bake "https://github.com/moby/buildkit.git#master:examples/create-certs"
   ```

   Ten en cuenta que aunque es posible exponer BuildKit a través de TCP sin usar TLS, no se recomienda, ya que permitiría el acceso arbitrario a BuildKit sin credenciales.

2. Con los certificados generados en `.certs/`, inicia el contenedor:

   ```console
   $ docker run -d --rm \
     --name=remote-buildkitd \
     --privileged \
     -p 1234:1234 \
     -v $PWD/.certs:/etc/buildkit/certs \
     moby/buildkit:latest \
     --addr tcp://0.0.0.0:1234 \
     --tlscacert /etc/buildkit/certs/daemon/ca.pem \
     --tlscert /etc/buildkit/certs/daemon/cert.pem \
     --tlskey /etc/buildkit/certs/daemon/key.pem
   ```

   Este comando inicia un contenedor de BuildKit y expone el puerto 1234 del demonio a `localhost`.

3. Conéctate a este contenedor en ejecución utilizando Buildx:

   ```console
   $ docker buildx create \
     --name remote-container \
     --driver remote \
     --driver-opt cacert=${PWD}/.certs/client/ca.pem,cert=${PWD}/.certs/client/cert.pem,key=${PWD}/.certs/client/key.pem,servername=<TLS_SERVER_NAME> \
     tcp://localhost:1234
   ```

   Alternativamente, puedes usar el esquema de URL `docker-container://` para conectarte al contenedor BuildKit sin especificar un puerto:

   ```console
   $ docker buildx create \
     --name remote-container \
     --driver remote \
     docker-container://remote-container
   ```

## Ejemplo: BuildKit remoto en Kubernetes

Esta guía te muestra cómo realizar una configuración similar a la del driver `kubernetes` creando manualmente un `Deployment` de BuildKit. Aunque el driver `kubernetes` hace esto de forma interna, a veces puede ser conveniente escalar BuildKit de manera manual. Además, al ejecutar compilaciones desde el interior de pods de Kubernetes, el builder de Buildx deberá volver a crearse desde dentro de cada pod o copiarse entre ellos.

1. Crea un despliegue (deployment) en Kubernetes de `buildkitd` siguiendo las instrucciones [de la documentación de BuildKit](https://github.com/moby/buildkit/tree/master/examples/kubernetes).

   Crea los certificados para el demonio y el cliente de BuildKit utilizando el script [create-certs.sh](https://github.com/moby/buildkit/blob/master/examples/kubernetes/create-certs.sh), y crea un despliegue de pods de BuildKit con un servicio que se conecte a ellos.

2. Suponiendo que el servicio se llama `buildkitd`, crea un builder remoto en Buildx, asegurándote de que los archivos de certificado indicados estén presentes:

   ```console
   $ docker buildx create \
     --name remote-kubernetes \
     --driver remote \
     --driver-opt cacert=${PWD}/.certs/client/ca.pem,cert=${PWD}/.certs/client/cert.pem,key=${PWD}/.certs/client/key.pem \
     tcp://buildkitd.default.svc:1234
   ```

Ten en cuenta que esto solo funciona internamente, dentro del clúster, ya que la guía de configuración de BuildKit solo crea un servicio `ClusterIP`. Para acceder a un builder de forma remota, puedes configurar y utilizar un ingress, lo cual queda fuera del alcance de esta guía.

### Depurar un builder remoto en Kubernetes

Si tienes problemas para acceder a un builder remoto desplegado en Kubernetes, puedes utilizar el esquema de URL `kube-pod://` para conectarte directamente a un pod de BuildKit a través de la API de Kubernetes. Ten en cuenta que este método solo se conecta a un único pod en el despliegue.

```console
$ kubectl get pods --selector=app=buildkitd -o json | jq -r '.items[].metadata.name'
buildkitd-XXXXXXXXXX-xxxxx
$ docker buildx create \
  --name remote-container \
  --driver remote \
  kube-pod://buildkitd-XXXXXXXXXX-xxxxx
```

Alternativamente, utiliza el mecanismo de reenvío de puertos (port forwarding) de `kubectl`:

```console
$ kubectl port-forward svc/buildkitd 1234:1234
```

Luego puedes apuntar el driver Remote a `tcp://localhost:1234`.

