一、快速介绍
什么是Kaniko
kaniko 是一个在容器或 Kubernetes 集群内从 Dockerfile 构建容器镜像的工具 ( Build Container Images In Kubernetes );官方一共提供了两个镜像,分别是:
- gcr.io/kaniko-project/executor:executor (该镜像基于 scratch,不包含 shell)
- gcr.io/kaniko-project/executor:debug (该镜像由kaniko executor镜像和一个 busybox shell 组成,主要用于)
为啥用Kaniko
- 由于 kaniko 不依赖于 Docker 守护进程,并且可以在用户空间中执行 Dockerfile 中的每个命令,这使得能够在轻松并且安全地运行在无Docker守护程序的环境(如标准Kubernetes集群 V1.24.x)中构建容器镜像。
- 在 Kubernetes V1.24.x 版本之后默认采用 containerd.io 作为缺省的cri,不再支持 docker-shim 意味着我们不需要安装 docker 环境
二、Kaniko工作原理
Kaniko 是如何工作的
- 读取并解析指定的Dockerfile
- 提取基础镜像的文件系统(Dockerfile 中的 FROM 镜像)
- 在独立的Dockerfile中分别运行每个命令
- 每次运行后都会对用户空间文件系统的做快照
- 每次运行时,将快照层附加到基础层并更新镜像元数据
- 最后推送镜像
Kaniko已知功能问题
- kaniko 不支持构建 Windows 容器。
- kaniko 不支持 v1 Registry API。(由于其不安全性当前基本都是使用V2协议, 例如 Harbor)
- 不支持在官方 kaniko 镜像以外的任何 Docker 镜像中运行 kaniko(这包括将 kaniko 可执行文件从官方镜像复制到另一个镜像中)
Kaniko 支持的存储解决方案
kaniko 的构建上下文和发送 Docker 守护程序以进行镜像构建的构建上下文非常相似;它代表一个包含 Dockerfile 的目录,kaniko 将使用它来构建镜像。
例如, Dockerfile 中的 COPY 命令应该引用构建上下文中的文件, 所以需要将构建上下文存储在 kaniko 可以访问的位置。
目前kaniko 支持以下存储解决方案:
- GCS Bucket
- S3 Bucket
- Azure Blob Storage
- Local Directory
- Local Tar
- Standard Input
- Git Repository
运行 kaniko 时,使用 --context 带有适当前缀的标志指定构建上下文的位置, 如果不指定前缀 kaniko 将假定一个本地目录, 该参数可用值:
Source | Prefix | Example | 注意 |
Local Directory | dir://[path to a directory in the kaniko container] | dir:///workspace | 此选项是指 kaniko 容器内的目录。如果希望使用此选项,则需要在构建上下文中将其作为目录挂载到容器中。 |
Local Tar Gz | tar://[path to a .tar.gz in the kaniko container] | tar://path/to/context.tar.gz | 此选项指的是 kaniko 容器中的 tar gz文件。如果希望使用此选项,则需要在构建上下文中将其作为文件挂载到容器中。 |
Standard Input | tar://[stdin] | tar://stdin | kaniko 允许的唯一标准输入是.tar.gz格式,如果要创建压缩 tar,可以运行tar -C -zcvf context.tar.gz命令。 |
GCS Bucket | gs://[bucket name]/[path to .tar.gz] | gs://kaniko-bucket/path/to/context.tar.gz | 如果使用 GCS 或 S3 存储桶,首先需要创建构建上下文的压缩 tar 并将其上传到存储桶。运行后,kaniko 将在开始镜像构建之前下载并解压构建上下文的压缩 tar。 |
S3 Bucket | s3://[bucket name]/[path to .tar.gz] | s3://kaniko-bucket/path/to/context.tar.gz | |
Azure Blob Storage | https://[account].[azureblobhostsuffix]/[container]/[path to .tar.gz] | myaccount.blob.core.windows.net/container/p… | |
Git Repository | git://[repository url][#reference][#commit-id] | git://github.com/acme/myproject.git#refs/heads/mybranch# | 仅支持此种格式,http的那种不支持。 |
Kaniko 缓存构建
1.Caching Layers :kaniko 可以在远程存储库中缓存由RUN(由flag--cache-RUN-layers配置)和COPY(由flag--cache-COPY-layeers配置)命令创建的层。
在执行命令之前 kaniko 会检查层的缓存,如果存在 kaniko将拉取并提取缓存层,而不是执行命令。如果没有 kaniko将执行命令,然后将新创建的层推送到缓存。
用户可以通过设置 --cache=true 标志选择缓存,并且可以通过--cache-repo 标志提供用于存储缓存层的远程存储库, 如果未提供此标志则将从提供的--destination推断缓存的repo。
在缓存未命中后,kaniko无法从缓存中找到读取层,所有后续层都将在本地构建,而无需咨询缓存。
2.Caching Base Images: kaniko 可以将镜像缓存在本地目录中,该目录可以卷装载到KanikoPod中。为此必须首先填充缓存, 我们在 gcr.io/kaniko-project/warmer 提供了一个kaniko缓存预热镜像:
--image : 指定所需任意数量的镜像, 填充缓存后 使用与上述相同的 --cache=true 标志选择缓存, 本地缓存的位置通过 --cache-dir 标志提供,默认为 /cache 与缓存预热器一样, 在实践中通常与 Kubernetes 集群和持久缓存卷一起使用。
示例:
docker run -v $(pwd):/workspace gcr.io/kaniko-project/warmer:latest --cache-dir=/workspace/cache --image=<image to cache> --image=<another image to cache>
Kaniko参数
- --build-arg:构建参数,类似于 Docker可以配置多个
- --cache:--cache=true选择使用 kaniko 进行缓存
- --cache-dir:以指定基本镜像的本地目录缓存,默认为 /cache;注意:必须和--cache一起使用
- --cache-repo:指定将用于存储缓存层的远程存储库;如果未指定将从--destination中推算出存储库;列:如果--destination=gcr.io/kaniko-project/test,则缓存层将存储在gcr.io/kaniko-project/test/cache
- --cache-copy-layers:缓存copy层
- --cache-run-layers:缓存run层
- --cache-ttl duration:以小时为单位的缓存超时。默认为两周
- --cleanup:在构建结束时清理文件系统
- --compressed-caching:将此设置为 false 以防止对缓存层进行 tar 压缩。这将增加构建的运行时间,但会减少内存使用量,尤其是对于大型构建。--compressed-caching=false如果您的构建因内存不足错误而失败,请尝试使用。默认为真。
- --context-sub-path:当上下文是一个 git 存储库,并且想要构建其子文件夹之一而不是根文件夹时,它特别有用
- --customPlatform:允许使用主机以外的另一个默认平台进行构建,类似于 docker build --platform xxx 该值必须在 form 上 --customPlatform=linux/arm,可接受的值列在此处: GOOS/GOARCH。也可以指定 CPU ,将其添加为第三个参数(如 --customPlatform=linux/arm/v5);注意:这种指定cpu的方式只能用于arm架构;由于 OCI 镜像规范的限制,生成的镜像无法提供有关 CPU 的任何元数据;注意:这不是虚拟化,无法帮助构建构建主机本身不支持的架构;例如,这用于在 amd64 主机上构建 i386,或在 arm64 主机上构建 arm32。
- --digest-file:设置此标志以指定容器中的文件;该文件将接收构建镜像的摘要,这可用于自动跟踪 kaniko 构建的确切镜像;例如,将标志设置为--digest-file=/dev/termination-log会将摘要写入该文件,Kubernetes 会自动将其拾取为 {{.state.terminated.message}}容器的摘要。
- --dockerfile:要构建的 dockerfile 的路径。(默认“Dockerfile”)
- --force:强制在容器外构建
- --git:如果构建上下文是 git 存储库,则要克隆的分支(默认 branch=,single-branch=false,recurse-submodules=false)
- --image-name-with-digest-file:指定一个文件来保存带有构建镜像摘要的镜像名称
- --image-name-tag-with-digest-file:指定一个文件来保存带有镜像标签和构建镜像摘要的镜像名称。
- --insecure:如果您想将镜像推送到纯 HTTP 注册表,请设置此标志。它应该仅用于测试目的,不应在生产中使用!
- --insecure-pull:如果你想从普通的 HTTP 注册表中提取镜像,请设置此标志。它应该仅用于测试目的,不应在生产中使用!
- --insecure-registry:您可以设置--insecure-registry 为在访问指定注册表时使用纯 HTTP 请求。它应该仅用于测试目的,不应在生产中使用!您可以为多个注册表多次设置它。
- --label:设置此标志以--label key=value将一些元数据设置为最终镜像。这等同于LABEL在 Dockerfile 中使用。
- --log-format:设置此标志以--log-format=设置日志格式;默认为color。
- --log-timestamp:将此标志设置为--log-timestamp=将时间戳添加到 日志格式;默认为false。
- --no-push:只构建镜像不推送
- --oci-layout-path:设置此标志以指定容器中的目录,其中将放置构建镜像的 OCI 镜像布局。这可用于自动跟踪 kaniko 构建的确切镜像;例如,要显示在 Tekton 任务中构建的镜像摘要,应设置此标志以匹配镜像资源outputImageDir; 注意:根据构建的镜像,镜像清单的媒体类型可能是application/vnd.oci.image.manifest.v1+json或application/vnd.docker.distribution.manifest.v2+json。
- --push-retry:将此标志设置为将镜像推送到远程目标时应该发生的重试次数;默认为0。
- --registry-certificate:设置此标志可为与给定注册表的 TLS 通信提供证书;预期格式是my.registry.url=/path/to/the/certificate.cert。
- --registry-mirror:如果您想使用注册表镜像而不是默认镜像,请设置此标志 index.docker.io;如果你想设置多个镜像,你可以多次使用这个标志;如果在第一个镜像上找不到镜像,Kaniko 将尝试下一个镜像,并在最后回退到默认注册表。预期格式mirror.gcr.io例如:
-
- mirror.gcr.io
- 127.0.0.1
- 192.168.0.1:5000
- mycompany-docker-virtual.jfrog.io
- --reproducible:设置此标志以从构建的镜像中去除时间戳并使其可重现。
- --single-snapshot:在构建结束时获取文件系统的单个快照,因此只会将一层附加到基础镜像。
- --skip-tls-verify:push到注册表时跳过 TLS 证书验证。
- --skip-tls-verify-pull:在从注册表中pull时跳过 TLS 证书验证
- --skip-tls-verify-registry:您可以设置--skip-tls-verify-registry 在访问指定注册表时跳过 TLS 证书验证
- --skip-unused-stages:跳过不必要的stage
- --snapshotMode:您可以设置--snapshotMode=标志以设置 kaniko 将如何快照文件系统。
-
- 如果--snapshotMode=full设置,则在拍摄快照时会考虑完整的文件内容和元数据;这是性能最低的选项,但也是最可靠的。
- 如果--snapshotMode=redo设置,则在快照时将考虑文件的 mtime、大小、模式、所有者 uid 和 gid;这可能比“完整”快 50%,尤其是当您的项目有大量文件时。
- 如果--snapshotMode=time已设置,则在拍摄快照时将仅考虑文件 mtime(请参阅与与 mtime 相关的限制)。
- --tar-path:将此标志设置为--tar-path=将镜像另存为路径中的压缩包。您还需要设置--destination(例如--destination=image)。如果你只想将镜像保存为 tar包,你还需要设置--no-push。
- --target:指示哪个构建阶段是目标构建阶段
- --use-new-run:使用实验运行实现来检测更改而无需文件系统快照。在某些情况下,这可能会将构建性能提高 75%。
- --verbosity:设置此标志以--verbosity=设置日志记录级别;默认为info。
- --ignore-var-run:镜像快照时忽略 /var/run。将其设置为 false 以在目标映像中保留 /var/run/*。(默认为真)。
- --ignore-path:-ignore-path=在镜像快照时忽略路径。为多个略路径设置多次。
- --image-fs-extract-retry:设置为提取镜像文件系统应该发生的重试次数;默认为0。
三、使用
Run in K8s
环境依赖
- kaniko镜像;这里可以直接用现成的,也可以选择自己拉源码构建:
- registry.cn-hangzhou.aliyuncs.com/weiyigeek/kaniko-executor:latest
- gcr.io/kaniko-project/executor:latest(这是谷歌官方镜像,正常是拉不下来的)
- 一个 Kubernetes 集群 或者 一个 Containerd 容器运行环境;这里可以选择用Minikube或kubeadmin快速安装一个,具体细节我就不介绍了;
- 一个镜像仓库;这里可以是DockerHub、Docker Regisitry、Harbor等;
各类镜像仓库类型secret创建
DockerHub
vim dockerhub-secret.sh
#!/bin/bash
export REGISTRY_SERVER=https://index.docker.io/v1/
export REGISTRY_USER=[xxx]
export REGISTRY_PASS=[xxx]
export REGISTRY_EMAIL=[xxx]
kubectl --namespace=default create secret docker-registry regcred --docker-server=$REGISTRY_SERVER --docker-username=$REGISTRY_USER --docker-password=$REGISTRY_PASS --docker-email=$REGISTRY_EMAIL
运行脚本并创建secret:
kubectl create ns kaniko && bash dockerhub-secret.sh
Harbor
vim harbor-secret.sh
#!/bin/bash
REGISTRY_SERVER=https://harbor.wxd.cn/v2/
REGISTRY_USER=[xxx]
REGISTRY_PASS=[xxx]
REGISTRY_EMAIL=tom@163.com
kubectl --namespace=kaniko create secret docker-registry harbor-regcred --docker-server=$REGISTRY_SERVER --docker-username=$REGISTRY_USER --docker-password=$REGISTRY_PASS --docker-email=$REGISTRY_EMAIL
运行脚本并创建secret:
kubectl create ns kaniko && bash harbor-secret.sh
Docker Registry
vim registry-secret.sh
#!/bin/bash
REGISTRY_SERVER=https://docker.domain.com:5043/v2/
REGISTRY_USER=[xxx]
REGISTRY_PASS=[xxx]
REGISTRY_EMAIL=tom@163.com
kubectl --namespace=kaniko create secret docker-registry registry-regcred --docker-server=$REGISTRY_SERVER --docker-username=$REGISTRY_USER --docker-password=$REGISTRY_PASS --docker-email=$REGISTRY_EMAIL
运行脚本并创建secret:
kubectl create ns kaniko && bash registry-secret.sh
Kaniko构建镜像并推送至不同的镜像仓库
GitHub 推送 DockerHub
创建 DockerHub secrets,详情请参考上面 编写kaniko-git-dockerhub.yaml:
cat > kaniko-github-dockerhub.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
containers:
- name: kaniko
#image: gcr.io/kaniko-project/executor:debug
image: ghostwritten/kaniko-project-executor:debug
args: ["--context=git://github.com/ghostwritten/kaniko-demo",
"--destination=ghostwritten/devops-toolkit:1.0.0"]
volumeMounts:
- name: kaniko-secret
mountPath: /kaniko/.docker
restartPolicy: Never
volumes:
- name: kaniko-secret
secret:
secretName: regcred
items:
- key: .dockerconfigjson
path: config.json
EOF
运行pod:
kubectl apply -f kaniko-git-dockerhub.yaml -n kaniko
创建pod并查看日志:
kubectl apply -f kaniko-github-dockerhub.yaml -n kaniko
kubectl logs -f kaniko-github-dockerhub.yaml -n kaniko
GitLab 推送 Harbor
社区issue: github.com/GoogleConta… 创建 harbor-secret,详情请参考上面 编写kaniko-gitlab-harbor.yaml:
cat > kaniko-gitlab-harbor.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
containers:
- name: kaniko
image: harbor.wxd.cn/dev/application-component-image/kaniko:latest
args: ["--context=git://gitlab.cn/wxd/kaniko-test#refs/heads/master",
"--skip-tls-verify",
"--destination=harbor.wxd.cn/dev/devops-toolkit-git:1.0.0"]
env:
- name: GIT_USERNAME
value: wxd
- name: GIT_PASSWORD
value: 'Lmhy22cfiy55BQrDQhyE'
volumeMounts:
- name: kaniko-secret
mountPath: /kaniko/.docker
restartPolicy: Never
volumes:
- name: kaniko-secret
secret:
secretName: harbor-regcred
items:
- key: .dockerconfigjson
path: config.json
EOF
注意: git仓库的填写格式不支持"https:"开头这样的格式,仅支持类似此格式:git://gitlab.cn/wxd/kaniko-test#refs/heads/master,kaniko-test的".git"后缀可加可不加 git仓库认证这边官方给了好几种填写的方式,什么TOKEN写在url前面、TOKEN通过环境变量GIT_TOKEN传进去等等,我试了都不行,唯一可行的是通过两个环境变量:GIT_USERNAME、GIT_PASSWORD(这个环境变量的值可以写) 运行pod:
kubectl apply -f kaniko-gitlab-harbor.yaml -n kaniko
创建pod并查看日志:
kubectl apply -f kaniko-gitlab-harbor.yaml -n kaniko
kubectl logs -f kaniko-gitlab-harbor.yaml -n kaniko
Local Directory 推送 Registry
创建secret脚本文件,详情请参考上面 创建Dockerfile:
cat > Dockerfile <<EOF
FROM nginx:1.14.2
COPY local-dir-registry.yaml /root
EXPOSE 80
EOF
编写local-dir-registry.yaml:
cat > local-dir-registry.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
containers:
- name: kaniko
image: harbor.wxd.cn/dev/application-component-image/kaniko:latest
args: ["--dockerfile=/workspace/Dockerfile",
"--skip-tls-verify",
"--destination=docker.domain.com:5043/devops-toolkit:1.0.0"]
volumeMounts:
- name: kaniko-secret
mountPath: /kaniko/.docker
- name: workspace
mountPath: /workspace
- name: hosts
mountPath: /etc/hosts
restartPolicy: Never
volumes:
- name: kaniko-secret
secret:
secretName: registry-regcred
items:
- key: .dockerconfigjson
path: config.json
- name: workspace
hostPath:
path: /home/kaniko
- name: hosts
hostPath:
path: /etc/hosts
EOF
注意:destination配置的推送镜像的地址如果需要配置域名解析,需要现在宿主机上配置后,然后把etc/hosts挂载到容器里面去
运行pod:
kubectl apply -f local-dir-registry.yaml -n kaniko
查看日志:
[root@node1 kaniko]# kubectl logs -f kaniko -n kaniko
INFO[0000] Retrieving image manifest harbor.wxd.cn/dev/application-component-image/nginx:amd64-1.14.2
INFO[0000] Retrieving image harbor.wxd.cn/dev/application-component-image/nginx:amd64-1.14.2 from registry harbor.wxd.cn
INFO[0000] Built cross stage deps: map[]
INFO[0000] Retrieving image manifest harbor.wxd.cn/dev/application-component-image/nginx:amd64-1.14.2
INFO[0000] Returning cached image manifest
INFO[0000] Executing 0 build triggers
INFO[0000] Building stage 'harbor.wxd.cn/dev/application-component-image/nginx:amd64-1.14.2' [idx: '0', base-idx: '-1']
INFO[0000] Unpacking rootfs as cmd COPY local-dir-registry.yaml /root requires it.
INFO[0004] COPY local-dir-registry.yaml /root
INFO[0004] Taking snapshot of files...
INFO[0004] EXPOSE 80
INFO[0004] Cmd: EXPOSE
INFO[0004] Adding exposed port: 80/tcp
INFO[0005] Pushing image to docker.domain.com:5043/devops-toolkit:1.0.0
INFO[0007] Pushed docker.domain.com:5043/devops-toolkit@sha256:6f4b3f80289970feaf23dbd81cc53d3c1a6131890e4e2ccabf2ee61ce465958f
Local Directory 推送 Harbor
创建 harbor-secret,详情请参考上面 创建Dockerfile:
cat > Dockerfile <<EOF
FROM nginx:1.14.2
COPY Dockerfile /root
EXPOSE 80
EOF
创建 local-dir-harbor.yaml:
cat > local-dir-harbor.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
containers:
- name: kaniko
image: harbor.wxd.cn/dev/application-component-image/kaniko:latest
args: ["--dockerfile=/workspace/Dockerfile",
"--skip-tls-verify",
"--destination=harbor.wxd.cn/dev/wxd/devops-toolkit:1.0.0"]
volumeMounts:
- name: kaniko-secret
mountPath: /kaniko/.docker
- name: workspace
mountPath: /workspace
- name: hosts
mountPath: /etc/hosts
restartPolicy: Never
volumes:
- name: kaniko-secret
secret:
secretName: harbor-regcred
items:
- key: .dockerconfigjson
path: config.json
- name: workspace
hostPath:
path: /home/kaniko
- name: hosts
hostPath:
path: /etc/hosts
EOF
运行pod:
kubectl apply -f local-dir-harbor.yaml -n kaniko
查看日志:
[root@node1 kaniko]# kubectl logs -f kaniko -n kaniko
INFO[0000] Retrieving image manifest harbor.wxd.cn/dev/application-component-image/nginx:amd64-1.14.2
INFO[0000] Retrieving image harbor.wxd.cn/dev/application-component-image/nginx:amd64-1.14.2 from registry harbor.wxd.cn
INFO[0000] Built cross stage deps: map[]
INFO[0000] Retrieving image manifest harbor.wxd.cn/dev/application-component-image/nginx:amd64-1.14.2
INFO[0000] Returning cached image manifest
INFO[0000] Executing 0 build triggers
INFO[0000] Building stage 'harbor.wxd.cn/dev/application-component-image/nginx:amd64-1.14.2' [idx: '0', base-idx: '-1']
INFO[0000] Unpacking rootfs as cmd COPY local-dir-registry.yaml /root requires it.
INFO[0005] COPY local-dir-registry.yaml /root
INFO[0005] Taking snapshot of files...
INFO[0005] EXPOSE 80
INFO[0005] Cmd: EXPOSE
INFO[0005] Adding exposed port: 80/tcp
INFO[0005] Pushing image to harbor.wxd.cn/dev/wxd/devops-toolkit:1.0.0
INFO[0006] Pushed harbor.wxd.cn/dev/wxd/devops-toolkit@sha256:379ca7f822896ef9177c213228a23f87d7747ed77ee3436aaab14dc451ed1d08
然后去harbor上查看下镜像是否推送成功: 可以看到镜像已经推上来了
Run in Docker
推送至 Harbor
环境依赖
Docker运行环境;我们可以在有Docker Demon的环境运行kaniko,从 Dockerfile 构建和推送镜像
创建config文件
- USERNAME harbor用户名
- PASSWORD harbor账号密码
- EMAIL harbor账号绑定的邮箱
USERNAME=dev
PASSWORD=Developer123
EMAIL=develop@163.com
AUTH=$(printf "$USERNAME:$PASSWORD" | base64)
cat > config.json <<EOF
{
"auths":{
"https://harbor.wxd.cn/v2/":{
"username":"$USERNAME",
"password":"$PASSWORD",
"email":"$EMAIL",
"auth":"$AUTH"
}
}
}
EOF
创建Dockerfile
cat > Dockerfile <<EOF
FROM nginx:1.14.2
COPY Dockerfile /root
EXPOSE 80
EOF
运行脚本
docker run -v /home/kaniko:/workspace \
-v /home/kaniko/config.json:/kaniko/.docker/config.json \
harbor.wxd.cn/dev/application-component-image/kaniko:debug \
--dockerfile /workspace/Dockerfile \
--destination "harbor.wxd.cn/dev/wxd/devops-toolkit:2.0.0" \
--context dir:///workspace/ \
--skip-tls-verify
推送至 Docker Registry
步骤和推送到Harbor差不多,只是登录认证方式改了改
创建config文件
USERNAME=admin
PASSWORD=admin
EMAIL=
AUTH=$(printf "$USERNAME:$PASSWORD" | base64)
cat > config-registry.json <<EOF
{
"auths":{
"https://docker.domain.com:5043/v2/":{
"username":"$USERNAME",
"password":"$PASSWORD",
"email":"$EMAIL",
"auth":"$AUTH"
}
}
}
EOF
创建Dockerfile
cat > Dockerfile <<EOF
FROM nginx:14.2
COPY Dockerfile /root
EXPOSE 80
EOF
运行脚本
docker run -v /home/kaniko:/workspace \
-v /etc/hosts:/etc/hosts \
-v /home/kaniko/config-registry.json:/kaniko/.docker/config.json \
harbor.wxd.cn/dev/application-component-image/kaniko:debug \
--dockerfile /workspace/Dockerfile \
--destination "docker.domain.com:5043/devops-toolkit:3.0.0" \
--context dir:///workspace/ \
--skip-tls-verify
Run in CICD Pipeline
准备
注意:
- 首先需要创建一个推送镜像仓库的Secret,具体操作这里就不再赘述了。
- CICD场景下使用Kaniko只能使用debug镜像,因为latest镜像基于 scratch构建,不包含 shell,无法进入容器。
流水线集成
pod声明
将下方容器yaml声明放到流水线脚本的pod声明里面:
- image: harbor.wxd.cn/dev/application-component-image/kaniko:debug
command: ["/busybox/sh"]
name: imagebuildandpush
tty: true
resources:
limits:
memory: 1024Mi
ephemeral-storage: 1Gi
cpu: 1000m
volumeMounts:
- name: kaniko-secret #挂载目标仓库的用户名密码
mountPath: /kaniko/.docker
- name: workspace #挂载工作空间
mountPath: /workspace
- name: hosts #挂载宿主机的host,使用宿主机的域名解析
mountPath: /etc/hosts
pod volume挂载
volumes:
- name: kaniko-secret
secret:
secretName: harbor-regcred
items:
- key: .dockerconfigjson
path: config.json
- name: workspace
hostPath:
path: /root/application/sharing/e2979973a5e440d897af913c6953b383/workspace/e2979973a5e440d897af913c6953b383 #jenkins的工作目录
- name: hosts
hostPath:
path: /etc/hosts
pipeline step脚本
steps {
container('jnlp') {
checkout ([$class: 'GitSCM', branches: [[name: 'master']],userRemoteConfigs: [[credentialsId: '091caf88db684cd8a62479c03535bd69',url: 'https://gitlab.wxd.cn/Haihe/application-center.git']]])
}
container('maven') {
sh "mvn clean package -Dmaven.test.skip=true"
sh "cp target/application-center-1.1.0.jar ./docker/"
sh "cp entrypoint.sh ./docker/"
sh "cp -r data/ ./docker/"
sh "cp -r helm/ ./docker/"
}
container('imagebuildandpush') {
sh "/kaniko/executor -f /workspace/docker/Dockerfile -c /workspace/docker --cache=true --skip-tls-verify --destination=harbor.wxd.cn/dev/wxd/devops-toolkit:2.0.0"
}
}
四、其他类似的镜像构建工具
- BuildKit:github.com/moby/buildk…
- img:github.com/genuinetool…
- orca-build:github.com/cyphar/orca…
- buildah:github.com/containers/…
对比:
- BuildKit和img可以在容器中作为非root用户执行,但需要禁用 seccomp 和 AppArmor 才能创建嵌套容器。 kaniko实际上并不创建嵌套容器,因此不需要禁用 seccomp 和 AppArmor。
- orca-build依赖于runc从 Dockerfiles 构建镜像,它不能在容器内运行。kaniko不使用runc,因此不需要使用内核命名空间技术。但是,orca-build不需要 Docker 或任何特权守护进程(因此构建可以完全在没有特权的情况下完成)。
- Buildah专门构建 OCI 镜像。Buildah 的命令复制了 Dockerfile 中的所有命令。这允许在不需要任何 root 权限的情况下使用和不使用 Dockerfile 构建镜像。Buildah 的最终目标是提供一个较低级别的 coreutils 接口来构建镜像。在没有 Dockerfiles 的情况下构建镜像的灵活性允许将其他脚本语言集成到构建过程中。Buildah 遵循简单的 fork-exec 模型,不作为守护进程运行,但它基于 golang 中的综合 API,可以供应给其他工具。