CLOUD/Docker&Kubernetes

[Kubernetes] MSA 실습하기 - Admin & Main MSA

alsruds 2023. 4. 28. 04:26

[ 이미지 준비 ]

● 이미지 만들기

https://github.com/scalablescripts/python-microservices

 

GitHub - scalablescripts/python-microservices

Contribute to scalablescripts/python-microservices development by creating an account on GitHub.

github.com

# git 설치
dnf -y install git

# git repository 다운로드
git clone https://github.com/scalablescripts/python-microservices

# 방화벽 실행
systemctl start firewalld

# 이미지 빌드
docker build --tag nuy0307/admin:1.0 .
docker build --tag nuy0307/main:1.0 .

# 도커 로그인
docker login

# 도커 허브에 업로드
docker push nuy0307/admin:1.0
docker push nuy0307/main:1.0

 

 

[ Admin MSA ]

ConfigMap

# admin-db-svc
apiVersion: v1
kind: ConfigMap
metadata:
  name: admin-db-svc
data:
  MYSQL_ROOT_PASSWORD: "root"		# 패스워드 설정
  MYSQL_DATABASE: "admin"		# 바로 데이터베이스 생성해줌
  
# admin-django-svc
apiVersion: v1
kind: ConfigMap
metadata:
  name: admin-django-svc
data:
  DBNAME: "admin"
  DBUSER: "root"
  DBPASS: "root"
  DBHOST: "127.0.0.1" 		# 같은 파드 안에 포트 번호로 구분해서 상관없음
  DBPORT: "3306"
  RABBITMQURL: "amqp://user:qwer1234@rabbitmq-svc/my_vhost"

 

ConfigMap 변수 데이터에 맞춰 워커 노드(node1)에서 프로젝트 파일 변경해주기

# settings.py
import os
ALLOWED_HOSTS = ['*',]
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ['DBNAME'],
        'USER': os.environ['DBUSER'],
        'PASSWORD': os.environ['DBPASS'],
        'HOST': os.environ['DBHOST'],
        'PORT': os.environ['DBPORT'],
    }
}

# consumer.py
import os
params = pika.URLParameters(os.environ['RABBITMQURL'])

# producer.py
import os
params = pika.URLParameters(os.environ['RABBITMQURL'])

 

Deployment

# admin-dpm
apiVersion: apps/v1
kind: Deployment
metadata:
  name: admin-dpm
spec:
  selector:
    matchLabels:
      type: admin
  replicas: 1
  template:
    metadata:
      labels:
        type: admin
    spec:
      nodeSelector:			# 워커 노드 지정 (미리 폴더에 프로젝트 파일 옮겨놓기)
        kubernetes.io/hostname: node1
      containers:
      - name: admin-db			# db container
        image: mysql:5.7.22
        volumeMounts:
        - name: admin-db
          mountPath: /var/lib/mysql
        envFrom:
        - configMapRef:
            name: admin-db-svc
      - name: admin-back-dpm		# backend container
        image: nuy0307/admin:1.0
        startupProbe:
          tcpSocket:
            port: 8000
          initialDelaySeconds: 10
          periodSeconds: 10
        command: ["python", "manage.py", "runserver", "0.0.0.0:8000"]
        volumeMounts:
        - name: admin-path
          mountPath: /app
        envFrom:
        - configMapRef:
            name: admin-django-svc
      - name: admin-queue-dpm		# queue container
        image: nuy0307/admin:1.0
        command: ["python", "-u", "consumer.py"]
        volumeMounts:
        - name: admin-path
          mountPath: /app
        envFrom:
        - configMapRef:
            name: admin-django-svc
      volumes:
      - name : admin-path
        hostPath:
          path: /admin-app		# host pc 에 생성되는 폴더 : 미리 프로젝트 폴더 옮겨놓기
          type: DirectoryOrCreate
      - name : admin-db
        hostPath:
          path: /admin-db		# host pc 에 생성되는 폴더
          type: DirectoryOrCreate

 

Service

# admin-svc
apiVersion: v1
kind: Service
metadata:
  name: admin-svc
spec:
  selector:
    type: admin
  ports:
  - port: 8000
    targetPort: 8000
  type: LoadBalancer

 

● 확인하기

백엔드 파드 접속 후 : python manage.py migrate

》 서비스(로드밸런서) 외부 엔드포인트 주소로 접속

ip:8000/api/products

데이터를 저장할 수 있습니다 ~

 

 

[ Main MSA ]

ConfigMap

# main-db-cm
apiVersion: v1
kind: ConfigMap
metadata:
  name: main-db-cm
data:
  MYSQL_ROOT_PASSWORD: "root"
  MYSQL_DATABASE: "main"
  
# main-django-cm
apiVersion: v1
kind: ConfigMap
metadata:
  name: main-django-cm
data:
  DBNAME: "main"
  DBUSER: "root"
  DBPASS: "root"
  DBHOST: "127.0.0.1"
  DBPORT: "3306"
  RABBITMQURL: "amqp://user:qwer1234@rabbitmq-svc/my_vhost"
  ADMIN_SVC: "admin-svc"

 

● ConfigMap 변수 데이터에 맞춰 워커 노드(node2)에서 프로젝트 파일 변경해주기 & 수정

# main.py
import os
app.config["SQLALCHEMY_DATABASE_URI"] = 'mysql://'+os.environ['DBUSER']+':'+os.environ['DBPASS']+'@'+os.environ['DBHOST']+'/'+os.environ['DBNAME']
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
def like(id):
    req = requests.get('http://'+os.environ['ADMIN_SVC']+'/api/user')
    json = req.json()

# consumer.py
import os
params = pika.URLParameters(os.environ['RABBITMQURL'])

# producer.py
import os
params = pika.URLParameters(os.environ['RABBITMQURL'])

# requirements.txt : 변경 후 이미지 빌드 다시 해주기
Flask==1.1.2
Werkzeug==0.16.0
itsdangerous==2.0.1
Jinja2==3.0.3
Flask-SQLAlchemy==2.4.4
SQLAlchemy==1.3.20
Flask-Migrate==2.5.3
Flask-Script==2.0.6
Flask-Cors==3.0.9
requests==2.25.0
mysqlclient==2.0.1
pika==1.1.0

 

Deployment

# main-dpm
apiVersion: apps/v1
kind: Deployment
metadata:
  name: main-dpm
spec:
  selector:
    matchLabels:
      type: main
  replicas: 1
  template:
    metadata:
      labels:
        type: main
    spec:
      nodeSelector:
        kubernetes.io/hostname: node2
      containers:
      - name: main-db
        image: mysql:5.7.22
        volumeMounts:
        - name: main-db
          mountPath: /var/lib/mysql
        envFrom:
        - configMapRef:
            name: main-db-cm
      - name: main-back-dpm
        image: nuy0307/main:1.1
        startupProbe:
          tcpSocket:
            port: 5000
          initialDelaySeconds: 10
          periodSeconds: 10
        command: ["python", "main.py"]
        volumeMounts:
        - name: main-path
          mountPath: /app
        envFrom:
        - configMapRef:
            name: main-django-cm
      - name: main-queue-dpm
        image: nuy0307/main:1.1
        command: ["python", "-u", "consumer.py"]
        volumeMounts:
        - name: main-path
          mountPath: /app
        envFrom:
        - configMapRef:
            name: main-django-cm
      volumes:
      - name : main-path
        hostPath:
          path: /main-app		# host pc 에 생성되는 폴더 : 미리 프로젝트 파일 옮겨놓기
          type: DirectoryOrCreate
      - name : main-db
        hostPath:
          path: /main-db
          type: DirectoryOrCreate

 

Service

# main-svc
apiVersion: v1
kind: Service
metadata:
  name: main-svc
spec:
  selector:
    type: main
  ports:
  - port: 5000
    targetPort: 5000
  type: LoadBalancer

 

 확인하기

 백엔드 파드 접속

python manager.py db init
python manager.py db migrate
python manager.py db stamp head
python manager.py db upgrade
python manager.py db migrate

》 서비스(로드밸런서) 외부 엔드포인트 주소로 접속

 ip:5000/api/products

admin 에서 데이터 저장 시 나타남