kaniko를 통해 docker daemon을 쓰지 않고 컨테이너 이미지를 빌드할 수 있다.
다만 kaniko의 executor 이미지를 커스텀하는 경우 kaniko 이미지 구조를 알아두는게 좋다.
kaniko README 문서에 아래와 같이 써있다.
How does kaniko work?
The kaniko executor image is responsible for building an image from a Dockerfile and pushing it to a registry. Within the executor image, we extract the filesystem of the base image (the FROM image in the Dockerfile). We then execute the commands in the Dockerfile, snapshotting the filesystem in userspace after each one. After each command, we append a layer of changed files to the base image (if there are any) and update image metadata.
즉 kaniko는 이미지를 빌드할 때, kaniko 컨테이너의 파일시스템 그 자체를 사용한다.
k8s에 아래 내용을 배포해서 직접 테스트해본다.
# Dockerfile
FROM nginx:1.19.5
USER root
RUN apt-get update -y \
&& apt-get install -y \
net-tools \
procps \
vim
WORKDIR /etc/nginx
# kaniko.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kaniko-debug
spec:
replicas: 1
template:
spec:
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:debug
command:
[
"/busybox/sleep", "infinity"
]
volumeMounts:
- name: dockerfile
mountPath: /test/Dockerfile
subPath: Dockerfile
volumes:
- name: dockerfile
configMap:
name: kaniko-cm
# kustomize.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- kaniko.yaml
namespace: default
commonLabels:
app: kaniko-debug
configMapGenerator:
- files:
- Dockerfile
name: kaniko-cm
❯ k apply -k ./
configmap/kaniko-cm-g2fc92d575 created
deployment.apps/kaniko-debug created
/ # ls
busybox dev etc kaniko proc sys test var
# configMap으로 추가한 도커파일
/ # ls /test
Dockerfile
# /etc에 있는 항목
/ # ls /etc/
hostname mtab resolv.conf
hosts nsswitch.conf
아래 명령어를 수행한다.
/kaniko/executor --context . --dockerfile /test/Dockerfile --no-push
이 옵션은 kaniko 컨테이너 상에서 이미지 빌드만 수행하고, 레지스트리 push는 수행하지 않는다.
명령어를 수행한 뒤를 확인하면 아래와 같다.
/ # ls /etc/
hostname mtab resolv.conf
hosts nsswitch.conf
/ # ls /etc/
hostname mtab resolv.conf
hosts nsswitch.conf
# 🙄 이미지 빌드 과정에서 nginx 이미지에 있던 /etc/ 항목들이 추가되었다.
/ # ls /etc/
adduser.conf kernel rc2.d
alternatives ld.so.cache rc3.d
apt ld.so.conf rc4.d
bash.bashrc ld.so.conf.d rc5.d
bindresvport.blacklist libaudit.conf rc6.d
cron.daily localtime rcS.d
debconf.conf login.defs resolv.conf
debian_version logrotate.d rmt
default machine-id securetty
deluser.conf mke2fs.conf security
dpkg motd selinux
environment mtab shadow
fstab nsswitch.conf shadow-
gai.conf opt shells
group os-release skel
group- pam.conf subgid
gshadow pam.d subuid
host.conf passwd systemd
hostname passwd- terminfo
hosts profile timezone
init.d profile.d update-motd.d
issue rc0.d xattr.conf
issue.net rc1.d
# 🙄 이미지 빌드 과정에서 nginx 이미지에 있던 /etc/ 항목들이 추가되었다. (2)
/ # ls /etc/
adduser.conf inputrc rc0.d
alternatives issue rc1.d
apt issue.net rc2.d
bash.bashrc kernel rc3.d
bindresvport.blacklist ld.so.cache rc4.d
ca-certificates ld.so.conf rc5.d
ca-certificates.conf ld.so.conf.d rc6.d
cron.daily ldap rcS.d
debconf.conf libaudit.conf resolv.conf
debian_version localtime rmt
default login.defs securetty
deluser.conf logrotate.d security
dpkg machine-id selinux
environment mke2fs.conf shadow
fonts motd shadow-
fstab mtab shells
gai.conf nginx skel
group nsswitch.conf ssl
group- opt subgid
gshadow os-release subuid
gshadow- pam.conf systemd
gss pam.d terminfo
host.conf passwd timezone
hostname passwd- ucf.conf
hosts profile update-motd.d
init.d profile.d xattr.conf
즉 kaniko는 컨테이너 이미지를 빌드할 때, kaniko가 떠있는 컨테이너의 파일시스템을 직접 사용하는 것을 알 수 있다. 따라서 kaniko 이미지에 CLI를 추가하는 경우는 파일시스템에 추가되는 사항을 최소로 가져가자. (이에 kaniko는 /busybox 안에 binary들을 보관한다.)