Recomendacións para executar Buildah dentro dun contedor

Cal é a beleza de desacoplar o tempo de execución do contedor en compoñentes de ferramentas separados? En particular, estas ferramentas poden comezar a combinarse para que se protexan entre si.

Recomendacións para executar Buildah dentro dun contedor

Moita xente séntese atraída pola idea de construír imaxes OCI en contenedores Kubernetes ou sistema similar. Digamos que temos un CI/CD que recolle constantemente imaxes, entón algo así RedHat OpenShift/Kubernetes sería bastante útil en termos de equilibrio de carga durante as compilacións. Ata hai pouco, a maioría da xente simplemente daba acceso aos contedores a un socket Docker e permitíalles executar o comando de compilación docker. Hai varios anos mostrámoloque isto é moi inseguro, de feito, é aínda peor que dar root sen contrasinal ou sudo.

É por iso que a xente tenta constantemente executar Buildah nun contedor. En resumo, creamos exemplo como, na nosa opinión, é mellor executar Buildah dentro dun contedor e publicar as imaxes correspondentes quay.io/buildah. Imos comezar...

axuste

Estas imaxes están construídas a partir de Dockerfiles, que se poden atopar no repositorio de Buildah no cartafol construír imaxe.
Aquí veremos versión estable de Dockerfile.

# stable/Dockerfile
#
# Build a Buildah container image from the latest
# stable version of Buildah on the Fedoras Updates System.
# https://bodhi.fedoraproject.org/updates/?search=buildah
# This image can be used to create a secured container
# that runs safely with privileges within the container.
#
FROM fedora:latest

# Don't include container-selinux and remove
# directories used by dnf that are just taking
# up space.
RUN yum -y install buildah fuse-overlayfs --exclude container-selinux; rm -rf /var/cache /var/log/dnf* /var/log/yum.*

# Adjust storage.conf to enable Fuse storage.
RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf

En lugar de OverlayFS, implementado a nivel do núcleo de Linux do host, usamos o programa dentro do contedor superposición de fusibles, porque actualmente OverlayFS só se pode montar se lle dá permisos SYS_ADMIN usando as capacidades de Linux. E queremos executar os nosos contedores Buildah sen ningún privilexio de root. A superposición de fusibles funciona con bastante rapidez e ten un mellor rendemento que o controlador de almacenamento VFS. Ten en conta que ao executar un contedor Buildah que use Fuse, debes proporcionar o dispositivo /dev/fuse.

podman run --device /dev/fuse quay.io/buildahctr ...
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock

A continuación, creamos un directorio para almacenamento adicional. Recipiente/almacenamento admite o concepto de conectar tendas de imaxes adicionais de só lectura. Por exemplo, pode configurar unha área de almacenamento de superposición nunha máquina e, a continuación, usar NFS para montar este almacenamento noutra máquina e usar imaxes desta sen descargalas mediante pull. Necesitamos este almacenamento para poder conectar algún almacenamento de imaxes do host como volume e utilizalo dentro do contedor.

# Set up environment variables to note that this is
# not starting with user namespace and default to
# isolate the filesystem with chroot.
ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot

Finalmente, ao usar a variable de ambiente BUILDAH_ISOLATION, dicímoslle ao contedor Buildah que se execute con illamento chroot por defecto. Aquí non se require illamento adicional, xa que xa estamos traballando nun contedor. Para que Buildah cree os seus propios contedores separados por espazos de nomes, é necesario o privilexio SYS_ADMIN, o que requiriría relaxar as regras SELinux e SECCOMP do contenedor, o que é contrario á nosa preferencia por construír desde un contedor seguro.

Execución de Buildah dentro dun contedor

O diagrama de imaxe de contedores Buildah comentado anteriormente permítelle variar de forma flexible os métodos de lanzamento destes contedores.

Velocidade fronte a seguridade

A seguridade informática é sempre un compromiso entre a velocidade do proceso e a cantidade de protección que hai. Esta afirmación tamén é certa cando se montan envases, polo que a continuación consideraremos opcións para tal compromiso.

A imaxe do contedor comentada anteriormente manterá o seu almacenamento en /var/lib/containers. Polo tanto, necesitamos montar o contido neste cartafol e como o fagamos afectará moito á velocidade de creación de imaxes de contedores.

Consideremos tres opcións.

Opción 1. Se se precisa a máxima seguridade, podes crear o teu propio cartafol para contedores/imaxes para cada contedor e conectalo ao contedor mediante o volume-mount. E ademais, coloque o directorio de contexto no propio contenedor, no cartafol /build:

# mkdir /var/lib/containers1
# podman run -v ./build:/build:z -v /var/lib/containers1:/var/lib/containers:Z quay.io/buildah/stable
buildah  -t image1 bud /build
# podman run -v /var/lib/containers1:/var/lib/containers:Z quay.io/buildah/stable buildah  push  image1 registry.company.com/myuser
# rm -rf /var/lib/containers1

Seguridade. Buildah que se executa nun contedor deste tipo ten a máxima seguridade: non se lle outorga ningún privilexio de root usando as capacidades e aplícanselle todas as restricións de SECOMP e SELinux. Un contedor deste tipo pode incluso executarse co illamento do espazo de nomes de usuario engadindo unha opción como —uidmap 0: 100000:10000.

Actuación. Pero o rendemento aquí é mínimo, xa que todas as imaxes dos rexistros de contedores cópiase no host cada vez e o almacenamento na caché non funciona en absoluto. Ao completar o seu traballo, o contedor Buildah debe enviar a imaxe ao rexistro e destruír o contido do servidor. A próxima vez que se constrúa a imaxe do contedor, terá que descargarse de novo desde o rexistro, xa que nese momento non quedará nada no servidor.

Opción 2. Se necesitas un rendemento a nivel de Docker, podes montar o recipiente/almacenamento host directamente no contedor.

# podman run -v ./build:/build:z -v /var/lib/containers:/var/lib/containers --security-opt label:disabled quay.io/buildah/stable buildah  -t image2 bud /build
# podman run -v /var/lib/containers:/var/lib/containers --security-opt label:disabled  quay.io/buildah/stable buildah push image2 registry.company.com/myuser

Seguridade. Esta é a forma menos segura de construír contedores porque permite que o contedor modifique o almacenamento do host e podería alimentar a Podman ou CRI-O cunha imaxe maliciosa. Ademais, terás que desactivar a separación de SELinux para que os procesos do contedor Buildah poidan interactuar co almacenamento do host. Teña en conta que esta opción aínda é mellor que un socket Docker porque o contedor está bloqueado polas funcións de seguranza restantes e non pode simplemente executar un contedor no host.

Actuación. Aquí é o máximo, xa que o caché úsase completamente. Se Podman ou CRI-O xa descargaron a imaxe necesaria no host, entón o proceso de Buildah dentro do contedor non terá que descargala de novo, e as compilacións posteriores baseadas nesta imaxe tamén poderán sacar o que necesitan da caché. .

Opción 3. A esencia deste método é combinar varias imaxes nun proxecto cun cartafol común para imaxes de contedores.

# mkdir /var/lib/project3
# podman run --security-opt label_level=s0:C100, C200 -v ./build:/build:z 
-v /var/lib/project3:/var/lib/containers:Z quay.io/buildah/stable buildah  -t image3 bud /build
# podman run --security-opt label_level=s0:C100, C200 
-v /var/lib/project3:/var/lib/containers quay.io/buildah/stable buildah push image3  registry.company.com/myuser

Neste exemplo, non eliminamos o cartafol do proxecto (/var/lib/project3) entre execucións, polo que todas as compilacións posteriores dentro do proxecto benefician da memoria caché.

Seguridade. Algo entre as opcións 1 e 2. Por unha banda, os contedores non teñen acceso ao contido no servidor e, en consecuencia, non poden introducir algo malo no almacenamento de imaxes Podman/CRI-O. Por outra banda, como parte do seu deseño, un recipiente pode interferir coa montaxe doutros recipientes.

Actuación. Aquí é peor que cando se usa unha caché compartida a nivel de host, xa que non pode usar imaxes que xa se descargaron mediante Podman/CRI-O. Non obstante, unha vez que Buildah descargue a imaxe, a imaxe pódese usar en calquera compilación posterior do proxecto.

Almacenamento adicional

У envases/almacenamento Hai unha cousa tan interesante como tendas adicionais (tendas adicionais), grazas á cal ao lanzar e construír contedores, os motores de contedores poden usar tendas de imaxes externas en modo de superposición de só lectura. Esencialmente, pode engadir un ou máis almacenamentos de só lectura ao ficheiro storage.conf para que cando inicie o contedor, o motor de contedores busque neles a imaxe desexada. Ademais, descargará a imaxe do rexistro só se non a atopa en ningún destes almacenamentos. O motor de contedores só poderá escribir no almacenamento escribible...

Se te desprazas cara arriba e miras o Dockerfile que usamos para construír a imaxe quay.io/buildah/stable, hai liñas como esta:

# Adjust storage.conf to enable Fuse storage.
RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock

Na primeira liña, modificamos /etc/containers/storage.conf dentro da imaxe do contedor, dicíndolle ao controlador de almacenamento que use "additionalimagestores" no cartafol /var/lib/shared. E na seguinte liña creamos un cartafol compartido e engadimos un par de ficheiros de bloqueo para que non haxa abusos dos contedores/almacenamento. Esencialmente, simplemente estamos creando unha tenda de imaxes de contedores baleiros.

Se montas contedores/almacenamento a un nivel superior a este cartafol, Buildah poderá utilizar as imaxes.

Agora volvamos á Opción 2 comentada anteriormente, cando o contedor Buildah pode ler e escribir nos contedores/almacenar nos hosts e, en consecuencia, ten o máximo rendemento debido ao almacenamento de imaxes en caché a nivel Podman/CRI-O, pero ofrece un mínimo de seguridade xa que pode escribir directamente no almacenamento. Agora imos engadir almacenamento adicional aquí e obter o mellor de ambos mundos.

# mkdir /var/lib/containers4
# podman run -v ./build:/build:z -v /var/lib/containers/storage:/var/lib/shared:ro -v  /var/lib/containers4:/var/lib/containers:Z  quay.io/buildah/stable 
 buildah  -t image4 bud /build
# podman run -v /var/lib/containers/storage:/var/lib/shared:ro  
-v >/var/lib/containers4:/var/lib/containers:Z quay.io/buildah/stable buildah push image4  registry.company.com/myuser
# rm -rf /var/lib/continers4

Teña en conta que o /var/lib/containers/storage do host está montado en /var/lib/shared dentro do contedor en modo de só lectura. Polo tanto, traballando nun contedor, Buildah pode usar calquera imaxe que se descargara previamente mediante Podman/CRI-O (ola, velocidade), pero só pode escribir no seu propio almacenamento (ola, seguridade). Teña en conta tamén que isto faise sen desactivar a separación de SELinux para o contedor.

Matices importantes

En ningún caso debes eliminar imaxes do repositorio subxacente. En caso contrario, o contedor Buildah pode fallar.

E estas non son todas as vantaxes

As posibilidades de almacenamento adicional non se limitan ao escenario anterior. Por exemplo, pode colocar todas as imaxes de contedores nun almacenamento de rede compartida e dar acceso a ela a todos os contedores de Buildah. Digamos que temos centos de imaxes que o noso sistema CI/CD usa habitualmente para crear imaxes de contedores. Concentramos todas estas imaxes nun host de almacenamento e despois, utilizando as ferramentas de almacenamento en rede preferidas (NFS, Gluster, Ceph, ISCSI, S3...), abrimos o acceso xeral a este almacenamento a todos os nodos de Buildah ou Kubernetes.

Agora abonda con montar este almacenamento de rede no contedor Buildah en /var/lib/shared e xa está: os contedores Buildah xa non teñen que descargar imaxes mediante pull. Así, botamos a fase de prepoboación e xa estamos listos para lanzar os contedores.

E, por suposto, pódese usar dentro dun sistema Kubernetes en directo ou dunha infraestrutura de contedores para lanzar e executar contedores en calquera lugar sen descargar imaxes. Ademais, o rexistro de contedores, ao recibir unha solicitude push para cargar nela unha imaxe actualizada, pode enviar automaticamente esta imaxe a un almacenamento de rede compartida, onde se fai instantáneamente dispoñible para todos os nós.

As imaxes dos contedores ás veces poden alcanzar moitos gigabytes de tamaño. A funcionalidade de almacenamento adicional permítelle evitar a clonación deste tipo de imaxes entre nós e fai que o lanzamento de contedores sexa case instantáneo.

Ademais, actualmente estamos a traballar nunha nova función chamada soportes de volume de superposición, que fará que a construción de contedores sexa aínda máis rápida.

Conclusión

Executar Buildah dentro dun contedor en Kubernetes/CRI-O, Podman ou incluso Docker é factible, sinxelo e moito máis seguro que usar docker.socket. Aumentamos moito a flexibilidade de traballar con imaxes, polo que pode executalas de varias formas para optimizar o equilibrio entre seguridade e rendemento.

A funcionalidade de almacenamento adicional permítelle acelerar ou incluso eliminar completamente a descarga de imaxes nos nodos.

Fonte: www.habr.com

Engadir un comentario