# Configurar BuildKit


Si creas un builder `docker-container` o `kubernetes` con Buildx, puedes
aplicar una [configuración de BuildKit](/build/buildkit/configure/toml-configuration/) personalizada pasando la
[opción `--buildkitd-config`](/reference/cli/docker/buildx/create/#buildkitd-config)
al comando `docker buildx create`.

## Espejo de registro (Registry mirror)

Puedes definir un espejo de registro (registry mirror) para usarlo en tus compilaciones.
Al hacerlo, se redirige a BuildKit para descargar imágenes desde un nombre de host diferente. Los siguientes pasos ejemplifican
cómo definir un espejo para `docker.io` (Docker Hub) hacia `mirror.gcr.io`.

1. Crea un archivo TOML en `/etc/buildkitd.toml` con el siguiente contenido:

   ```toml
   debug = true
   [registry."docker.io"]
     mirrors = ["mirror.gcr.io"]
   ```

   > [!NOTE]
   >
   > `debug = true` activa las solicitudes de depuración en el demonio de BuildKit, lo que registra un
   > mensaje que muestra cuándo se está utilizando un espejo.

2. Crea un builder `docker-container` que utilice esta configuración de BuildKit:

   ```console
   $ docker buildx create --use --bootstrap \
     --name mybuilder \
     --driver docker-container \
     --buildkitd-config /etc/buildkitd.toml
   ```

3. Compila una imagen:

   ```bash
   docker buildx build --load . -f - <<EOF
   FROM alpine
   RUN echo "hello world"
   EOF
   ```

Los registros de BuildKit para este builder ahora muestran que utiliza el espejo de GCR. Puedes
saberlo por el hecho de que los mensajes de respuesta incluyen las cabeceras HTTP `x-goog-*`.

```console
$ docker logs buildx_buildkit_mybuilder0
```

```text
...
time="2022-02-06T17:47:48Z" level=debug msg="do request" request.header.accept="application/vnd.docker.container.image.v1+json, */*" request.header.user-agent=containerd/1.5.8+unknown request.method=GET spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="fetch response received" response.header.accept-ranges=bytes response.header.age=1356 response.header.alt-svc="h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" response.header.cache-control="public, max-age=3600" response.header.content-length=1469 response.header.content-type=application/octet-stream response.header.date="Sun, 06 Feb 2022 17:25:17 GMT" response.header.etag="\"774380abda8f4eae9a149e5d5d3efc83\"" response.header.expires="Sun, 06 Feb 2022 18:25:17 GMT" response.header.last-modified="Wed, 24 Nov 2021 21:07:57 GMT" response.header.server=UploadServer response.header.x-goog-generation=1637788077652182 response.header.x-goog-hash="crc32c=V3DSrg==" response.header.x-goog-hash.1="md5=d0OAq9qPTq6aFJ5dXT78gw==" response.header.x-goog-metageneration=1 response.header.x-goog-storage-class=STANDARD response.header.x-goog-stored-content-encoding=identity response.header.x-goog-stored-content-length=1469 response.header.x-guploader-uploadid=ADPycduqQipVAXc3tzXmTzKQ2gTT6CV736B2J628smtD1iDytEyiYCgvvdD8zz9BT1J1sASUq9pW_ctUyC4B-v2jvhIxnZTlKg response.status="200 OK" spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="fetch response received" response.header.accept-ranges=bytes response.header.age=760 response.header.alt-svc="h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" response.header.cache-control="public, max-age=3600" response.header.content-length=1471 response.header.content-type=application/octet-stream response.header.date="Sun, 06 Feb 2022 17:35:13 GMT" response.header.etag="\"35d688bd15327daafcdb4d4395e616a8\"" response.header.expires="Sun, 06 Feb 2022 18:35:13 GMT" response.header.last-modified="Wed, 24 Nov 2021 21:07:12 GMT" response.header.server=UploadServer response.header.x-goog-generation=1637788032100793 response.header.x-goog-hash="crc32c=aWgRjA==" response.header.x-goog-hash.1="md5=NdaIvRUyfar8201DleYWqA==" response.header.x-goog-metageneration=1 response.header.x-goog-storage-class=STANDARD response.header.x-goog-stored-content-encoding=identity response.header.x-goog-stored-content-length=1471 response.header.x-guploader-uploadid=ADPycdtR-gJYwC7yHquIkJWFFG8FovDySvtmRnZBqlO3yVDanBXh_VqKYt400yhuf0XbQ3ZMB9IZV2vlcyHezn_Pu3a1SMMtiw response.status="200 OK" spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="do request" request.header.accept="application/vnd.docker.image.rootfs.diff.tar.gzip, */*" request.header.user-agent=containerd/1.5.8+unknown request.method=GET spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="fetch response received" response.header.accept-ranges=bytes response.header.age=1356 response.header.alt-svc="h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" response.header.cache-control="public, max-age=3600" response.header.content-length=2818413 response.header.content-type=application/octet-stream response.header.date="Sun, 06 Feb 2022 17:25:17 GMT" response.header.etag="\"1d55e7be5a77c4a908ad11bc33ebea1c\"" response.header.expires="Sun, 06 Feb 2022 18:25:17 GMT" response.header.last-modified="Wed, 24 Nov 2021 21:07:06 GMT" response.header.server=UploadServer response.header.x-goog-generation=1637788026431708 response.header.x-goog-hash="crc32c=ZojF+g==" response.header.x-goog-hash.1="md5=HVXnvlp3xKkIrRG8M+vqHA==" response.header.x-goog-metageneration=1 response.header.x-goog-storage-class=STANDARD response.header.x-goog-stored-content-encoding=identity response.header.x-goog-stored-content-length=2818413 response.header.x-guploader-uploadid=ADPycdsebqxiTBJqZ0bv9zBigjFxgQydD2ESZSkKchpE0ILlN9Ibko3C5r4fJTJ4UR9ddp-UBd-2v_4eRpZ8Yo2llW_j4k8WhQ response.status="200 OK" spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
...
```

## Configuración de certificados de registro

Si especificas certificados de registro en la configuración de BuildKit, el demonio
copia los archivos dentro del contenedor bajo `/etc/buildkit/certs`. Los siguientes
pasos muestran cómo añadir un certificado de registro autofirmado a la configuración de BuildKit.

1. Añade la siguiente configuración a `/etc/buildkitd.toml`:

   ```toml
   # /etc/buildkitd.toml
   debug = true
   [registry."myregistry.com"]
     ca=["/etc/certs/myregistry.pem"]
     [[registry."myregistry.com".keypair]]
       key="/etc/certs/myregistry_key.pem"
       cert="/etc/certs/myregistry_cert.pem"
   ```

   Esto le indica al builder que suba las imágenes al registro `myregistry.com` utilizando
   los certificados en la ubicación especificada (`/etc/certs`).

2. Crea un builder `docker-container` que utilice esta configuración:

   ```console
   $ docker buildx create --use --bootstrap \
     --name mybuilder \
     --driver docker-container \
     --buildkitd-config /etc/buildkitd.toml
   ```

3. Inspecciona el archivo de configuración del builder (`/etc/buildkit/buildkitd.toml`), este
   muestra que la configuración de certificados ahora está aplicada en el builder.

   ```console
   $ docker exec -it buildx_buildkit_mybuilder0 cat /etc/buildkit/buildkitd.toml
   ```

   ```toml
   debug = true
 
   [registry]
 
     [registry."myregistry.com"]
       ca = ["/etc/buildkit/certs/myregistry.com/myregistry.pem"]
 
       [[registry."myregistry.com".keypair]]
         cert = "/etc/buildkit/certs/myregistry.com/myregistry_cert.pem"
         key = "/etc/buildkit/certs/myregistry.com/myregistry_key.pem"
   ```

4. Verifica que los certificados estén dentro del contenedor:

   ```console
   $ docker exec -it buildx_buildkit_mybuilder0 ls /etc/buildkit/certs/myregistry.com/
   myregistry.pem    myregistry_cert.pem   myregistry_key.pem
   ```

Ahora puedes subir (push) al registro utilizando este builder, y este se autenticará
utilizando los certificados:

```console
$ docker buildx build --push --tag myregistry.com/myimage:latest .
```

## Redes CNI (CNI networking)

Las redes CNI para builders pueden ser útiles para lidiar con el conflicto (contención) de puertos de red
durante compilaciones concurrentes. CNI [aún no](https://github.com/moby/buildkit/issues/28)
está disponible en la imagen predeterminada de BuildKit. Sin embargo, puedes crear tu propia imagen que
incluya soporte para CNI.

El siguiente ejemplo de Dockerfile muestra una imagen de BuildKit personalizada con soporte para CNI.
Utiliza la [configuración CNI para pruebas de integración](https://github.com/moby/buildkit/blob/master//hack/fixtures/cni.json)
en BuildKit como ejemplo. Siéntete libre de incluir tu propia configuración CNI.

```dockerfile
# syntax=docker/dockerfile:1
 
ARG BUILDKIT_VERSION=v0.28.0
ARG CNI_VERSION=v1.0.1
 
FROM --platform=$BUILDPLATFORM alpine AS cni-plugins
RUN apk add --no-cache curl
ARG CNI_VERSION
ARG TARGETOS
ARG TARGETARCH
WORKDIR /opt/cni/bin
RUN curl -Ls https://github.com/containernetworking/plugins/releases/download/$CNI_VERSION/cni-plugins-$TARGETOS-$TARGETARCH-$CNI_VERSION.tgz | tar xzv
 
FROM moby/buildkit:${BUILDKIT_VERSION}
ARG BUILDKIT_VERSION
RUN apk add --no-cache iptables
COPY --from=cni-plugins /opt/cni/bin /opt/cni/bin
ADD https://raw.githubusercontent.com/moby/buildkit/${BUILDKIT_VERSION}/hack/fixtures/cni.json /etc/buildkit/cni.json
```

Ahora puedes compilar esta imagen y crear una instancia de builder a partir de ella utilizando
[la opción `--driver-opt image`](/reference/cli/docker/buildx/create/#driver-opt):

```console
$ docker buildx build --tag buildkit-cni:local --load .
$ docker buildx create --use --bootstrap \
  --name mybuilder \
  --driver docker-container \
  --driver-opt "image=buildkit-cni:local" \
  --buildkitd-flags "--oci-worker-net=cni"
```

## Limitación de recursos

### Paralelismo máximo

Puedes limitar el paralelismo del solucionador (solver) de BuildKit, lo cual es particularmente útil
para máquinas de baja potencia, utilizando una [configuración de BuildKit](/build/buildkit/configure/toml-configuration/)
al crear un builder con la [opción `--buildkitd-config`](/reference/cli/docker/buildx/create/#buildkitd-config).

```toml
# /etc/buildkitd.toml
[worker.oci]
  max-parallelism = 4
```

Ahora puedes [crear un builder `docker-container`](/build/builders/drivers/docker-container/)
que utilizará esta configuración de BuildKit para limitar el paralelismo.

```console
$ docker buildx create --use \
  --name mybuilder \
  --driver docker-container \
  --buildkitd-config /etc/buildkitd.toml
```

### Límite de conexiones TCP

Las conexiones TCP están limitadas a 4 conexiones simultáneas por registro para
descargar y subir imágenes, más una conexión adicional dedicada para las solicitudes de
metadatos. Este límite de conexiones evita que tu compilación se quede atascada mientras
descarga imágenes. La conexión dedicada a los metadatos ayuda a reducir el tiempo total de la
compilación.

Más información: [moby/buildkit#2259](https://github.com/moby/buildkit/pull/2259)


