雲原生之旅

2022-11-19 12:02:31

前言

前一篇文章【雲原生之旅 - 11)基於 Kubernetes 動態伸縮 Jenkins Build Agents】有講到在 Kubernetes Pod (Jenkins build agent) 裡面構建 docker 容器映象,當時我們採取了一種簡單快速的方式來 run docker in docker,也就是 mount /var/run/docker.sock 到主機的 docker engine,這需要docker run在特權 privileged 模式下,有很大的安全隱患。另外這種方式還有個很大的缺陷就是當一臺機器上同時執行多個docker build agent時,會出現阻塞的情況,因為這一批agent用的都是宿主機上的同一個docker engine。

所以我們今天介紹一款專門用於Kubernetes 構建容器映象的工具 Kaniko,它是 Google 建立的一個開源工具. 並且不需要 privileged access to the host,解決了前一種方式的缺陷。
 
關鍵詞:使用Kaniko構建容器映象,Run docker in docker,  在 Kubernetes上構建 Docker 容器映象,無需特權在Kubernetes中構建映象,docker privileged,更安全的方式構建容器映象
 
### 本文同步發表於知乎 https://zhuanlan.zhihu.com/p/584805862
 

原理

Kaniko會先提取基礎映象(Dockerfile FROM 之後的映象)的檔案系統,然後根據Dockerfile中所描述的,一條條執行命令,每一條命令執行完以後會在使用者空間下面建立一個snapshot,並與儲存與記憶體中的上一個狀態進行比對,如果有變化,就將新的修改生成一個映象層新增在基礎映象上,並且將相關的修改資訊寫入映象後設資料中。等所有命令執行完,kaniko會將最終映象推播到指定的遠端映象倉庫。
 

準備

我們需要在Kubernetes 裡建立一個 docker-registry 型別的 secret,後面會掛載到 kaniko container,這樣kaniko才有許可權push image到Docker Hub registry
kubectl -n jenkins create secret docker-registry dockercred \
--docker-server=https://index.docker.io/v1/ \
--docker-username=<dockerhub-username> \
--docker-password=<dockerhub-password>

 

使用 Kaniko 構建映象

Define kaniko container in Pod Template

並且掛載剛才建的 docker-registry型別的secret

kind: Pod
spec:
  containers:  # list of containers that you want present for your build, you can define a default container in the Jenkinsfile
    - name: kaniko
      image: gcr.io/kaniko-project/executor:v1.9.0-debug # include shell
      imagePullPolicy: IfNotPresent
      command:
        - /busybox/cat
      tty: true
      resources:
        limits:
          cpu: 500m
          memory: 1024Mi
      volumeMounts:
      - name: kaniko-secret
        mountPath: /kaniko/.docker
  volumes:
  - name: kaniko-secret
    secret:
        secretName: dockercred
        items:
        - key: .dockerconfigjson
          path: config.json

 

Jenkins pipeline

  • --context: This is the location of the Dockerfile.
  • --destination: You need to replace Docker Hub username `wadexu007` with your Docker Hub username for kaniko to push the image to the Docker Hub registry.
pipeline {
  options {
    timeout(time: 10, unit: 'MINUTES')
    buildDiscarder(logRotator(numToKeepStr: '10', daysToKeepStr: '7'))
  }

  agent {
    kubernetes {
      idleMinutes 3  // how long the pod will live after no jobs have run on it
      yamlFile 'Jenkins/kaniko-demo/build-pod.yaml'  // path to the pod definition relative to the root of our project 
    }
  }
stages { stage('Kaniko Build and Push Docker Image') { steps { script { dir('Jenkins/kaniko-demo') { container('kaniko') { sh """ /kaniko/executor --context `pwd` --destination wadexu007/demo-app:1.0.5 """ } } } } } } }

完整例子參考我的 Github Repo

### 本文同步發表於知乎 https://zhuanlan.zhihu.com/p/584805862

 

測試

建立一個Pipeline job

Repository URL = https://github.com/wadexu007/learning_by_doing

Script Path = Jenkins/kaniko-demo/Jenkinsfile

Click `Build now`

 感謝閱讀,如果您覺得本文的內容對您的學習有所幫助,您可以打賞和推薦,您的鼓勵是我創作的動力

### 本文同步發表於知乎 https://zhuanlan.zhihu.com/p/584805862