쿠버네티스 실습 1 - Nodejs와 Nginx로 리버스 프록시 Pod 만들기
개요
nginx conatiner 한 개, nodejs express container 2개 총 3개의 container를 구성한 뒤 1개의 pod에서 구동하여 외부에서 접속 가능한 형태의 간이 서비스를 제작 80으로 접속시 node-1에 접속하여 a-server라는 문구가 뜨게 하고 8080으로 접속시 node-2에 접속하여 b-server라는 문구를 뜨게하는게 목표이다.
환경
실습을 진행한 환경은 다음과 같다.
OS : UBUNTU 22.04
RAM : 8GB
Hypervisor : VMWARE community
사전 설치 프로그램
- minikube
- docker
절차
minikube 구동
minikube를 구동한 뒤 사용하기 편하도록 alias 처리를 해주고 docker image를 공유할 수 있도록 환경변수 설정을 해준다.
1
2
3
minikube start
eval $(minikube -p minikube docker-env)
alias kubectl="minikube kubectl --"
image 만들기
docker를 통해서 container를 총 3개 만든뒤 각각 이미지로 만든다.
- nginx
- node-1
- node-2
nginx
먼저 ubuntu 20.04 이미지에 host 네트워크로 container를 구동한다.
1
docker run -i -t --name nginx --net host ubuntu:20.04
컨테이너에 접속하자마자 먼저 apt update를 한다
1
apt update
이후에 vim과 nginx를 설치한다.
1
2
apt install -y vim
apt install -y nginx
/etc/nginx/conf.d 경로로 가서 server.conf 파일을 만든다
1
vim /etc/nginx/conf.d/server.conf
만든 파일에 설정을 아래와 같이 지정한다. 3000번과 3030번으로 들어오되 3000번은 3001번으로 3030번은 3031번으로 요청이 이동한다. 외부로 노출되는 port는 3000과 3030번이된다.
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
server {
listen 3000;
access_log off;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen 3030;
access_log off;
location / {
proxy_pass http://127.0.0.1:3031;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
이후 인스턴스가 실행되면 nginx가 자동 실행되게 설정한다.
1
sudo systemctl start nginx
컨트롤 + p + q를 눌러 컨테이너를 나온 뒤 image 작업한 걸 commit 하고 image로 만든다
1
docker commit -a "nginx" nginx nginx
node-1
먼저 ubuntu 20.04 이미지에 host 네트워크로 container를 구동한다.
1
docker run -i -t --name node-1 --net host ubuntu:20.04
컨테이너에 접속하자마자 먼저 apt update를 한다
1
apt update
이후에 vim와 wget을 설치한다.
1
2
apt install -y vim
apt install -y wget
apt install을 한 후에 node 파일을 받고 사용할 수 있도록 경로를 옮겨준다. 여기서 받을 파일은 nodejs 20.12버전이다
1
2
3
4
wget https://nodejs.org/dist/latest-v20.x/node-v20.12.2-linux-x64.tar.gz
tar -xvf node-v20.12.2-linux-x64.tar.gz
cd node-v20.12.2-linux-x64
cp -r * /usr/local
/home에 test폴더를 만들어 들어가서 express generator를 설치후에 ejs를 view-engine으로 myapp 프로젝트를 만든다.
1
2
3
4
npm install -g express-generator
cd /home
mkdir test
express --view=ejs myapp
만들어진 myapp 프로젝트에 기본 패키지를 설치하고 접속시에 A-SERVER라는걸 나타나게 기본 페이지를 수정해준다.
1
2
3
4
cd myapp
npm install
cd view
vim index.ejs
port도 3000번이 아닌 3001번이 되게 변경해준다.
1
vim /home/test/myapp/bin/www
컨트롤 + p + q를 눌러 컨테이너를 나온 뒤 image 작업한 걸 commit 하고 image로 만든다
1
docker commit node-1 node-1
node-2
node-1 image를 잘 만들었으면 해당 이미지로 container를 만들고 접속한다
1
docker run -i -t --name node-2 --net host node-1
myapp경로로 들어가서 port를 3000번에서 3031로 변경해주고 화면에서도 B-SERVER라고 표기되게 바꿔준다.
1
2
3
vim /home/test/myapp/bin/www
vim /home/test/myapp/view/index.ejs
# 필요한 부분 변경
컨트롤 + p + q를 눌러 컨테이너를 나온 뒤 image 작업한 걸 commit 하고 image로 만든다
1
docker commit node-2 node-2
kubernetes yaml 파일 만들기
원하는 곳에 my-revers-proxy.yaml 파일을 만든다.
이해를 돕기위해 #으로 주석을 달아두었다.
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
apiVersion: v1
kind: Pod
metadata:
name: my-revers-proxy
spec:
containers:
- name: nginx
image: nginx # 사용할 image이름
imagePullPolicy: Never # image가 없으면 repo에서 받아오지 않는다.
command: ["/bin/sh","-c"] # nginx를 실행시키고 exit 되지 않게 하기 위해 tail로 log를 출력
args:
- service nginx start;
tail -f /var/log/nginx/access.log;
ports:
- name: a-server
protocol: TCP
containerPort: 3000
- name: b-server
protocol: TCP
containerPort: 3030
- name: node-1
image: node-1
imagePullPolicy: Never
command: ["/bin/sh","-c"]
args:
- cd /home;
cd test;
cd myapp;
node bin/www;
- name: node-2
image: node-2
imagePullPolicy: Never
command: ["/bin/sh","-c"]
args:
- cd /home;
cd test;
cd myapp;
node bin/www;
Pod 구동
만든 my-revers-proxy.yaml을 통해 pod를 구동한다.
1
kubectl apply -f my-revers-proxy.yaml
구동하고 난 뒤 pod를 살피려면 아래의 명령어를 입력한다
1
kubectl get pods
문제가 있는 것 같으면 아래의 명령어로 세세한 상황을 살필 수 있다.
1
kubectl descibe pods my-revers-proxy
Image load가 안되면?
docker에서 만든 image가 로드가 안될 수 있다. 그럴 경우 직접 docker에서 이미지를 추출해서 minikube image에 올려줘야한다.
1
2
3
4
5
6
7
docker save -o nginx.tar nginx
docker save -o node-1.tar node-1
docker save -o node-2.tar node-2
minikube image load nginx.tar
minikube image load node-1.tar
minikube image load node-2.tar
Pod를 사용가능하게 끔 노출
생성한 pod는 구동하는 nginx나 node에 외부에서는 엑세스가 불가능하다. 클러스터 내에서만 접근이 가능한다. nginx나 node에 접근이 가능하기 위해서는 Pod를 외부에 노출 시켜야한다.
따라서 service.yaml 파일을 만들고 노출할 방식을 정하고 노출할 port를 지정해주고 해당 내용에 따라 배포해야한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Service
metadata:
name: my-proxy-service
spec:
type: NodePort # 제외하면 ClusterIP 방식이 되고 Cluster 내에서만 Access가 가능해진다.
selector:
app: revers-proxy
ports:
- name: a-server
nodePort: 30000 # Service로 들어오는 port
port: 3000 # Node로 들어오는 port
targetPort: 3000 # Pod로 들어오는 port
protocol: TCP
- name: b-server
nodePort: 30300 # Service로 들어오는 port
port: 3030 # Node로 들어오는 port
targetPort: 3031 # Pod로 들어오는 port
protocol: TCP
위의 yaml 파일을 만들었다면 minikube에서 해당 service.yaml 파일을 배포해준다.
1
kubectl apply -f service.yaml
minikube의 경우 docker 안에서 돌아가기 때문에 외부에서 접근하기 위해서는 별도의 터널링이나 포트 포워딩이 필요하다.
아래의 두 가지 방법중 하나를 사용하면 접근이 가능하다.
터널링
1
minikube service my-proxy-service --url
해당 명령 입력후 나오는 url로 접근시 엑세스 가능
포트포워딩
대상 pod 이름으로 {입력할 port}:{접근하기 원하는 port}로 입력
1
2
kubectl port-forward my-revers-proxy 3030:3030
kubectl port-forward my-revers-proxy 3031:3031
한번에 한 개의 port만 포트포워딩이 안되기 때문에 여러개를 열거라면 터널링이 더 낫다.