티스토리 뷰
Kubernetes Cluster 에 MySQL 설치하기(Deployment, Local Persistent Volume)
Kubernetes MySQL Pod 생성
- 작업폴더 설정
$ sudo mkdir -p /workspace/kubernetes/mysql
$ sudo chown -R tommypagy:tommypagy /workspace/kubernetes
$ cd /workspace/kubernetes/mysql
먼저 mysql 배포를 위한 폴더를 생성 후 적절한 권한을 설정해줍니다.
- StorageClass 생성
$ vi storageClass-local-storage.yaml
vi 편집기로 StorageClass 생성을 위한 yaml 파일을 생성합니다.
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
Local Persistent Volume 은 Dynamic Provisioning 을 지원하지 않으므로 Static Provisioner 를 통해 직접 PV 를 생성하도록 하겠습니다. 또한 Persistent Volume Claim(pvc)의 Binding 시점을 Pod 가 생성된 후로 연기하도록 VolumeBindingMode 를 설정합니다. 위의 내용을 입력하고 파일을 저장합니다.
$ kubectl apply -f storageClass-local-storage.yaml
kubectl 명령을 통해 StorageClass 를 생성해 줍니다.
storageclass.storage.k8s.io/local-storage created
정상적으로 생성이 되었다면 위와 같은 메세지가 출력됩니다.
- 각 노드에 볼륨 디렉토리를 생성해줘야 합니다.
- Persistent Volume 생성
$ sudo mkdir -p /workspace/data/kubernetes/pv/mysql
$ sudo chmod 777 /workspace/data/kubernetes/pv/mysql
우선 worker1, worker2 각각 위의 명령을 통해 mysql 의 데이터가 저장될 폴더를 생성하고 적절한 권한을 부여합니다. 우선은 777으로 권한을 설정했으나 향후 RBAC 기반으로 전체적인 권한체계를 구성할 예정입니다.
$ vi pv-mysql.yaml
vi 편집기로 pv 생성을 위한 yaml 파일을 생성합니다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-mysql
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /workspace/data/kubernetes/pv/mysql
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- worker1
10GB 의 용량으로 설정하고 하나의 pod 만 접근하기 때문에 ReadWriteOnce, pod 가 삭제되더라도 데이터 보존을 위해 Retain 전략으로 설정합니다. NodeAffinity 설정을 통해 worker1 에 pv 를 생성하도록 합니다. 즉, MySQL pv 는 worker1 노드에 만들어지고 MySQL pod 역시 worker1 노드에 생성되게 됩니다.
$ kubectl apply -f pv-mysql.yaml
kubectl 명령을 통해 pv 를 생성해 줍니다.
persistentvolume/pv-mysql created
정상적으로 생성이 되었다면 위와 같은 메세지가 출력됩니다.
- Persistent Volume Claim 생성
$ vi pvc-mysql.yaml
vi 편집기로 pvc 생성을 위한 yaml 파일을 생성합니다.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-mysql
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-storage
resources:
requests:
storage: 10Gi
위에서 생성한 local-storage 타입으로 10GB 의 용량의 pvc 를 생성합니다.
$ kubectl apply -f pvc-mysql.yaml
kubectl 명령을 통해 pv 를 생성해 줍니다.
persistentvolumeclaim/pvc-mysql created
정상적으로 생성이 되었다면 위와 같은 메세지가 출력됩니다.
$ kubectl get pvc
생성된 pvc 의 상태를 조회해봅니다.
root@master:/home/mysql# k get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-mysql Bound pv-mysql 10Gi RWO local-storage 83m
root@master:/home/mysql#
생성된 pv 의 상태도 조회해봅니다.
root@master:/home/mysql# k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-mysql 10Gi RWO Retain Bound mysql/pvc-mysql local-storage 83m
root@master:/home/mysql#
VolumeBindingMode 를 WaitForFirstConsumer로 설정했기 때문에 Status 가 아직 Available 인 점을 확인할 수 있습니다.
- Configmap, Secret 생성
기본적으로 MySQL 의 설정은 Remote Access 를 허용하지 않습니다. 또한 사용자 계정역시 root 외에는 생성되어 있지 않습니다. 이 설정들을 Deployment yaml 파일에 설정해도 되지만 배포 Context 라던지 상황에 따라 Variation 이 존재할 수 있으므로 유연한 설정을 위해 Configmap 으로 관리하도록 하겠습니다.
$ kubectl create configmap configmap-mysql --from-literal MYSQL_USER=truelifer --from-literal MYSQL_ROOT_HOST=%
사용자 계정을 생성하고 외부에서 접속가능한 설정을 Configmap 으로 생성합니다.
configmap/configmap-mysql created
정상적으로 생성이 되었다면 위와 같은 메세지가 출력됩니다.
$ kubectl create secret generic secret-mysql --from-literal MYSQL_PASSWORD=12345 --from-literal MYSQL_ROOT_PASSWORD=12345
위에서 생성한 사용자 계정에 매핑되는 비밀번호와 기본계정인 root 의 비밀번호를 Secret 을 통해 관리하겠습니다.
secret/secret-mysql created
정상적으로 생성이 되었다면 위와 같은 메세지가 출력됩니다.
- Deployment 생성
$ vi deployment-mysql.yaml
vi 편집기로 deployment 생성을 위한 yaml 파일을 생성합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql/mysql-server:latest
name: mysql
env:
- name: MYSQL_USER
valueFrom:
configMapKeyRef:
name: configmap-mysql
key: MYSQL_USER
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: secret-mysql
key: MYSQL_PASSWORD
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: secret-mysql
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_ROOT_HOST
valueFrom:
configMapKeyRef:
name: configmap-mysql
key: MYSQL_ROOT_HOST
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: volume-mysql
mountPath: /var/lib/mysql
volumes:
- name: volume-mysql
persistentVolumeClaim:
claimName: pvc-mysql
arm 기반의 Raspberry Pi 4B 에 몇가지 MySQL Docker Image 를 테스트해봤으나 모두 실패하고 mysql/mysql-server:latest 만 정상적으로 작동함을 확인했습니다. 위에서 생성한 pv, pvc, configmap, secret 을 기반으로 deployment yaml 파일을 작성합니다.
$ kubectl apply -f deployment-mysql.yaml
kubectl 명령을 통해 deployment 를 생성해 줍니다.
deployment.apps/mysql created
정상적으로 생성이 되었다면 위와 같은 메세지가 출력됩니다.
root@master:/home/mysql# k get po
NAME READY STATUS RESTARTS AGE
mysql-5c8676c85-4bj6h 1/1 Running 0 79m
root@master:/home/mysql#
생성된 pod 를 조회해봅니다.
NAME READY STATUS RESTARTS AGE
mysql-78b9dbcf7b-hzsjz 1/1 Running 0 108s
Status 가 Running 상태로 정상적으로 배포되었음을 확인할 수 있습니다. 참고로 물리적인 H/W 의 성능에 따라서 배포가 되었음에도 불구하고 바로 로그인 되지 않을 수 있습니다. Pod 가 배포되더라도 기본적인 Initialization 이 완료되기까지는 조금의 시간이 필요하기 때문입니다. 제가 구성한 Kubernetes Cluster 의 H/W 기반이 Raspberry Pi 4B 이기에, 대략 1분정도의 Delay 가 발생함을 확인하였습니다.
- Service 생성
$ vi service-mysql.yaml
vi 편집기로 service 생성을 위한 yaml 파일을 생성합니다.
apiVersion: v1
kind: Service
metadata:
name: service-mysql
spec:
type: NodePort
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
nodePort: 30000
targetPort: 3306
보안 등의 이유로 MySQL 을 Kubernetes Cluster 내부에서만 접근 가능하도록 하기 위해서는 Service 의 Type 을 ClusterIP 로 설정하면 됩니다. 하지만 저는 Database 의 상태 및 데이터 조회를 위해 Kubernetes Cluster 외부에서 Client 툴을 통해 접속할 예정입니다. 이를 위해 NodePort 타입으로 설정하도록 합니다. Node 의 Port 기본 범위는 30000 ~ 32767로 정해져있습니다. 저는 30000 포트를 사용하도록 하겠습니다.
$ kubectl apply -f ./service-mysql.yaml
kubectl 명령을 통해 service 를 생성해 줍니다.
service/service-mysql created
정상적으로 생성이 되었다면 위와 같은 메세지가 출력됩니다.
$ kubectl get services
생성된 service를 조회해봅니다.
root@master:/home/mysql# k get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service-mysql NodePort 10.103.211.20 <none> 3306:30000/TCP 69m
root@master:/home/mysql#
NodePort 타입으로 service 가 정상적으로 생성되었음을 확인할 수 있습니다.
# k exec -it mysql-5c8676c85-kxddn bash
bash-4.4# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 8.0.32 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.02 sec)
##########################################
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> CREATE DATABASE study_db;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE DATABASE example_db;
Query OK, 1 row affected (0.00 sec)
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| example_db |
| information_schema |
| mysql |
| performance_schema |
| study_db |
| sys |
+--------------------+
6 rows in set (0.00 sec)
mysql> use study_db
Database changed
mysql> INSERT INTO professor
-> (name, belong, phone)
-> VALUES('', 'IDE','01112345678');
ERROR 1146 (42S02): Table 'study_db.professor' doesn't exist
mysql> CREATE TABLE professor
-> (
-> _id INT AUTO_INCREMENT,
-> name VARCHAR(32) NOT NULL,
-> belong VARCHAR(12) DEFAULT 'FOO',
-> phone VARCHAR(12),
-> PRIMARY KEY(_id)
-> ) ENGINE=INNODB;
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> INSERT INTO professor
-> (name, belong, phone)
-> VALUES('', 'IDE','01112345678');
Query OK, 1 row affected (0.01 sec)
mysql>
mysql> INSERT INTO professor
-> (name, belong, phone)
-> VALUES('', 'MSE', '01121342443');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> INSERT INTO professor
-> (name, belong, phone)
-> VALUES('', 'ESE', '01123424343');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> INSERT INTO professor
-> (_id, name, belong, phone)
-> VALUES(256, '', 'IME', '01134343222');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> INSERT INTO professor
-> (name, belong, phone)
-> VALUES( '', 'IDE', '01123432432');
SELECT _id, belong, phone FROM professor;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT _id, belong, phone FROM professor;
+-----+--------+-------------+
| _id | belong | phone |
+-----+--------+-------------+
| 1 | IDE | 01112345678 |
| 2 | MSE | 01121342443 |
| 3 | ESE | 01123424343 |
| 256 | IME | 01134343222 |
| 257 | IDE | 01123432432 |
+-----+--------+-------------+
5 rows in set (0.00 sec)
mysql> SELECT * FROM professor;
+-----+------+--------+-------------+
| _id | name | belong | phone |
+-----+------+--------+-------------+
| 1 | | IDE | 01112345678 |
| 2 | | MSE | 01121342443 |
| 3 | | ESE | 01123424343 |
| 256 | | IME | 01134343222 |
| 257 | | IDE | 01123432432 |
+-----+------+--------+-------------+
5 rows in set (0.00 sec)
mysql>
- Total
- Today
- Yesterday
- 테라폼
- 버쳐박스
- 5.4.0.1072
- 키알리
- 오라클 홈디렉토리 copy 후 startup 에러
- 오라클 트러블 슈팅(성능 고도화 원리와 해법!)
- CVE 취약점 점검
- startup 에러
- 코로나19
- 트리이스
- ubuntu
- 오라클
- 커널
- directory copy 후 startup 에러
- 앤시블
- (InstantClient) 설치하기(HP-UX)
- ORACLE 트러블 슈팅(성능 고도화 원리와 해법!)
- [오라클 튜닝] sql 튜닝
- MSA
- [오라클 튜닝] instance 튜닝2
- K8s
- Oracle
- 쿠버네티스
- 여러서버 컨트롤
- 튜닝
- 설치하기(HP-UX)
- 오라클 인스턴트클라이언트(InstantClient) 설치하기(HP-UX)
- 우분투
- 스토리지 클레스
- pod 상태
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |