简介

Github地址:https://github.com/GoogleContainerTools/kaniko

Kaniko 是谷歌开源的一款构建容器镜像的工具。

Kaniko 并不依赖于 Docker 守护进程,完全在用户空间根据 Dockerfile 的内容逐行执行命令来构建镜像,这就使得在一些无法获取 docker 守护 进程的环境下也能够构建镜像。

img_27

Kaniko 会先提取基础镜像(Dockerfile FROM 之后的镜像)的文件系统,然后根据 Dockerfile 中所描述的,一条条执行命令,每一条命令执行完以后会在用户空间下面创建一个 snapshot,并与存储与内存中的上一个状态进行比对,如果有变化,就将新的修改生成一个镜像层添加在基础镜像上,并且将相关的修改信息写入镜像元数据中。等所有命令执行完,kaniko 会将最终镜像推送到指定的远端镜像仓库。

获取Kaniko镜像

这个需要在linux环境下执行:

1
2
3
4
5
6
7
8
9
10
11
# docker 登陆
docker login --username=huari@xxx public-registry.cn-hangzhou.cr.aliyuncs.com

# 通过代理拉取镜像
docker pull --platform linux/amd64 m.daocloud.io/gcr.io/kaniko-project/executor:latest

# 修改tag
docker tag m.daocloud.io/gcr.io/kaniko-project/executor:latest public-registry.cn-hangzhou.cr.aliyuncs.com/public/kaniko-executor:latest

# 推送镜像
docker push public-registry.cn-hangzhou.cr.aliyuncs.com/public/kaniko-executor:latest

–platform linux/amd64:实现在mac上pull amd64的镜像,

pull镜像时,会默认匹配当前架构,因此若不设置该参数,则会自动匹配下载arm64镜像,在amd64上运行时会遇见下面这个报错:

1
exec /kaniko/executor: exec format error

Kaniko Demo

demo项目选择

在gitlab上新建一个demo项目,仅添加一个Dockerfile即可。内容如下:

1
2
3
FROM ubuntu:20.04
LABEL maintainer="yourname@example.com"
RUN apt-get update && apt-get install -y nginx

对项目的要求是,通过 Dockerfile 能够直接编译得到镜像。一共有两个验证点:

  • 通过kaniko可以直接构建docker镜像
  • 构建的镜像可以正常运行

Docker环境进行测试

生成推送镜像的凭证

凭证信息:

  • YOUR_USERNAME(我的阿里云 dockerhub账户):huari@xxx
  • YOUR_PASSWORD(我的阿里云 dockerhub账户密码): 域账号密码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    export AUTH=$(echo -n YOUR_USERNAME:YOUR_PASSWORD | base64 )

    cat > config.json <<-EOF
    {
    "auths": {
    "https://index.docker.io/v1/": {
    "auth": "${AUTH}"
    }
    }
    }
    EOF

执行构建

因为我在mac环境执行,所以pull image时,要加–platform linux/arm64
也可以直接使用原始镜像(经过代理):m.daocloud.io/gcr.io/kaniko-project/executor:latest

1
2
3
4
5
docker run \
--interactive -v `pwd`/config.json:/kaniko/.docker/config.json m.daocloud.io/gcr.io/kaniko-project/executor:latest \
--context git://gitlab.papegames.com/huari/kaniko-build-test \
--dockerfile Dockerfile \
--destination=dev-registry.cn-hangzhou.cr.aliyuncs.com/ops/kaniko-demo:v2

参数说明:

  • context:构建需要的上下文。支持多种格式,S3、本地目录、标准输入、Git 仓库等
  • dockerfile:Dockerfile 路径
  • destination:构建后推送的镜像地址

已经可以完成镜像编译和上传:

img_28

K8s集群环境进行测试

生成推送镜像凭证

这个是用来给kaniko向阿里云推送镜像使用的

凭证信息:

  • YOUR_USERNAME(我的阿里云 dockerhub账户):huari@xxx
  • YOUR_PASSWORD(我的阿里云 dockerhub账户密码): 域账号密码
  • YOUR_EMAIL (我的叠纸邮箱):xxx@yyy.net
  • YOUR_NAMESPACE (集群内的namespace)
1
kubectl create secret docker-registry aliyun-regsecret --docker-server=dev-registry.cn-hangzhou.cr.aliyuncs.com --docker-username=<YOUR_USERNAME> --docker-password=<YOUR_PASSWORD> --docker-email=<YOUR_EMAIL> -n <YOUR_NAMESPACE>

参数解释:

  • kubectl create secret aliyun-regsecret:核心命令
    • 创建一个专门用于 Docker 镜像仓库认证的 Kubernetes Secret
    • 这种 Secret 会自动生成 ~/.docker/config.json 格式的认证文件
  • aliyun-regsecret:Secret 名称
    • 自定义的 Secret 名称(可任意命名)
    • 后续在 Pod 中通过此名称引用认证信息
  • –docker-server=dev-registry.cn-hangzhou.cr.aliyuncs.com:仓库服务器地址
    • 阿里云容器镜像服务的 Registry 地址
    • cn-hangzhou 表示杭州地域(根据你的仓库所在地域修改)
  • 认证凭据
    • –docker-username= # 阿里云账号用户名
      • 用户名:阿里云 主账号 或 RAM 子账号 用户名
    • –docker-password= # 阿里云账号密码或访问凭证
      • 主账号:登录密码
      • 推荐使用 访问凭证(更安全):
        1. 进入 阿里云访问控制台
        2. 创建 AccessKey(包含 AccessKey ID 和 AccessKey Secret)
    • –docker-email= # 账号邮箱(Kubernetes 要求但实际不验证)

查看secret:

1
2
3
4
5
6
7
8
9
10
11
kubectl describe secret aliyun-regsecret -n huari
Name: aliyun-regsecret
Namespace: huari
Labels: <none>
Annotations: <none>

Type: kubernetes.io/dockerconfigjson

Data
====
.dockerconfigjson: 218 bytes

构建pod的yaml

因为最终镜像在amd64环境执行,所以pull image时,要加–platform linux/amd64

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: v1
kind: Pod
metadata:
name: kaniko-builder
namespace: huari
spec:
containers:
- name: kaniko
image: m.daocloud.io/gcr.io/kaniko-project/executor:latest
args: ["--dockerfile=Dockerfile",
"--context=git://gitlab.papegames.com/huari/kaniko-build-test",
"--destination=dev-registry.cn-hangzhou.cr.aliyuncs.com/ops/kaniko-demo:v3"]
volumeMounts:
- name: kaniko-secret
mountPath: "/kaniko/.docker"
volumes:
- name: kaniko-secret
secret:
secretName: aliyun-regsecret
items:
- key: .dockerconfigjson
path: config.json
restartPolicy: Never

执行构建

将pod的yaml保存进kaniko-test.yaml内,然后执行apply:

1
kubectl apply -f kaniko-test.yaml

查看运行日志(部分):

1
2
3
4
5
6
7
8
➜ kubectl logs pod/kaniko-builder -n huari      


···

INFO[0020] Taking snapshot of full filesystem...
INFO[0022] Pushing image to dev-registry.cn-hangzhou.cr.aliyuncs.com/ops/kaniko-demo:v3
INFO[0032] Pushed dev-registry.cn-hangzhou.cr.aliyuncs.com/ops/kaniko-demo@sha256:baf97628a3981542e85db343f77c9e0dba5f666c868c2c6671290f7bfdc0d207

已经打包好镜像:

img_29

并且pod状态已经变为:Completed

1
2
3
➜ kubectl get pod -n huari
NAME READY STATUS RESTARTS AGE
kaniko-builder 0/1 Completed 0 2m22s