사이드 프로젝트를 간단히 진행하면서 쿠버네티스에 익숙해지기 위해 Minikube로 환경을 구성해 보기로 했다. 외부에서 서비스를 노출해야 했지만, Minikube만으로는 이를 해결할 수 없어서 방법을 공유하려고 한다.

(minikube 설치는 생략한다.)

 

인프라 세팅

 

편리성을 위해서 무료 도메인이 필요한데, 나 같은 경우 무료 도메인 발급 여기에서 무료로 생성한다. 그후에 도메인을 내 IP와 연결해 주면 된다. 

 

그 후에 공유기를 사용하고 있다면, 공유기에서 80이나 ssl을 사용한다면 443 포트를 열어줘야 한다. 나 같은 경우 netis 공유기를 사용하기에 http://192.168.1.1/ 로 접근해서 고급 설정 -> 방화벽에서 80 포트를 허용해 줬다. 

 

 

다음은 minikube 셋팅이다. 

minikube start를 해서 클러스터를 생성한다. 이때 --nodes 3 옵션을 줘서 클러스터 형식으로 설정해 준다.

minikube start --nodes 3 --cpus 2 --memory 4096

 

생성이 완료되면, kubectl을 사용할 수 있게 되고, minikube status를 입력했을 때 컨트롤 플레인과 워커 노드가 보인다.

 

간단하게는 도커 모드를 활성화해서 로컬의 이미지를 사용하도록 설정할 수 ㅏ있지만 클러스터 모드일 때는 아래처럼 도커 모드로 전환할 때 에러가 발생한다. 

eval $(minikube -p minikube docker-env)

 

저 주소로 가보면 minikube를 시작할 때 --insecure-registry옵션을 주거나 외부 이미지 저장소를 사용해야 한다. 나는 ECR을 선택했다.

 

ECR을 사용하는 방법은 간단하다. 

minikube addons configure registry-creds // 입력시 accessKey, region 등 입력 나옴
minikube addons enable registry-creds

 

AccessKey를 발급받고 위의 명령어를 실행하여 입력만 해주면 된다. 그러면 ECR에 접근할 수 있게 된다. 

 

이제 Service와 Deployment를 생성해 주자. 

 

apiVersion: v1
kind: Service
metadata:
name: server-service
spec:
type: LoadBalancer
selector:
app: server
ports:
- protocol: TCP
port: 8080
targetPort: 8080

 

apiVersion: apps/v1
kind: Deployment
metadata:
name: server
spec:
replicas: 3
selector:
matchLabels:
app: server
template:
metadata:
labels:
app: server
spec:
containers:
- name: server
image: {account_id}.dkr.ecr.ap-northeast-2.amazonaws.com/server:latest
imagePullPolicy: Always
ports:
- containerPort: 8080

 

파드가 생성된 것을 확인할 수 있다. 

 

이제 문제는 어떻게 접근하냐는 것이다. 생성된 서비스는 각각의 pod들의 접근점을 제공해 주지만 minikube 외부에서의 진입을 제공해주지 않는다. 그래서 minikube에서는 service-url 기능을 제공해 주는데, 호스트 컴퓨터와 서비스를 연결해 주는 지점을 제공해 준다. 이 기능을 활용하여 외부에 제공할 수 있다. 하나씩 알아보자. 

 

외부에 서비스 노출

 

의외로 간단한데, minikube server-url 기능에 nginx를 더해주면 된다. minikube service server-service --url를 입력하면 ip와 port가 나온다. 터미널을 잡고 있기 때문에 nohup으로 실행해 주면 편리하다.

nohup minikube service server-service --url > server.log 2>&1 &

 

 

나 같은 경우 127.0.0.1:50199가 나왔다. 이것을 nginx에 설정해 준다. 맥북 실리콘칩의 nginx.conf의 위치는 /opt/homebrew/etc/nginx 경로다. 여기서 nginx.conf를 아래와 같이 수정해 준다. 

worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name kim-test.p-e.kr;
location / {
proxy_pass http://127.0.0.1:50199/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}

 

여기서 server_name은 내가 만든 도메인이고, proxy_pass에 minikube service-url을 통해서 나온 것을 적어준다. 이렇게 하면 80 포트로 요청이 왔을 때 저기로 리버스 프락시 해준다. 실제로 요청을 보내보면 정상 동작한다.

 

이렇게 프런트엔드와 백엔드를 모두 설정하면, 내 로컬 맥북에서도 외부로 서비스를 할 수 있다. 이것은 service-url이 프로세스가 종료되거나 minikube 삭제 혹은 service가 삭제되면 다시 설정해줘야 한다. 그래서 간단한 스크립트로 편리하게 할 수 있다. nginx.conf를 자동으로 주입해 주는 것이다. 

# Minikube 서비스 실행
nohup minikube service server-service --url > server.log 2>&1 &
# 잠시 대기하여 로그 파일에 URL이 기록될 시간을 줌
sleep 2
# 서버의 URL을 server.log의 첫 번째 줄에서 읽어옴
URL=$(head -n 1 server.log)
# Nginx 설정 파일 경로
NGINX_CONF="/opt/homebrew/etc/nginx/nginx.conf"
# Nginx 설정 파일 생성
cat <<EOF > "$NGINX_CONF"
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name kim-test.p-e.kr;
location / {
proxy_pass $URL;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
}
EOF
nginx -s reload

 

이렇게 하면 간편하게 nginx.conf 작성을 자동화할 수 있다.