當前位置: 妍妍網 > 碼農

【運維幹貨分享】如何在 Kubernetes Pod 中構建 Docker 映像

2024-09-23碼農


本初學者指南重點介紹使用 Kaniko 映像生成器在 Kubernetes pod 中設定 Docker 映像構建的分步過程。

當涉及到CI/CD,可能會有基於VM和容器的應用程式。理想情況下,人們會使用現有的 VM 基礎設施來構建 Docker 映像。但是,如果你擁有容器化基礎設施,最好將其用於 CI/CD 工作流。

在 Docker 中構建 Docker 在 CI 中,主要階段之一是構建 Docker 映像。在容器化構建中,你可以在 Docker 工作流程中使用 Docker。

但這種方法有以下缺點。

  • Docker 構建容器在特權模式下執行。這是一個很大的安全問題,它為惡意攻擊敞開了大門。

  • Kubernetes 從其核心中刪除了 Docker。因此,除非你向所有 Kubernetes 節點添加 docker,否則將來將無法掛載到主機。docker.sock

  • 這些問題可以使用 Kaniko 解決。

    還有一個名為 podman 的實用程式,它可以在沒有 root 許可權的情況下執行和建立容器。你可以檢視 podman 教程以了解更多資訊。

  • 使用 Kaniko 在 Kubernetes 中構建 Docker 映像

  • Kaniko 是由 Google 建立的開源容器映像構建工具。

  • 它不需要對主機的特權存取來構建容器映像。

    這是 Kaniko 的工作原理,

  • 有一個專用的 Kaniko 執行器映像,用於構建容器映像。建議使用 gcr.io/kaniko-project/executor 映像以避免任何可能的問題。因為此映像僅包含靜態 go 二進制檔和從映像倉庫推播/拉取映像/向映像倉庫推播/拉取映像的邏輯。

  • Kaniko 接受三個參數。一個 Dockerfile、構建上下文和一個遠端 Docker registry。

  • 當你部署 kaniko 映像時,它會讀取 Dockerfile 並使用 FROM 指令提取基本映像檔案系統。

  • 然後,它執行來自 Dockerfile 的每條指令,並在使用者空間中拍攝快照。

  • 每次快照後,kaniko 僅將更改的影像圖層附加到基礎影像並更新影像後設資料。Dockerfile 中的所有指令都會發生這種情況。

  • 最後,它將映像推播到給定的registry。

  • 如你所見,所有映像構建操作都發生在 Kaniko 容器的使用者空間內,它不需要對主機的任何特權存取。

  • Kaniko 支持以下型別的構建上下文。

  • GCS 儲存桶

  • S3 儲存桶

  • Azure Blob 儲存

  • 本地目錄

  • 本地 Tar

  • 標準輸入

  • Git 儲存庫 對於此部落格,我將使用 Github 儲存庫作為上下文。

  • 此外,你還可以推播到任何容器registry。

    使用Kaniko、Github、Docker Registry和Kubernetes構建Docker映像

    為了演示 Kaniko 工作流程,我將使用公開可用的工具,使用 Kaniko 在 kubernetes 上構建 Docker 映像。

    這是你需要的

  • 帶有 Dockerfile:kaniko 的有效 Github 儲存庫將使用儲存庫 URL 路徑作為 Dockerfile 上下文

  • 有效的 docker hub 帳戶:用於 kaniko pod 進行身份驗證並推播構建的 Docker 映像。

  • 存取 Kubernetes 集群:部署 kaniko pod 並建立 docker registry secret。

  • 下圖顯示了我們將要構建的工作流。

    建立 Dockerhub Kubernetes Secret

    我們必須為 kaniko pod 建立一個 kubernetes secret 型別,以驗證 Docker hub registry並推播映像。docker-registry

    使用以下命令格式建立 docker registry金鑰。替換以粗體標記的參數。

    kubectl create secret docker-registry dockercred \
    --docker-server=https://index.docker.io/v1/ \
    --docker-username=<dockerhub-username> \
    --docker-password=<dockerhub-password>\
    --docker-email=<dockerhub-email>

    此金鑰被掛載到 kaniko pod 上,以便它對 Docker registry進行身份驗證以推播構建的映像。

    註意:如果你有自托管的 docker registry,則可以將伺服器 URL 替換為你的 docker registry API 端點。

    部署 Kaniko Pod 以構建 Docker 映像

    現在,讓我們使用 Pod 部署來測試 kaniko 映像生成器。

    我已將清單和 Dockerfile 托管在公共 GitHub 儲存庫中。這是一個帶有說明的簡單 Dockerfile。update

    我將使用該儲存庫進行演示。你可以 fork 它或使用類似配置建立自己的儲存庫。

    https://github.com/scriptcamp/kubernetes-kaniko

    將以下清單另存為pod.yaml

    apiVersion: v1
    kind: Pod
    metadata:
    name: kaniko
    spec:
    containers:
    - name: kaniko
    image: gcr.io/kaniko-project/executor:latest
    args:
    "--context=git://github.com/scriptcamp/kubernetes-kaniko"
    "--destination=<dockerhub-username>/kaniko-demo-image:1.0"
    volumeMounts:
    - name: kaniko-secret
    mountPath: /kaniko/.docker
    restartPolicy: Never
    volumes:
    - name: kaniko-secret
    secret:
    secretName: dockercred
    items:
    - key: .dockerconfigjson
    path: config.json

  • –上下文:這是 Dockerfile 的位置。在我們的例子中,Dockerfile 位於儲存庫的根目錄中。所以我給出了倉庫的 git URL。如果您使用的是私有 git 儲存庫,則可以使用 GIT_USERNAME 和 GIT_PASSWORD(API 令牌)變量來驗證 git 儲存庫。

  • –目的地:在這裏,您需要將 替換為您的 docker hub 使用者名稱,以便 kaniko 將映像推播到 dockerhub 登錄檔。例如,在我的情況下, bibinwilson/kaniko-test-image:1.0 所有其他配置保持不變。

  • 現在部署 Pod。

    kubectl apply -f pod.yaml

    要驗證 docker 映像構建和推播,請檢查 Pod 日誌。

    kubectl logs kaniko --follow


    註意:這裏我們使用了靜態 pod 名稱。所以再次部署;首先,你必須刪除 Kaniko Pod。當你將 kaniko 用於 CI/CD 管道時,Pod 會根據你使用的 CI 工具獲得一個隨機名稱,並負責刪除 Pod。

    在Kubernetes上使用Jenkins和kaniko的Docker構建管道

    如果你使用 Kubernetes 來擴充套件 Jenkins 構建代理,則可以使用 Kaniko docker 構建 Pod 在 CI 管道中構建 docker 映像。

    你可以檢視我在 Kubernetes 上的 Jenkins 構建代理設定,其中 Jenkins 主節點和代理在 kubernetes 集群上執行。

    要將 Kaniko 用於你的構建管道,你應該擁有 Dockerfile 和應用程式。

    此外,你應該將多容器 pod 樣版與構建和 kaniko 容器一起使用。例如,用於 Java 構建的 maven 容器和 kaniko 容器采用 jar 並使用儲存庫中的 Dockerfile 構建 docker 映像。

    這是一個基於多容器 pod 樣版的 Jenkinsfile,你可以在其中構建應用程式並使用 kaniko 容器使用應用程式構建 docker 映像,並將其推播到 Docker registry。

    重要提示:你應該在 pod 樣版中使用帶有 debug 標簽的 kaniko 映像,因為我們將使用 bash 顯式執行 kaniko 執行程式。最新的標記影像沒有 bash。

    podTemplate(yaml: '''
    apiVersion: v1
    kind: Pod
    spec:
    containers:
    - name: maven
    image: maven:3.8.1-jdk-8
    command:
    - sleep
    args:
    - 60
    - name: kaniko
    image: gcr.io/kaniko-project/executor:debug
    command:
    - sleep
    args:
    - 60
    volumeMounts:
    - name: kaniko-secret
    mountPath: /kaniko/.docker
    restartPolicy: Never
    volumes:
    - name: kaniko-secret
    secret:
    secretName: dockercred
    items:
    - key: .dockerconfigjson
    path: config.json
    '
    '') {
    node(POD_LABEL) {
    stage('Get a Maven project') {
    git url: 'https://github.com/scriptcamp/kubernetes-kaniko.git', branch: 'main'
    container('maven') {
    stage('Build a Maven project') {
    sh '''
    echo pwd
    '
    ''
    }
    }
    }
    stage('Build Java Image') {
    container('kaniko') {
    stage('Build a Go project') {
    sh '''
    /kaniko/executor --context `pwd` --destination bibinwilson/hello-kaniko:1.0
    '
    ''
    }
    }
    }
    }
    }

    你可以直接在流水線作業上使用上述 Jenkinsfile 並對其進行測試。它只是一個入門樣版。你需要將儲存庫替換為程式碼儲存庫,並根據應用程式的需要編寫構建邏輯。

    結論

    使用 kaniko 構建 Docker 映像是容器化 Docker 構建的一種安全方式。

    你可以嘗試將 kaniko 與你的管道相結合,而不會影響安全性。