CI/CD 1์ฃผ์ฐจ ์ ๋ฆฌ
๐๏ธ ์ค์ต ์ค๋น
1. ์ค์ต ๋ ํฌ์งํ ๋ฆฌ ํด๋ก
1
git clone https://github.com/gitops-cookbook/chapters
2. ๋์ปคํ๋ธ Acess Token ๋ฐ๊ธ
3. ๋ฐ๊ธ๋ ํ ํฐ์ผ๋ก ๋ก๊ทธ์ธ
1
2
3
4
5
docker login -u <id>
# ๊ฒฐ๊ณผ
i Info โ A Personal Access Token (PAT) can be used instead.
To create a PAT, visit https://app.docker.com/settings
1
2
3
4
5
6
7
8
Password: <๋ฐ๊ธ๋ ํ ํฐ>
# ๊ฒฐ๊ณผ
WARNING! Your credentials are stored unencrypted in '/home/devshin/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/
Login Succeeded
4. kind ํด๋ฌ์คํฐ ์์ฑ
1
2
3
4
5
6
7
8
9
10
11
12
kind create cluster --name myk8s --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
- role: worker
EOF
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Creating cluster "myk8s" ...
โ Ensuring node image (kindest/node:v1.32.8) ๐ผ
โ Preparing nodes ๐ฆ ๐ฆ
โ Writing configuration ๐
โ Starting control-plane ๐น๏ธ
โ Installing CNI ๐
โ Installing StorageClass ๐พ
โ Joining worker nodes ๐
Set kubectl context to "kind-myk8s"
You can now use your cluster with:
kubectl cluster-info --context kind-myk8s
Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community ๐
5. kind ๋ ธ๋ ๋ชฉ๋ก ํ์ธ
1
kind get nodes --name myk8s
โ ย ์ถ๋ ฅ
1
2
myk8s-control-plane
myk8s-worker
6. ๊ธฐ๋ณธ ๋ค์์คํ์ด์ค ์ ํ
1
2
3
4
kubens default
# ๊ฒฐ๊ณผ
โ Active namespace is "default"
7. ๋์ปค ๋คํธ์ํฌ ๋ชฉ๋ก ํ์ธ
1
docker network ls
โ ย ์ถ๋ ฅ
1
2
3
4
5
NETWORK ID NAME DRIVER SCOPE
fc329dabc0ef bridge bridge local
bec308f23ee5 host host local
1da18f85ffec kind bridge local
225e867f21f9 none null local
kind์ ์ฉ ๋ธ๋ฆฌ์ง ๋คํธ์ํฌ ์์ฑ
8. kind ๋คํธ์ํฌ ์ธ๋ถ ์ ๋ณด ์กฐํ
1
docker inspect kind | jq
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[
{
"Name": "kind",
"Id": "1da18f85ffecfc8a2170a57b9369bf4387586703d6c83f3accf900e9145b7772",
"Created": "2025-10-18T15:06:51.081819223+09:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv4": true,
"EnableIPv6": true,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "fc00:f853:ccd:e793::/64"
},
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"1ef7f7ad8535332606690ec5ff56ae72df32c85fbf2c889a5618785e75b5967a": {
"Name": "myk8s-worker",
"EndpointID": "865f00e0498a27f4afc48696e63a9928b06a6c3670befefb1b2bac00b5e2867f",
"MacAddress": "d2:2b:3a:f4:b2:5b",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": "fc00:f853:ccd:e793::2/64"
},
"e4d4f4c84c020e54ba54045c7f09305982cf660ee483bd23e87c72067b479d95": {
"Name": "myk8s-control-plane",
"EndpointID": "b99e31c8649d55aa7d08eb452bb81b13f30b0bf1316919e1ad0e159ecab84585",
"MacAddress": "3a:68:23:56:48:a5",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": "fc00:f853:ccd:e793::3/64"
}
},
"Options": {
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
- IPv4 ์๋ธ๋ท
172.18.0.0/16, ๊ฒ์ดํธ์จ์ด172.18.0.1 - IPv6 ์๋ธ๋ท
fc00:f853:ccd:e793::/64 - ์ปจํ
์ด๋ IP: control-plane
172.18.0.3, worker172.18.0.2
9. Kubernetes ๋ ธ๋ ์์ธ ์กฐํ
1
kubectl get node -o wide
โ ย ์ถ๋ ฅ
1
2
3
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
myk8s-control-plane Ready control-plane 3m30s v1.32.8 172.18.0.3 <none> Debian GNU/Linux 12 (bookworm) 6.17.3-arch2-1 containerd://2.1.3
myk8s-worker Ready <none> 3m14s v1.32.8 172.18.0.2 <none> Debian GNU/Linux 12 (bookworm) 6.17.3-arch2-1 containerd://2.1.3
10. ๋์ปค ์ปจํ ์ด๋ ๋ชฉ๋ก ํ์ธ
1
docker ps
โ ย ์ถ๋ ฅ
1
2
3
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e4d4f4c84c02 kindest/node:v1.32.8 "/usr/local/bin/entrโฆ" 5 minutes ago Up 5 minutes 0.0.0.0:30000-30001->30000-30001/tcp, 127.0.0.1:35121->6443/tcp myk8s-control-plane
1ef7f7ad8535 kindest/node:v1.32.8 "/usr/local/bin/entrโฆ" 5 minutes ago Up 5 minutes myk8s-worker
myk8s-control-plane: ํธ์คํธ127.0.0.1:35121โ ์ปจํ ์ด๋6443(API ์๋ฒ) ํฌ์๋ฉ, ํธ์คํธ0.0.0.0:30000-30001โ ์ปจํ ์ด๋30000-30001NodePort ํฌ์๋ฉmyk8s-worker: ์ ์ ๊ธฐ๋(ํฌํธ ๋งคํ ์์, ๋ด๋ถ ๋คํธ์ํน ์ฐธ์ฌ)
11. ์์คํ ํ๋ ๋ฐ CNI(kindnet) ์ํ ํ์ธ
1
kubectl get pod -A -o wide
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-668d6bf9bc-c8nvg 1/1 Running 0 4m2s 10.244.0.3 myk8s-control-plane <none> <none>
kube-system coredns-668d6bf9bc-x558x 1/1 Running 0 4m2s 10.244.0.4 myk8s-control-plane <none> <none>
kube-system etcd-myk8s-control-plane 1/1 Running 0 4m10s 172.18.0.3 myk8s-control-plane <none> <none>
kube-system kindnet-5qv46 1/1 Running 0 4m2s 172.18.0.3 myk8s-control-plane <none> <none>
kube-system kindnet-g7mlp 1/1 Running 0 3m56s 172.18.0.2 myk8s-worker <none> <none>
kube-system kube-apiserver-myk8s-control-plane 1/1 Running 0 4m10s 172.18.0.3 myk8s-control-plane <none> <none>
kube-system kube-controller-manager-myk8s-control-plane 1/1 Running 0 4m9s 172.18.0.3 myk8s-control-plane <none> <none>
kube-system kube-proxy-c2wvh 1/1 Running 0 3m56s 172.18.0.2 myk8s-worker <none> <none>
kube-system kube-proxy-sqjsg 1/1 Running 0 4m2s 172.18.0.3 myk8s-control-plane <none> <none>
kube-system kube-scheduler-myk8s-control-plane 1/1 Running 0 4m10s 172.18.0.3 myk8s-control-plane <none> <none>
local-path-storage local-path-provisioner-7dc846544d-9wnfp 1/1 Running 0 4m2s 10.244.0.2 myk8s-control-plane <none>
kindnet(CNI) ๊ฐ ๋ ธ๋์ ์ค์น/Running
12. ์ปจํธ๋กค ํ๋ ์ธ ํฌํธ ๋ฆฌ์ค๋ ํ์ธ
1
docker exec -it myk8s-control-plane ss -tnlp
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.1:2381 0.0.0.0:* users:(("etcd",pid=718,fd=13))
LISTEN 0 4096 127.0.0.1:2379 0.0.0.0:* users:(("etcd",pid=718,fd=8))
LISTEN 0 4096 127.0.0.1:45205 0.0.0.0:* users:(("containerd",pid=112,fd=11))
LISTEN 0 4096 127.0.0.11:33261 0.0.0.0:*
LISTEN 0 4096 172.18.0.3:2380 0.0.0.0:* users:(("etcd",pid=718,fd=7))
LISTEN 0 4096 172.18.0.3:2379 0.0.0.0:* users:(("etcd",pid=718,fd=9))
LISTEN 0 4096 127.0.0.1:10259 0.0.0.0:* users:(("kube-scheduler",pid=561,fd=3))
LISTEN 0 4096 127.0.0.1:10257 0.0.0.0:* users:(("kube-controller",pid=582,fd=3))
LISTEN 0 4096 127.0.0.1:10249 0.0.0.0:* users:(("kube-proxy",pid=1016,fd=10))
LISTEN 0 4096 127.0.0.1:10248 0.0.0.0:* users:(("kubelet",pid=793,fd=8))
LISTEN 0 4096 *:10256 *:* users:(("kube-proxy",pid=1016,fd=12))
LISTEN 0 4096 *:10250 *:* users:(("kubelet",pid=793,fd=22))
LISTEN 0 4096 *:6443 *:* users:(("kube-apiserver",pid=603,fd=3))
13. ์ปจํธ๋กค ํ๋ ์ธ ์ปจํ ์ด๋ ์ ธ ์ ์
1
2
3
docker exec -it myk8s-control-plane bash
root@myk8s-control-plane:/# hostname
myk8s-control-plane
๐ฆ ๋์ปค๋ฅผ ์ฌ์ฉํ ์ปจํ ์ด๋ (์ด๋ฏธ์ง) ๋น๋ : layer , image build / push
1. ๋ก์ปฌ ์ด๋ฏธ์ง ๋ชฉ๋ก ํ์ธ
1
docker images
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/cilium/cilium v1.17.8 ab0dfe84bb2a 3 weeks ago 794MB
quay.io/cilium/operator-generic v1.17.8 710ed26a6a26 3 weeks ago 128MB
kindest/node v1.32.8 05f8e4e76c17 7 weeks ago 1.04GB
quay.io/cilium/cilium v1.17.6 40c15f03eb84 3 months ago 819MB
quay.io/cilium/operator-generic v1.17.6 95a65abe2c97 3 months ago 127MB
quay.io/cilium/cilium-envoy v1.33.4-1752151664-7c2edb0b44cf95f326d628b837fcdd845102ba68 48bdcd4253db 3 months ago 174MB
nicolaka/netshoot latest 0ac86781a84f 3 months ago 594MB
2. ์์ ๋๋ ํ ๋ฆฌ ์ด๋
1
cd chapters/chapters/ch03/python-app
3. Dockerfile ๊ฐ์
chapters/chapters/ch03/python-app/Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
FROM registry.access.redhat.com/ubi8/python-39 # ๊ธฐ๋ฐ ๋ ์ด์ด๊ฐ ๋๋ ์ด๋ฏธ์ง # ์ฐธ๊ณ ๋ก ubi8/python-39 ์ด๋ฏธ์ง๋ 25๋
11์ ๋ง๋ฃ ์์
ENV PORT 8080
EXPOSE 8080
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENTRYPOINT ["python"] # ์ปจํ
์ด๋ ๋ด๋ถ์ ์ฑ ์ง์
์ entrypoint ์ ์
CMD ["app.py"] # ์ปจํ
์ด๋๋ฅด ์์ํ ๋ ์ฌ์ฉํ๋ ๋ช
๋ น์ด
4. ๋ ์ง์คํธ๋ฆฌ ๋ณ์ ์ง์
1
2
3
MYREGISTRY=docker.io
MYUSER=<๋ด ๊ณ์ >
MYTOKEN=<๋ฐ๊ธ๋ฐ์ ํ ํฐ>
- ํธ์ ๋์ ๋ ์ง์คํธ๋ฆฌ/์ฌ์ฉ์ ๊ณ์ /ํ ํฐ ๋ณ์ ์ค์
5. ์ปจํ ์ด๋ ์ด๋ฏธ์ง ๋น๋
1
docker build -f Dockerfile -t $MYREGISTRY/$MYUSER/pythonapp:latest .
โ ย ์ถ๋ ฅ
1
2
3
...
Successfully built a8ea70de71df
Successfully tagged shinminjin/pythonapp:latest
6. ๋น๋ ๊ฒฐ๊ณผ ํ์ธ
1
docker images
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
REPOSITORY TAG IMAGE ID CREATED SIZE
shinminjin/pythonapp latest a8ea70de71df 2 minutes ago 878MB
registry.access.redhat.com/ubi8/python-39 latest 9a62815cc4ee 3 days ago 874MB
quay.io/cilium/cilium v1.17.8 ab0dfe84bb2a 3 weeks ago 794MB
quay.io/cilium/operator-generic v1.17.8 710ed26a6a26 3 weeks ago 128MB
kindest/node v1.32.8 05f8e4e76c17 7 weeks ago 1.04GB
quay.io/cilium/cilium v1.17.6 40c15f03eb84 3 months ago 819MB
quay.io/cilium/operator-generic v1.17.6 95a65abe2c97 3 months ago 127MB
quay.io/cilium/cilium-envoy v1.33.4-1752151664-7c2edb0b44cf95f326d628b837fcdd845102ba68 48bdcd4253db 3 months ago 174MB
nicolaka/netshoot latest 0ac86781a84f 3 months ago 594MB
shinminjin/pythonapp:latest์์ฑ- ๋ฒ ์ด์ค ์ด๋ฏธ์ง๋ ๋ก์ปฌ์ ์กด์ฌ
7. ๋ ์ด์ด ๊ตฌ์กฐ ํ์ธ
1
docker inspect $MYUSER/pythonapp:latest | jq
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:efbb01c414da9dbe80503875585172034d618260b0179622a67440af141ada49",
"sha256:0e770dacd8dd8e0f783addb2f8e2889360ecc1443acc1ca32f03158f8b459b14",
"sha256:03b1af2d2f1752f587c99bf9afca0a564054b79f46cf22cef211f86f1d4a4497",
"sha256:ae81327beceb885cbdb2663e2f89e6e55aaa614f5ce2d502f772420d6fe37f2f",
"sha256:f3254a7dd3384ddbb3c0e625d2468c77b1fd7eeff593a4151f1dcdb7b4585a88",
"sha256:a94bd60400ee5d1ed6225c7cc8e3ac321c2b07714d8c8b196e01bff9ac1b6250",
"sha256:b588d060ae71588c819934b2923b3a01aa5bbee6220f105a0aa1b2cfcbda4c3a",
"sha256:c51214f09723d2a982015329f6403d2f6cd622a43bf63b1b85fbd80d724a252e"
]
},
...
"Labels": {
"architecture": "x86_64",
...
RootFS.layers๋ฅผ ํตํด ์ด๋ฏธ์ง๊ฐ ์ฌ๋ฌ ๋ ์ด์ด๋ก ๊ตฌ์ฑ๋จ์ ํ์ธ- ๋์ผํ ๋ฒ ์ด์ค ๋ ์ด์ด๋ ์บ์/์ค๋ณต์ ๊ฑฐ๋ก ์ฌ์ฌ์ฉ๋จ
Labels.architecture๋ก CPU ์ํคํ ์ฒ(์: x86_64/amd64) ํ์ธ
8. ๋น๋ ํ์คํ ๋ฆฌ ํ์ธ
1
docker history $MYUSER/pythonapp:latest
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
IMAGE CREATED CREATED BY SIZE COMMENT
a8ea70de71df 5 minutes ago /bin/sh -c #(nop) CMD ["app.py"] 0B
b2ad3083a346 5 minutes ago /bin/sh -c #(nop) ENTRYPOINT ["python"] 0B
d585858ececc 5 minutes ago /bin/sh -c #(nop) COPY dir:8da83ed45573a3f70โฆ 399B
9364763d41ce 6 minutes ago /bin/sh -c pip install --no-cache-dir -r reqโฆ 4.05MB
10975489ffe5 6 minutes ago /bin/sh -c #(nop) COPY file:54785910b54a4aa5โฆ 5B
2222d1f682e5 6 minutes ago /bin/sh -c #(nop) WORKDIR /usr/src/app 0B
10793852df9a 6 minutes ago /bin/sh -c #(nop) EXPOSE 8080 0B
531e18d75ae0 6 minutes ago /bin/sh -c #(nop) ENV PORT=8080 0B
9a62815cc4ee 3 days ago /bin/sh -c #(nop) LABEL "architecture"="x86_โฆ 221MB
...
9. ๋ฒ ์ด์ค ์ด๋ฏธ์ง ๋๊ธฐํ ยท ๊ฒ์ฆ
1
2
3
4
5
6
7
docker pull registry.access.redhat.com/ubi8/python-39:latest
# ๊ฒฐ๊ณผ
latest: Pulling from ubi8/python-39
Digest: sha256:1f8117d04c016fc6c161d4809e0b89f33c31a545a3217573bf1edbca30d105da
Status: Image is up to date for registry.access.redhat.com/ubi8/python-39:latest
registry.access.redhat.com/ubi8/python-39:latest
1
docker inspect registry.access.redhat.com/ubi8/python-39:latest | jq
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
...
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:efbb01c414da9dbe80503875585172034d618260b0179622a67440af141ada49",
"sha256:0e770dacd8dd8e0f783addb2f8e2889360ecc1443acc1ca32f03158f8b459b14",
"sha256:03b1af2d2f1752f587c99bf9afca0a564054b79f46cf22cef211f86f1d4a4497",
"sha256:ae81327beceb885cbdb2663e2f89e6e55aaa614f5ce2d502f772420d6fe37f2f"
]
},
...
- ๋ฒ ์ด์ค
ubi8/python-39:latest์ต์ ์ํ ํ์ธ ํ ๋ ์ด์ด ๋น๊ต - ๋ฒ ์ด์ค์ ์์ 4๊ฐ ๋ ์ด์ด๊ฐ
pythonapp์ด๋ฏธ์ง์ ํ์ 4๊ฐ ๋ ์ด์ด์ ๋์ผ โ ํจ์จ์ ์บ์/์ ์ก
10. ๋ ์ง์คํธ๋ฆฌ ํธ์
1
2
3
4
5
6
7
8
9
10
11
12
13
docker push $MYREGISTRY/$MYUSER/pythonapp:latest
# ๊ฒฐ๊ณผ
The push refers to repository [docker.io/shinminjin/pythonapp]
c51214f09723: Pushed
b588d060ae71: Pushed
a94bd60400ee: Pushed
f3254a7dd338: Pushed
ae81327beceb: Pushed
03b1af2d2f17: Pushed
0e770dacd8dd: Pushed
efbb01c414da: Pushed
latest: digest: sha256:f56d5b4a97bea885d92a4557b865cbe01c78ec555ad6af1e39999f072457d471 size: 1999
11. ์ปจํ ์ด๋ ์คํ
1
2
3
4
docker run -d --name myweb -p 8080:8080 -it $MYREGISTRY/$MYUSER/pythonapp:latest
# ๊ฒฐ๊ณผ
0527fecad198ef5a5f592c5b11fe7e682e8b90e70cf95e12455a3eb621810693
- ๊ณต๊ฐ ๋ ์ง์คํธ๋ฆฌ์ ์ด๋ฏธ์ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ปจํ
์ด๋ ์คํ, ํฌํธ ๋งคํ
8080:8080
1
docker ps
โ ย ์ถ๋ ฅ
1
2
3
4
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0527fecad198 shinminjin/pythonapp:latest "python app.py" 23 seconds ago Up 22 seconds 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp myweb
e4d4f4c84c02 kindest/node:v1.32.8 "/usr/local/bin/entrโฆ" 44 minutes ago Up 44 minutes 0.0.0.0:30000-30001->30000-30001/tcp, 127.0.0.1:35121->6443/tcp myk8s-control-plane
1ef7f7ad8535 kindest/node:v1.32.8 "/usr/local/bin/entrโฆ" 44 minutes ago Up 44 minutes myk8s-worker
- ์ปจํ
์ด๋
myweb์์ฑยท๊ธฐ๋
12. ์ ํ๋ฆฌ์ผ์ด์ ์๋ต ํ์ธ
1
2
3
4
curl 127.0.0.1:8080
# ๊ฒฐ๊ณผ
Hello, World! # ์ฑ ์ ์ ๋์
13. ์ปจํ ์ด๋ ๋ก๊ทธ ํ์ธ
1
2
3
4
docker logs myweb
...
172.17.0.1 - - [18/Oct/2025 06:52:26] "GET / HTTP/1.1" 200 -
14. ๋ค์ ์ค์ต์ ์ํ ์ ๋ฆฌ
1
docker rm -f myweb
โ ๋์ปค๊ฐ ํ์ ์๋ Jib์ ์ฌ์ฉํ ์ปจํ ์ด๋ ๋น๋
1. ์์ปค ์ปจํ ์ด๋ bash ์ง์
1
2
docker exec -it myk8s-worker bash
root@myk8s-worker:/#
- ์์ปค ์ปจํ ์ด๋ ๋ด๋ถ์์ ์ค์ต ์งํ
2. openjdk ์ค์น
1
2
3
4
root@myk8s-worker:/# apt update
mkdir -p /usr/share/man/man1
apt install perl-modules-5.36 -y
apt install openjdk-17-jdk -y
3. java ๋ฒ์ ํ์ธ
1
2
3
4
5
6
root@myk8s-worker:/# java -version
# ๊ฒฐ๊ณผ
openjdk version "17.0.16" 2025-07-15
OpenJDK Runtime Environment (build 17.0.16+8-Debian-1deb12u1)
OpenJDK 64-Bit Server VM (build 17.0.16+8-Debian-1deb12u1, mixed mode, sharing)
4. maven ์ค์น ๋ฐ ํ์ธ
1
root@myk8s-worker:/# apt install maven -y
1
2
3
4
5
6
7
root@myk8s-worker:/# mvn -version
Apache Maven 3.8.7
Maven home: /usr/share/maven
Java version: 17.0.16, vendor: Debian, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "6.17.3-arch2-1", arch: "amd64", family: "unix"
5. ๋ณด์กฐ ํด ์ค์น
1
root@myk8s-worker:/# apt install git tree wget curl jq -y
6. ์์ค ์ฝ๋ ํด๋ก ๋ฐ ์ด๋
1
2
root@myk8s-worker:/# git clone https://github.com/gitops-cookbook/chapters
root@myk8s-worker:/# cd /chapters/chapters/ch03/springboot-app/
7. ๋น๋ ์ ๊ตฌ์กฐ ์ค๋ ์ท ์์ฑ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@myk8s-worker:/chapters/chapters/ch03/springboot-app# tree | tee -a before.txt
.
|-- mvnw
|-- mvnw.cmd
|-- pom.xml
`-- src
|-- main
| |-- java
| | `-- com
| | `-- redhat
| | `-- hello
| | |-- Greeting.java
| | |-- GreetingController.java
| | `-- HelloApplication.java
| `-- resources
| `-- application.properties
`-- test
`-- java
`-- com
`-- redhat
`-- hello
`-- HelloApplicationTests.java
13 directories, 8 files
8. Docker ๋ฏธ์ค์น ์ํ ํ์ธ
1
2
root@myk8s-worker:/chapters/chapters/ch03/springboot-app# docker info
bash: docker: command not found
9. Jib๋ก Docker ์์ด ์ด๋ฏธ์ง ๋น๋ยทํธ์
1
2
3
4
5
6
7
mvn compile com.google.cloud.tools:jib-maven-plugin:3.4.6:build \
-Dimage=docker.io/shinminjin/jib-example:latest \
-Djib.to.auth.username=$MYUSER \
-Djib.to.auth.password=$MYTOKEN
# MAC ์ฌ์ฉ์๋ ์๋ ๋ด์ฉ ์ถ๊ฐ
-Djib.from.platforms=linux/arm64
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
[INFO] Using credentials from <to><auth> for shinminjin/jib-example
[INFO] The base image requires auth. Trying again for eclipse-temurin:11-jre...
[INFO] Using base image with digest: sha256:12e6611e8bdd47af0a12574f69c178745b09998459ccbac2ec2b08e837bce1a7
[INFO]
[INFO] Container entrypoint set to [java, -cp, @/app/jib-classpath-file, com.redhat.hello.HelloApplication]
[INFO]
[INFO] Built and pushed image as shinminjin/jib-example
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:00 min
[INFO] Finished at: 2025-10-18T07:13:19Z
[INFO] ------------------------------------------------------------------------
jib-maven-plugin์ฌ์ฉํ์ฌdocker.io/<๋ด ๊ณ์ >/jib-example:latest๋ก ๋น๋ ๋ฐ ๋ ์ง์คํธ๋ฆฌ ํธ์ ์ํํจ
10. ํ๊น ๋ฐ ์บ์ ์ฐ์ถ๋ฌผ ํ์ธ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
root@myk8s-worker:/chapters/chapters/ch03/springboot-app# tree | tee -a after.txt
.
|-- after.txt
|-- before.txt
|-- mvnw
|-- mvnw.cmd
|-- pom.xml
|-- src
| |-- main
| | |-- java
| | | `-- com
| | | `-- redhat
| | | `-- hello
| | | |-- Greeting.java
| | | |-- GreetingController.java
| | | `-- HelloApplication.java
| | `-- resources
| | `-- application.properties
| `-- test
| `-- java
| `-- com
| `-- redhat
| `-- hello
| `-- HelloApplicationTests.java
`-- target
|-- classes
| |-- application.properties
| `-- com
| `-- redhat
| `-- hello
| |-- Greeting.class
| |-- GreetingController.class
| `-- HelloApplication.class
|-- generated-sources
| `-- annotations
|-- jib-cache
| |-- jib-classpath-file
| |-- jib-main-class-file
| |-- layers
| | |-- 6d6cf0398708e59e5a4e91e9f666d82687b54231c18464f6fa4374c545950561
| | | `-- 19453caec741a081acf3685cfd1cd9b92b8bb6685a7154c3a154fb5192796338
| | |-- 80179ad604dc1a50d17a7522de854594aadb14ea38cb15e5036b52e9df65d580
| | | `-- 32aa8a1c89daefa50dd23dc2f178889e2008f5e7f08c380263798f95b8ea23b6
| | |-- d2bcf32f8182a5ac9249f422ea33e6330258546e9795099d154e09f073108a9b
| | | `-- 12f836f93b6bb6fc700bee8bab11f19b8737647d247545568f2e35d99f74ba65
| | `-- d3589b3a4a640a631770abb1568e2c8fa9af3826b67fc08991e0be6dfdae81f2
| | `-- d0047b3741306dc4c7234a4cc69d9f972160b76ca8cbe2774660913604bfff29
| |-- selectors
| | |-- 2d6ea2f6fbf63f3caf2c2aa164e4999faaab096183f439e555bd9ee453bf3684
| | |-- d6b95711ce792518c4e1db29232a7b6a2075f15379d19d59c5b1a93e7afab012
| | |-- d9dae33b6c627d451afcf9280630f3458966d13158bffc9892411eaa1ab6802c
| | `-- f0e4752dd04821b9490d0bb8330b3a716ae229a80262f93c816d6545ab65bc24
| `-- tmp
|-- jib-image.digest
|-- jib-image.id
|-- jib-image.json
`-- maven-status
`-- maven-compiler-plugin
`-- compile
`-- default-compile
|-- createdFiles.lst
`-- inputFiles.lst
32 directories, 29 files
target/๋๋ ํฐ๋ฆฌ ์์ฑ ๋ฐjib-cache,jib-image.*ํ์ผ ์์ฑ ํ์ธ
11. ์ปจํ ์ด๋ ์ ธ ์ข ๋ฃ
1
root@myk8s-worker:/chapters/chapters/ch03/springboot-app# exit
12. Jib๋ก ํธ์ํ ์ด๋ฏธ์ง๋ก ์ปจํ ์ด๋ ์คํ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
docker run -d --name myweb2 -p 8080:8080 -it docker.io/$MYUSER/jib-example
# ๊ฒฐ๊ณผ
Unable to find image 'shinminjin/jib-example:latest' locally
latest: Pulling from shinminjin/jib-example
4b3ffd8ccb52: Pull complete
0b2668578c63: Pull complete
0b04dbdb2b3f: Pull complete
fd4132a90b04: Pull complete
43cbcd26df05: Pull complete
80179ad604dc: Pull complete
6d6cf0398708: Pull complete
d2bcf32f8182: Pull complete
d3589b3a4a64: Pull complete
Digest: sha256:63b47bedc99cb91c3e690d4942f4608045534078b992c04374f4cde40601ae9a
Status: Downloaded newer image for shinminjin/jib-example:latest
9b96595492a1a15bfbdf9001495426340c2e702fa354f7e0ed85c0076dcbb0dd
13. ์ปจํ ์ด๋ ์ํ ํ์ธ
1
docker ps
โ ย ์ถ๋ ฅ
1
2
3
4
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9b96595492a1 shinminjin/jib-example "java -cp @/app/jib-โฆ" 28 seconds ago Up 27 seconds 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp myweb2
e4d4f4c84c02 kindest/node:v1.32.8 "/usr/local/bin/entrโฆ" About an hour ago Up About an hour 0.0.0.0:30000-30001->30000-30001/tcp, 127.0.0.1:35121->6443/tcp myk8s-control-plane
1ef7f7ad8535 kindest/node:v1.32.8 "/usr/local/bin/entrโฆ" About an hour ago Up About an hour myk8s-worker
- ์ปจํ
์ด๋
myweb2Up ์ํ ํ์ธ
14. API ํธ์ถ ๋์ ํ์ธ
1
curl -s 127.0.0.1:8080/hello | jq
โ ย ์ถ๋ ฅ
1
2
3
4
{
"id": 1,
"content": "Hello, World!"
}
15. ๋ก์ปฌ ์ด๋ฏธ์ง ๋ชฉ๋ก ํ์ธ
1
docker images
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
REPOSITORY TAG IMAGE ID CREATED SIZE
shinminjin/pythonapp latest a8ea70de71df 48 minutes ago 878MB
registry.access.redhat.com/ubi8/python-39 latest 9a62815cc4ee 3 days ago 874MB
quay.io/cilium/cilium v1.17.8 ab0dfe84bb2a 3 weeks ago 794MB
quay.io/cilium/operator-generic v1.17.8 710ed26a6a26 3 weeks ago 128MB
kindest/node v1.32.8 05f8e4e76c17 7 weeks ago 1.04GB
quay.io/cilium/cilium v1.17.6 40c15f03eb84 3 months ago 819MB
quay.io/cilium/operator-generic v1.17.6 95a65abe2c97 3 months ago 127MB
quay.io/cilium/cilium-envoy v1.33.4-1752151664-7c2edb0b44cf95f326d628b837fcdd845102ba68 48bdcd4253db 3 months ago 174MB
nicolaka/netshoot latest 0ac86781a84f 3 months ago 594MB
shinminjin/jib-example latest 2574b2ca2237 55 years ago 281MB
shinminjin/jib-example:latest์์ฑ ํ์ธํจ
16. ์ํคํ ์ฒ ํ์ธ
1
docker inspect $MYUSER/jib-example | jq
โ ย ์ถ๋ ฅ
1
2
3
...
"Architecture": "amd64",
...
- Mac/ARM ํ๊ฒฝ์์ ๋น๋ ์
arm64๋ก ์ถ๋ ฅ
17. ๋ค์ ์ค์ต์ ์ํ ์ ๋ฆฌ
1
docker rm -f myweb2
๐ ๋น๋ค Buildah (+Podman) ๋ฅผ ์ฌ์ฉํ ์ปจํ ์ด๋ ๋น๋
- ๋น๋ค๋ ๋ฐ๋ชฌ์ด ํ์ ์๋ ์๋ฃจ์ ์ผ๋ก, ๋์ปค ์์ผ์ ๋ง์ดํธํ์ง ์๊ณ ๋ ์ปจํ ์ด๋ ์์ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ ์ ์๋ค.
- https://www.redhat.com/ko/topics/containers/what-is-buildah
- https://buildah.io/
1. ์ปจํธ๋กค ํ๋ ์ธ ์ ธ ์ง์
1
2
docker exec -it myk8s-control-plane bash
root@myk8s-control-plane:/#
2. Podman ์ค์น ๋ฐ ์ด๊ธฐ ์ํ ํ์ธ
1
2
3
root@myk8s-control-plane:/# apt update
mkdir -p /usr/share/man/man1
apt install podman -y
1
2
root@myk8s-control-plane:/# podman images
podman ps
โ ย ์ถ๋ ฅ
1
2
3
REPOSITORY TAG IMAGE ID CREATED SIZE
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
podman images,podman ps๊ฒฐ๊ณผ ๋น์ด ์์
3. Buildah ์ฌ์ฉ ๊ฐ๋ฅ ์ฌ๋ถ ์ ๊ฒ
1
2
root@myk8s-control-plane:/# buildah images
buildah containers
โ ย ์ถ๋ ฅ
1
2
3
REPOSITORY TAG IMAGE ID CREATED SIZE
CONTAINER ID BUILDER IMAGE ID IMAGE NAME CONTAINER NAME
- Podman ์ค์น ์ Buildah ๋๋ฐ ์ค์น๋จ
buildah images,buildah containers๋ชจ๋ ๋น์ด ์์
4. ๋ฒ ์ด์ค ์ด๋ฏธ์ง ์ค๋น(๋์ปค ๋ฐ๋ชฌ ์์ด)
1
2
3
4
5
6
7
8
9
10
11
root@myk8s-control-plane:/# buildah from --arch amd64 quay.io/centos/centos:latest
# macOS: buildah from --arch arm64 quay.io/centos/centos:latest
# ๊ฒฐ๊ณผ
Trying to pull quay.io/centos/centos:latest...
Getting image source signatures
Copying blob bf573055768d done
Copying config 4fbde73dcc done
Writing manifest to image destination
Storing signatures
centos-working-container
5. Buildah๋ โ๋น๋ ์ ์ฉโ ๋๊ตฌ์์ ํ์ธ
1
2
3
root@myk8s-control-plane:/# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- Buildah๋ ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค๊ณ ์กฐ์ํ์ง๋ง ์ปจํ ์ด๋ ์คํ์ ํ์ง ์์
6. ์ด๋ฏธ์ง ์กด์ฌ ํ์ธ
1
2
3
4
root@myk8s-control-plane:/# buildah images
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/centos/centos latest 4fbde73dcc66 4 days ago 316 MB
1
2
3
4
root@myk8s-control-plane:/# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/centos/centos latest 4fbde73dcc66 4 days ago 316 MB
quay.io/centos/centos:latestํ์ธ
7. ๋น๋(์ ์ฉ) ์ปจํ ์ด๋ ์ํ ํ์ธ
1
root@myk8s-control-plane:/# buildah containers
โ ย ์ถ๋ ฅ
1
2
CONTAINER ID BUILDER IMAGE ID IMAGE NAME CONTAINER NAME
7650deaf4203 * 4fbde73dcc66 quay.io/centos/centos:latest centos-working-container
- BUILDER * (์คํ ์ํ๊ฐ ์๋)
8. ํจํค์ง ์ค์น๋ก ๋ ์ด์ด ์์ฑ
1
2
3
4
5
6
7
8
9
10
11
12
root@myk8s-control-plane:/# buildah run centos-working-container yum install httpd -y
# ๊ฒฐ๊ณผ
...
Installed:
apr-1.7.5-3.el10.x86_64 apr-util-1.6.3-21.el10.x86_64 apr-util-lmdb-1.6.3-21.el10.x86_64
apr-util-openssl-1.6.3-21.el10.x86_64 centos-logos-httpd-100.2-3.el10.noarch httpd-2.4.63-5.el10.x86_64
httpd-core-2.4.63-5.el10.x86_64 httpd-filesystem-2.4.63-5.el10.noarch httpd-tools-2.4.63-5.el10.x86_64
libbrotli-1.1.0-6.el10.x86_64 lmdb-libs-0.9.32-4.el10.x86_64 mailcap-2.1.54-8.el10.noarch
mod_http2-2.0.29-3.el10.x86_64 mod_lua-2.4.63-5.el10.x86_64
Complete!
9. ์ ์ ํ์ผ ์ถ๊ฐ
(1) index.html ํ์ผ ์์ฑ
1
2
3
4
5
6
7
8
9
10
root@myk8s-control-plane:/# cat << EOF > index.html
<html>
<head>
<title>Cloudneta CICD Study</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
EOF
(2) ์ ๋ ์ด์ด์ ํ์ผ ์ถ๊ฐ
1
2
3
4
root@myk8s-control-plane:/# buildah copy centos-working-container index.html /var/www/html/index.html
# ๊ฒฐ๊ณผ
8440a1923c28a8191233d25ccf21579a7a5131276655466471d6a22ce4962a79
10. ์ํธ๋ฆฌํฌ์ธํธ ์ค์
1
2
3
4
root@myk8s-control-plane:/# buildah config --entrypoint "/usr/sbin/httpd -DFOREGROUND" centos-working-container
# ๊ฒฐ๊ณผ
WARN[0000] cmd "/bin/bash" exists but will be ignored because of entrypoint settings
11. ์ด๋ฏธ์ง ์ปค๋ฐ ๋ฐ ํ๊น
1
2
3
4
5
6
7
8
9
10
root@myk8s-control-plane:/# buildah commit centos-working-container docker.io/$MYUSER/gitops-website
# ๊ฒฐ๊ณผ
Getting image source signatures
Copying blob 288e9c66457d skipped: already exists
Copying blob 957e9335c924 done
Copying config 938fa8386a done
Writing manifest to image destination
Storing signatures
938fa8386a92e68b8dd10ccdccaa3e5fb1fcaba96e7b79a9246e4c3a6b4ac888
1
2
3
root@myk8s-control-plane:/# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- ํ์ฌ ๊ธฐ๋๋ ๊ฑด ์์
1
2
3
4
5
6
7
8
9
root@myk8s-control-plane:/# buildah images && podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/shinminjin/gitops-website latest 938fa8386a92 22 seconds ago 361 MB
quay.io/centos/centos latest 4fbde73dcc66 4 days ago 316 MB
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/shinminjin/gitops-website latest 938fa8386a92 23 seconds ago 361 MB
quay.io/centos/centos latest 4fbde73dcc66 4 days ago 316 MB
- ์์ฑ๋ ์ด๋ฏธ์ง ํ์ธ
12. ๋ฉํ๋ฐ์ดํฐ ํ์ธ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
root@myk8s-control-plane:/# podman inspect docker.io/$MYUSER/gitops-website | jq
[
{
"Id": "938fa8386a92e68b8dd10ccdccaa3e5fb1fcaba96e7b79a9246e4c3a6b4ac888",
"Digest": "sha256:45bd7216a3e5a7045d58276ddce67691564ae924e041c972647c4535dd3b62da",
"RepoTags": [
"docker.io/shinminjin/gitops-website:latest"
],
"RepoDigests": [
"docker.io/shinminjin/gitops-website@sha256:45bd7216a3e5a7045d58276ddce67691564ae924e041c972647c4535dd3b62da"
],
"Parent": "4fbde73dcc66c4096cdf69b4501944bb10b8cc122f8e6697f6008e79a0ec0a78",
"Comment": "",
"Created": "2025-10-18T08:24:45.893945154Z",
"Config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Entrypoint": [
"/bin/sh",
"-c",
"/usr/sbin/httpd -DFOREGROUND"
],
"Cmd": [
"/bin/bash"
],
"Labels": {
"io.buildah.version": "1.28.2",
"org.label-schema.build-date": "20251014",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Stream 10 Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
"Version": "",
"Author": "",
"Architecture": "amd64",
"Os": "linux",
"Size": 361206115,
"VirtualSize": 361206115,
"GraphDriver": {
"Name": "overlay",
"Data": {
"LowerDir": "/var/lib/containers/storage/overlay/288e9c66457def91d1c4b833c1d7c27b74e5ee668d9c2693b7a524eacdb6f6bd/diff",
"UpperDir": "/var/lib/containers/storage/overlay/7525618a6d8f819d17933fe4343c39d4dc5d583992db20e01dbb8496744b3500/diff",
"WorkDir": "/var/lib/containers/storage/overlay/7525618a6d8f819d17933fe4343c39d4dc5d583992db20e01dbb8496744b3500/work"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:288e9c66457def91d1c4b833c1d7c27b74e5ee668d9c2693b7a524eacdb6f6bd",
"sha256:957e9335c924e02b42c4233231d0b6b57f9afa9636797393a6371a487a1674c9"
]
},
"Labels": {
"io.buildah.version": "1.28.2",
"org.label-schema.build-date": "20251014",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Stream 10 Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
},
"Annotations": {
"org.opencontainers.image.base.digest": "sha256:caff14a3c4a998010ebbac7a6043a51099d01bdef4cc5440adb65ed394af651c",
"org.opencontainers.image.base.name": "quay.io/centos/centos:latest"
},
"ManifestType": "application/vnd.oci.image.manifest.v1+json",
"User": "",
"History": [
{
"created": "2025-10-14T05:03:24.931468502Z",
"created_by": "/bin/sh -c #(nop) ADD file:3759e74e60f67ef6a1280cb05dc9a36d058c801452e4f32e1c8238bfdc60ccd8 in / ",
"empty_layer": true
},
{
"created": "2025-10-14T05:03:24.931531936Z",
"created_by": "/bin/sh -c #(nop) LABEL org.label-schema.schema-version=\"1.0\" org.label-schema.name=\"CentOS Stream 10 Base Image\" org.label-schema.vendor=\"CentOS\" org.label-schema.license=\"GPLv2\" org.label-schema.build-date=\"20251014\"",
"empty_layer": true
},
{
"created": "2025-10-14T05:03:27.441354994Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/bash\"]"
},
{
"created": "2025-10-18T08:24:46.346083851Z",
"created_by": "/bin/sh",
"comment": "FROM quay.io/centos/centos:latest"
}
],
"NamesHistory": [
"docker.io/shinminjin/gitops-website:latest"
]
}
]
13. Podman์ผ๋ก ์ปจํ ์ด๋ ์คํ
1
2
3
4
root@myk8s-control-plane:/# podman run --runtime /usr/local/sbin/runc -d --name myweb -p 8080:80 -it docker.io/$MYUSER/gitops-website
# ๊ฒฐ๊ณผ
ae4ffb535484069fd069b317b18a107c8a6a87048c576e867bb0d32d18599f59
1
2
3
4
root@myk8s-control-plane:/# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ae4ffb535484 docker.io/shinminjin/gitops-website:latest /bin/bash 14 seconds ago Up 14 seconds ago 0.0.0.0:8080->80/tcp myweb
- ํฌํธ ๋งคํ
0.0.0.0:8080->80/tcpํ์ธ
14. ๋์ ๊ฒ์ฆ
1
2
3
4
5
6
7
8
9
10
root@myk8s-control-plane:/# curl -s 127.0.0.1:8080
<html>
<head>
<title>Cloudneta CICD Study</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
index.html๋ด์ฉ ํ์ธ
15. ์ปจํ ์ด๋ ๋ฐํ์ ๊ตฌ๋ถ ์ฃผ์
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@myk8s-control-plane:/# crictl images
IMAGE TAG IMAGE ID SIZE
docker.io/kindest/kindnetd v20250512-df8de77b 409467f978b4a 44.4MB
docker.io/kindest/local-path-helper v20241212-8ac705d0 baa0d31514ee5 3.08MB
docker.io/kindest/local-path-provisioner v20250214-acbabc1a bbb6209cc873b 22.5MB
registry.k8s.io/coredns/coredns v1.11.3 c69fa2e9cbf5f 18.6MB
registry.k8s.io/etcd 3.5.16-0 a9e7e6b294baf 57.7MB
registry.k8s.io/kube-apiserver-amd64 v1.32.8 0d4edaa48e2f9 98.1MB
registry.k8s.io/kube-apiserver v1.32.8 0d4edaa48e2f9 98.1MB
registry.k8s.io/kube-controller-manager-amd64 v1.32.8 b248d0b0c74ad 90.8MB
registry.k8s.io/kube-controller-manager v1.32.8 b248d0b0c74ad 90.8MB
registry.k8s.io/kube-proxy-amd64 v1.32.8 d7b94972d43c5 95.3MB
registry.k8s.io/kube-proxy v1.32.8 d7b94972d43c5 95.3MB
registry.k8s.io/kube-scheduler-amd64 v1.32.8 2ac266f06c9a5 70.7MB
registry.k8s.io/kube-scheduler v1.32.8 2ac266f06c9a5 70.7MB
registry.k8s.io/pause 3.10 873ed75102791 320kB
crictl images์๋ ๋ณด์ด์ง ์์- ์ด์ ๋ kind ๋ ธ๋๊ฐ containerd๋ฅผ K8s ๋ฐํ์์ผ๋ก ์ฌ์ฉํ๊ณ , Podman/Buildah๋ ๋ณ๋์ ์คํ ๋ฆฌ์ง๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์
16. ๋ค์ ์ค์ต์ ์ํ ์ ๋ฆฌ
1
2
3
root@myk8s-control-plane:/# podman rm -f myweb
root@myk8s-control-plane:/# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
๐งพ Dockerfile๋ก Buildah ์ด๋ฏธ์ง ๋น๋
1. Dockerfile ์์ฑ
1
2
3
4
5
6
7
root@myk8s-control-plane:/# cat << EOF > Dockerfile
FROM centos:latest
RUN yum -y install httpd
COPY index.html /var/www/html/index.html
EXPOSE 80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
EOF
2. Buildah๋ก ์ด๋ฏธ์ง ๋น๋
1
2
3
4
5
6
root@myk8s-control-plane:/# buildah build -f Dockerfile -t docker.io/shinminjin/gitops-website
# ๊ฒฐ๊ณผ
...
Successfully tagged docker.io/shinminjin/gitops-website:latest
608d6d7411053434a23414231b8bbe89365a4c593e33b1bb4f26a6d14f43ff57
3. ๋น๋ ์ฐ์ถ๋ฌผ ํ์ธ
1
2
3
4
root@myk8s-control-plane:/# buildah ps
CONTAINER ID BUILDER IMAGE ID IMAGE NAME CONTAINER NAME
7650deaf4203 * 4fbde73dcc66 quay.io/centos/centos:latest centos-working-container
4. ๋ ์ง์คํธ๋ฆฌ ๋ก๊ทธ์ธ
1
2
3
4
5
root@myk8s-control-plane:/# buildah login --username $MYUSER docker.io
# ๊ฒฐ๊ณผ
Password: $MYTOKEN
Login Succeeded!
5. ์ด๋ฏธ์ง ํธ์
1
2
3
4
5
6
7
8
root@myk8s-control-plane:/# buildah push <imageID> docker.io/$MYUSER/gitops-website
# ๊ฒฐ๊ณผ
Getting image source signatures
Copying blob 288e9c66457d done
Copying config 4fbde73dcc done
Writing manifest to image destination
Storing signatures
๐งฐ ๋น๋ํฉ(Buildpacks)์ผ๋ก ์ปจํ ์ด๋ ๋น๋
1. ๋น๋ํฉ ์ค์น (Arch Linux)
(1) pack-cli ์ค์น
1
sudo pacman -S pack-cli
(2) which pack ์
๋ ฅ ์, ์ฐพ์ ์ ์๋ค๋ ๊ฒฐ๊ณผ ๋์ด
1
2
3
4
which pack
# ๊ฒฐ๊ณผ
pack not found
(3) ์คํ ํ์ผ ๊ฒฝ๋ก ์ ๋ฆฌ
1
2
3
4
sudo pacman -Ql pack-cli | grep /usr/bin/pack
# ๊ฒฐ๊ณผ
pack-cli /usr/bin/pack-cli
- ํจํค์ง ๋ฐ์ด๋๋ฆฌ๋ช
์ด
/usr/bin/pack-cli
1
sudo ln -s /usr/bin/pack-cli /usr/bin/pack
pack์ด๋ฆ์ผ๋ก ๋งํฌ ์์ฑ
1
2
3
4
which pack
# ๊ฒฐ๊ณผ
/usr/bin/pack
(4) .zshrc์ ์๋์์ฑ(fpath) ์ค์ ์ถ๊ฐ
1
2
3
4
5
6
7
8
grep -qxF 'fpath=("$HOME/.zsh/completions" $fpath)' ~/.zshrc || \
printf '%s\n' 'fpath=("$HOME/.zsh/completions" $fpath)' >> ~/.zshrc
# compinit ๋ณด์ฅ
grep -q 'autoload -Uz compinit' ~/.zshrc || \
printf '%s\n' 'autoload -Uz compinit' >> ~/.zshrc
grep -q '^compinit' ~/.zshrc || \
printf '%s\n' 'compinit' >> ~/.zshrc
(5) ์ ์ฉ
1
source ~/.zshrc
2. ์ํ ์ฑ ๋๋ ํฐ๋ฆฌ ์ด๋
1
2
3
4
5
6
cd chapters/chapters/ch03/nodejs-app/
tree
โโโ package.json
โโโ package-lock.json
โโโ server.js
3. ์ถ์ฒ Builder ๋ชฉ๋ก ํ์ธ
1
pack builder suggest
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
Suggested builders:
Google: gcr.io/buildpacks/builder:google-22 Ubuntu 22.04 base image with buildpacks for .NET, Dart, Go, Java, Node.js, PHP, Python, and Ruby
Heroku: heroku/builder:24 Ubuntu 24.04 AMD64+ARM64 base image with buildpacks for .NET, Go, Java, Node.js, PHP, Python, Ruby & Scala.
Paketo Buildpacks: paketobuildpacks/builder-jammy-base Ubuntu 22.04 Jammy Jellyfish base image with buildpacks for Java, Go, .NET Core, Node.js, Python, Apache HTTPD, NGINX and Procfile
Paketo Buildpacks: paketobuildpacks/builder-jammy-buildpackless-static Static base image (Ubuntu Jammy Jellyfish build image, distroless-like run image) with no buildpacks included. To use, specify buildpacks at build time.
Paketo Buildpacks: paketobuildpacks/builder-jammy-full Ubuntu 22.04 Jammy Jellyfish full image with buildpacks for Apache HTTPD, Go, Java, Java Native Image, .NET, NGINX, Node.js, PHP, Procfile, Python, and Ruby
Paketo Buildpacks: paketobuildpacks/builder-jammy-tiny Tiny base image (Ubuntu Jammy Jellyfish build image, distroless-like run image) with buildpacks for Java, Java Native Image and Go
Paketo Buildpacks: paketobuildpacks/builder-ubi8-base Ubi 8 base builder with buildpacks for Node.js, Java, Quarkus and Procfile
Tip: Learn more about a specific builder with:
pack builder inspect <builder-image>
4. ๋น๋ ์ ๋ก์ปฌ ์ด๋ฏธ์ง ์ํ ํ์ธ
1
docker images
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
REPOSITORY TAG IMAGE ID CREATED SIZE
shinminjin/pythonapp latest a8ea70de71df 6 hours ago 878MB
registry.access.redhat.com/ubi8/python-39 latest 9a62815cc4ee 3 days ago 874MB
quay.io/cilium/cilium v1.17.8 ab0dfe84bb2a 3 weeks ago 794MB
quay.io/cilium/operator-generic v1.17.8 710ed26a6a26 3 weeks ago 128MB
kindest/node v1.32.8 05f8e4e76c17 7 weeks ago 1.04GB
quay.io/cilium/cilium v1.17.6 40c15f03eb84 3 months ago 819MB
quay.io/cilium/operator-generic v1.17.6 95a65abe2c97 3 months ago 127MB
quay.io/cilium/cilium-envoy v1.33.4-1752151664-7c2edb0b44cf95f326d628b837fcdd845102ba68 48bdcd4253db 3 months ago 174MB
nicolaka/netshoot latest 0ac86781a84f 3 months ago 594MB
shinminjin/jib-example latest 2574b2ca2237 55 years ago 281MB
5. Buildpacks๋ก ์ด๋ฏธ์ง ๋น๋
1
2
3
4
5
6
pack build nodejs-app --builder paketobuildpacks/builder-jammy-base
# macOS์ผ ๊ฒฝ์ฐ: heroku/builder:24
# ๊ฒฐ๊ณผ
...
Successfully built image nodejs-app
- Dockerfile ์์ด ๋น๋๋ฅผ ์ง์ ํด ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ฏธ์ง๋ฅผ ์์ฑ
6. ๋น๋ ํ ์ด๋ฏธ์ง ํ์ธ
1
docker images
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
REPOSITORY TAG IMAGE ID CREATED SIZE
shinminjin/pythonapp latest a8ea70de71df 6 hours ago 878MB
paketobuildpacks/run-jammy-base latest 63ae3d417547 33 hours ago 110MB
registry.access.redhat.com/ubi8/python-39 latest 9a62815cc4ee 3 days ago 874MB
quay.io/cilium/cilium v1.17.8 ab0dfe84bb2a 3 weeks ago 794MB
quay.io/cilium/operator-generic v1.17.8 710ed26a6a26 3 weeks ago 128MB
kindest/node v1.32.8 05f8e4e76c17 7 weeks ago 1.04GB
quay.io/cilium/cilium v1.17.6 40c15f03eb84 3 months ago 819MB
quay.io/cilium/operator-generic v1.17.6 95a65abe2c97 3 months ago 127MB
quay.io/cilium/cilium-envoy v1.33.4-1752151664-7c2edb0b44cf95f326d628b837fcdd845102ba68 48bdcd4253db 3 months ago 174MB
nicolaka/netshoot latest 0ac86781a84f 3 months ago 594MB
paketobuildpacks/builder-jammy-base latest 2e24e4fa6193 45 years ago 2.65GB
nodejs-app latest 6b36b0446f4e 45 years ago 374MB
shinminjin/jib-example latest 2574b2ca2237 55 years ago 281MB
paketobuildpacks/builder-jammy-base(builder)paketobuildpacks/run-jammy-base(run) +nodejs-app:latest๊ฐ ๋ก์ปฌ์ ์กด์ฌ
7. ์ปจํ ์ด๋ ๊ธฐ๋(๋ฐํ์ ๊ฒ์ฆ)
1
2
3
4
docker run -d --name myapp --rm -p 3000:3000 nodejs-app
# ๊ฒฐ๊ณผ
ca05981571cc349b28eed15e43537851b116fa4646c0ccf387717e015c126c05
1
docker ps
โ ย ์ถ๋ ฅ
1
2
3
4
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca05981571cc nodejs-app "/cnb/process/web" 24 seconds ago Up 23 seconds 0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp myapp
e4d4f4c84c02 kindest/node:v1.32.8 "/usr/local/bin/entrโฆ" 7 hours ago Up 7 hours 0.0.0.0:30000-30001->30000-30001/tcp, 127.0.0.1:35121->6443/tcp myk8s-control-plane
1ef7f7ad8535 kindest/node:v1.32.8 "/usr/local/bin/entrโฆ" 7 hours ago Up 7 hours myk8s-worker
8. ์ ํ๋ฆฌ์ผ์ด์ ์๋ต ํ์ธ
1
2
3
4
curl -s 127.0.0.1:3000
# ๊ฒฐ๊ณผ
Hello Buildpacks!
9. ๋ค์ ์ค์ต์ ์ํ ์ ๋ฆฌ
1
docker rm -f myapp
๐ Shipwrite์ kaniko or Buildah๋ฅผ ์ฌ์ฉํ ์ฟ ๋ฒ๋คํฐ์ค ๊ธฐ๋ฐ ์ปจํ ์ด๋ ๋น๋
1. Tekton ํ์ดํ๋ผ์ธ ์ค์น
1
kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.70.0/release.yaml
2. Tekton CRD ํ์ธ
1
kubectl get crd
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
NAME CREATED AT
clustertasks.tekton.dev 2025-10-18T12:48:30Z
customruns.tekton.dev 2025-10-18T12:48:30Z
pipelineruns.tekton.dev 2025-10-18T12:48:30Z
pipelines.tekton.dev 2025-10-18T12:48:30Z
resolutionrequests.resolution.tekton.dev 2025-10-18T12:48:30Z
stepactions.tekton.dev 2025-10-18T12:48:30Z
taskruns.tekton.dev 2025-10-18T12:48:31Z
tasks.tekton.dev 2025-10-18T12:48:30Z
verificationpolicies.tekton.dev 2025-10-18T12:48:31Z
tasks.tekton.dev,pipelineruns.tekton.dev๋ฑ ๋ค์ CRD ํ์ธ
3. Shipwright Builds ์ค์น
1
kubectl apply -f https://github.com/shipwright-io/build/releases/download/v0.11.0/release.yaml
4. Shipwright CRD ํ์ธ
1
kubectl get crd | grep shipwright
โ ย ์ถ๋ ฅ
1
2
3
4
buildruns.shipwright.io 2025-10-18T12:50:47Z
builds.shipwright.io 2025-10-18T12:50:47Z
buildstrategies.shipwright.io 2025-10-18T12:50:47Z
clusterbuildstrategies.shipwright.io 2025-10-18T12:50:47Z
5. Build ๋ฆฌ์์ค ์คํค๋ง ์กฐํ
1
kubectl explain builds.shipwright.io
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
GROUP: shipwright.io
KIND: Build
VERSION: v1alpha1
DESCRIPTION:
Build is the Schema representing a Build definition
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <ObjectMeta>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object> -required-
BuildSpec defines the desired state of Build
status <Object>
BuildStatus defines the observed state of Build
NOTICE: This is deprecated and will be removed in a future release.
spec.source,spec.strategy,spec.output๋ฑ ํ์ ํ๋ ํ์ธ
6. Shipwright ์ปจํธ๋กค๋ฌ ๋์ ํ์ธ
1
kubectl get all -n shipwright-build
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
NAME READY STATUS RESTARTS AGE
pod/shipwright-build-controller-86f455d89b-krms7 1/1 Running 0 2m11s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/shipwright-build-controller 1/1 1 1 2m11s
NAME DESIRED CURRENT READY AGE
replicaset.apps/shipwright-build-controller-86f455d89b 1 1 1 2m11s
7. ๋น๋ ์ ๋ต ์ค์น
1
kubectl apply -f https://github.com/shipwright-io/build/releases/download/v0.11.0/sample-strategies.yaml
8. ๋น๋ ์ ๋ต ๋ชฉ๋ก ํ์ธ
1
kubectl get clusterbuildstrategy
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
NAME AGE
buildah 77s
buildkit 77s
buildpacks-v3 77s
buildpacks-v3-heroku 77s
kaniko 77s
kaniko-trivy 77s
ko 77s
source-to-image 77s
source-to-image-redhat 77s
9. ํน์ ์ ๋ต ์ธ๋ถ ํ์ธ
1
2
3
4
5
6
7
8
9
10
11
kubectl get clusterbuildstrategy buildah -o yaml
...
image: quay.io/containers/buildah:v1.27.0
name: build-and-push
...
kubectl get clusterbuildstrategy buildkit -o yaml
...
image: moby/buildkit:nightly-rootless
...
- buildah๋
quay.io/containers/buildah, buildkit์moby/buildkit์ฌ์ฉ
10. ๋ ์ง์คํธ๋ฆฌ ์๊ฒฉ ๋ณ์ ์ง์
1
2
3
4
REGISTRY_SERVER=https://index.docker.io/v1/ # or quay.io
REGISTRY_USER=<your_registry_user>
REGISTRY_PASSWORD=<your_registry_password>
EMAIL=<your_email>
11. ํธ์์ฉ ์ํฌ๋ฆฟ ์์ฑ
1
2
3
4
5
6
7
8
kubectl create secret docker-registry push-secret \
--docker-server=$REGISTRY_SERVER \
--docker-username=$REGISTRY_USER \
--docker-password=$REGISTRY_PASSWORD \
--docker-email=$EMAIL
# ๊ฒฐ๊ณผ
secret/push-secret created
1
2
3
4
kubectl get secret
NAME TYPE DATA AGE
push-secret kubernetes.io/dockerconfigjson 1 27s
12. Build ๋ฆฌ์์ค ์์ฑ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat <<EOF | kubectl apply -f -
apiVersion: shipwright.io/v1alpha1
kind: Build
metadata:
name: kaniko-golang-build
annotations:
build.shipwright.io/build-run-deletion: "true" # ๋น๋ ์๋ฃ ํ BuildRun ์ญ์
spec:
source:
url: https://github.com/shipwright-io/sample-go # ์์ค ์ฝ๋๋ฅผ ๊ฐ์ ธ์ฌ ์ ์ฅ์
contextDir: docker-build # ์์ค ์ฝ๋๊ฐ ์๋ ๋๋ ํฐ๋ฆฌ
strategy:
name: kaniko # ๋น๋์ ์ฌ์ฉํ ClusterBuildStrategy ์ด๋ฆ
kind: ClusterBuildStrategy
dockerfile: Dockerfile
output:
image: docker.io/$REGISTRY_USER/sample-golang:latest # ๊ฒฐ๊ณผ ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ ์ฅ์
credentials:
name: push-secret # ๋ ์ง์คํธ๋ฆฌ์ ์ธ์ฆํ๊ณ ์ด๋ฏธ์ง๋ฅผ ํธ์ํ๋ ๋ฐ ์ฌ์ฉํ ์ํฌ๋ฆฟ ์ด๋ฆ
EOF
# ๊ฒฐ๊ณผ
build.shipwright.io/kaniko-golang-build created
13. Build ์์ฑ ๊ฒฐ๊ณผ ํ์ธ
1
kubectl get builds kaniko-golang-build -o yaml
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
spec:
dockerfile: Dockerfile
output:
credentials:
name: push-secret
image: docker.io/shinminjin/sample-golang:latest
source:
contextDir: docker-build
url: https://github.com/shipwright-io/sample-go
strategy:
kind: ClusterBuildStrategy
name: kaniko
...
1
kubectl get builds
โ ย ์ถ๋ ฅ
1
2
NAME REGISTERED REASON BUILDSTRATEGYKIND BUILDSTRATEGYNAME CREATIONTIME
kaniko-golang-build True Succeeded ClusterBuildStrategy kaniko 2m10s
REGISTERED=True,REASON=Succeededํ์ธ
14. ๋น๋ ํ๋ ๋ชจ๋ํฐ๋ง ์ค๋น (์ ๊ทํฐ๋ฏธ๋)
1
kubectl get pod -n default -w
15. BuildRun ๋งค๋ํ์คํธ ์์ฑ
1
2
3
4
5
6
7
8
9
cat << EOF > buildrun-go.yaml
apiVersion: shipwright.io/v1alpha1
kind: BuildRun
metadata:
generateName: kaniko-golang-buildrun-
spec:
buildRef:
name: kaniko-golang-build
EOF
16. BuildRun ์คํ
1
kubectl create -f buildrun-go.yaml
- ์์ค ํด๋ก โ Dockerfile ๊ธฐ๋ฐ kaniko ๋น๋ โ ๋ ์ง์คํธ๋ฆฌ ํธ์ ์ํ
- ์๋ฃ๊น์ง ๋๋ต 1๋ถ ์ ๋ ์์
17. ๋ก๊ทธ ยท ์ํ ๋ชจ๋ํฐ๋ง
1
k9s -> pod -> l (์ต์
f, w, t)
18. ๋น๋ ํ๋ ์ด๋ฏธ์ง/์คํ ํ์ธ
1
kubectl describe pod -l clusterbuildstrategy.shipwright.io/name=kaniko | grep 'Image:' -B2
โ ย ์ถ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
prepare:
Container ID: containerd://34ce5e58a1c51b9663dc6e343805e65f8f0f30c4108c43e7c66765eb6bb5471d
Image: ghcr.io/tektoncd/pipeline/entrypoint-bff0a22da108bc2f16c818c97641a296:v0.70.0@sha256:763d4cd4e362d381b46a5474d3d358e7731d7c13e22ebf632ef530b857521a48
--
working-dir-initializer:
Container ID: containerd://eb80306209c38d7f79599ab27753d07e6fdb882e5f945d24ca56c37fb8f64a12
Image: ghcr.io/tektoncd/pipeline/workingdirinit-0c558922ec6a1b739e550e349f2d5fc1:v0.70.0@sha256:ed97cc8058e349c48be1364753a6e47732ba4f8d8aec814bd2cdb8a4ddafa23a
--
step-source-default:
Container ID: containerd://1f6e3b0c210f895c5207bd2d42086b1dbd2d284e999bb01bed827dcf837d97bc
Image: ghcr.io/shipwright-io/build/git:v0.11.0@sha256:aecf8bdc01ea00be83e933162a0b6d063846b315fe9dcae60e4be1a34e85d514
--
step-build-and-push:
Container ID: containerd://e8c30bbe0490f9ade3929e4c83da3db026d1d627e2a1d3826162c2595c5f1520
Image: gcr.io/kaniko-project/executor:v1.9.0
--
step-results:
Container ID: containerd://4860ac68761a750df3aa95c53e8d29704f0c24392e0e4d69f0700281632c23fe
Image: registry.access.redhat.com/ubi9/ubi-minimal
19. BuildRun ๊ฒฐ๊ณผ ํ์ธ
1
kubectl get buildruns.shipwright.io
โ ย ์ถ๋ ฅ
1
2
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
kaniko-golang-buildrun-k7s94 True Succeeded 12m 11m
20. ๋ค์ ์ค์ต์ ์ํ ์ ๋ฆฌ
1
kubectl delete build,buildrun --all
This post is licensed under CC BY 4.0 by the author.







