Kubernetes Kaniko

参考:https://mp.weixin.qq.com/s?__biz=MzUxNTg5NTQ0NA==&mid=2247485123&idx=1&sn=95d3785fe862567329e38e002cf93e19&chksm=f8f36c27517a7d37b330f6e78fd66a019b05fcee6b37d3044a487f5af451a1b75f1188c19e5f&scene=126&sessionid=1704951873#rd
如何构建 Kubernetes 所需的容器镜像?我想你答案肯定是 Docker,没错,Docker 确实是首选。
我们在使用 Jenkins 进行 CI/CD构建容器镜像的时候,做法通常是将 Jenkins 服务部署在物理机上,然后使用物理机的 docker build 命令来构建镜像。
但是在 Jenkins on K8s 环境下,Jenkins Master 和 Jenkins Slave 都以 Pod 形式运行在 Kubernetes 集群的 Node 上,我们的构建环境都是 Pod ,
没有 docker 命令。众所周知 Kubernetes 在 V1.24.x 版本之后默认采用 containerd 作为容器运行时,不再支持 Docker,
我们想用宿主机上的 /var/run/docker.sock 也用不了了。
我们就需要另一种方式在 Kubernetes 集群中构建容器镜像,本文将介绍 Kaniko工具。

什么是Kaniko

Github地址:https://github.com/GoogleContainerTools/kanikoKaniko 是Google开源的一款在 Kubernetes 用来构建容器镜像的工具,
它是一个从 Dockerfile 构建容器镜像的工具,就像 Docker 一样,但主要区别在于 Kaniko 可以在容器内运行,
这意味着它可以在 Kubernetes 集群内运行。不需要特权模式,也不需要公开任何套接字。不需要在我们集群的节点上运行 Docker,
因此我们使用哪个容器引擎来运行容器并不重要。重要的是 Kaniko 可以在容器内构建容器镜像,并在 Kubernetes 集群内自动构建,
这就和宿主机上的 Docker 解绑了,更加安全可靠。特点如下:

    docker in docker
    不依赖 Docker守护进程
    不需要 privilege 权限,安全构建
    仅需一条命令
    支持 Dockerfile 构建

现在,让我们一步一步来探索 Kaniko

在Kubernetes中使用Kaniko

#1、创建Dockerfile
[root@k8s-master01 kaniko]# cat Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/bash", "-c", "echo hello"]

[root@k8s-master01 kaniko]# kubectl create configmap kaniko-dockerfile --from-file=./Dockerfile
configmap/kaniko-dockerfile created

#2、创建镜像仓库凭证的Secret 
# 几个节点都要登录保证后续登录正常 推送正常
# 创建一个配置kaniko推送到 阿里云镜像仓库的凭证,找一台有安装docker的机子,登录仓库
[root@k8s-master01 kaniko]# docker login --username=xxx registry.cn-beijing.aliyuncs.com
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

#3、登入成功之后,会生成一个config.json的文件,使用该文件创建一个secret供kaniko容器使用。
# centos环境中文件位置:/root/.docker/config.json
[root@k8s-master01 kaniko]# kubectl create secret generic kaniko-secret --from-file=/root/.docker/config.json
secret/kaniko-secret created

#4、启动kaniko容器用来构建镜像
[root@k8s-master01 kaniko]# cat kaniko_build_image.yaml
apiVersion: v1
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
  - name: kaniko
    #image: gcr.io/kaniko-project/executor:latest
    image: gcr.lank8s.cn/kaniko-project/executor:latest
    args: ["--dockerfile=/workspace/Dockerfile",
            "--context=dir://workspace",
            "--destination=registry.cn-shanghai.aliyuncs.com/birkhoff/kaniko-Dockerfile:v1.0"] # 替换成自己的仓库地址
    volumeMounts:
      - name: kaniko-secret
        mountPath: /kaniko/.docker
      - name: dockerfile
        mountPath: /workspace
  volumes:
    - name: kaniko-secret
      secret:
        secretName: kaniko-secret
        items:
          - key: config.json
            path: config.json
    - name: dockerfile
      configMap:
        name: kaniko-dockerfile
        
[root@k8s-master01 kaniko]# kubectl apply -f kaniko_build_image.yaml
pod/kaniko created

[root@k8s-master01 kaniko]# kubectl  get pods
NAME                          READY   STATUS             RESTARTS         AGE
kaniko                        1/1     Running            0                2s

[root@k8s-master01 kaniko]# kubectl logs -f kaniko
INFO[0000] Retrieving image manifest ubuntu
INFO[0000] Retrieving image ubuntu from registry index.docker.io
INFO[0014] Built cross stage deps: map[]
INFO[0014] Retrieving image manifest ubuntu
INFO[0014] Returning cached image manifest
INFO[0014] Executing 0 build triggers
INFO[0014] Building stage 'ubuntu' [idx: '0', base-idx: '-1']
INFO[0014] Skipping unpacking as no commands require it.
INFO[0014] ENTRYPOINT ["/bin/bash", "-c", "echo hello"]
INFO[0014] Pushing image to registry.cn-hangzhou.aliyuncs.com/birkhoff/kaniko-test:1.0
INFO[0184] Pushed registry.cn-hangzhou.aliyuncs.com/birkhoff/kaniko-test@sha256:b0c6f543b4d8bb8c9b8ed0d4859d20d8fd861efbaa31ac98071706f4d685792c

#用kaniko生成的镜像来测试下是否可用-hello显示出来了
[root@k8s-master01 kaniko]# docker run -it --rm registry.cn-hangzhou.aliyuncs.com/birkhoff/kaniko-test:1.0
Unable to find image 'registry.cn-hangzhou.aliyuncs.com/birkhoff/kaniko-test:1.0' locally
1.0: Pulling from birkhoff/kaniko-test
a48641193673: Pull complete
Digest: sha256:b0c6f543b4d8bb8c9b8ed0d4859d20d8fd861efbaa31ac98071706f4d685792c
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/birkhoff/kaniko-test:1.0
hello

 

自定义一个Kaniko镜像

官方 kaniko 镜像是基于 scratch 构建的,里面没有 shell,想在 kaniko 原生镜像里在调用 shell 命令是很麻烦的。
所以我们可以自定义我们自己私有的 Kaniko 镜像。kaniko 的关键文件其实是/kaniko目录下的二进制文件,
官方推荐是用 gcr.io/kaniko-project/executor 镜像,
我们就可以拷贝这个/kaniko目录下的 executor 到我们自己的私有镜像 Dockerfile:
[root@k8s-master01 zdy]# cp /root/.docker/config.json .

[root@k8s-master01 zdy]# cat Dockerfile
FROM gcr.lank8s.cn/kaniko-project/executor:latest AS plugin

FROM ubuntu

ENV DOCKER_CONFIG /kaniko/.docker

COPY --from=plugin /kaniko/executor /usr/local/bin/kaniko

RUN mkdir -p /kaniko/.docker/
COPY config.json /kaniko/.docker/
上面 Dockerfile 构建了一个基于Ubuntu的Docker镜像,

    FROM gcr.io/kaniko-project/executor:latest AS plugin
        从名为gcr.io/kaniko-project/executor:latest的Docker镜像开始构建一个临时阶段,并将其命名为plugin。
        这个步骤是在一个已经包含了Kaniko工具的Docker镜像中构建一个中间容器。
    FROM ubuntu
        接下来创建一个新的Docker镜像,基于官方的Ubuntu基础镜像。
    ENV DOCKER_CONFIG /kaniko/.docker
        设置环境变量DOCKER_CONFIG为/kaniko/.docker,这是Kaniko工具使用的Docker配置目录。这是为了确保Kaniko可以找到必要的Docker配置信息。
    COPY --from=plugin /kaniko/executor /usr/local/bin/kaniko
        从之前构建的plugin阶段的镜像中复制/kaniko/executor文件到新的镜像的/usr/local/bin/kaniko路径下。这将把Kaniko二进制文件复制到新的Ubuntu镜像中,以便后续在该镜像中使用。
    RUN mkdir -p /kaniko/.docker/
        在新的镜像中创建/kaniko/.docker/目录,用于存放Docker配置文件。
    COPY config.json /kaniko/.docker/
        将本地的config.json文件复制到新的镜像的/kaniko/.docker/目录下。这个config.json文件很可能包含了Docker仓库的认证信息和其他配置,以便Kaniko可以访问和推送Docker镜像。

最终,这个Docker镜像将包含了Ubuntu操作系统和Kaniko工具,并配置了Kaniko所需的Docker环境,使得可以在容器内使用Kaniko构建Docker镜像,并且有了 shell 环境,同时保持了一定程度的隔离性和安全性。构建并上传镜像:
[root@k8s-master01 zdy]# docker build -t registry.cn-hangzhou.aliyuncs.com/birkhoff/kaniko:customize .
[+] Building 79.5s (11/11) FINISHED                                                                                                                                        docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                 0.0s
 => => transferring dockerfile: 275B                                                                                                                                                 0.0s
 => [internal] load .dockerignore                                                                                                                                                    0.0s
 => => transferring context: 2B                                                                                                                                                      0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest                                                                                                                    15.5s
 => [internal] load metadata for gcr.lank8s.cn/kaniko-project/executor:latest                                                                                                        0.4s
 => [plugin 1/1] FROM gcr.lank8s.cn/kaniko-project/executor:latest@sha256:f913ab076f92f1bdca336ab8514fea6e76f0311e52459cce5ec090c120885c8b                                          63.2s
 => => resolve gcr.lank8s.cn/kaniko-project/executor:latest@sha256:f913ab076f92f1bdca336ab8514fea6e76f0311e52459cce5ec090c120885c8b                                                  0.0s
 => => sha256:f913ab076f92f1bdca336ab8514fea6e76f0311e52459cce5ec090c120885c8b 3.12kB / 3.12kB                                                                                       0.0s
 => => sha256:4d0182087ab9e2272ac77f6067f1549a6d803bd2163f367335766493c579f108 2.00kB / 2.00kB                                                                                       0.0s
 => => sha256:c584974b87ed07c55bb3cbca5063bdc56d4e0c092872eb09a7e4b2347fa2436a 3.60kB / 3.60kB                                                                                       0.0s
 => => sha256:24ac6486824c19f4e93c5ced995f8af71aad3d91d7a12e2f1ba1cf1baf4cd119 144B / 144B                                                                                           0.7s
 => => sha256:12e76367120f87420d7a129e2903be9d9f6fb4a5a84a8c67c407e6ef5a48feb2 115.23kB / 115.23kB                                                                                   1.5s
 => => extracting sha256:24ac6486824c19f4e93c5ced995f8af71aad3d91d7a12e2f1ba1cf1baf4cd119                                                                                            0.0s
 => => sha256:9ccaebf3f717c39cabfca6b82c3c86b615de14a00366a1c44ff17ffddeaa9a47 511B / 511B                                                                                           1.6s
 => => extracting sha256:12e76367120f87420d7a129e2903be9d9f6fb4a5a84a8c67c407e6ef5a48feb2                                                                                            0.0s
 => => sha256:1415c527ba9e2e175d3fff39bdb2bbaecf211d6a1dfac7d884d636461421a886 4.96MB / 4.96MB                                                                                      19.1s
 => => extracting sha256:9ccaebf3f717c39cabfca6b82c3c86b615de14a00366a1c44ff17ffddeaa9a47                                                                                            0.0s
 => => sha256:2bef7b2979b2e244b6792026dbc885afc524aa9c5402af901e12a3f55eb6d7c6 5.85MB / 5.85MB                                                                                      19.2s
 => => extracting sha256:1415c527ba9e2e175d3fff39bdb2bbaecf211d6a1dfac7d884d636461421a886                                                                                            0.1s
 => => sha256:fb761cd73d99aa0654a84951e643fed78501508476d8aaad4607d7a4d2cc561d 7.13MB / 7.13MB                                                                                      35.3s
 => => extracting sha256:2bef7b2979b2e244b6792026dbc885afc524aa9c5402af901e12a3f55eb6d7c6                                                                                            0.1s
 => => sha256:6b6593a4fbdf6b2d49490663a333ab7376dc18b3c7a20cd285e73e9f97c887ba 129B / 129B                                                                                          19.4s
 => => sha256:7dae52ebc01be1a371c7991d5ca912349cb813648a31fa33cc094f6103e5464c 99B / 99B                                                                                            35.7s
 => => sha256:b19157c35055333d85bf48cc68f611d5155ade22a1c2c41ef6ffe6b2c6ed426c 12.44MB / 12.44MB                                                                                    62.6s
 => => extracting sha256:fb761cd73d99aa0654a84951e643fed78501508476d8aaad4607d7a4d2cc561d                                                                                            0.1s
 => => extracting sha256:6b6593a4fbdf6b2d49490663a333ab7376dc18b3c7a20cd285e73e9f97c887ba                                                                                            0.0s
 => => extracting sha256:7dae52ebc01be1a371c7991d5ca912349cb813648a31fa33cc094f6103e5464c                                                                                            0.0s
 => => extracting sha256:b19157c35055333d85bf48cc68f611d5155ade22a1c2c41ef6ffe6b2c6ed426c                                                                                            0.5s
 => [stage-1 1/4] FROM docker.io/library/ubuntu@sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322                                                             63.4s
 => => resolve docker.io/library/ubuntu@sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322                                                                      0.0s
 => => sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322 1.42kB / 1.42kB                                                                                       0.0s
 => => sha256:7cc0576c7c0ec2384de5cbf245f41567e922aab1b075f3e8ad565f508032df17 529B / 529B                                                                                           0.0s
 => => sha256:ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1 1.46kB / 1.46kB                                                                                       0.0s
 => => sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54 28.57MB / 28.57MB                                                                                    61.8s
 => => extracting sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54                                                                                            1.5s
 => [internal] load build context                                                                                                                                                    0.0s
 => => transferring context: 232B                                                                                                                                                    0.0s
 => [stage-1 2/4] COPY --from=plugin /kaniko/executor /usr/local/bin/kaniko                                                                                                          0.1s
 => [stage-1 3/4] RUN mkdir -p /kaniko/.docker/                                                                                                                                      0.2s
 => [stage-1 4/4] COPY config.json /kaniko/.docker/                                                                                                                                  0.0s
 => exporting to image                                                                                                                                                               0.1s
 => => exporting layers                                                                                                                                                              0.1s
 => => writing image sha256:91cc4d59f25aeed61a23740035c4b4e9544501da0c898bdf8ad6c8d916f6f26b                                                                                         0.0s
 => => naming to registry.cn-hangzhou.aliyuncs.com/birkhoff/kaniko:customize        
 

[root@k8s-master01 zdy]# docker push registry.cn-hangzhou.aliyuncs.com/birkhoff/kaniko:customize

Kaniko 更多参数

    --context:指定构建上下文的路径。默认情况下,上下文是Dockerfile所在的目录。可简写 -c
    --dockerfile:指定要使用的Dockerfile的路径。默认情况下,Kaniko会在上下文中查找名为Dockerfile的文件。可简写 -f
    --destination:指定构建完成后的Docker镜像名称,可以包括标签。例如:myregistry/myimage:tag。可简写 -d
    --cache:启用或禁用Kaniko的构建缓存功能。默认情况下,缓存是启用的。
    --cache-ttl:设置构建缓存的生存时间。例如,--cache-ttl=10h表示缓存在构建完成后的10小时内有效。
    --cache-repo:指定用于存储构建缓存的Docker仓库。默认情况下,缓存存储在本地。
    --cache-dir:指定用于存储构建缓存的本地目录路径。
    --skip-tls-verify:跳过TLS证书验证,用于不安全的Docker仓库。
    --build-arg:传递构建参数给Dockerfile中的ARG指令。例如:--build-arg key=value。
    --insecure:允许从不受信任的Registry拉取基础镜像。
    --insecure-registry:允许连接到不受信任的Registry。
    --verbosity:设置构建的详细程度,可以是panic、error、warning、info、debug或trace。
    --digest-file:指定一个文件,用于存储构建生成的镜像的摘要(Digest)。
    --oci-layout-path:指定OCI(Open Container Initiative)布局文件的路径,用于存储构建过程的元数据。

更多参考 官方:https://github.com/GoogleContainerTools/kaniko#additional-flags
Kaniko 构建缓存

--cache-copy-layers 此参数在执行命令之前 kaniko 会检查层的缓存,如果存在 kaniko将拉取并提取缓存层,而不是执行命令。如果没有 kaniko将执行命令,然后将新创建的层推送到缓存。用户可以通过设置 --cache=true 参数决定是否启用缓存,并且可以通过--cache-repo 标志提供用于存储缓存层的远程存储库,如果未提供此标志则将从提供的 –destination 推断缓存的repo。通常  --cache=true --cache-copy-layers=true 这两个参数同时使用。

CI/CD 中使用Kaniko

// 镜像仓库地址
def registry = "registry.cn-shanghai.aliyuncs.com/kubesre02/demo"
 
pipeline {
    agent {
        kubernetes {
      yaml """
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
  - name: kaniko
    # 使用自定义的 kaniko 镜像
    image: registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko:latest
    imagePullPolicy: Always
    command:
    - cat
    tty: true
"""
      }
    }
   
    stages {
        stage('拉代码') {
            steps {
                git clone ...
            }
        }
       
        stage('构建镜像') {
            steps {
                // 使用 kaniko 来构建镜像
                container(name: 'kaniko') {
                    Dockerfile 内容...
                    sh "kaniko -f Dockerfile -c ./ -d $registry:$BUILD_NUMBER --force"
                }
            }
        }
         
        stage('部署') {
            steps {
                部署...
            }
        }
         
    }
}

 

posted @ 2024-01-12 10:07  しみずよしだ  阅读(154)  评论(0)    收藏  举报