CLOUD/Docker&Kubernetes

[Kubernetes] Nginx - Gunicorn - Mysql 3계층 연동하기 (Pod/ConfigMap/Service)

alsruds 2023. 4. 24. 17:51

안녕 ¡∇¡ !!

오늘은 ~ K8S Dashboard 의 Pod / ConfigMap / Service 를 이용해 

Nginx(front) - Gunicorn(back) - MySQL(db) 3계층을 연동해보자 !

 

♡ 순서 ♡

1. MySQL - Service, ConfigMap, Pod 작성

2. 장고 프로젝트 준비

3. Gunicorn 이미지 도커에 업로드

4. Gunicorn - Service, ConfigMap, Pod 작성

5. 리액트 프로젝트 준비

6. Nginx 이미지 도커에 업로드

7. Nginx - Service, ConfigMap, Pod 작성

8. 확인해보기 (푸티 / 웹 브라우저)

 

¡ Dashboard 에 생성할 것 ¡

> Service : nginx-svc, django-svc, mysql-svc

> ConfigMap : nginx-dev, django-dev, mysql-dev

> Pod : nginx-pod, gunicorn-pod, mysql-pod

 

 


 

[ MySQL ]

● Service

# mysql-svc
apiVersion: v1
kind: Service
metadata:
  name: mysql-svc
spec:
  selector:
    app: mysql-pod	# Pod 랑 맞춰줘야 하는 값
  ports:
  - port: 3306
    targetPort: 3306

 

ConfigMap

# mysql-dev
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-dev
data:
  MYSQL_ROOT_PASSWORD: "qwer1234"	# 패스워드 설정

 

Pod

# mysql-pod
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
  labels:
    app: mysql-pod	# Service 랑 맞춰줘야 하는 값
spec:
  containers:
  - name: container
    image: mysql:8.0.32-debian
    envFrom:
    - configMapRef:
        name: mysql-dev		# ConfigMap 지정

 

mysql-pod 쉘에서 데이터베이스 만들어주기

> mysql -u root -p

> create database web;

 

 

[ Gunicorn ]

도커 허브에 이미지 업로드

》 장고 프로젝트 준비

미리 Pycharm을 이용해 Django 프로젝트를 대충 만들어놨어 !

# urls.py
urlpatterns = [
    path('dev/data', web.views.read)
]

# web - views.py
def read(request):
    datas = Data.objects.all().values()

    data_list = []
    for data in datas:
        print(data)
        data_list.append(data)

    context = {"result": data_list}
    return JsonResponse(context)

# web - models.py
class Data(models.Model):
    value = models.CharField(max_length=100)
    
# config - settings.py
import os
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ['DBNAME'],	# ConfigMap 에서 정의
        'USER': os.environ['DBUSER'],
        'PASSWORD': os.environ['DBPASS'],
        'HOST': os.environ['DBHOST'],
        'PORT': os.environ['DBPORT'],
        'OPTIONS': {
            'init_command': 'SET sql_mode="STRICT_TRANS_TABLES"'
        }
    }
}

프로젝트를 압축해서 FileZilla 를 통해 도커가 설치된 리눅스 가상머신으로 옮겨주자 !

 

Dockerfile

FROM python:3.9
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip3 install --upgrade pip
RUN pip install -r requirements.txt
COPY . /app

 

requirements.txt

# 장고 프로젝트에서 pip freeze > requirements.txt 로 생성 가능
asgiref==3.6.0
Django==4.2
django-cors-headers==3.14.0
gunicorn==20.1.0
mysqlclient==2.1.1
sqlparse==0.4.4
tzdata==2023.3

 

이미지 빌드 & 도커 업로드

# 이미지 빌드
# docker build --tag [docker hub id]/[directory]:[version] .
docker build --tag nuy0307/back:1.0 .	# docker hub 에 미리 directory 만들어 놔야 함

# 도커에 이미지 올리기
# docker push [docker hub id]/[directory]:[version]
docker push nuy0307/back:1.0

 

Service

# django-svc
apiVersion: v1
kind: Service
metadata:
  name: django-svc
spec:
  selector:
    app: django-pod
  ports:
  - port: 8000
    targetPort: 8000

 

ConfigMap

# django-dev
apiVersion: v1
kind: ConfigMap
metadata:
  name: django-dev
data:
  DBNAME: "web"
  DBUSER: "root"
  DBPASS: "qwer1234"
  DBHOST: "mysql-svc"
  DBPORT: "3306"

 

Pod

# gunicorn-pod
apiVersion: v1
kind: Pod
metadata:
  name: gunicorn-pod
  labels:
    app: django-pod	# Service 랑 맞춰주기
spec:
  containers:
  - name: container
    image: nuy0307/back:1.0
    command: ["/bin/sh", "-ec", "python manage.py migrate && gunicorn config.wsgi --bind 0.0.0.0:8000"]
    envFrom:
    - configMapRef:
        name: django-dev	# ConfigMap 이랑 맞춰주기

 

 

[ Nginx ]

도커 허브에 이미지 업로드

React 프로젝트 준비

# App.js
import React from 'react';
import './App.css';

function App() {
  const [datas, setDatas] = React.useState([]);
  React.useEffect(() => {
    fetch("http://200.200.200.135:31897/dev/data", {	# 외부에서 접속할 ip:[nginx nodeport]
      method: "GET",
    })
      .then(res => {
        return res.json();
      })
      .then(res => {
        setDatas(res.result);
      });
  }, []);

  return (
    <div className="App">
      {datas.map((data) => {
        return <div key={data.id}>{data.value}</div>
      })}
    </div>
  );
}

export default App;

> npm run build

프로젝트를 압축해서 FileZilla 를 통해 도커가 설치된 리눅스 가상머신으로 옮겨주자 !

필요한 건 build 파일과 default.conf 파일!

 

Dockerfile

FROM nginx:latest
RUN rm -rf /usr/share/nginx/html/index.html
ADD build /usr/share/nginx/html/
RUN rm -rf /etc/nginx/conf.d/default.conf
ADD default.conf.template /etc/nginx/conf.d/default.conf.template

 

default.conf.template

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /usr/share/nginx/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                try_files $uri $uri/ =404;
        }

        location /dev {
                proxy_set_header Host $http_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;
                proxy_pass http://${DJANGO_IP}:8000;	# ConfigMap 에서 지정
        }
}

 

 이미지 빌드 & 도커 업로드

# 이미지 빌드
docker build --tag nuy0307/front:1.2 .

# 도커에 이미지 업로드
docker push nuy0307/front:1.2

 

 Service

# nginx-svc
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx-pod
  ports:
  - port: 80
    targetPort: 80
  type: NodePort	# 외부에서 접속 가능한 포트 번호 할당 (default : Cluster IP - 내부 접속)

 

ConfigMap

# nginx-dev
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-dev
data:
  DJANGO_IP: "django-svc"

 

Pod

# nginx-pod
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx-pod
spec:
  containers:
  - name: container
    image: nuy0307/front:1.2
    command: ["/bin/sh", "-ec", "envsubst '$DJANGO_IP' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"]
    envFrom:
    - configMapRef:
        name: nginx-dev

 

 

[ 확인해보기 ]

PuTTy 에서 확인

# master node
curl [nginx-svc ip]:80			# html 출력
curl [nginx-svc ip]:80/dev/data		# django project 출력

성공~

 

웹 브라우저에서 확인

》 http://[master/node1/node2 ip]:[nginx port]/dev/data 로 접속

성공~