들어가며
안녕하세요?
Kind 라는 도구와 Orbstack를 함께 사용해본 후기를 써보겠습니다.
이 글은 CloudNeta팀 가시다님의 KANS (Kubernetes Advanced Network Study) 2주차 스터디의 과제로 작성하였습니다.
Kind가 뭔가요?
Kind를 이용하면 로컬에서 Kubernetes를 쉽고 간단하게 올릴 수 있습니다.
Macbook M1 Pro를 사용하는 제 환경에서도 아주 편리하게 할 수 있습니다.
Kind 공식문서에서는 이렇게 소개하고 있습니다.
kind is a tool for running local Kubernetes clusters using Docker container “nodes”.
kind was primarily designed for testing Kubernetes itself, but may be used for local development or CI.
kind는 도커 컨테이너 "노드"를 사용하여 로컬 쿠버네티스 클러스터를 실행하는 도구로, 주로 쿠버네티스 자체를 테스트하기 위해 설계되었지만 로컬 개발이나 CI에 사용할 수도 있다.
Kind를 로컬에서 쓰려면 어쨌거나 로컬에서 Container를 구동할 수 있어야 합니다.
하지만 편리한 도구였던 Docker Desktop은 이제 사용하지 않습니다.
그래서 OrbStack 이란 도구를 소개합니다.
OrbStack이 뭔가요?
OrbStack은 이 글을 작성한 2024.9.3 기준 최근에 GeekNews에 소개되었습니다.
OrbStack - macOS에서 빠르고 쉽게 Docker 컨테이너 및 Linux 실행하기 | GeekNews
OrbStack은 Docker Desktop의 대체재를 찾다가 사용하게 된 도구입니다.
틈틈이 유료화된 Docker Desktop의 대체제를 찾는 과정이 있었습니다.
EC2에서 container build하기, Rancher Desktop쓰기.... 하지만 아무래도 Docker Desktop을 사용하던 경험으로는 불편했습니다.
GeekNew에서는 Orbstack의 도구를 아래와 같이 소개하고 있습니다.
굉장히 성능이 좋다고 합니다.
M1 Mac에서 Docker를 사용하는 사람들에게 강력 추천! 이라고 하네요.
Geeknews의 요약
- 맥에서 Docker 컨테이너, 쿠버네티스, 각종 Linux 배포본을 빠르고 간편하게 실행하는 Docker Desktop 대체제
- 몇초만에 부팅 가능 : 부드러운 Rosetta x86 에뮬레이션, VirtioFS 파일 공유, 최적화된 네트워크
- 더 적은 CPU 및 디스크 사용량. 배터리를 절약하고 더 적은 메모리에서 동작하는 네이티브 Swift 앱
- Apple Silicon에서 백그라운드 CPU 사용량 0.1% 미만. 디스크 사용량 10MB 미만
- 각 컨테이너에 대해 자동으로 도메인 네임 설정 (*.orb.local)
- 기존 Docker Desktop 마이그레이션 지원
- 네이티브 앱 외에도 모든 작업을 CLI 명령어로 수행 가능. Mac과 Linux 간 파일 복사 및 명령어 실행 용이
- 성능 벤치 마크
- Open edX 빌드 : OrbStack 17분, Docker Desktop 45분
- PostHog 빌드 : OrbStack 7분, Docker Desktop 19분
- CPU & 배터리 사용량 (쿠버네티스 wth Traefik/Grafana) : OrbStack 27mW, Docker Desktop 123mW
- CPU & 배터리 사용량 (Supabase) : OrbStack 82mW, Docker Desktop 137mW
- 개인 사용자는 무료, 비즈니스 & 상용은 사용자당 월 $8, 교육용 무료 라이센스 제공
사용자 리뷰
- Mark_Shust: Docker Desktop을 삭제하고 OrbStack을 사용. 성능이 100배 더 좋음.
- Michael Roberts: Docker Desktop에서 OrbStack으로 전환 후 성능이 획기적으로 향상됨.
- Hynek Schlawack: Docker, Colima 등을 완전히 대체. 빠르고 업데이트도 잘 됨.
- Francesco Di Lorenzo: M1 Mac에서 Docker를 사용하는 사람들에게 강력 추천.
- Koen Bok: Docker를 사용하는 사람들에게 OrbStack을 추천.
- Sibelius Seraphini: OrbStack 덕분에 Docker 사용이 다시 좋아짐.
- Mikael Henriksson: M1/M2 Mac 사용자에게 강력 추천.
- Mohamed Akram: OrbStack을 사용하여 컴퓨터 팬 소음 줄임.
- Luis Dalmolin: Intel Mac에서 Docker를 OrbStack으로 대체 후 성능 향상.
OrbStack · Fast, light, simple Docker & Linux on macOS
위 공식홈페이지에서 다운 받아 설치할 수 있습니다.
brew install orbstack
OrbStack의 UI
사실 OrbStack 은 Container를 로컬에서 구동하기 위해 Docker Desktop의 대체재로 사용한 것뿐이라 사용 경험에 대해 많이 쓸 건 없습니다.
편하고 빠릅니다.
UI는 아래와 같이 생겼습니다.
이렇게 구동하면 바로 docker를 사용할 수 있습니다.
심지어 좌측 간이 Kubernetes Cluster도 쉽게 띄울 수 있습니다.
아마 곧 자세히 소개하게 될 Kind와 같이 D in D 원리를 이용한 것이 아닌가 하는 생각이 듭니다.
Kind의 사용
Kind 설치
설치해서 사용하는 방법은 굉장히 간단합니다.
설치하는 김에 유용한 도구들도 같이 설치해줍니다.
가시다님의 스터디는 유용한 도구들을 많이 알려줍니다.
- 터미널에서 쿠버네티스 사용시 유용한 도구들
kube-ps1 : 현재 쿠버네티스 컨텍스트와 네임스페이스를 Bash/Zsh 프롬프트 문자열에 추가해줍니다.
kubecolor: kubectl output에 예쁘게 색을 넣어줍니다.
kubectx: kube context 전환이 굉장히 쉬워집니다.
brew install kind
brew install kubernetes-cli
berw install helm
brew install krew
brew install kube-ps1
brew install kubecolor
brew install kubectx
Kind 클러스터는 아래와 같이 실행하면 순식간에 생성됩니다.
Kind의 장점 중 하나는 제가 사용 중인 Mac M1은 ARM 인데,
알아서 크로스플랫폼 이미지를 제공해서 상관없이 구동할 수 있게 해줍니다.
kind create cluster
kind get nodes
kind-control-plane
클러스터가 잘 생성되었는지 확인해봅니다.
순식간에 생성되었지만 진짜 제대로 쿠버네티스 클러스터처럼 정보들을 볼 수 있습니다.
kind get clusters
kind
kind get nodes
kind-control-plane
kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6f6b679f8f-h59c7 1/1 Running 0 42s
kube-system coredns-6f6b679f8f-l5zg9 1/1 Running 0 42s
kube-system etcd-kind-control-plane 1/1 Running 0 49s
kube-system kindnet-r4xb4 1/1 Running 0 42s
kube-system kube-apiserver-kind-control-plane 1/1 Running 0 49s
kube-system kube-controller-manager-kind-control-plane 1/1 Running 0 48s
kube-system kube-proxy-swgbn 1/1 Running 0 42s
kube-system kube-scheduler-kind-control-plane 1/1 Running 0 48s
local-path-storage local-path-provisioner-57c5987fd4-68qlw 1/1 Running 0 42s
그럼 컨테이너로서 동작하고 있는걸까요?
네 이건 실제로 컨테이너입니다!
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c9eb7705bcf kindest/node:v1.31.0 "/usr/local/bin/entr…" About a minute ago Up About a minute 127.0.0.1:60363->6443/tcp kind-control-plane
도커 이미지로 보면 아래와 같습니다.
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
kindest/node <none> 9d05f134f12f 2 weeks ago 1.04GB
traefik latest dfdbdfae3fb3 3 weeks ago 172MB
timberio/vector 0.39.0-debian 87e3c55810d3 2 months ago 245MB
traefik/whoami latest 9dd7aa3decf4 3 months ago 6.66MB
이제 이 컨테이너로 이루어진 클러스터에 테스트용 nginx pod를 배포해보겠습니다.
딱히 제약을 두지는 않아서 컨트롤플레인 노드에 배포가 된다.
kubectl run nginx --image=nginx:alpine
pod/nginx created
k get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 0/1 ContainerCreating 0 5s <none> kind-control-plane <none> <none>
이번엔 컨테이너로 배포된 "노드" 에 대해 describe를 실행해보겠습니다.
노드.. 네요?
k describe node
Name: kind-control-plane
Roles: control-plane
Labels: beta.kubernetes.io/arch=arm64
beta.kubernetes.io/os=linux
kubernetes.io/arch=arm64
kubernetes.io/hostname=kind-control-plane
kubernetes.io/os=linux
node-role.kubernetes.io/control-plane=
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: unix:///run/containerd/containerd.sock
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Sun, 01 Sep 2024 20:16:44 +0900
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: kind-control-plane
AcquireTime: <unset>
RenewTime: Sun, 01 Sep 2024 20:19:50 +0900
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Sun, 01 Sep 2024 20:19:49 +0900 Sun, 01 Sep 2024 20:16:42 +0900 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Sun, 01 Sep 2024 20:19:49 +0900 Sun, 01 Sep 2024 20:16:42 +0900 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Sun, 01 Sep 2024 20:19:49 +0900 Sun, 01 Sep 2024 20:16:42 +0900 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Sun, 01 Sep 2024 20:19:49 +0900 Sun, 01 Sep 2024 20:17:05 +0900 KubeletReady kubelet is posting ready status
Addresses:
InternalIP: 192.168.247.2
Hostname: kind-control-plane
Capacity:
cpu: 10
ephemeral-storage: 615233208Ki
memory: 5440520Ki
pods: 110
Allocatable:
cpu: 10
ephemeral-storage: 615233208Ki
memory: 5440520Ki
pods: 110
System Info:
Machine ID: d3b62ae81dc448168ffd6b457507e591
System UUID: d3b62ae81dc448168ffd6b457507e591
Boot ID: ae1c832f-c1d0-4672-a00c-652a29151768
Kernel Version: 6.10.6-orbstack-00249-g92ad2848917c
OS Image: Debian GNU/Linux 12 (bookworm)
Operating System: linux
Architecture: arm64
Container Runtime Version: containerd://1.7.18
Kubelet Version: v1.31.0
Kube-Proxy Version:
PodCIDR: 10.244.0.0/24
PodCIDRs: 10.244.0.0/24
ProviderID: kind://docker/kind/kind-control-plane
Non-terminated Pods: (10 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default nginx 0 (0%) 0 (0%) 0 (0%) 0 (0%) 32s
kube-system coredns-6f6b679f8f-h59c7 100m (1%) 0 (0%) 70Mi (1%) 170Mi (3%) 3m1s
kube-system coredns-6f6b679f8f-l5zg9 100m (1%) 0 (0%) 70Mi (1%) 170Mi (3%) 3m1s
kube-system etcd-kind-control-plane 100m (1%) 0 (0%) 100Mi (1%) 0 (0%) 3m8s
kube-system kindnet-r4xb4 100m (1%) 100m (1%) 50Mi (0%) 50Mi (0%) 3m1s
kube-system kube-apiserver-kind-control-plane 250m (2%) 0 (0%) 0 (0%) 0 (0%) 3m8s
kube-system kube-controller-manager-kind-control-plane 200m (2%) 0 (0%) 0 (0%) 0 (0%) 3m7s
kube-system kube-proxy-swgbn 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3m1s
kube-system kube-scheduler-kind-control-plane 100m (1%) 0 (0%) 0 (0%) 0 (0%) 3m7s
local-path-storage local-path-provisioner-57c5987fd4-68qlw 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3m1s
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 950m (9%) 100m (1%)
memory 290Mi (5%) 390Mi (7%)
ephemeral-storage 0 (0%) 0 (0%)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Starting 3m kube-proxy
Normal Starting 3m7s kubelet Starting kubelet.
Normal NodeAllocatableEnforced 3m7s kubelet Updated Node Allocatable limit across pods
Normal NodeHasSufficientMemory 3m7s kubelet Node kind-control-plane status is now: NodeHasSufficientMemory
Normal NodeHasNoDiskPressure 3m7s kubelet Node kind-control-plane status is now: NodeHasNoDiskPressure
Normal NodeHasSufficientPID 3m7s kubelet Node kind-control-plane status is now: NodeHasSufficientPID
Normal RegisteredNode 3m2s node-controller Node kind-control-plane event: Registered Node kind-control-plane in Controller
Normal NodeReady 2m48s kubelet Node kind-control-plane status is now: NodeReady
kind로 배포한 뒤에 지우는것도 쉽게 할 수 있습니다.
kind delete cluster
Deleting cluster "kind" ...
Deleted nodes: ["kind-control-plane"]
Kind의 구조
설치를 먼저 해봤으니 Kind 구조에 대한 내용을 확인해보겠습니다.
공식 문서는 이곳입니다. kind – Initial design
Kind는 Docker in Docker 구조로 구성되어 있다고 합니다.
무슨 의미인지는 아래 그림을 보면 알 수 있습니다.
docker가 떠서 "컨테이너"로 된 컨트롤 플레인 노드, 워커 노드를 띄우고 그 안에서 docker가 다시 pod를 띄우는 모습을 볼 수 있습니다.
위 구조대로 띄워서 Kind 내부 확인해보기
아래와 같이 node를 role을 지정하여 2개를 띄울 수 있습니다.
control-plane, worker 각각 1개씩입니다.
cat << EOT > kind-2node.yaml
# two node (one workers) cluster config
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
EOT
kind create cluster --config kind-2node.yaml --name myk8s
Creating cluster "myk8s" ...
✓ Ensuring node image (kindest/node:v1.31.0) 🖼
✓ 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 nice day! 👋
도커가 각 노드 컨테이너들을 이미지로 띄웁니다.
이렇게 컨테이너를 조회해보면
myk8s-control-plane
myk8s-worker
의 이름을 가진 컨테이너 2개가 떠있습니다.
컨테이너지만 각각 control-plane node, worker node의 역할을 하는 것입니다.
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
788fb26a49c1 kindest/node:v1.31.0 "/usr/local/bin/entr…" 40 seconds ago Up 38 seconds 127.0.0.1:51046->6443/tcp myk8s-control-plane
5430e59496dd kindest/node:v1.31.0 "/usr/local/bin/entr…" 40 seconds ago Up 38 seconds myk8s-worker
이제 OrbStack을 통해 control-plane에 접근해보겠습니다.
Terminal을 클릭하면
이런 식으로 접근이 가능합니다.
여기서 docker command가 아니라 crictl command를 사용하겠습니다.
노드 내부에는 container runtime이 CRI 기반의 런타임인 containerd로 되어있기 때문입니다.
이미지를 조회해보면 pod로 뜰 image들을 볼 수 있습니다.
crictl image ls
IMAGE TAG IMAGE ID SIZE
docker.io/kindest/kindnetd v20240813-c6f155d6 6a23fa8fd2b78 33.3MB
docker.io/kindest/local-path-helper v20230510-486859a6 d022557af8b63 2.92MB
docker.io/kindest/local-path-provisioner v20240813-c6f155d6 282f619d10d4d 17.4MB
registry.k8s.io/coredns/coredns v1.11.1 2437cf7621777 16.5MB
registry.k8s.io/etcd 3.5.15-0 27e3830e14027 66.5MB
registry.k8s.io/kube-apiserver-arm64 v1.31.0 add78c37da6e2 92.6MB
registry.k8s.io/kube-apiserver v1.31.0 add78c37da6e2 92.6MB
registry.k8s.io/kube-controller-manager-arm64 v1.31.0 c50d473e11f63 86.9MB
registry.k8s.io/kube-controller-manager v1.31.0 c50d473e11f63 86.9MB
registry.k8s.io/kube-proxy-arm64 v1.31.0 c573e1357a14e 95.9MB
registry.k8s.io/kube-proxy v1.31.0 c573e1357a14e 95.9MB
registry.k8s.io/kube-scheduler-arm64 v1.31.0 8377f1e14db4c 67MB
registry.k8s.io/kube-scheduler v1.31.0 8377f1e14db4c 67MB
registry.k8s.io/pause 3.10 afb61768ce381 268kB
또한 실제로 동작하고 있는 컨테이너들로서 존재하고 있는 것을 볼 수 있습니다.
crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
540f586b174e6 282f619d10d4d 7 minutes ago Running local-path-provisioner 0 af1a6218fcb80 local-path-provisioner-57c5987fd4-fkh2c
f830ab7f6a99c 2437cf7621777 7 minutes ago Running coredns 0 860c9795268ee coredns-6f6b679f8f-t2dzn
01b40847359e4 2437cf7621777 7 minutes ago Running coredns 0 235c208e5ddac coredns-6f6b679f8f-f6drq
27a35c43a02fb 6a23fa8fd2b78 7 minutes ago Running kindnet-cni 0 b405b0f3f2fa9 kindnet-qtpsz
57c41de1d4995 c573e1357a14e 7 minutes ago Running kube-proxy 0 7f936e130c2f9 kube-proxy-rnlqz
d4bb82e61d08c 27e3830e14027 7 minutes ago Running etcd 0 b3a4fdfe5caf6 etcd-myk8s-control-plane
1abadf943e468 add78c37da6e2 7 minutes ago Running kube-apiserver 0 8bafab3726336 kube-apiserver-myk8s-control-plane
94c33059b4b3b c50d473e11f63 7 minutes ago Running kube-controller-manager 0 7976afb4c1494 kube-controller-manager-myk8s-control-plane
1189bb3c7a923 8377f1e14db4c 7 minutes ago Running kube-scheduler 0 9961e0f2fd8db kube-scheduler-myk8s-control-plane
이제 다시 일반 터미널로 돌아와서 pod들을 조회해보겠습니다.
위에서 본 컨테이너들과 같은 pod들이 떠 있는 것을 알 수 있습니다.
k get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6f6b679f8f-f6drq 1/1 Running 0 9m12s
kube-system coredns-6f6b679f8f-t2dzn 1/1 Running 0 9m12s
kube-system etcd-myk8s-control-plane 1/1 Running 0 9m19s
kube-system kindnet-qtpsz 1/1 Running 0 9m12s
kube-system kindnet-tz28w 1/1 Running 0 9m10s
kube-system kube-apiserver-myk8s-control-plane 1/1 Running 0 9m19s
kube-system kube-controller-manager-myk8s-control-plane 1/1 Running 0 9m18s
kube-system kube-proxy-rnlqz 1/1 Running 0 9m12s
kube-system kube-proxy-txwbd 1/1 Running 0 9m10s
kube-system kube-scheduler-myk8s-control-plane 1/1 Running 0 9m19s
local-path-storage local-path-provisioner-57c5987fd4-fkh2c 1/1 Running 0 9m12s
이제 컨트롤 플레인 노드의 내부 파일들을 한번 볼까요?
다시 OrbStack으로 돌아와서 Files를 클릭해보겠습니다.
이렇게 쉽게 컨트롤 플레인의 파일 목록을 볼 수 있습니다.
/etc/kubernetes/manifests 경로로 가보면 아래와 같이 저희가 생각하는 파일들이 있는 모습을 볼 수 있습니다.
Reference
https://kind.sigs.k8s.io/
https://news.hada.io/topic?id=16581&utm_source=slack&utm_medium=bot&utm_campaign=T01DC7G8W4X
https://kind.sigs.k8s.io/docs/design/initial/
'Kubernetes' 카테고리의 다른 글
Pod내 container들의 namespace 정보와 Pause 컨테이너의 역할 알아보기 (1) | 2024.09.08 |
---|---|
Container Runtime과 CRI, 그리고 Containerd 알아보기 (0) | 2024.09.08 |
Container 격리 기술 이해하기 (3) | 2024.08.31 |
GitOps : Tekton, ArgoCD 로 CI/CD 하기 (0) | 2023.03.24 |
[스터디] Kubernetes Container Networking 정리 (0) | 2023.03.18 |