kubectl를 사용하기위한 명령어
--region 과 --name은 생성한 지역과 자신의 cluster로 맞춰줘야한다.
aws eks update-kubeconfig --region us-east-2 --name eks-JaeHyuk
apply 명령어
kubectl apply -f db-statefulset.yaml
kubectl apply -f db-storagelass.yaml
kubectl apply -f db-pv.yaml
kubectl apply -f db-service.yaml
delete 명령어
kubectl delete -f db-statefulset.yaml
kubectl delete -f db-storagelass.yaml
kubectl delete -f db-pv.yaml
kubectl delete -f db-service.yaml
pv 목록 조회
kubectl get pv
pv 상세 조회
kubectl describe pv [PV 이름]
모든 리소스 조회 명령어
kubectl get all -n default
pv,pvc 목록 조회 명령어
kubectl get pv,pvc -n default
StorageClass 생성(db-storagelass.yaml)
- 동적으로 스토리지를 프로비져닝 하기 위해 사용되는 kubernetes resource 객체
- 즉, Persistent Volume이 필요할 때 자동으로 생성되도록 설정하는 역할
- • 일반적으로 시스템 운영자가 Storage Class를 생성하면, 이후 개발자가 pod를 생성할때 PersisentVolumeClaim 을 통해서 볼륨을 필요에 따라 생성할 수 있게 된다.
- 파드가 스케줄링되기 전까지 PVC의 바인딩과 프로비저닝을 지연
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: my-storage
namespace: default
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
PersistentVolume Claim 생성
- Persistent Volume Claim은 볼륨을 pod에서 요청할때 볼륨을 요청한 만큼 할당해 주는 역할
- StatefulSet을 이용하여 mysql을 이용하기 때문에 PVC를 바로 생성하지 않고, StatefulSet에서 volumeClaimTemplates 을 이용하여 생성
- 일반 케이스에서는 직접 생성
PersistentVolume 생성(db-pv.yaml)
- pv-statefulset-mysql-0라는 이름의 PV를 생성
- PV는 2GB의 용량
- 한 번에 한 개의 노드에서만 읽기/쓰기가 가능
- PV가 해제되면 자동으로 삭제되며, 특정 노드에만 바인딩되도록 설정
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-statefulset-mysql-0
namespace: default
spec:
storageClassName: "my-storage"
capacity:
storage: 2Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
hostPath:
path: /tmp/k8s-pv
type: DirectoryOrCreate
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: "kubernetes.io/hostname"
operator: "In"
values:
- GLW4XPMQ2X
StatefulSet 지정 (db-statefulset.yaml)
- 'mysql'이라는 이름의 StatefulSet을 생성
- S1개의 'mysql' 컨테이너를 가진 파드를 1개 생성
- 파드는 3306 포트를 열고, '/var/lib/mysql'에 볼륨을 마운트
- 각 파드는 'mysql-data'라는 이름의 PVC를 사용하며, 이 PVC는 500Mi의 스토리지를 요청
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: default
spec:
replicas: 1
serviceName: mysql
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mysql
image: mariadb:latest
ports:
- name: tpc
protocol: TCP
containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: password
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
namespace: storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
Service 생성(db-service.yaml)
- 각 노드의 3306 포트를 노출
- 이 포트로 들어오는 트래픽을 app: mysql 레이블을 가진 파드의 3306 포트로 전달
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
type: NodePort
ports:
- port: 3306
protocol: TCP
targetPort: 3306
selector:
app: mysql
deployment 수정(flask-deployment.yaml)
- 컨테이너의 환경 변수를 설정
- MySQL 서버의 호스트 이름(mysql), 포트(3306), 사용자 이름(root), 비밀번호(password), 데이터베이스 이름(petclinic)을 설정
apiVersion: apps/v1
kind: Deployment
metadata:
name: osint-flask
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: osint-flask
template:
metadata:
labels:
app: osint-flask
spec:
containers:
- name: osint-flask
image: 871065065486.dkr.ecr.us-east-2.amazonaws.com/jenkinsflask:17
imagePullPolicy: Always
ports:
- containerPort: 5000
env:
- name: MYSQL_HOST
value: 'mysql' # MySQL 서비스의 이름
- name: MYSQL_PORT
value: '3306' # MySQL 포트
- name: MYSQL_USER
value: 'root'
- name: MYSQL_PASSWORD
value: password
- name: MYSQL_DB
value: 'petclinic' # MySQL 데이터베이스 이름
여기서부터는 이미 올라간 서비스의 내부 코드를 변경하는 모습이다.
flask 수정(login_module.py)
- import os 추가
- MySQL 데이터베이스에 연결하기 위한 정보를 환경 변수에서 가져오는데 사용
- os 모듈을 사용하여 환경 변수를 읽어와 MySQL 데이터베이스에 접속하기 위한 정보를 설정
from flask import Flask, session, render_template, redirect, request, url_for, Blueprint
import pymysql
import os
mysql_host = os.environ.get('MYSQL_HOST', 'mysql')
mysql_port= int(os.environ.get('MYSQL_PORT', 3306))
mysql_user = os.environ.get('MYSQL_USER', 'root')
mysql_password = os.environ.get('MYSQL_PASSWORD', 'password')
mysql_db = os.environ.get('MYSQL_DB', 'petclinic')
login_module = Blueprint("login_module", __name__)
@login_module.route("/login", methods=['GET', 'POST'])
def login_result():
if request.method == 'POST':
error = None
db = pymysql.connect(host=mysql_host,port=mysql_port, user=mysql_user, password=mysql_password, db=mysql_db, charset='utf8')
id = request.form['id']
pw = request.form['pw']
cursor = db.cursor()
sql = "SELECT id FROM login_table WHERE id = %s AND pw = %s"
value = (id, pw)
cursor.execute(sql, value)
data = cursor.fetchone()
db.commit()
db.close()
if data:
session['login_user'] = data[0]
return render_template("index.html", user_id=data[0])
else:
error = 'invalid input data detected !'
return render_template("error.html", error=error)
return render_template("login.html")
(register_module.py)
- import os 추가
- MySQL 데이터베이스에 연결하기 위한 정보를 환경 변수에서 가져오는데 사용
- os 모듈을 사용하여 환경 변수를 읽어와 MySQL 데이터베이스에 접속하기 위한 정보를 설정
from flask import Flask, session, render_template, redirect, request, url_for, Blueprint
import pymysql
import os
mysql_host = os.environ.get('MYSQL_HOST', 'mysql')
mysql_port= int(os.environ.get('MYSQL_PORT', 3306))
mysql_user = os.environ.get('MYSQL_USER', 'root')
mysql_password = os.environ.get('MYSQL_PASSWORD', 'password')
mysql_db = os.environ.get('MYSQL_DB', 'petclinic')
register_module = Blueprint("register_module", __name__)
@register_module.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('index'))
@register_module.route("/register", methods=['GET', 'POST'])
def register_result():
if request.method == 'POST':
db = pymysql.connect(host=mysql_host,port=mysql_port, user=mysql_user, password=mysql_password, db=mysql_db, charset='utf8')
id = request.form['id']
pw = request.form['pw']
cursor = db.cursor()
cursor.execute("SELECT * FROM login_table WHERE id = %s", (id,))
data = cursor.fetchone()
if data is None:
cursor.execute("INSERT INTO login_table (id, pw) VALUES (%s, %s)", (id, pw))
db.commit()
db.close()
return render_template("register_success.html")
else:
return render_template("register_fail.html")
return render_template("register.html")
MySQL, POD 연동 방식
- db-storageclass.yaml:StorageClass는 PersistentVolume의 동적 프로비저닝을 위한 설정을 제공 즉, 필요에 따라 자동으로 PersistentVolume을 생성
- db-pv.yaml: MySQL 데이터베이스가 데이터를 영구적으로 저장하기 위한 공간을 제공
- db-statefulset.yaml: StatefulSet은 네트워크 식별자와 저장소를 유지하면서 Pod를 실행하는데 사용, 이 설정을 통해 MySQL 데이터베이스가 실행
- db-service.yaml: Service는 MySQL 데이터베이스에 접근하는 데 사용, Flask 애플리케이션의 Pod는 이 Service를 통해 데이터베이스와 통신
- flask-deployment.yaml: Flask 애플리케이션의 Pod를 생성, 이 Pod는 login_module.py와 register_module.py에 정의된 로직을 실행
- login_module.py 및 register_module.py: MySQL 데이터베이스와 연결하여 사용자의 로그인 및 회원 가입 요청을 처리
모든 yaml 파일을 apply 시키고 모든 리소스를 조회
파드가 정상적으로 작동되는 것을 확인할 수 있었다.
'mysql' 서비스는 각 노드의 31278 포트를 통해 클러스터 외부에서 접근할 수 있다.
StatefulSet 역시 정상적으로 작동 중인 것을 확인
DB 정상 동작 확인
table 생성 확인
table 조회 명령어
SHOW TABLES;
table안의 값
SELECT * FROM login_table;
회원 가입 기능 동작 확인
id=kim, pw=123 지정
DB확인
정상 로그인 확인
서브넷 오류 모습
vpc → 서브넷으로간뒤 각 서브넷 태그를 다음과 같이 추가해줬다.
kubernetes.io/role/internal-elb 1
'DevOps' 카테고리의 다른 글
Jenkins + gitops (0) | 2023.12.18 |
---|---|
CI / CD 란? (0) | 2023.12.18 |
Terraform을 이용한 EKS 클러스터 생성 및 서비스 배포 (0) | 2023.12.18 |
EKS 구축 테라폼 코드 설명 (0) | 2023.12.18 |
쿠버네티스(K8) , EKS란? (1) | 2023.12.17 |