Usar resumos de imagens de contentores em manifestos do Kubernetes

Este tutorial mostra aos programadores e operadores que implementam contentores no Kubernetes como usar resumos de imagens de contentores para identificar imagens de contentores. Um resumo da imagem do contentor identifica de forma única e imutável uma imagem do contentor.

A implementação de imagens de contentores através do resumo da imagem oferece várias vantagens em comparação com a utilização de etiquetas de imagem. Para mais informações sobre resumos de imagens, consulte o documento que acompanha este tutorial sobre a utilização de resumos de imagens de contentores antes de continuar.

O argumento image para contentores numa especificação de pod do Kubernetes aceita imagens com resumos. Este argumento aplica-se em todos os locais onde usa uma especificação de Pod, como na secção template dos recursos Deployment, StatefulSet, DaemonSet, ReplicaSet, CronJob e Job.

Para implementar uma imagem através do resumo, usa o nome da imagem, seguido de @sha256: e do valor do resumo. Segue-se um exemplo de um recurso de implementação que usa uma imagem com um resumo. Uma implementação é um objeto da API Kubernetes que lhe permite executar várias réplicas de pods distribuídas entre os nós num cluster.

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

Uma desvantagem da utilização de resumos de imagens é que não conhece o valor do resumo até publicar a imagem num registo. À medida que cria novas imagens, o valor do resumo muda e precisa de uma forma de atualizar os manifestos do Kubernetes sempre que implementa.

Este tutorial mostra como pode usar ferramentas como: Skaffold, kpt, digester, kustomize, gke-deploy, e ko para usar resumos de imagens nos seus manifestos.

Recomendações

Este documento apresenta várias formas de usar resumos de imagens em implementações do Kubernetes. As ferramentas descritas neste documento são complementares. Por exemplo, pode usar o resultado de uma função kpt com o kustomize para criar variantes para diferentes ambientes. O Skaffold pode criar imagens com o ko e implementar as imagens nos seus clusters do Kubernetes com o kubectl ou o kpt.

O motivo pelo qual as ferramentas são complementares é que realizam edições estruturadas com base no modelo de recursos do Kubernetes (KRM). Este modelo torna as ferramentas conectáveis, e pode desenvolver a sua utilização das ferramentas para criar processos e pipelines que ajudam a implementar as suas apps e serviços.

Para começar, recomendamos a abordagem que funciona melhor com as suas ferramentas e processos existentes:

  • O Skaffold pode adicionar resumos às referências de imagens. Ativa esta função com uma pequena alteração de configuração. A adoção do Skaffold oferece vantagens adicionais, como a abstração da forma como diferentes ferramentas criam e implementam imagens de contentores.

  • Ao usar a ferramenta de análise como um webhook de admissão de mutação nos seus clusters do Kubernetes, pode adicionar resumos a todas as suas implementações com um impacto mínimo nos seus processos atuais de criação e implementação de imagens de contentores. O webhook do digestor também simplifica a adoção da autorização binária, porque só requer que seja adicionada uma etiqueta a um espaço de nomes.

  • O kpt é uma excelente opção se precisar de uma ferramenta flexível para manipular manifestos do Kubernetes. A ferramenta de digestão pode ser usada como uma função KRM do lado do cliente numa pipeline kpt.

  • Se já usa o kustomize para gerir manifestos do Kubernetes em vários ambientes, recomendamos que tire partido dos respetivos transformadores de imagens para implementar imagens por digest.

  • ko é uma excelente forma de criar e publicar imagens para apps Go e é usada por projetos de código aberto, como o Knative, o Tekton e o sigstore.

Se não usar nenhuma das ferramentas descritas neste documento, recomendamos que comece com o Skaffold e o webhook do digestor. O Skaffold é uma ferramenta comum usada por programadores e equipas de lançamento, e integra-se com as outras ferramentas descritas neste tutorial. Pode tirar partido destas opções de integração à medida que os seus requisitos evoluem. O webhook do Kubernetes do digester complementa o Skaffold ao permitir implementações baseadas em resumos para um cluster inteiro.

Usar o Skaffold

O Skaffold é uma ferramenta de linha de comandos para o desenvolvimento e a implementação contínuos de aplicações em clusters do Kubernetes.

Use o Skaffold para criar uma imagem, enviar a imagem para o Artifact Registry e substituir o valor do marcador de posição image num modelo de manifesto do Kubernetes pelo nome, pela etiqueta e pelo resumo da imagem enviada:

  1. No Cloud Shell, crie e aceda a um diretório para armazenar os ficheiros que criar nesta secção:

    mkdir -p ~/container-image-digests-tutorial/skaffold
    cd ~/container-image-digests-tutorial/skaffold
    
  2. Clone o repositório Git do Skaffold:

    git clone https://github.com/GoogleContainerTools/skaffold.git
    
  3. Aceda ao diretório do exemplo getting-started:

    cd skaffold/examples/getting-started
    
  4. Consulte a etiqueta Git que corresponde à sua versão do Skaffold:

    git checkout $(skaffold version)
    
  5. Veja o ficheiro de configuração skaffold.yaml:

    cat skaffold.yaml
    

    O ficheiro é semelhante ao seguinte:

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

    A secção build.artifacts contém um nome de imagem de marcador de posição. O Skaffold procura este marcador de posição nos ficheiros de manifesto de entrada.

    A secção manifests indica ao Skaffold que deve ler um manifesto de entrada do diretório atual com o nome k8s-pod.yaml.

    Para uma vista geral de todas as opções disponíveis, consulte a skaffold.yaml documentação de referência.

  6. Veja o modelo de manifesto do Kubernetes:

    cat k8s-pod.yaml
    

    O ficheiro é o seguinte:

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

    O valor do marcador de posição skaffold-example no campo image corresponde ao valor do campo image no ficheiro skaffold.yaml. O Skaffold substitui este valor do marcador de posição pelo nome completo da imagem e pelo resumo na saída renderizada.

  7. Crie e envie a imagem para o 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 as seguintes flags:

    • O sinalizador --file-output especifica o ficheiro onde o Skaffold guarda as informações sobre a imagem criada, incluindo o valor de resumo.
    • A flag --push indica ao Skaffold que deve enviar a imagem criada para o registo de imagens de contentores especificado pela flag --default-repo.
    • As flags --interactive e --update-check estão ambas definidas como false. Defina estas flags como false em ambientes não interativos, como pipelines de compilação, mas deixe-as com os respetivos valores predefinidos (true para ambas as flags) para o desenvolvimento local.

    Se usar o Cloud Deploy para implementar no GKE, use o ficheiro da flag --file-output como o valor da flag --build-artifacts quando criar uma versão.

  8. Renderize o manifesto do Kubernetes expandido com o nome, a etiqueta e o resumo da imagem do contentor do passo anterior:

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

    Este comando usa as seguintes flags:

    • A flag --build-artifacts faz referência ao ficheiro de saída do comando skaffold build no passo anterior.
    • A flag --digest-source=none significa que o Skaffold usa o valor de digest do ficheiro fornecido na flag --build-artifacts, em vez de resolver o digest a partir do registo de imagens de contentores.
    • A flag --offline=true significa que pode executar o comando sem precisar de acesso a um cluster do Kubernetes.
    • A flag --output especifica o ficheiro de saída para o manifesto renderizado.
  9. Ver o manifesto renderizado:

    cat rendered.yaml
    

    O resultado é semelhante ao seguinte:

    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

    Neste resultado, vê os seguintes valores:

    • TAG: a etiqueta que o Skaffold atribuiu à imagem.
    • DIGEST: o valor do resumo de imagens

Usar digestor

O Digester adiciona resumos a imagens de contentores e contentores de inicialização em especificações de modelos de pods e pods do Kubernetes. O digestor substitui as referências de imagens de contentores que usam etiquetas:

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

Com referências que usam o resumo da imagem:

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

O Digester pode ser executado como um webhook de admissão de mutação num cluster do Kubernetes ou como uma função KRM do lado do cliente com as ferramentas de linha de comandos kpt ou kustomize.

Usar a função KRM do digestor

  1. No Cloud Shell, crie e aceda a um diretório para armazenar os ficheiros que criar nesta secção:

    mkdir -p ~/container-image-digests-tutorial/digester-fn
    cd ~/container-image-digests-tutorial/digester-fn
    
  2. Transfira o ficheiro binário do digestor:

    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. Crie um manifesto do pod do Kubernetes que faça referência à imagem gcr.io/google-containers/echoserver através da 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. Execute a função KRM do digestor usando o kpt com os manifestos no diretório atual (.):

    kpt fn eval . --exec digester
    

    Quando executa este comando, o kpt faz uma atualização no local dos manifestos no diretório atual. Se quiser que o kpt mostre o manifesto atualizado na consola e deixe o ficheiro de manifesto inalterado, adicione a flag --output unwrap.

  5. Veja o manifesto atualizado:

    cat pod.yaml
    

    O ficheiro é o seguinte:

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

Usar o webhook de admissão do digestor

  1. No Cloud Shell, crie e aceda a um diretório para armazenar os ficheiros que criar nesta secção:

    mkdir -p ~/container-image-digests-tutorial/digester-webhook
    cd ~/container-image-digests-tutorial/digester-webhook
    
  2. Crie um cluster Kubernetes local com o kind:

    kind create cluster
    

    O kind é uma ferramenta de linha de comandos para executar clusters Kubernetes locais através do Docker.

  3. Implemente o webhook do digestor:

    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. Crie um espaço de nomes do Kubernetes denominado digester-demo no cluster do tipo:

    kubectl create namespace digester-demo
    
  5. Adicione a etiqueta digest-resolution: enabled ao espaço de nomes digester-demo:

    kubectl label namespace digester-demo digest-resolution=enabled
    

    O webhook do digestor adiciona resumos aos pods em espaços de nomes com esta etiqueta.

  6. Crie um manifesto de implementação do Kubernetes que faça referência à imagem gcr.io/google-containers/echoserver através da 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. Aplique o manifesto no espaço de nomes digester-demo:

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

    A flag --output indica ao kubectl que deve enviar o nome da imagem para a consola, seguido de um caráter de nova linha. O resultado é o seguinte:

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

    Este resultado mostra que o webhook do digest adicionou o digest da imagem à especificação do modelo de pod no recurso de implementação.

  8. Elimine o cluster do tipo para libertar recursos na sua sessão do Cloud Shell:

    kind delete cluster
    

Usar definidores do kpt

O kpt é uma ferramenta de linha de comandos para gerir, manipular, personalizar e aplicar manifestos de recursos do Kubernetes.

Pode usar as funções create-setters e apply-setters KRM do catálogo de funções do kpt para atualizar os resumos de imagens nos seus manifestos do Kubernetes quando cria novas imagens.

  1. No Cloud Shell, crie e aceda a um diretório para armazenar os ficheiros que criar nesta secção:

    mkdir -p ~/container-image-digests-tutorial/kpt
    cd ~/container-image-digests-tutorial/kpt
    
  2. Crie um pacote kpt no diretório atual:

    kpt pkg init --description "Container image digest tutorial"
    
  3. Crie um manifesto do pod do Kubernetes que faça referência à imagem gcr.io/google-containers/echoserver através da 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. Use o kpt para criar um setter denominado echoimage para o campo do manifesto, onde o valor existente é 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. Veja o manifesto:

    cat pod.yaml
    

    O ficheiro é o seguinte:

    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. Obtenha o valor de resumo da imagem do contentor:

    DIGEST=$(gcloud container images describe \
        gcr.io/google-containers/echoserver:1.10 \
        --format='value(image_summary.digest)')
    
  7. Defina o novo valor do campo:

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

    Quando executa este comando, o kpt faz uma substituição no local do valor do campo image no manifesto.

  8. Veja o manifesto atualizado:

    cat pod.yaml
    

    O ficheiro é o seguinte:

    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

Usar transformadores de imagens do kustomize

O kustomize é uma ferramenta de linha de comandos que lhe permite personalizar manifestos do Kubernetes através de sobreposições, patches e transformadores.

Pode usar o transformador de imagens do kustomize para atualizar o nome, a etiqueta e o resumo da imagem no manifesto existente.

O fragmento kustomization.yaml seguinte mostra como configurar o transformador de imagens para usar o valor do transformador digest para imagens em que o valor da especificação do bloco image corresponde ao valor do transformador name:

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

Para usar um transformador de imagens kustomize com um resumo de imagem, faça o seguinte:

  1. No Cloud Shell, crie e aceda a um diretório para armazenar os ficheiros que criar nesta secção:

    mkdir -p ~/container-image-digests-tutorial/kustomize
    cd ~/container-image-digests-tutorial/kustomize
    
  2. Crie um ficheiro kustomization.yaml:

    kustomize init
    
  3. Crie um manifesto do Kubernetes com uma especificação de pod que faça referência à imagem gcr.io/google-containers/echoserver através da 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. Adicione o manifesto como um recurso no ficheiro kustomization.yaml:

    kustomize edit add resource pod.yaml
    
  5. Use um transformador de imagens para atualizar o resumo da imagem:

    kustomize edit set image \
        gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
    
  6. Veja o transformador de imagens no ficheiro kustomization.yaml:

    cat kustomization.yaml
    

    O ficheiro é o seguinte:

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

    kustomize build .
    

    O resultado é o seguinte:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
        name: echoserver
        ports:
        - containerPort: 8080
  8. Para executar o transformador kustomize e aplicar o manifesto resultante a um cluster do Kubernetes num único passo, pode usar o comando kubectl apply com a flag --kustomize:

    kubectl apply --kustomize .
    

    Se quiser aplicar a saída mais tarde, pode redirecionar a saída do comando kustomize build para um ficheiro.

A usar gke-deploy

gke-deploy é uma ferramenta de linha de comandos que usa com o Google Kubernetes Engine (GKE). O gke-deploy envolve a ferramenta de linha de comandos kubectl e pode modificar os recursos que cria seguindo as práticas recomendadas da Google.

Se usar os subcomandos gke-deployprepare ou run, gke-deployresolve as etiquetas de imagem em resumos e guarda os manifestos expandidos com os resumos de imagem no ficheiro output/expanded/aggregated-resources.yaml por predefinição.

Pode usar gke-deploy run para substituir a etiqueta de imagem por um resumo e aplicar o manifesto expandido ao cluster do GKE. Embora este comando seja conveniente, tem uma desvantagem: a etiqueta de imagem é substituída no momento da implementação. A imagem associada à etiqueta pode ter sido alterada no período entre a decisão de implementação e a implementação, o que resultou na implementação de uma imagem inesperada. Para implementações de produção, recomendamos passos separados para gerar e aplicar manifestos.

Para substituir uma etiqueta de imagem num manifesto de implementação do Kubernetes pelo resumo da imagem, faça o seguinte:

  1. No Cloud Shell, crie e aceda a um diretório para armazenar os ficheiros que criar nesta secção:

    mkdir -p ~/container-image-digests-tutorial/gke-deploy
    cd ~/container-image-digests-tutorial/gke-deploy
    
  2. Instale a app gke-deploy:

    go install github.com/GoogleCloudPlatform/cloud-builders/gke-deploy@latest
    
  3. Crie um manifesto de implementação do Kubernetes que faça referência à imagem gcr.io/google-containers/echoserver através da 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. Gere um manifesto expandido com base no manifesto deployment.yaml:

    gke-deploy prepare \
        --filename deployment.yaml \
        --image gcr.io/google-containers/echoserver:1.10 \
        --version 1.10
    
  5. Veja o manifesto expandido:

    cat output/expanded/aggregated-resources.yaml
    

    O resultado é o seguinte:

    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

    No manifesto expandido, a etiqueta de imagem é substituída pelo resumo.

    O argumento --version que usou com o comando gke-deploy define o valor da etiqueta app.kubernetes.io/version na implementação e nos metadados do modelo de agrupamento do manifesto expandido.

    Para saber como usar o gke-deploy com o Cloud Build, consulte a documentação do Cloud Build para o gke-deploy.

A usar ko

O ko é uma ferramenta de linha de comandos e uma biblioteca para criar Go imagens de contentores e implementá-las em clusters do Kubernetes. O ko cria imagens sem usar o daemon do Docker, pelo que pode usá-lo em ambientes onde não pode instalar o Docker.

O subcomando ko build cria imagens e publica-as num registo de imagens de contentores ou carrega-as no seu daemon Docker local.

O subcomando ko resolve faz o seguinte:

  • Identifica as imagens a criar encontrando marcadores de posição nos campos image dos manifestos do Kubernetes que fornece através do argumento --filename.
  • Cria e publica as suas imagens.
  • Substitui os marcadores de posição de valor image pelos nomes e resumos das imagens criadas.
  • Imprime os manifestos expandidos.

Os subcomandos ko apply, create, e run executam os mesmos passos que resolve e, em seguida, executam kubectl apply, create ou run com os manifestos expandidos.

Para criar uma imagem a partir do código fonte Go e adicionar o resumo da imagem a um manifesto de implementação do Kubernetes, faça o seguinte

  1. No Cloud Shell, crie e aceda a um diretório para armazenar os ficheiros que criar nesta secção:

    mkdir -p ~/container-image-digests-tutorial/ko
    cd ~/container-image-digests-tutorial/ko
    
  2. Transfira o ficheiro ko e adicione-o ao seu 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. Crie uma app Go com o nome do módulo example.com/hello-world num novo diretório denominado 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. Defina o repositório de imagens que o ko usa para publicar imagens:

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

    Este exemplo usa o Artifact Registry, mas pode usar ko com um registo de imagens de contentores diferente.

  5. Para criar e publicar uma imagem para a sua app, siga um dos seguintes passos:

    • Crie e publique uma imagem para a sua app indicando o caminho para o seu pacote principal do Go:

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

      O argumento opcional --base-import-paths significa que ko usa o nome abreviado do diretório do pacote principal como o nome da imagem.

      O comando ko imprime o nome e o resumo da imagem para stdout no seguinte formato:

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

      Neste resultado, DIGEST é o valor do resumo da imagem.

    • Use ko para substituir um marcador de posição do manifesto pelo nome e o resumo da imagem que cria e publica:

      1. Crie um manifesto de agrupamento do Kubernetes. O manifesto usa o marcador de posição ko://IMPORT_PATH_OF_YOUR_MAIN_PACKAGE como o valor do 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. Crie e publique uma imagem para a sua app e substitua o marcador de posição do manifesto pelo nome e o resumo da imagem:

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

        ko imprime o manifesto com o nome da imagem e o resumo para 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

        Neste resultado, DIGEST é o valor do resumo da imagem.