Usa resúmenes de imágenes de contenedores en los manifiestos de Kubernetes

Last reviewed 2023-07-21 UTC

En este instructivo, se indica a los desarrolladores y operadores que implementan contenedores en Kubernetes cómo usar resúmenes de imágenes de contenedores para identificar imágenes de contenedor. El resumen de una imagen de contenedor identifica de manera inequívoca y no intencional la imagen de un contenedor.

La implementación de imágenes de contenedores mediante el resumen de imágenes proporciona varios beneficios en comparación con el uso de etiquetas de imagen. Para obtener más información sobre los resúmenes de imágenes, consulta el documento adjunto sobre el uso de resúmenes de imágenes de contenedor antes de continuar con este instructivo.

El argumento image para contenedores en una especificación de pod de Kubernetes acepta imágenes con resúmenes. Este argumento se aplica en cualquier lugar en el que uses una especificación de pod, como en la sección template de los recursos de implementación, StatefulSet, DaemonSet, ReplicaSet, CronJob y Job.

Para implementar una imagen con el resumen, usa el nombre de la imagen, seguido de @sha256: y el valor del resumen. El siguiente es un ejemplo de un recurso de implementación que usa una imagen con un resumen:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-deployment
spec:
  selector:
    matchLabels:
      app: echo
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
        ports:
        - containerPort: 8080

Una desventaja de usar resúmenes de imágenes es que no conoces el valor del resumen hasta que hayas publicado tu imagen en un registro. A medida que compilas imágenes nuevas, el valor del resumen cambia y necesitas encontrar una forma de actualizar los manifiestos de Kubernetes cada vez que lo implementas.

En este instructivo, se muestra cómo puedes usar herramientas como, por ejemplo, Skaffold, kpt, digester, kustomize, gke-deploy y ko para usar resúmenes de imágenes en tus manifiestos.

Recomendaciones

En este documento, se presentan varias formas de usar resúmenes de imágenes en las implementaciones de Kubernetes. Las herramientas descritas en este documento son complementarias. Por ejemplo, puedes usar el resultado de una función kpt con kustomize para crear variantes para entornos diferentes. Skaffold puede compilar imágenes con ko y, luego, implementarlas en los clústeres de Kubernetes con kubectl o kpt.

El motivo por el que las herramientas son complementarias es que realizan ediciones estructuradas en función del modelo de recursos de Kubernetes (KRM). Este modelo hace que las herramientas sean acoplables y que puedas desarrollar el uso de estas para crear procesos y canalizaciones que te ayuden a implementar tus apps y servicios.

Para comenzar, recomendamos el enfoque que funciona mejor con tus herramientas y procesos existentes:

  • Skaffold puede agregar resúmenes a las referencias de imágenes. Esta función se habilita con un pequeño cambio de configuración. La adopción de Skaffold proporciona beneficios adicionales, como la abstracción de las herramientas para compilar y, luego, implementar imágenes de contenedor.

  • Si usas la herramienta de resumen como un webhook de admisión de mutación en tus clústeres de Kubernetes, puedes agregar resúmenes a todas tus implementaciones con un impacto mínimo en tus procesos actuales para compilar y, luego, implementar imágenes de contenedores. El webhook de resumen también simplifica la adopción de la autorización binaria, porque solo requiere que se agregue una etiqueta a un espacio de nombres.

  • kpt es una gran opción si necesitas una herramienta flexible para manipular los manifiestos de Kubernetes. La herramienta de resumen se puede usar como una función de KRM del cliente en una canalización de kpt.

  • Si ya usas kustomize para administrar los manifiestos de Kubernetes en diferentes entornos, te recomendamos aprovechar sus transformadores de imágenes para implementar imágenes mediante el resumen.

  • ko es una excelente forma de compilar y publicar imágenes para apps de Go, y se usa en proyectos de código abierto como Knative, Tekton y sigstore.

Si no usas ninguna de las herramientas que se describen en este documento, te recomendamos comenzar con Skaffold y el webhook de resumen. Skaffold es una herramienta común que usan los desarrolladores y los equipos de versiones. Además, se integra con las otras herramientas que se describen en este instructivo. Puedes aprovechar estas opciones de integración a medida que evolucionan tus requisitos. El webhook de Kubernetes de resumen complementa Skaffold; para ello, habilita implementaciones basadas en resúmenes para todo un clúster.

Objetivos

  • Usa Skaffold para compilar y enviar una imagen, y para insertar el nombre de la imagen y el resumen en un manifiesto de Kubernetes.
  • Usa la función del cliente de resumen y el webhook de admisión de mutación para agregar resúmenes a las imágenes de los Pods de Kubernetes y las plantillas de Pods.
  • Usa los métodos set de kpt para reemplazar la etiqueta de una imagen en un manifiesto de Kubernetes por un resumen de imágenes.
  • Usa kustomize para generar un manifiesto de Kubernetes con un resumen de imágenes.
  • Usa gke-deploy para resolver la etiqueta de una imagen en un resumen en un manifiesto de Kubernetes.
  • Usa ko para compilar y enviar una imagen, y para insertar el nombre de la imagen y el resumen en un manifiesto de Kubernetes.

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.

Antes de comenzar

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the Artifact Registry API.

    Enable the API

  4. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  5. En Cloud Shell, configura el proyecto predeterminado para Google Cloud CLI:

    gcloud config set project PROJECT_ID
    

    Reemplaza PROJECT_ID por el ID del proyecto.

  6. Crea un repositorio de imágenes de contenedor en Artifact Registry:

    gcloud artifacts repositories create REPOSITORY \
        --location=LOCATION \
        --repository-format=docker
    

    Reemplaza lo siguiente:

    • REPOSITORY: Es el nombre que deseas usar para el repositorio, por ejemplo, digest-tutorial.
    • LOCATION: una ubicación de Artifact Registry, por ejemplo, us-central1.
  7. Configura la autenticación en la ubicación de Artifact Registry para las herramientas de la CLI que se usan en este instructivo:

    gcloud auth configure-docker LOCATION-docker.pkg.dev
    

Usa Skaffold

Skaffold es una herramienta de línea de comandos para el desarrollo y la implementación continuas de aplicaciones en clústeres de Kubernetes.

Usa Skaffold para compilar una imagen, enviarla a Artifact Registry y reemplazar el valor de marcador de posición image en una plantilla del manifiesto de Kubernetes por el nombre, la etiqueta y el resumen de la imagen enviada:

  1. En Cloud Shell, crea un archivo y ve a un directorio para almacenar los archivos que creas en esta sección:

    mkdir -p ~/container-image-digests-tutorial/skaffold
    cd ~/container-image-digests-tutorial/skaffold
    
  2. Clona el repositorio de Git de Skaffold:

    git clone https://github.com/GoogleContainerTools/skaffold.git
    
  3. Ve al directorio del ejemplo de getting-started:

    cd skaffold/examples/getting-started
    
  4. Consulta la etiqueta de Git que coincide con tu versión de Skaffold:

    git checkout $(skaffold version)
    
  5. Consulta el archivo de configuración skaffold.yaml:

    cat skaffold.yaml
    

    El archivo es similar al siguiente:

    apiVersion: skaffold/v4beta6
    kind: Config
    build:
      artifacts:
      - image: skaffold-example
    manifests:
      rawYaml:
      - k8s-pod.yaml
    

    La sección build.artifacts contiene un nombre de imagen de marcador de posición. Skaffold busca este marcador de posición en los archivos del manifiesto de entrada.

    En la sección manifests, se le indica a Skaffold que lea un manifiesto de entrada del directorio actual con el nombre k8s-pod.yaml.

    Para obtener una descripción general de todas las opciones disponibles, consulta la documentación de referencia de skaffold.yaml.

  6. Consulta la plantilla del manifiesto de Kubernetes:

    cat k8s-pod.yaml
    

    El archivo es el siguiente:

    apiVersion: v1
    kind: Pod
    metadata:
      name: getting-started
    spec:
      containers:
      - name: getting-started
        image: skaffold-example
    

    El valor de marcador de posición skaffold-example en el campo image coincide con el valor del campo image en el archivo skaffold.yaml. Skaffold reemplaza este valor de marcador de posición con el nombre completo de la imagen y el resumen en el resultado renderizado.

  7. Compila y envía la imagen a Artifact Registry:

    skaffold build \
        --default-repo=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY \
        --file-output=artifacts.json \
        --interactive=false \
        --push=true \
        --update-check=false
    

    Este comando usa las siguientes marcas:

    • La marca --file-output especifica el archivo en el que Skaffold guarda la información sobre la imagen compilada, incluido el valor del resumen.
    • La marca --push indica a Skaffold que envíe la imagen compilada al registro de imágenes del contenedor que especifica la marca --default-repo.
    • Las marcas --interactive y --update-check se configuraron como false. Establece estas marcas en false en entornos no interactivos, como las canalizaciones de compilación, pero déjalas como sus valores predeterminados (true para ambas marcas) para el desarrollo local.

    Si usas Cloud Deploy para implementar en GKE, usa el archivo de la marca --file-output como el valor de la marca --build-artifacts cuando crees una versión.

  8. Renderiza el manifiesto de Kubernetes expandido con el nombre, la etiqueta y el resumen de la imagen de contenedor del paso anterior:

    skaffold render \
        --build-artifacts=artifacts.json \
        --digest-source=none \
        --interactive=false \
        --offline=true \
        --output=rendered.yaml \
        --update-check=false
    

    Este comando usa las siguientes marcas:

    • La marca --build-artifacts hace referencia al archivo de salida del comando skaffold build en el paso anterior.
    • La marca --digest-source=none significa que Skaffold usa el valor de resumen del archivo proporcionado en la marca --build-artifacts, en lugar de resolver el resumen desde el registro de imágenes del contenedor.
    • La marca --offline=true significa que puedes ejecutar el comando sin requerir acceso a un clúster de Kubernetes.
    • La marca --output especifica el archivo de salida para el manifiesto renderizado.
  9. Visualiza el manifiesto renderizado:

    cat rendered.yaml
    

    El resultado se parece al siguiente:

    apiVersion: v1
    kind: Pod
    metadata:
      name: getting-started
    spec:
      containers:
      - image: LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/skaffold-example:TAG@sha256:DIGEST
        name: getting-started
    

    En este resultado, encontrarás los siguientes valores:

    • TAG: Es la etiqueta que Skaffold asignó a la imagen.
    • DIGEST: El valor de resumen de la imagen

Usa el resumen

El Digester agrega resúmenes al contenedor y a las imágenes de contenedor init en el Pod de Kubernetes y en las especificaciones de las plantillas de Pods. El resumen reemplaza las referencias de imágenes de contenedor que usan etiquetas:

spec:
  containers:
  - image: gcr.io/google-containers/echoserver:1.10

Con referencias que usan el resumen de la imagen:

spec:
  containers:
  - image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229

El resumen puede ejecutarse como un webhook de admisión de mutación en un clúster de Kubernetes, o como una función de KRM del cliente con las herramientas de línea de comandos de kpt o kustomize.

Usa la función de KRM del resumen

  1. En Cloud Shell, crea un archivo y ve a un directorio para almacenar los archivos que creas en esta sección:

    mkdir -p ~/container-image-digests-tutorial/digester-fn
    cd ~/container-image-digests-tutorial/digester-fn
    
  2. Descarga el objeto binario del resumen:

    mkdir -p ${HOME}/bin
    export PATH=${HOME}/bin:${PATH}
    DIGESTER_VERSION=$(curl -sL https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r .tag_name)
    curl -L "https://github.com/google/k8s-digester/releases/download/${DIGESTER_VERSION}/digester_$(uname -s)_$(uname -m)" --output ${HOME}/bin/digester
    chmod +x ${HOME}/bin/digester
    
  3. Crea un manifiesto del Pod de Kubernetes que haga referencia a la imagen gcr.io/google-containers/echoserver mediante la etiqueta 1.10:

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. Ejecuta la función de KRM del resumen mediante kpt con los manifiestos en el directorio actual (.):

    kpt fn eval . --exec digester
    

    Cuando ejecutas este comando, kpt realiza una actualización local de los manifiestos en el directorio actual. Si deseas que kpt muestre el manifiesto actualizado en la consola y deje el archivo de manifiesto sin cambios, agrega la marca --output unwrap.

  5. Visualiza el manifiesto actualizado:

    cat pod.yaml
    

    El archivo es el siguiente:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
        - name: echoserver
          image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
          ports:
            - containerPort: 8080
    

Usa el webhook de admisión del resumen

  1. En Cloud Shell, crea un archivo y ve a un directorio para almacenar los archivos que creas en esta sección:

    mkdir -p ~/container-image-digests-tutorial/digester-webhook
    cd ~/container-image-digests-tutorial/digester-webhook
    
  2. Crea un clúster local de Kubernetes con kind:

    kind create cluster
    

    kind es una herramienta de línea de comandos para ejecutar clústeres locales de Kubernetes con Docker.

  3. Implementa el webhook de resumen:

    DIGESTER_VERSION=$(curl -sL https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r .tag_name)
    kustomize build "https://github.com/google/k8s-digester.git/manifests?ref=${DIGESTER_VERSION}" | kubectl apply -f -
    
  4. Crea un espacio de nombres de Kubernetes llamado digester-demo en el clúster de kind:

    kubectl create namespace digester-demo
    
  5. Agrega la etiqueta digest-resolution: enabled al espacio de nombres digester-demo:

    kubectl label namespace digester-demo digest-resolution=enabled
    

    El webhook de resumen agrega resúmenes a los Pods en los espacios de nombres con esta etiqueta.

  6. Crea un manifiesto de implementación de Kubernetes que haga referencia a la imagen gcr.io/google-containers/echoserver mediante la etiqueta 1.10:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
        spec:
          containers:
          - name: echoserver
            image: gcr.io/google-containers/echoserver:1.10
            ports:
            - containerPort: 8080
    EOF
    
  7. Aplica el manifiesto en el espacio de nombres digester-demo:

    kubectl apply --filename deployment.yaml --namespace digester-demo \
        --output jsonpath='{.spec.template.spec.containers[].image}{"\n"}'
    

    La marca --output indica a kubectl que genere el nombre de la imagen en la consola, seguido de un carácter de salto de línea. Este es el resultado:

    gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
    

    Este resultado muestra que el webhook de resumen agregó el resumen de la imagen a la especificación de la plantilla del Pod en el recurso de implementación.

  8. Borra el clúster de kind para liberar recursos en tu sesión de Cloud Shell:

    kind delete cluster
    

Usa métodos set de kpt

kpt es una herramienta de línea de comandos para administrar, manipular, personalizar y aplicar manifiestos de recursos de Kubernetes.

Puedes usar las funciones KRM create-setters y apply-setters del catálogo de funciones de kpt para actualizar los resúmenes de imágenes en tus manifiestos de Kubernetes cuando compilas imágenes nuevas.

  1. En Cloud Shell, crea un archivo y ve a un directorio para almacenar los archivos que creas en esta sección:

    mkdir -p ~/container-image-digests-tutorial/kpt
    cd ~/container-image-digests-tutorial/kpt
    
  2. Crea un paquete de kpt en el directorio actual:

    kpt pkg init --description "Container image digest tutorial"
    
  3. Crea un manifiesto del Pod de Kubernetes que haga referencia a la imagen gcr.io/google-containers/echoserver mediante la etiqueta 1.10:

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. Usa kpt a fin de crear un método set llamado echoimage para el campo del manifiesto, en el que el valor existente es gcr.io/google-containers/echoserver:1.10:

    kpt fn eval . \
        --image gcr.io/kpt-fn/create-setters@sha256:0220cc87f29ff9abfa3a3b5643aa50f18d355d5e9dc9e1f518119633ddc4895c \
        -- "echoimage=gcr.io/google-containers/echoserver:1.10"
    
  5. Visualiza el manifiesto:

    cat pod.yaml
    

    El archivo es el siguiente:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10 # kpt-set: ${echoimage}
        ports:
        - containerPort: 8080
    
  6. Obtén el valor de resumen de la imagen de contenedor:

    DIGEST=$(gcloud container images describe \
        gcr.io/google-containers/echoserver:1.10 \
        --format='value(image_summary.digest)')
    
  7. Establece el nuevo valor de campo:

    kpt fn eval . \
        --image gcr.io/kpt-fn/apply-setters@sha256:4d4295727183396f0c3c6a75d2560254c2f9041a39e95dc1e5beffeb49cc1a12 \
        -- "echoimage=gcr.io/google-containers/echoserver:1.10@$DIGEST"
    

    Cuando ejecutas esta comando, kpt realiza un reemplazo local del valor del campo image en el manifiesto.

  8. Visualiza el manifiesto actualizado:

    cat pod.yaml
    

    El archivo es el siguiente:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 # kpt-set: ${echoimage}
        ports:
        - containerPort: 8080
    

Usa transformadores de imágenes de Kustomize

kustomize es una herramienta de línea de comandos que te permite personalizar los manifiestos de Kubernetes mediante superposiciones, parches y transformadores.

Puedes usar el transformador de imágenes de kustomize para actualizar el nombre, la etiqueta y el resumen de la imagen en tu manifiesto existente.

En el siguiente fragmento de kustomization.yaml, se muestra cómo configurar el transformador de imagen a fin de usar el valor digest de transformador para imágenes en las que el valor image de la especificación del Pod coincide con el valor name del transformador:

images:
- name: gcr.io/google-containers/echoserver
  digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229

Para usar un transformador de imagen de kustomize con un resumen de imágenes, haz lo siguiente:

  1. En Cloud Shell, crea un archivo y ve a un directorio para almacenar los archivos que creas en esta sección:

    mkdir -p ~/container-image-digests-tutorial/kustomize
    cd ~/container-image-digests-tutorial/kustomize
    
  2. Crea un archivo kustomization.yaml:

    kustomize init
    
  3. Crea un manifiesto de Kubernetes con una especificación de pod que haga referencia a la imagen gcr.io/google-containers/echoserver con la etiqueta 1.10:

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. Agrega el manifiesto como un recurso en el archivo kustomization.yaml:

    kustomize edit add resource pod.yaml
    
  5. Usa un transformador de imágenes para actualizar el resumen de la imagen:

    kustomize edit set image \
        gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
    
  6. Consulta el transformador de imágenes en el archivo kustomization.yaml:

    cat kustomization.yaml
    

    El archivo es el siguiente:

    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
    - pod.yaml
    images:
    - digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
      name: gcr.io/google-containers/echoserver
    
  7. Consulta el manifiesto resultante:

    kustomize build .
    

    Esta es la salida:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
        name: echoserver
        ports:
        - containerPort: 8080
    
  8. Para ejecutar el transformador de kustomize y aplicar el manifiesto resultante a un clúster de Kubernetes en un solo paso, puedes usar el comando kubectl apply con la marca --kustomize:

    kubectl apply --kustomize .
    

    Si deseas aplicar el resultado más tarde, puedes redireccionar los resultados del comando kustomize build a un archivo.

Usa gke-deploy

gke-deploy es una herramienta de línea de comandos que se usa con Google Kubernetes Engine (GKE). gke-deploy une la herramienta de línea de comandos de kubectl y puede modificar los recursos que creas de acuerdo con las prácticas recomendadas de Google.

Si utiliza los subcomandos gke-deploy, prepare o run, gke-deploy resuelve las etiquetas de tu imagen en los resúmenes y guarda los manifiestos expandidos con los resúmenes de las imágenes en el archivo output/expanded/aggregated-resources.yaml de forma predeterminada.

Puedes usar gke-deploy run para sustituir la etiqueta de imagen por un resumen y aplicar el manifiesto expandido a tu clúster de GKE. Aunque este comando es conveniente, tiene una desventaja: la etiqueta de la imagen se reemplaza en el momento de la implementación. Es posible que la imagen asociada con la etiqueta haya cambiado desde el momento en que decidiste realizar la implementación y después de hacerla, lo que genera una imagen inesperada. En el caso de las implementaciones de producción, recomendamos seguir pasos independientes para generar y aplicar manifiestos.

Para reemplazar la etiqueta de una imagen en un manifiesto de implementación de Kubernetes con el resumen de la imagen, haz lo siguiente:

  1. En Cloud Shell, crea un archivo y ve a un directorio para almacenar los archivos que creas en esta sección:

    mkdir -p ~/container-image-digests-tutorial/gke-deploy
    cd ~/container-image-digests-tutorial/gke-deploy
    
  2. Instala gke-deploy:

    go install github.com/GoogleCloudPlatform/cloud-builders/gke-deploy@latest
    
  3. Crea un manifiesto de implementación de Kubernetes que haga referencia a la imagen gcr.io/google-containers/echoserver mediante la etiqueta 1.10:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
        spec:
          containers:
          - name: echoserver
            image: gcr.io/google-containers/echoserver:1.10
            ports:
            - containerPort: 8080
    EOF
    
  4. Genera un manifiesto expandido en función del manifiesto deployment.yaml:

    gke-deploy prepare \
        --filename deployment.yaml \
        --image gcr.io/google-containers/echoserver:1.10 \
        --version 1.10
    
  5. Consulta el manifiesto expandido:

    cat output/expanded/aggregated-resources.yaml
    

    Este es el resultado:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/managed-by: gcp-cloud-build-deploy
        app.kubernetes.io/version: "1.10"
      name: echo-deployment
      namespace: default
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
            app.kubernetes.io/managed-by: gcp-cloud-build-deploy
            app.kubernetes.io/version: "1.10"
        spec:
          containers:
          - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
            name: echoserver
            ports:
            - containerPort: 8080
    

    En el manifiesto expandido, la etiqueta de imagen se reemplaza por el resumen.

    El argumento --version que usaste con el comando gke-deploy establece el valor de la etiqueta app.kubernetes.io/version en la implementación y los metadatos de la plantilla de Pod del manifiesto expandido.

    Para obtener información sobre cómo usar gke-deploy con Cloud Build, consulta la documentación de Cloud Build para gke-deploy.

Usa ko

ko es una herramienta de línea de comandos y una biblioteca que permite compilar imágenes de contenedor de Go para implementarlas luego en clústeres de Kubernetes. ko compila imágenes sin usar el daemon de Docker, por lo que puedes usarlo en entornos en los que no puedas instalar Docker.

El subcomando ko (build) compila las imágenes y las publica en un registro de imágenes de contenedor o las carga en tu daemon de Docker local.

El subcomando koresolve realiza las siguientes opciones:

  • Identifica las imágenes que se compilarán mediante la búsqueda de marcadores de posición en los campos image de los manifiestos de Kubernetes que proporciones con el argumento --filename.
  • Compila y publica tus imágenes.
  • Reemplaza los marcadores de posición del valor image con los nombres y resúmenes de las imágenes que compiló.
  • Imprime los manifiestos expandidos.

Los subcomandos ko apply, create y run realizan los mismos pasos que resolve y, luego, ejecutan kubectl apply, create o run con los manifiestos expandidos.

Sigue estos pasos para compilar una imagen desde el código fuente de Go y agregar el resumen de la imagen a un manifiesto de implementación de Kubernetes:

  1. En Cloud Shell, crea un archivo y ve a un directorio para almacenar los archivos que creas en esta sección:

    mkdir -p ~/container-image-digests-tutorial/ko
    cd ~/container-image-digests-tutorial/ko
    
  2. Descarga ko y agrégalo a tu PATH:

    mkdir -p ${HOME}/bin
    export PATH=${HOME}/bin:${PATH}
    KO_VERSION=$(curl -sL https://api.github.com/repos/ko-build/ko/releases/latest | jq -r .tag_name | cut -c2-)
    curl -L "https://github.com/ko-build/ko/releases/download/v${KO_VERSION}/ko_${KO_VERSION}_$(uname -s)_$(uname -m).tar.gz" | tar -zxC ${HOME}/bin ko
    
  3. Crea una aplicación Go con el nombre del módulo example.com/hello-world en un directorio nuevo llamado app:

    mkdir -p app/cmd/ko-example
    
    cd app
    
    go mod init example.com/hello-world
    
    cat << EOF > cmd/ko-example/main.go
    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("hello world")
    }
    EOF
    
  4. Define el repositorio de imágenes que usa ko para publicar imágenes:

    export KO_DOCKER_REPO=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY
    

    En este ejemplo, se usa Artifact Registry, pero puedes usar ko con un registro de imágenes de contenedor diferente.

  5. Si deseas compilar y publicar una imagen para tu app, sigue uno de estos pasos:

    • Proporciona la ruta de acceso al paquete principal de Go de modo que puedas compilar y publica una imagen para tu app:

      ko build --base-import-paths ./cmd/ko-example
      

      El argumento opcional --base-import-paths significa que ko usa el nombre corto del directorio del paquete principal como el nombre de la imagen.

      ko imprime el nombre de la imagen y el resumen en stdout en el siguiente formato:

      LOCATION-docker.pkg.dev/PROJECT_ID/ko-example@sha256:DIGEST
      

      En este resultado, DIGEST es el valor de resumen de la imagen.

    • Usa ko para reemplazar un marcador de posición del manifiesto con el nombre y el resumen de la imagen que compila y publica:

      1. Crear un manifiesto de pod de Kubernetes. El manifiesto usa el marcador de posición ko://IMPORT_PATH_OF_YOUR_MAIN_PACKAGE como el valor del campo image:

        cat << EOF > ko-pod.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          name: ko-example
        spec:
          containers:
          - name: hello-world
            image: ko://example.com/hello-world/cmd/ko-example
        EOF
        
      2. Compila y publica una imagen para tu app y reemplaza el marcador de posición del manifiesto por el nombre y el resumen de la imagen:

        ko resolve --base-import-paths --filename ko-pod.yaml
        

        ko imprime el manifiesto con el nombre y el resumen de la imagen en stdout:

        apiVersion: v1
        kind: Pod
        metadata:
          name: ko-example
        spec:
          containers:
          - name: hello-world
            image: LOCATION-docker.pkg.dev/PROJECT_ID/ko-example@sha256:DIGEST
        

        En este resultado, DIGEST es el valor de resumen de la imagen.

Limpia

La manera más fácil de eliminar la facturación es borrar el proyecto de Google Cloud que creaste para el instructivo. Como alternativa, puedes borrar los recursos individuales.

Borra el proyecto

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Borra recursos

Si deseas conservar el proyecto de Google Cloud que usaste en este instructivo, borra los recursos individuales:

  1. En Cloud Shell, borra los archivos que creaste en este instructivo:

    cd
    rm -rf ~/container-image-digests-tutorial
    
  2. Borra el repositorio de imágenes del contenedor en Artifact Registry:

    gcloud artifacts repositories delete REPOSITORY \
        --location=LOCATION --async --quiet
    

¿Qué sigue?