KanikoをMinikubeで試す

[Kaniko](https://github.com/GoogleContainerTools/kaniko)をMinikubeで試してみたメモ。Kanikoを使うとKubernetes上で動くコンテナ上でDockerイメージをビルドすることができる。

|コンポーネント|バージョン|
|---|---|
|Minikube|v1.3.0|
|Kubernetes|v1.15.2|
|Docker|18.09.8|

## Minikubeの起動

Minikubeを起動する。

```shell
minikube start
```

## 認証情報のSecret作成

KanikoはビルドしたイメージはどこかのレジストリーにPushするので、Dockerレジストリーの認証情報を格納したSecretを作成する。
今回はDockerHubにPushする。

```shell:コマンド
kubectl create secret docker-registry regcred \
  --docker-server=https://index.docker.io/v1/ \
  --docker-username=<your-name> \
  --docker-password=<your-pword> \
  --docker-email=<your-email>
```

```shell-session:実行例
$ kubectl create secret docker-registry regcred \
>   --docker-server=https://index.docker.io/v1/ \
>   --docker-username=sotoiwa540 \
>   --docker-password=hogehoge \
>   --docker-email=hogehoge@example.com
secret/regcred created
$
```

## ビルド

Kanikoではビルドコンテキストに以下が指定できる。

- GCS Bucket
- S3 Bucket
- Local Directory
- Git Repository

### Local Directory

まず、ローカルディレクトリーを試してみる。Kanikoのコンテナから見てローカルディレクトリーである必要があるので、Minikube上にhostPathのPVを作成し、KanikoのPodにマウントする。

MinikubeのVMにsshログインし、ディレクトリーを作成し、Dockerfileを作成する。

```shell:コマンド
minikube ssh
mkdir kaniko && cd kaniko
cat <<EOF > Dockerfile
FROM ubuntu
CMD ["echo", "Hello World"]
EOF
exit
```

```shell-session:実行例
$ minikube ssh
                         _             _
            _         _ ( )           ( )
  ___ ___  (_)  ___  (_)| |/')  _   _ | |_      __
/' _ ` _ `\| |/' _ `\| || , <  ( ) ( )| '_`\  /'__`\
| ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )(  ___/
(_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____)

$ pwd
/home/docker
$ mkdir kaniko && cd kaniko
$ cat <<EOF > Dockerfile
> FROM ubuntu
> CMD ["echo", "Hello World"]
> EOF
$ cat Dockerfile
FROM ubuntu
CMD ["echo", "Hello World"]
$ exit
logout
$
```

PVを作成する。

```yaml:kaniko-volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: kaniko-volume
  labels:
    type: local
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  hostPath:
    path: "/home/docker/kaniko"
```

```shell
kubectl apply -f kaniko-volume.yaml
```

PVCを作成する。

```yaml:kaniko-claim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: kaniko-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: local-storage
```

```shell
kubectl apply -f kaniko-claim.yaml
```

PVCのSTATUSがBoundとなったことを確認する。

```
$ kubectl get pvc
NAME           STATUS   VOLUME          CAPACITY   ACCESS MODES   STORAGECLASS    AGE
kaniko-claim   Bound    kaniko-volume   1Gi        RWO            local-storage   3s
$
```

KanikoのPodのyamlを準備する。

```kaniko-local-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: kaniko-local
spec:
  containers:
  - name: kaniko
    image: gcr.io/kaniko-project/executor:latest
    args:
    - --dockerfile=/workspace/Dockerfile
    - --context=dir://workspace
    - --destination=sotoiwa540/kaniko-sample:local
    volumeMounts:
    - name: kaniko-secret
      mountPath: /root
    - name: kaniko-storage
      mountPath: /workspace
  restartPolicy: Never
  volumes:
  - name: kaniko-secret
    secret:
      secretName: regcred
      items:
      - key: .dockerconfigjson
        path: .docker/config.json
  - name: kaniko-storage
    persistentVolumeClaim:
      claimName: kaniko-claim
```

Podを起動する。

```shell
kubectl apply -f kaniko-local-pod.yaml
```

ログを確認する。

```shell-session
$ kubectl apply -f kaniko-local-pod.yaml
pod/kaniko-local created
$ kubectl get po
NAME           READY   STATUS    RESTARTS   AGE
kaniko-local   1/1     Running   0          4s
$ kubectl logs -f kaniko-local
INFO[0002] Resolved base name ubuntu to ubuntu
INFO[0002] Resolved base name ubuntu to ubuntu
INFO[0002] Downloading base image ubuntu
INFO[0004] Error while retrieving image from cache: getting file info: stat /cache/sha256:d91842ef309155b85a9e5c59566719308fab816b40d376809c39cf1cf4de3c6a: no such file or directory
INFO[0004] Downloading base image ubuntu
INFO[0006] Built cross stage deps: map[]
INFO[0006] Downloading base image ubuntu
INFO[0008] Error while retrieving image from cache: getting file info: stat /cache/sha256:d91842ef309155b85a9e5c59566719308fab816b40d376809c39cf1cf4de3c6a: no such file or directory
INFO[0008] Downloading base image ubuntu
INFO[0009] Skipping unpacking as no commands require it.
INFO[0009] Taking snapshot of full filesystem...
INFO[0009] CMD ["echo", "Hello World"]
2019/08/09 05:16:20 mounted blob: sha256:344da5c95cecd0f55238ce59b8469ee301056001ece2b769e9691b80f94f9f37
2019/08/09 05:16:20 mounted blob: sha256:7413c47ba209e555018c4be91101d017737f24b0c9d1f65339b97a4da98acb2a
2019/08/09 05:16:20 mounted blob: sha256:0fe7e7cbb2e88617d969efeeb3bd3125f7d309335c736a0525233ec2dc06aee1
2019/08/09 05:16:21 mounted blob: sha256:1d425c98234572d4221a1ac173162c4279f9fdde4726ec22ad3c399f59bb7503
2019/08/09 05:16:22 pushed blob: sha256:3b86359dbd531012513abc6385a198a1ea8362efdd41df78659568044dbb7bad
2019/08/09 05:16:23 index.docker.io/sotoiwa540/kaniko-sample:local: digest: sha256:a066b9af667ba08ac9c18f1b70e7a73655f2d3e277da6bbbc92cc39f372b4d3b size: 911
$ kubectl get po
NAME           READY   STATUS      RESTARTS   AGE
kaniko-local   0/1     Completed   0          27s
$
```

完了したPodを削除。

```shell
kubectl delete po kaniko-local
```

イメージがpushされているかをpullして確認。

```shell-session
$ docker pull sotoiwa540/kaniko-sample:local
local: Pulling from sotoiwa540/kaniko-sample
7413c47ba209: Pull complete
0fe7e7cbb2e8: Pull complete
1d425c982345: Pull complete
344da5c95cec: Pull complete
Digest: sha256:a066b9af667ba08ac9c18f1b70e7a73655f2d3e277da6bbbc92cc39f372b4d3b
Status: Downloaded newer image for sotoiwa540/kaniko-sample:local
docker.io/sotoiwa540/kaniko-sample:local
$
```

コンテナをローカルで実行してみる。

```shell-session
$ docker run sotoiwa540/kaniko-sample:local
Hello World
$
```

### Git Repository

続いてGitリポジトリーからのビルドを試してみる。
GitHubにDockerfileをおいたリポジトリーを作成する。

- https://github.com/sotoiwa/kaniko-sample

KanikoのPodのyamlを準備する。

```kaniko-github-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: kaniko-github
spec:
  containers:
  - name: kaniko
    image: gcr.io/kaniko-project/executor:latest
    args:
    - --dockerfile=Dockerfile
    - --context=git://github.com/sotoiwa/kaniko-sample.git
    - --destination=sotoiwa540/kaniko-sample:github
    volumeMounts:
    - name: kaniko-secret
      mountPath: /root
  restartPolicy: Never
  volumes:
  - name: kaniko-secret
    secret:
      secretName: regcred
      items:
      - key: .dockerconfigjson
        path: .docker/config.json
```

Podを起動する。

```shell
kubectl apply -f kaniko-github-pod.yaml
```

確認する。

```shell-session
$ kubectl apply -f kaniko-github-pod.yaml
pod/kaniko-github created
$ kubectl get po
NAME            READY   STATUS      RESTARTS   AGE
kaniko-github   1/1     Running     0          6s
$ kubectl logs -f kaniko-github
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Compressing objects: 100% (3/3), done.
Total 6 (delta 0), reused 3 (delta 0), pack-reused 0
INFO[0004] Resolved base name ubuntu to ubuntu
INFO[0004] Resolved base name ubuntu to ubuntu
INFO[0004] Downloading base image ubuntu
INFO[0006] Error while retrieving image from cache: getting file info: stat /cache/sha256:d91842ef309155b85a9e5c59566719308fab816b40d376809c39cf1cf4de3c6a: no such file or directory
INFO[0006] Downloading base image ubuntu
INFO[0008] Built cross stage deps: map[]
INFO[0008] Downloading base image ubuntu
INFO[0009] Error while retrieving image from cache: getting file info: stat /cache/sha256:d91842ef309155b85a9e5c59566719308fab816b40d376809c39cf1cf4de3c6a: no such file or directory
INFO[0009] Downloading base image ubuntu
INFO[0011] Skipping unpacking as no commands require it.
INFO[0011] Taking snapshot of full filesystem...
INFO[0011] CMD ["echo", "Hello World!!!"]
2019/08/09 05:28:37 existing blob: sha256:1d425c98234572d4221a1ac173162c4279f9fdde4726ec22ad3c399f59bb7503
2019/08/09 05:28:37 existing blob: sha256:344da5c95cecd0f55238ce59b8469ee301056001ece2b769e9691b80f94f9f37
2019/08/09 05:28:37 existing blob: sha256:0fe7e7cbb2e88617d969efeeb3bd3125f7d309335c736a0525233ec2dc06aee1
2019/08/09 05:28:37 existing blob: sha256:7413c47ba209e555018c4be91101d017737f24b0c9d1f65339b97a4da98acb2a
2019/08/09 05:28:38 pushed blob: sha256:103f2e4089bd2a24a2c98704efc4316981edcc9e550523e51192fe1e3c2832c6
2019/08/09 05:28:39 index.docker.io/sotoiwa540/kaniko-sample:github: digest: sha256:6829ca5604b851f4f260b6a847d947cbd685386af8eefe96721e8f1a9c9d4c36 size: 911
$ kubectl get po
NAME            READY   STATUS      RESTARTS   AGE
kaniko-github   0/1     Completed   0          39s
$
```

完了したPodを削除。

```shell
kubectl delete po kaniko-github
```

イメージがpushされているかをpullして確認。

```shell-session
$ docker pull sotoiwa540/kaniko-sample:github
github: Pulling from sotoiwa540/kaniko-sample
7413c47ba209: Already exists
0fe7e7cbb2e8: Already exists
1d425c982345: Already exists
344da5c95cec: Already exists
Digest: sha256:6829ca5604b851f4f260b6a847d947cbd685386af8eefe96721e8f1a9c9d4c36
Status: Downloaded newer image for sotoiwa540/kaniko-sample:github
docker.io/sotoiwa540/kaniko-sample:github
$
```
コンテナをローカルで実行してみる。

```shell-session
$ docker run sotoiwa540/kaniko-sample:github
Hello World!!!
$
```

## 参考リンク

- https://github.com/debuggy/kaniko-example
- [Kanikoを使ってみる](https://qiita.com/soymsk/items/2633345be44f7266ae0a)
- [Kanikoによるコンテナビルドをlocal環境で試す](https://qiita.com/tetrar124/items/e9bf06ed7b533e5984e8)