# Multiarch building con tekton --- ## Multiarchitectura --- ## ¿Por qué multiarquitectura? Porque ARM se está haciendo cada vez más popular Raspberry con armv7 y armv8 Apple con M1 y M2 **AWS** lanzó tres generaciones de **graviton** Todos los grandes cloud providers están publicando sus instancias ARM --- Porque x86 tiene una base de mercado enorme y además tenemos powerpc y [RISC-V](https://www.theregister.com/2022/10/05/china_riscvv_arm_datacenter/) ... ya podemos correr [ubuntu en starfive](https://canonical.com/blog/canonical-enables-ubuntu-on-starfive-visionfive2-risc-v-board) --- ## ¿Como se traduce eso hoy? ARM nos permite bajar costos. además en el caso de [Graviton](https://aws.amazon.com/es/ec2/graviton/), tenemos algunas ventajas en seguridad: - cifrado de memoria - caches dedicados para cada vCPU - autenticación de punteros - mejoras en el cifrado de volúmenes ARM esta ampliamente soportada por muchas distribuciones Linux. Peeeero, no todas las imágenes que usamos están compiladas para las arquitecturas que queremos. --- ## Entonces, a buildear Construir nuestras imágenes puede implicar: - realizar el build en arquitectura nativa - usar un stage especial en Dockerfile que haga [cross-compile](https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/) - usar QEMU [Docker tiene un buildkit que ya soporta multiarch](https://docs.docker.com/build/building/multi-platform/) --- En particular elegí buildah porque prefiero que mis contenedores no dependan de una empresa en concreto, había probado [podman](https://podman.io/) (que comparte código con buildah) luego de que en [twitter me comentaron que había evolucionado mucho](https://twitter.com/pulpox/status/1316957164045553664), y tenían razón. ![](/uploads/upload_df1869a9f19f45216728c979e23ff6a8.png) Tambien en esa fecha el cambio de manos de docker no me dejó del todo tranquilo. --- ## Buildah ![](https://buildah.io/images/buildah.png =300x) No es mas que una tool que facilita la construcción de containers [OCI](https://opencontainers.org/) No necesita un daemon corriendo, puede armar un contenedor desde cero (scratch) o bien desde un Dockerfile. ```bash ❯ buildah from alpine alpine-working-container-1 ``` [Podemos pegarle una mirada al quickstart](https://developers.redhat.com/blog/2021/01/11/getting-started-with-buildah#building_a_container) --- Si necesito ejecutar un comando ```bash ❯ buildah run alpine-working-container-1 cat /etc/os-release NAME="Alpine Linux" ID=alpine VERSION_ID=3.18.0 PRETTY_NAME="Alpine Linux v3.18" HOME_URL="https://alpinelinux.org/" BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues" ``` Tengo muchos comandos disponibles con los cuales puedo modificar una imagen, la forma más cómoda y a la que estamos acostumbrados es mediante un Dockerfile ``` FROM alpine:latest CMD echo "hola" ``` --- Y para buildearla ```bash ❯ buildah bud -f Dockerfile -t prueba STEP 1/2: FROM alpine:latest STEP 2/2: CMD echo "hola" COMMIT prueba Getting image source signatures Copying blob bb01bd7e32b5 skipped: already exists Copying blob 5f70bf18a086 done Copying config e6633c211d done Writing manifest to image destination Storing signatures --> e6633c211dff Successfully tagged localhost/prueba:latest e6633c211dff7216a43d3df9782ad5e843ca4b3ecf300284782945899b0682aa ``` bud = build-using-dockerfile --- Luego para ejecutar, usando podman por ejemplo ```bash ❯ podman run --rm prueba hola ``` --- Sí, si haces un alias de podman a docker usás los mismos comandos, con algunas ventajas al usar podman: - deamonless - seguro ([con rootleess containers no comprometemos seguridad por funcionalidad](https://blog.podman.io/2023/05/rootless-podman-user-namespaces-in-plain-english/)) Y como docker: - opensource - compatible con OCI --- Y respecto al multiarch... los resultados en internet al respecto son una pesadilla, después de algo de prueba y error, la forma más concisa de alcanzarlo hoy es... --- - crear un manifest con algo como `buildah manifest create multiarchmanifest` - pasar el manifest al comando de build `buildah bud --manifest multiarchmanifest ...` - también pasarle como argumentos al build las plataformas a buildear junto con la arquitectura `--jobs 3 --platform linux/arm,linux/arm64,linux/amd64` - al realizar el push, pasarle un parámetro `--all` para que suba todas las imágenes referenciadas en el manifest --- Hacemos una prueba ... ```bash ❯ buildah manifest create multiarchmanifest 1492c93e2d0cd4247fef281a19863c03fb39415ef0ce6fceb67b5a52aec1e588 ``` --- ```bash ❯ buildah bud -f Dockerfile --manifest multiarchmanifest --jobs 3 --platform linux/arm,linux/arm64,linux/amd64 [linux/amd64] STEP 1/2: FROM alpine:latest [linux/arm64] STEP 1/2: FROM alpine:latest [linux/arm/v7] STEP 1/2: FROM alpine:latest Resolved "alpine" as an alias (/etc/containers/registries.conf.d/00-shortnames.conf) Trying to pull docker.io/library/alpine:latest... Resolved "alpine" as an alias (/etc/containers/registries.conf.d/00-shortnames.conf) Trying to pull docker.io/library/alpine:latest... [linux/amd64] STEP 2/2: CMD echo "hola" [linux/amd64] COMMIT Getting image source signatures Copying blob bb01bd7e32b5 skipped: already exists Copying blob 5f70bf18a086 skipped: already exists Copying config b50effc8ed done Writing manifest to image destination Storing signatures --> b50effc8ed11 b50effc8ed111c1a89b8fda158e1bb42cd842ec870dcd07bda892c764cb43bc5 Getting image source signatures Getting image source signatures Copying blob e14425cf8fb9 [--------------------------------------] 0.0b / 2.8MiB (skipped: 0.0b = 0.00%) Copying blob e14425cf8fb9 done Copying config d5aad8e3ba done Writing manifest to image destination Storing signatures [linux/arm/v7] STEP 2/2: CMD echo "hola" [linux/arm/v7] COMMIT Getting image source signatures Copying blob f27c3a1f7c02 skipped: already exists Copying blob 5f70bf18a086 skipped: already exists Copying config c4faaf96cc done Writing manifest to image destination Storing signatures --> c4faaf96cc07 Copying blob 08409d417260 done Copying config 44dd6f2230 done Writing manifest to image destination Storing signatures [linux/arm64] STEP 2/2: CMD echo "hola" [linux/arm64] COMMIT Getting image source signatures Copying blob 94dd7d531fa5 skipped: already exists Copying blob 5f70bf18a086 skipped: already exists Copying config 6c572ee3b5 done Writing manifest to image destination Storing signatures --> 6c572ee3b5fb 6c572ee3b5fbf2c6686553aa5be1055776189f784fb8116521485c6c03a7f3b7 ``` --- Inspecionamos el manifest ```bash ❯ buildah manifest inspect multiarchmanifest { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", "manifests": [ { "mediaType": "application/vnd.oci.image.manifest.v1+json", "size": 750, "digest": "sha256:9654098360c19a2ecb756a796606b4a5027d0b581cc2fb698d6195f8110e214a", "platform": { "architecture": "amd64", "os": "linux" } }, { "mediaType": "application/vnd.oci.image.manifest.v1+json", "size": 750, "digest": "sha256:589da5a6a1d09ebe7699653012d48f03e68974819afc41ead88b396aaf0f60f1", "platform": { "architecture": "arm", "os": "linux", "variant": "v7" } }, { "mediaType": "application/vnd.oci.image.manifest.v1+json", "size": 750, "digest": "sha256:1b0bc937f834fecdf44fdd954a898166801e787eef5bb128874d04c2257f077f", "platform": { "architecture": "arm64", "os": "linux", "variant": "v8" } } ] } ``` --- Ok, hasta acá todo genial, veamos como meterlo en un CI/CD, cloud native style :octopus: :cloud: --- ![](/uploads/upload_c1f389d7757a9f06c77a7e9681e0602b.png) --- # Nope! dije... cloud native style... --- ## [Tekton](https://tekton.dev/) ![](https://tekton.dev/images/tekton-horizontal-color.png =200x) Es un framework opensource para crear sistemas de CI/CD. - Está disponible como [CRD](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions) (Kubernetes Custom Resource Definition) - Se puede instalar en cualquier cluster Kubernetes - Usa imágenes de contenedores para realizar las operaciones en nuestro pipeline de CI/CD --- Veamos entonces algunos conceptos básicos... --- ### Steps: ![](/uploads/upload_7e9b1322d2828f49ac58fc4283f24ee8.png =150x) La unidad más pequeña, es un contenedor que toma un **input** y produce un **ouput** ```yaml steps: - name: decir-hola image: ubuntu env: - name: SALUDO value: "Hola mundo" script: | echo ${SALUDO} ``` --- ### Task ![](/uploads/upload_7265bc7dde050d20329ffaa2dbf0defc.png =100x) Es una secuencia de **steps** ejecutando una secuencia de **contenedores**. En kubernetes crea un **pod**. Todos los steps en una tarea tienen acceso a un workspace compartido. Es un [CR](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) (Custom Resource) de tipo Task. --- Tiene un nombre para poder referenciarla y reutilizarla ```yaml apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: hola spec: params: - name: saludo default: Hola mundo steps: - name: decir-hola image: ubuntu script: | echo $(params.saludo) ``` Tambien una lista de parametros con su nombre, descripciones y/o valores por defecto. A su vez tiene una lista de **steps**. --- ### TaskRun Es el recurso que ejecuta una **Task**, acá es donde se proveen los parámetros y cualquier otro recurso que necesite una **Task**. ```yaml apiVersion: tekton.dev/v1beta1 kind: TaskRun metadata: generateName: saludador- spec: params: - name: saludo value: Todo bien gente? taskRef: - name: hola ``` [Recomiendo mirar el getting started](https://tekton.dev/docs/getting-started/) --- ### Tekton Pipeline Las **tasks** comparten recursos mediante **results** y mediante **workspace** ![](/uploads/upload_76eca96fcead6ea80333c710862e9615.png =400x) - **results**: cuando la cantidad de datos a compartir es poca - **workspace**: en caso contrario (crea un PVC en kubernetes) --- ```yaml apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: project-pipeline spec: params: - name: api-url - name: cloud-region tasks: - name: clone taskRef: name: git-clone - name: build taskRef: name: build runAfter: - clone - name: publish taskRef: name: publish runAfter: - build ``` --- Los pipelines se ejecutan usando un **PipelineRun** con los parámetros y recursos que necesite el **Pipeline** ```yaml apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: generateName: project-pipeline-run- spec: params: - name: api-url value: demo.com - name: cloud-region value: us-east-1 pipelineRef: - name: project-pipeline ``` --- ### Tekton Catalog ![](https://hub.tekton.dev/static/media/logo.9e712511.png =200x) En https://hub.tekton.dev/ podemos encontrar un repositorio de tasks y pipelines reutilizables. --- Entonces, vamos a instalar tekton en nuestro cluster kubernetes ``` kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml ``` --- Luego vamos a buscar algún recurso de [buildah en el hub](https://hub.tekton.dev/?query=buildah) --- Creamos una task propia con algunas modifaciones ``` kubectl apply -f https://gist.githubusercontent.com/pulpo/fa0a34e717de398754530917c8a274ae/raw/cf9231cb302030e6d9302c314bd7a233c7eddb9e/custombuildah.yaml ``` --- Adicionalmente agregamos otras task que vamos a necesitar, la de git-clone: ``` kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.9/git-clone.yaml ``` Y luego estamos en condiciones de crear un pipelinerun --- Como lo va a manejar kubernetes ![](https://d2908q01vomqb2.cloudfront.net/d435a6cdd786300dff204ee7c2ef942d3e9034e2/2021/02/24/wwpslccbraps_image003.jpg =500x) --- Qué más hay para leer y probar? - https://aws.amazon.com/es/blogs/aws-spanish/ejecucion-de-contenedores-multiarquitectura-con-amazon-eks/ - https://aws.amazon.com/es/blogs/containers/cloud-native-ci-cd-with-tekton-and-argocd-on-aws/ - https://aws.amazon.com/es/blogs/aws-spanish/comparando-el-desempeno-de-las-instancias-amazon-ec2-aws-graviton2-intel-x64-y-amd-epyc/ --- Preguntas? --- ### Bonus track: Ñamandú ![](/uploads/upload_6b9d53c16a93cf67c9841e1b509d48bc.png =100x) ``` kubectl apply -f https://gist.githubusercontent.com/pulpo/e5ea055c03786c0dc55e0847630a70dc/raw/e6ae77fe5c82f6923070b3ccae0a4741a6763988/namandu.yaml ``` ---
{"title":"Multiarch building con tekton","author":"pulpo","type":"slide","slideOptions":{"theme":"sky","transition":"zoom"}}