Unidad 3.3: Pipelines de CI/CD para IONOS CLOUD
Introducción
Ha containerizado TaskBoard, ha subido sus imágenes a IONOS CLOUD Container Registry y lo ha desplegado en Managed Kubernetes de forma manual. Ejecutar docker push y kubectl apply desde su portátil no es escalable para un equipo, y no sobrevive al momento en que olvida qué etiqueta de imagen está en producción. En esta unidad conecta todo el ciclo para que git push sea el único paso manual. Un commit desencadena una compilación, la imagen se almacena en Container Registry etiquetada con el SHA de git, y la nueva etiqueta se despliega en el clúster.
También someterá la infraestructura a la misma disciplina. Terraform plan se ejecuta en cada solicitud de extracción para que los revisores vean la diferencia antes de que se produzca cualquier cambio, y apply se ejecuta solo después de la fusión. Dos restricciones de IONOS CLOUD determinan cada pipeline que escriba aquí: la API es asíncrona, por lo que los despliegues deben esperar la preparación en lugar de darla por sentada, y la autenticación de Container Registry se basa únicamente en docker login con token, sin RBAC y sin repositorios por equipo, por lo que las credenciales se almacenan en secretos de CI.
1. Diseño de pipelines para IONOS CLOUD
Un pipeline de CI/CD en IONOS CLOUD se divide en dos flujos distintos que no deben compartir un trabajo. Los cambios de aplicación siguen build -> test -> push image -> deploy to Kubernetes. Los cambios de infraestructura siguen plan -> apply. Mezclarlos significa que un error tipográfico en un manifiesto de Kubernetes puede bloquear una corrección urgente de infraestructura, y un terraform apply lento retrasa cada despliegue de aplicación.
El flujo de aplicación termina con kubectl apply o, más precisamente, con una actualización controlada de la etiqueta de imagen contra un Deployment existente. El flujo de infraestructura termina con terraform apply contra sus recursos de IONOS CLOUD. Ambos flujos se autentican en IONOS CLOUD, pero utilizan credenciales diferentes: el flujo de aplicación necesita un token de Container Registry y un kubeconfig, mientras que el flujo de infraestructura necesita un token bearer IONOS_TOKEN para la API de la nube.
1.1 Etiquetado de imágenes con el SHA de Git
Nunca despliegue :latest. Una etiqueta mutable hace que las reversiones sean ambiguas y rompe el vínculo entre un pod en ejecución y el commit que lo generó. Etiquete cada imagen con el SHA de git inmutable para que la revisión en ejecución sea siempre rastreable.
# Derive an immutable tag from the commit
REGISTRY="taskboard.cr.de-fra.ionos.com"
SHA=$(git rev-parse --short HEAD)
IMAGE="${REGISTRY}/taskboard-api:${SHA}"
docker build -t "${IMAGE}" ./api
docker push "${IMAGE}"
El nombre de host del registro sigue el patrón {registry-name}.cr.{location-with-dash}.ionos.com, por ejemplo, tue1608es.cr.es-vit.ionos.com. El nombre de host se asigna solo después de que el registro alcance el estado Running y permanece vacío hasta entonces, por lo que una canalización que aprovisiona un registro nuevo debe leer el nombre de host desde la salida de Terraform en lugar de codificarlo de forma fija.
1.2 Separación de los repositorios de aplicación e infraestructura
Mantenga Terraform en un repositorio de infraestructura y los manifiestos de Kubernetes junto con el código de la aplicación en un repositorio de aplicación. El repositorio de infraestructura se aplica al fusionar; el repositorio de aplicación compila y despliega al enviar. Esta separación mantiene el alcance de un cambio incorrecto reducido y permite otorgar a diferentes equipos diferentes niveles de acceso.
taskboard-app/ # build, push, kubectl deploy
api/Dockerfile
k8s/deployment.yaml
.github/workflows/deploy.yml
taskboard-infra/ # terraform plan/apply
main.tf
modules/
.github/workflows/terraform.yml
2. GitHub Actions para IONOS CLOUD
Un flujo de trabajo de GitHub Actions para el flujo de la aplicación tiene tres etapas lógicas en un solo trabajo: compilación y pruebas, inicio de sesión y publicación con docker, y luego despliegue en Managed Kubernetes. Las partes específicas de IONOS CLOUD son el inicio de sesión en el registro (basado en token) y la obtención del kubeconfig.
2.1 Almacenamiento de secretos de IONOS CLOUD
Los tokens nunca deben estar en el repositorio. Almacene el token de Container Registry y el kubeconfig como secretos del repositorio o del entorno. La contraseña del token de Container Registry se muestra solo una vez en el momento de la creación, por lo que captúrela de inmediato y almacénela en CI. Un token de registro puede ser permanente o temporal con un expiryDate, y al expirar, el token se elimina en lugar de desactivarse, lo que significa que un token expirado en CI hace que docker login falle de forma directa en lugar de degradarse de manera silenciosa.
| Nombre del secreto | Contenido | Utilizado por |
|---|---|---|
CR_USERNAME |
Nombre del token de Container Registry | docker login |
CR_PASSWORD |
Contraseña del token de Container Registry (se muestra una vez) | docker login |
KUBECONFIG |
kubeconfig codificado en base64 desde la salida de Terraform | kubectl |
IONOS_TOKEN |
Token bearer de la API de la nube | Terraform / ionosctl |
2.2 El flujo de trabajo de despliegue
# .github/workflows/deploy.yml
name: deploy-taskboard
on:
push:
branches: [main]
env:
REGISTRY: taskboard.cr.de-fra.ionos.com
IMAGE_NAME: taskboard-api
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set image tag
run: echo "TAG=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
- name: Run tests
run: |
cd api
pip install -r requirements.txt
pytest
- name: Log in to IONOS CLOUD Container Registry
run: echo "${{ secrets.CR_PASSWORD }}" | docker login "$REGISTRY" \
-u "${{ secrets.CR_USERNAME }}" --password-stdin
- name: Build and push image
run: |
docker build -t "$REGISTRY/$IMAGE_NAME:$TAG" ./api
docker push "$REGISTRY/$IMAGE_NAME:$TAG"
- name: Configure kubectl
run: |
mkdir -p "$HOME/.kube"
echo "${{ secrets.KUBECONFIG }}" | base64 -d > "$HOME/.kube/config"
- name: Deploy to Managed Kubernetes
run: |
kubectl set image deployment/taskboard-api \
api="$REGISTRY/$IMAGE_NAME:$TAG"
kubectl rollout status deployment/taskboard-api --timeout=180s
kubectl set image actualiza únicamente el campo de imagen en el Deployment existente, lo que desencadena una actualización gradual sin volver a aplicar el manifiesto completo. La etapa kubectl rollout status se bloquea hasta que la implementación se complete o se agote el tiempo de espera, que es la forma correcta de mostrar una implementación fallida como un pipeline fallido. El propio kubeconfig proviene del clúster de Managed Kubernetes: se descarga desde la configuración del clúster o, en un pipeline automatizado, se lee desde la salida de Terraform (cubierto en la Unidad 3.2) y se almacena el valor codificado en base64 como el secreto KUBECONFIG.
3. GitLab CI para IONOS CLOUD
GitLab CI expresa el mismo flujo como etapas discretas en .gitlab-ci.yml. Los detalles específicos de IONOS CLOUD son idénticos: inicio de sesión con Docker basado en token en el registro y un kubeconfig para el clúster. GitLab proporciona un servicio Docker-in-Docker para construir imágenes dentro de la canalización.
3.1 Etapas de la canalización
# .gitlab-ci.yml
stages: [test, build, deploy]
variables:
REGISTRY: taskboard.cr.de-fra.ionos.com
IMAGE_NAME: taskboard-api
test:
stage: test
image: python:3.12
script:
- cd api && pip install -r requirements.txt && pytest
build:
stage: build
image: docker:24
services: [docker:24-dind]
script:
- export TAG=$CI_COMMIT_SHORT_SHA
- echo "$CR_PASSWORD" | docker login "$REGISTRY" -u "$CR_USERNAME" --password-stdin
- docker build -t "$REGISTRY/$IMAGE_NAME:$TAG" ./api
- docker push "$REGISTRY/$IMAGE_NAME:$TAG"
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
- echo "$KUBECONFIG_B64" | base64 -d > /tmp/kubeconfig
- export KUBECONFIG=/tmp/kubeconfig
- kubectl set image deployment/taskboard-api api="$REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA"
- kubectl rollout status deployment/taskboard-api --timeout=180s
only: [main]
Almacene CR_USERNAME, CR_PASSWORD y KUBECONFIG_B64 como variables CI/CD enmascaradas y protegidas en la configuración del proyecto de GitLab. Las variables protegidas solo se exponen a las pipelines que se ejecutan en ramas protegidas, lo que mantiene las credenciales de producción fuera de las pipelines de ramas de características. CI_COMMIT_SHORT_SHA es el equivalente de GitLab de la etiqueta SHA de git, lo que ofrece la misma garantía de etiqueta inmutable que el ejemplo de GitHub Actions.
4. Terraform en CI/CD
Los cambios de infraestructura merecen una revisión antes de afectar a los recursos de IONOS CLOUD, ya que terraform apply crea recursos facturables y puede destruirlos. El patrón estándar ejecuta terraform plan en cada solicitud de extracción (pull request) y publica el plan como un comentario en la PR, y luego ejecuta terraform apply solo después de la fusión (merge) en main. Esto proporciona a los revisores la diferencia exacta y evita que cualquier persona aplique cambios sin revisar.
4.1 Plan en PR, Apply en Merge
# .github/workflows/terraform.yml
name: terraform
on:
pull_request:
branches: [main]
push:
branches: [main]
env:
IONOS_TOKEN: ${{ secrets.IONOS_TOKEN }}
jobs:
plan:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform plan -no-color -out=tfplan
- run: terraform show -no-color tfplan > plan.txt
- uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const plan = fs.readFileSync('plan.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '```\n' + plan.slice(0, 60000) + '\n```'
});
apply:
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform apply -auto-approve
El proveedor Terraform de IONOS CLOUD se autentica a partir de la variable de entorno IONOS_TOKEN, por lo que pasar el token de portador como variable de entorno es todo lo que necesita el bloque del proveedor. El proveedor consulta internamente las operaciones asíncronas de IONOS CLOUD, por lo que terraform apply se bloquea hasta que cada recurso alcanza su estado de listo antes de continuar. Esto significa que la línea de integración no necesita sus propios bucles de preparación para los recursos administrados por Terraform.
4.2 Estado remoto para CI/CD
El estado local no funciona en CI/CD porque cada ejecutor comienza con una extracción limpia. Utilice el backend de IONOS CLOUD Object Storage compatible con S3 para que cada ejecución de la línea de integración lea y escriba el mismo estado, y para que el bloqueo del estado impida que dos aplicaciones simultáneas lo corrompan.
terraform {
backend "s3" {
bucket = "taskboard-tfstate"
key = "infra/terraform.tfstate"
region = "de"
endpoints = { s3 = "https://s3-eu-central-1.ionoscloud.com" }
skip_credentials_validation = true
skip_region_validation = true
skip_requesting_account_id = true
}
}
Object Storage utiliza autenticación con Access Key y Secret Key, no tokens de portador, por lo que las credenciales del backend son distintas de IONOS_TOKEN. Proporcione estas credenciales a la pipeline como secretos AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY, que el backend de S3 lee automáticamente.
5. Estrategias de despliegue y reversión
La estrategia de despliegue predeterminada de Kubernetes es RollingUpdate, que reemplaza los pods de forma incremental para que el servicio siga disponible durante un despliegue. Para cargas de trabajo que no pueden ejecutar dos versiones simultáneamente, use Recreate, que termina todos los pods antiguos antes de iniciar los nuevos, a costa de una breve interrupción.
5.1 Configuración de la estrategia
apiVersion: apps/v1
kind: Deployment
metadata:
name: taskboard-api
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels: { app: taskboard-api }
template:
metadata:
labels: { app: taskboard-api }
spec:
imagePullSecrets:
- name: cr-pull-secret
containers:
- name: api
image: taskboard.cr.de-fra.ionos.com/taskboard-api:abc1234
readinessProbe:
httpGet: { path: /healthz, port: 8080 }
initialDelaySeconds: 5
maxUnavailable: 0 garantiza que no se pierda capacidad durante la implementación, y readinessProbe asegura que el tráfico solo llegue a los pods que informan de un estado saludable. La entrada imagePullSecrets hace referencia al token de Container Registry, ya que el clúster descarga las imágenes utilizando las mismas credenciales basadas en token que su pipeline utilizó para publicarlas. Las implementaciones canary y blue-green son posibles mediante Deployments paralelos y el cambio de tráfico, o mediante una herramienta de GitOps como ArgoCD, que se aborda como un patrón en la Unidad 5.3 y no aquí.
5.2 Reversión
Cuando una implementación falla, revierta la aplicación con kubectl rollout undo, lo cual devuelve el Deployment a su revisión anterior sin reconstruir nada.
# Inspect revision history
kubectl rollout history deployment/taskboard-api
# Roll back to the immediately previous revision
kubectl rollout undo deployment/taskboard-api
# Roll back to a specific revision
kubectl rollout undo deployment/taskboard-api --to-revision=4
Dado que cada imagen se etiqueta con su SHA de git, también puede revertir de manera determinista con kubectl set image apuntando a una etiqueta conocida como correcta. En el caso de la infraestructura, revertir significa deshacer el commit problemático y volver a ejecutar terraform apply, lo cual reconcilia los recursos en vivo con el estado comprometido. Si el estado en sí está dañado, restáurelo desde una copia versionada en el backend de Object Storage.
6. Creación de una biblioteca de módulos de Terraform
Una vez que la infraestructura de TaskBoard funcione, extraiga los patrones repetidos en módulos para que el próximo servicio no tenga que empezar desde cero. Un módulo agrupa recursos relacionados detrás de variables de entrada y expone salidas, convirtiendo una pila verbosa en unas pocas líneas de código del llamador.
6.1 Estructura del módulo
# modules/k8s-service/variables.tf
variable "name" { type = string }
variable "node_count" { type = number, default = 2 }
variable "k8s_version" { type = string, default = "1.34" }
# modules/k8s-service/main.tf
resource "ionoscloud_k8s_cluster" "this" {
name = var.name
k8s_version = var.k8s_version
}
resource "ionoscloud_k8s_node_pool" "this" {
name = "${var.name}-pool"
k8s_cluster_id = ionoscloud_k8s_cluster.this.id
node_count = var.node_count
# ... cores, ram, availability_zone, etc.
}
# modules/k8s-service/outputs.tf
output "cluster_id" { value = ionoscloud_k8s_cluster.this.id }
Las versiones de Kubernetes compatibles son 1.34, 1.33, 1.32 y 1.31, por lo que debe fijar una versión conocida y estable en el valor predeterminado del módulo y permitir que los llamadores la sobrescriban. Los grupos de Node pueden utilizar tipos de servidor Dedicated Core o vCPU, y un grupo de node tiene un máximo absoluto de 100 nodos con un máximo recomendado de 20, por lo que debe validar node_count contra esos límites en lugar de permitir que un error tipográfico provisione un grupo de tamaño excesivo.
6.2 Consumir el módulo
module "taskboard" {
source = "./modules/k8s-service"
name = "taskboard-prod"
node_count = 3
}
output "taskboard_cluster" {
value = module.taskboard.cluster_id
}
Versione el repositorio de su módulo con etiquetas de git y haga referencia a una etiqueta específica en source para que un cambio aguas abajo en el módulo no modifique silenciosamente una pila existente. De esta manera, un equipo convierte una implementación funcional en una biblioteca reutilizable.
Tarjeta rápida de referencia de la API
Puntos finales clave utilizados por las pipelines de CI/CD en IONOS CLOUD:
| Método | Punto final | Descripción |
|---|---|---|
POST |
/containerregistries/registries/{id}/tokens |
Crear un token de registro para CI |
GET |
/k8s/{clusterId}/kubeconfig |
Obtener kubeconfig para la implementación |
GET |
/k8s/{clusterId}/nodepools |
Listar pools de nodos para un clúster |
GET |
/requests/{requestId}/status |
Consultar operación asíncrona hasta DONE |
DELETE |
/containerregistries/registries/{id}/repositories/{name} |
Eliminar un repositorio (nombre codificado en URL) |
URL base: https://api.ionos.com/cloudapi/v6
Autenticación: Authorization: Bearer <token>
Laboratorio de código
Objetivo: Crear una pipeline de GitHub Actions que construya, publique y despliegue TaskBoard en Managed Kubernetes en cada push a main.
Requisitos previos:
- Cuenta de IONOS CLOUD con token de API (
IONOS_TOKEN) - Un Container Registry y un clúster de Managed Kubernetes existentes (de las Unidades 3.1 y 3.2)
- Un repositorio de GitHub para la aplicación TaskBoard
docker,kubectlyionosctlinstalados localmente
Paso 1: Crear un token de registro para CI
ionosctl container-registry token create \
--registry-id "$REGISTRY_ID" --name ci-deploy
Salida esperada:
TokenId Name Status ExpiryDate
a1b2c3d4 ci-deploy enabled -
Password: <shown once - copy it now>
Paso 2: Almacenar secretos en GitHub
gh secret set CR_USERNAME --body "ci-deploy"
gh secret set CR_PASSWORD --body "<password from step 1>"
gh secret set KUBECONFIG --body "$(ionosctl k8s kubeconfig get \
--cluster-id "$CLUSTER_ID" | base64 -w0)"
Salida esperada:
✓ Set secret CR_USERNAME
✓ Set secret CR_PASSWORD
✓ Set secret KUBECONFIG
Paso 3: Agregar el archivo de flujo de trabajo
Commitee .github/workflows/deploy.yml de la sección 2.2 en el repositorio.
Salida esperada:
[main 9f3c1ab] add deploy workflow
1 file changed, 38 insertions(+)
Paso 4: Activar la canalización
git commit --allow-empty -m "trigger deploy"
git push origin main
Salida esperada:
To github.com:you/taskboard-app.git
8d2e1f0..9f3c1ab main -> main
Paso 5: Supervisar la ejecución
gh run watch
Salida esperada:
✓ build-and-deploy succeeded
✓ Build and push image
✓ Deploy to Managed Kubernetes
Paso 6: Verificar la implementación en el clúster
kubectl get deployment taskboard-api -o wide
Salida esperada:
NAME READY IMAGE
taskboard-api 3/3 taskboard.cr.de-fra.ionos.com/taskboard-api:9f3c1ab
Lista de verificación:
- [ ] La imagen con la etiqueta git-SHA existe en Container Registry
- [ ] La imagen de la implementación coincide con la etiqueta enviada
- [ ]
kubectl rollout statusinformó éxito en la canalización - [ ] Una segunda generación de una nueva etiqueta SHA y una actualización gradual limpia
Limpieza:
gh secret delete CR_USERNAME CR_PASSWORD KUBECONFIG
ionosctl container-registry token delete --registry-id "$REGISTRY_ID" --token-id "$TOKEN_ID"
Errores comunes
Errores de desarrollo a evitar con CI/CD en IONOS CLOUD:
-
Codificar de forma fija el nombre de host del registro antes de que el registro esté en estado Running
- Problema: La pipeline falla en docker login con un error de resolución de DNS contra un nombre de host vacío.
- Por qué ocurre: El nombre de host del registro se asigna solo después de que el registro alcanza el estado Running, por lo que un registro recién aprovisionado aún no tiene nombre de host.
- Solución: Lea el nombre de host desde la salida de Terraform en lugar de codificarlo de forma fija, y condicione la tarea de push a que el registro esté listo:
output "registry_hostname" { value = ionoscloud_container_registry.this.hostname } -
Esperar que un servicio LoadBalancer de Kubernetes sea un equilibrador de carga externo auténtico
- Problema: El rendimiento se estanca y la IP de origen de cada solicitud aparece como una dirección interna del clúster, lo que rompe el control de frecuencia y los registros de auditoría.
- Por qué ocurre: Un servicio LoadBalancer en Managed Kubernetes no aprovisiona un LB externo. IONOS CLOUD reserva una IP pública estática y la asigna como IP secundaria a un nodo de trabajo, y kube-proxy aplica NAT al tráfico hacia el pod, lo que limita el rendimiento al límite público de ese único nodo y pierde la IP de origen.
- Solución: Establezca
externalTrafficPolicy: Localpara preservar la IP de origen, y coloque un Managed ALB aprovisionado por separado delante del servicio o distribuya el tráfico entre varias IPs de LB para superar el rendimiento de un solo nodo:
spec: type: LoadBalancer externalTrafficPolicy: Local -
Ejecución de Terraform con estado local en CI/CD
- Problema: Cada ejecución de la pipeline comienza con un estado vacío, por lo que
terraform applyintenta recrear recursos que ya existen y produce errores por nombres duplicados. - Por qué ocurre: Los ejecutores de CI realizan la extracción de un espacio de trabajo limpio sin archivo de estado, y no hay un backend compartido.
- Solución: Configure el backend de Object Storage compatible con S3 para que todas las ejecuciones compartan el estado, y proporcione las credenciales de Access Key y Secret Key como secretos de la pipeline:
export AWS_ACCESS_KEY_ID="$IONOS_S3_KEY" export AWS_SECRET_ACCESS_KEY="$IONOS_S3_SECRET" terraform init - Problema: Cada ejecución de la pipeline comienza con un estado vacío, por lo que
Resumen
Ahora puede ejecutar el ciclo completo de compilación, prueba y despliegue desde un único git push. La línea de aplicaciones compila un contenedor, le asigna una etiqueta con el SHA de git, inicia sesión en IONOS CLOUD Container Registry mediante un inicio de sesión de docker basado en token, sube la imagen y la despliega en Managed Kubernetes con un kubectl set image y un kubectl rollout status con control de preparación. La línea de infraestructura mantiene a Terraform en un estado coherente al planificar en solicitudes de extracción y aplicar solo en la fusión, respaldada por un estado compartido en Object Storage. Cuando algo falla, kubectl rollout undo y un commit revertido de Terraform le devuelven a un estado conocido y estable, y su biblioteca de módulos extraídos significa que el siguiente servicio reutiliza estos patrones en lugar de reinventarlos.
Puntos clave:
- Separe el flujo de aplicaciones (
build -> test -> push -> deploy) del flujo de infraestructura (plan -> apply); nunca comparta un trabajo entre ellos - Asigne una etiqueta a cada imagen con el SHA de git inmutable, nunca
:latest, para que la revisión en ejecución sea siempre rastreable y las reversiones sean deterministas - Los tokens de Container Registry se muestran una sola vez al crearse y se eliminan al expirar; guárdelos como secretos de CI y extraiga las imágenes con las mismas credenciales basadas en token
- Ejecute
terraform planen las solicitudes de extracción yterraform applyen la fusión, con un estado compartido compatible con S3 en Object Storage yIONOS_TOKENcomo secreto - Revierta las aplicaciones con
kubectl rollout undoy la infraestructura revirtiendo el commit y volviendo a aplicar
Terminología importante:
- Etiqueta inmutable: Una etiqueta de imagen de contenedor derivada del SHA de git que nunca cambia, vinculando cada pod en ejecución con el commit exacto que la compiló.
- Actualización gradual: La estrategia de despliegue predeterminada de Kubernetes que reemplaza los pods de forma incremental para que el servicio siga disponible durante un despliegue.
- Planificar en solicitud de extracción: El patrón de CI de Terraform que consiste en ejecutar
terraform planen las solicitudes de extracción y publicar la diferencia para su revisión antes de cualquierapply. - Backend de estado remoto: Un almacén de estado de Terraform compartido (Object Storage compatible con S3 en IONOS CLOUD) que permite a cada ejecución de CI leer y escribir el mismo estado con bloqueo.
- imagePullSecret: Un Secret de Kubernetes que contiene las credenciales de token de Container Registry para que el clúster pueda extraer imágenes privadas.
Próximos pasos
Continuar aprendiendo: Unidad 3.4: Verificación de conocimientos: contenedores y CI/CD
Temas relacionados: