๐๐ป ๋์ปค ๋ฐ์คํฌํ์์ ์ฟ ๋ฒ๋คํฐ์ค๋ฅผ ์ด์ฉํด์ ๋ฉํฐ ๋
ธ๋๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ค๋ช
์
๋๋ค.
This is an explanation of how to implement multi-nodes using Kubernetes on Docker Desktop.
๐๐ป ์ ์ฒด ๋
ธ๋๋ ์ปจํธ๋กค ํ๋ ์ธ+์์ปค๋
ธ๋2๊ฐ๋ก ๊ตฌ์ฑํฉ๋๋ค.
The entire node consists of a control plane + 2 worker nodes.
๐๐ป ํ ์คํธ ํ๊ฒฝ / test environment
โ๏ธ ๋จ์ด 8๊ธฐ๊ฐ ์ด์์ธ ํ๊ฒฝ์์ ํด๋ฌ์คํฐ๋ฅผ ๊ตฌ์ฑํ๊ธฐ๋ฅผ ์ถ์ฒํฉ๋๋ค.
We recommend configuring the cluster in an environment with 8GB or more of RAM.
โ๏ธ MacOS ,M3, RAM 16GB
๐๐ป ์ฟ ๋ฒ๋คํฐ์ค ๋ฉํฐ ๋
ธ๋ ํด๋ฌ์คํฐ๋ฅผ ์ค์นํฉ๋๋ค.
Install a Kubernetes multi-node cluster.

โ๏ธ kind๋ฅผ ์ ํํ๊ณ Node๋ฅผ 3๊ฐ ์ ํํฉ๋๋ค.
Select kind and select 3 nodes.

โ๏ธ Create๋ฒํผ์ ํด๋ฆญํด์ ํด๋ฌ์คํฐ๋ฅผ ์์ฑํฉ๋๋ค.
Click the Create button to create a cluster.

โ๏ธ ์ฟ ๋ฒ๋คํฐ์ค ํด๋ฌ์คํฐ ์ค์น / Kubernetees Cluster Installation

โ๏ธ ์ค์น ์ค / installing

โ๏ธ ํด๋ฌ์คํฐ ์ ํ ์๋ฃ / Cluster setup complete

โ๏ธ ๋ ธ๋ ํ์ธ / Check node status
— ์๋ ๊ทธ๋ฆผ์ ๋์ปค๋ฐ์คํฌํ์์ ํ์ธํ ๋ด์ฉ์
๋๋ค. ํฐ๋ฏธ๋์์๋ ์๋์ ๊ฐ์ด ํ์ธ ํ ์ ์์ต๋๋ค.
The image below shows the results verified in Docker Desktop. In the terminal, you can verify it as follows.
— ํด๋ฌ์คํฐ ๋ฒ์ ์ 1.35.1์ด๊ณ ๋ด๋ถ ์์ดํผ๋ 172.18.0.2 ~ 172.18.0.4๋ฒ๊น์ง ๋ถ์ฌ๋๊ฒ์ ํ์ธ ํ ์ ์์ต๋๋ค.
You can confirm that the cluster version is 1.35.1 and internal IPs from 172.18.0.2 to 172.18.0.4 have been assigned.
MacBookAir ~ % kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
desktop-control-plane Ready control-plane 10m v1.35.1 172.18.0.3 <none> Debian GNU/Linux 13 (trixie) 6.12.69-linuxkit containerd://2.2.1
desktop-worker Ready <none> 10m v1.35.1 172.18.0.2 <none> Debian GNU/Linux 13 (trixie) 6.12.69-linuxkit containerd://2.2.1
desktop-worker2 Ready <none> 10m v1.35.1 172.18.0.4 <none> Debian GNU/Linux 13 (trixie) 6.12.69-linuxkit containerd://2.2.1
— ๋์ปค ๋ฐ์คํฌํ์์ ๋
ธ๋ ์ํ ํ์ธํ ๊ฒฝ์ฐ
If you checked the node status in Docker Desktop

๐๐ป ์ฌ๊ธฐ๊น์ง ํ๋ฉด ํด๋ฌ์คํฐ ์ค์น๊ฐ ๋๋ฉ๋๋ค.
Once you get to this point, the cluster installation is complete.
๐๐ป ์ฟ ๋ฒ๋คํฐ์ค์ Nginx๋ฅผ ์ค์นํด ๋ด
๋๋ค.
Let’s try installing Nginx on Kubernetes.
โ๏ธ deployment ์์ฑ / Create deployment
— deployment๋ฅผ ์์ฑํ๋ฉด pod์ด ํจ๊ป ์์ฑ๋ฉ๋๋ค.
When you create a deployment, a pod is created along with it.
— deployment๋ฅผ ์์ฑํฉ๋๋ค.์ด๋ฆ์ my-app์ด๊ณ image=nginx์
๋๋ค.
Create a deployment. The name is my-app and image=nginx.
MacBookAir ~ % kubectl create deployment my-app --image=nginx
deployment.apps/my-app created
— deployment๋ฅผ ํ์ธํ๋ฉด ๋ค์์ฒ๋ผ ๋์ค๋ฉด ์ ์์
๋๋ค.
If you check the deployment and it appears as follows, it is normal.
MacBookAir ~ % kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
my-app 1/1 1 1 4m2s
— ๊ทธ๋ฐ๋ฐ ์๋์ฒ๋ผ deployment์ pod์ ํ์ธํ๋ฉด “READE 0/1”, “ImagePullBackOff”๋กํ์ธ๋๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
However, if you check the deployment and pod as shown below, there are cases where they are confirmed as “READE 0/1” and “ImagePullBackOff”.
MacBookAir ~ % kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
my-app 0/1 1 0 19s
MacBookAir ~ % kubectl get pods
NAME READY STATUS RESTARTS AGE
my-app-64b78bfff-7v7rc 0/1 ImagePullBackOff 0 23s
— ์์ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ๋ฉด rollout restart๋ก pod์ ํ๋์ฉ ์๋ก ๋ง๋ค๊ณ ๊ต์ฒดํฉ๋๋ค.
If the above case occurs, create new pods one by one and replace them using a rollout restart.
MacBookAir ~ % kubectl rollout restart deployment my-app
โญ๏ธ pod์์ ์ ๋ณด ๋ณด๊ธฐ / View Pod Information
MacBookAir ~ % kubectl describe pod my-app-64b78bfff-7v7rc
— ๋ค์ deployment์ ๋ณด๋ฅผ ํ์ธํ๋ฉด ์๋์ฒ๋ผ ๋์ต๋๋ค.
If you check the deployment information again, it appears as shown below.
MacBookAir ~ % kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
my-app 1/1 1 1 4m2s
๐๐ป deployment๋ฅผ ์ธ๋ถ์ ๋
ธ์ถ ํ๋๋ก ์๋น์ค๋ฅผ ์์ฑํฉ๋๋ค.
Create a service to expose the deployment externally.
— ์๋น์ค์ ์ข
๋ฅ๋ฅผ NodePort๋ก ์ค์ ํ๊ณ ์๋น์คํฌํธ๋ 80๋ฒ์ผ๋ก ์ค์ ํฉ๋๋ค.
Set the service type to NodePort and the service port to 80.
— ๋ชจ๋ ์์ปค ๋
ธ๋์ ํน์ ํฌํธ(์: 31515)๋ฅผ ๊ฐ๋ฐฉํ์ฌ, “๋
ธ๋ IP:ํฌํธ” ์ฃผ์๋ก ์ ์ํ๋ฉด ํด๋น Pod๋ก ์ฐ๊ฒฐํด ์ค๋๋ค.
By opening a specific port (e.g., 31515) on all worker nodes, connecting to the corresponding Pod via the “node IP:port” address will connect you.
— ์ฟ ๋ฒ๋คํฐ์ค๋ ๋ณดํต 30000~32767 ์ฌ์ด์ ํฌํธ ์ค ํ๋๋ฅผ ๋ฌด์์๋ก ํ ๋นํฉ๋๋ค.
Kubernetes usually assigns one of the ports between 30000 and 32767 randomly.
MacBookAir ~ % kubectl expose deployment my-app --type=NodePort --port=80
— ์๋น์ค๊ฐ ์ ๋๋ก ์์ฑ๋์๋์ง ํ์ธํฉ๋๋ค.
Check if the service was created properly.
MacBookAir ~ % kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9m
my-app NodePort 10.96.177.193 <none> 80:31515/TCP 37s
๐๐ป ์ํฌ ๋ด๋ถ์์ nginx์ ์ํ ์คํธ / Nginx connection test inside the workspace
— ์์ปค ๋ ธ๋์ ์ ์ํ๊ธฐ / Connect to the worker node
-MacBookAir ~ % docker exec -it desktop-worker bash
— ์์ปค ๋ ธ๋2์ ์ ์ํ๊ธฐ / Connect to Worker Node 2
-MacBookAir ~ % docker exec -it desktop-worker2 bash
— ์์ปค ๋
ธ๋ ๋ด๋ถ์์ ํ
์คํธํ๊ธฐ(curl localhost:31515 ๋๋ curl 172.18.0.2:31515)
Testing inside a worker node (curl localhost:31515 or curl 172.18.0.2:31515)
— ์์ปค๋
ธ๋2 ๋ด๋ถ์์ ํ
์คํธ ํ ๊ฒฝ์ฐ ์์ดํผ ์ฃผ์๋ curl 172.18.0.4:31515 ์
๋๋ค.
When testing inside Worker Node 2, the IP address is curl 172.18.0.4:31515.
root@desktop-worker:/# curl localhost:31515
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, nginx is successfully installed and working.
Further configuration is required for the web server, reverse proxy,
API gateway, load balancer, content cache, or other features.</p>
<p>For online documentation and support please refer to
<a href="https://nginx.org/">nginx.org</a>.<br/>
To engage with the community please visit
<a href="https://community.nginx.org/">community.nginx.org</a>.<br/>
For enterprise grade support, professional services, additional
security features and capabilities please refer to
<a href="https://f5.com/nginx">f5.com/nginx</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@desktop-worker:/# exit
exit
— ๋ ธ๋ ์์ดํผ ์ฃผ์ ํ์ธ ํ๊ธฐ / Checking Node IP Address
MacBookAir ~ % kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
desktop-control-plane Ready control-plane 10m v1.35.1 172.18.0.3 <none> Debian GNU/Linux 13 (trixie) 6.12.69-linuxkit containerd://2.2.1
desktop-worker Ready <none> 10m v1.35.1 172.18.0.2 <none> Debian GNU/Linux 13 (trixie) 6.12.69-linuxkit containerd://2.2.1
desktop-worker2 Ready <none> 10m v1.35.1 172.18.0.4 <none> Debian GNU/Linux 13 (trixie) 6.12.69-linuxkit containerd://2.2.1
๐๐ป๋ธ๋ผ์ฐ์ ์ ์ํ๊ธฐ / Access browser
— ๋ธ๋ผ์ฐ์ ์์ 8080๋ฒ์ผ๋ก ์ ์ํ ๋ my-app์ 80๋ฒ์๋น์ค์ ์ ์์ค์
Connection settings for the 80-service in my-app when accessing 8080 from the browser
MacBookAir ~ % kubectl port-forward svc/my-app 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080
— ๋ธ๋ผ์ฐ์ ์์ ์ ์ํ๊ธฐ / Access from browser

๐๐ป ํด๋ฌ์คํฐ ์ ํ ์ญ์ / Delete cluster settings
MacBookAir ~ % kubectl delete service my-app
MacBookAir ~ % kubectl delete deployment my-app