아래의 포스트들은 저 혼자 kubernetes에 대한 이해와 실습을 위해서
시행착오들을 적어놓은 포스트들입니다.
완벽하지 않고 순서가 뒤죽박죽임을 알아주시고
참고해주시면 감사하겠습니다!
Mysql Docker Image를 이용해서 React-Node.js-MySQL 애플리케이션 구현해보기
React와 Node.js 애플리케이션 Docker image build
6. React-Node.js image 생성하기
Kubespray와 Ansible을 이용한 Kubernetes 설치하기 - 1편
8. Ansible을 이용해서 Master와 Worker 연결
9. Ansible-playbook을 이용해서 한꺼번에 명령내리기
Kubespray와 Ansible을 이용한 Kubernetes 설치하기 - 2편
10. Kuberspray를 이용해 kubernetes 설치하기
Kubespray와 Ansible을 이용한 Kubernetes 설치하기 - 3편
10. Kuberspray를 이용해 kubernetes 설치하기(계속)
Kubespray와 Ansible을 이용한 Kubernetes 설치하기 - 4편
13. docker image pull 받고 실행시키기
15. Database의 Volume설정(PersistentVolume, PersistentVolumeClaim)
16. Database의 초기화 설정(configMap 사용하기)
17. 현재 파일 구조와 오브젝트들 설명과 목표 짚고 가기.
18. DB와 Web-app을 같은 Pod에서 구동시키기
지난 4,5편에서는 kubespray가 계속 오류가 나면서 삽질을 엄청했습니다..
결국 설치가 되어서 이제 제가 만든 react-node-db 앱을 테스트 하는 일만 남았습니다.
12. dashboard 띄우기
proxy를 통해서 띄우기 (localhost에서만 띄울 수 있습니다.)
http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/.
을 통해서 들어갈 수 있습니다.
토큰은
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
을 입력해서 나오는
저 긴 토큰을 복사해서 붙여넣기 하면 됩니다.
13. docker image pull 받고 실행시키기
제가 만든 도커 이미지 (react-node-app-with-mysql)입니다.
docker-compose 설치
curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
docker-compose.yml파일 작성
adminer는 실행시켜도 되고 포함을 안시켜도됩니다. (mysql 시각화 툴)
저는 포함을 안시켰습니다.(주석처리)
docker-compose up -d --build
그러고 docker ps를 쳐보면
웹 앱은 restart를 시도하고있을겁니다.
이유는 react에서 db와 연결을 시도했는데 db에 테이블과
데이터베이스가 생성이 안되어 있어서 그렇습니다.
그래서 container안에서 데이터베이스와 컨테이너를 생성해주었습니다.
(저는 제 도커 이미지를 다운받았기 때문에 데이터베이스는 무조건 "db", 테이블명은 "table1" 으로 지정해주었습니다.)
create database db;
use db;
create table table1(name char(20));
요기까지 하고 나면 이제 정상적으로 실행이 될겁니다.
와우
그리고 로컬에서
localhost:3000으로 접속하면
다음과 같이 실행이 되었습니다.
14. deployment 생성 후 pod관리
deployments 폴더를 생성해주고 그 안에 deployment들을 생성해주겠습니다.
service나 persistantvolume, ingress등등.. 생성해주어야 할 것이 많기 때문에 나눠주었습니다.
우선은 mysql deployment부터 생성해주었습니다.
이유는 react-node 이미지 먼저 실행을 시키면
데이터베이스가 연결이 안되어있기 때문에 오류가 날게 분명하기 때문입니다.
mysql deployment 작성
kubectl apply -f mysql-deployment.yaml
위 명령어로 deployment를 생성시켜 줍니다.
kubectl get pods -o wide
위 명령어로 pod들을 확인해보면 정상적으로 생성되었고
node는 랜덤으로 배치가 된 것을 알 수 있습니다.
그리고 node6과 node3에 각각들어가서 데이터베이스와 테이블들을 생성 시켜주었습니다.
node안에서 컨테이너를 실행하는 명령어는 아래와 같고
docker exec -it a9454e5728f2 /bin/bash
node6에서 생성
node3에서 생성
그러고나서 web-app deployment를 적용시켜줄 차례입니다.
deployment를 생성합니다.
kubectl apply -f react-deployment.yaml
위 명령어로 적용을 해보았습니다.
이 에러에 대해서 생각을 해보았는데
mysql pod와, web-app pod는 같은 node에 위치하지만 같은 pod에 위치해있지 않아서
같은 localhost를 사용하지못합니다.
그래서 web-app 컨테이너를 실행하면 맨처음에 8080 port로 db를 연결 시도하는데,
mysql 컨테이너가 다른 IP를 가지고있어서 (같은 local이 아니라서)
web-app에서 계속 Error가 뜨는 것 같습니다.
그래서 생각한것은 같은 pod에서 web-app과 db 컨테이너를 구동시키는 것이었습니다.
우리가 해주어야 하는 것은
1. db의 volume 설정
2. db 컨테이너 생성시 database 생성과 table 생성 자동화(web-app에서 database와 table을 요구함)
3. db와 web-app을 같은 pod에서 실행
입니다.
15. Database의 Volume설정(PersistentVolume, PersistentVolumeClaim)
간략하게 PV(PersistentVolume), PVC(PersistentVolumeClaim)에 대해서 설명을 하자면
컨테이너가 생성이되고 컨테이너가 삭제되면
컨테이너에서 사용한 데이터는 전부 날아가게 됩니다.
저장소에 대해서 쿠버네티스는 멋지게 PV, PVC로 해결을 하였는데
우리가 만약 관리자로써 저장소를 만들고
PV로 생성을 해놓게되면
Pod에서는 Volume으로 PVC에 볼륨 bind를 요청하고, PVC는 PV로 요청을 하게 되는 구조입니다.
kubectl apply -f volume.yaml
위 코드로 클러스터에 PV, PVC를 생성합니다.
테스트를 위해 Node2에 생성된 pod에 실행되는 컨테이너에 접속을 해서
PV, PVC가 잘 적용되었는지 확인해봅시다.
node2에 실행중인 pod
node2에 우리가 bind해줄 폴더를 "/tmp/mysql" 폴더로 지정해줬으니
해당 폴더에 접속을해서 "a" 라는 파일을 만들어줍니다.
만약 성공적으로 PV,PVC가 연결이 되었다면
컨테이너 안의 bind한 폴더도 똑같이 "a"라는 파일을 가지고 있어야 합니다.
node2에 실행중인 mysql 컨테이너를 확인합니다.
우리는 node2의 /tmp/mysql 폴더를
mysql 컨테이너의 /docker-entrypoint-initdb.d 폴더에 바인드해줬기 때문에
"a"라는 파일이 똑같이 생성된 것을 확인할 수 있습니다.
docker rm -f <mysql 컨테이너 id>
그리고 PV, PVC 가 잘 작동되는지 확인하기 위해
고의로 mysql 컨테이너를 삭제를 하고,
다시 생성된 mysql 컨테이너에 똑같이 "a" 파일이 있는지 확인해봅니다.
삭제 후 새롭게 생성된 mysql 컨테이너입니다.
/docker-entrypoint-initdb.d 폴더에 접속을 해서 파일을 확인해보니
정상적으로 "a" 파일이 계속해서 있는것을 확인할 수 있습니다.
그럼 pv, pvc는 나중에 컨테이너 생성 후 추가적인 데이터가 생성되면 저장을 하는 방식으로 사용해야될 것 같습니다.
그리고 node끼리 서로 데이터를 공유하는 방법에 대해서도 조금 고민을 해봐야할 것 같습니다
(아마 git repository를 사용하는 방법이 있었는데 그것을 사용하면 되지않을까?..)
16. Database의 초기화 설정(configMap 사용하기)
저희의 web-app은 생성되면 즉시 "db"라는 이름을 가진 database와 연동을 시도합니다.
그렇기 때문에 mysql 컨테이너는 생성 즉시 database를 생성해야합니다.
database를 생성한 컨테이너를 image로 build해서 사용하는 방법도 있겠지만
더욱더 쉬운 방법으로 컨피그맵을 사용하면 됩니다.
컨피그맵을 정의해줍니다.
data에 적힌 내용의 의미는
initdb.sql 이라는 파일을 생성하는데
생성하는 내용은
CREATE db;
USE db;
CREATE TABLE table1(name char(20));
위의 명령어를 차례대로 실행한다는 얘기입니다.
저희가 아까 pv와 pvc의 이름을 용도에 맞게 지정을 해주지 못해서
용도에 맞게 pv, pvc 를 이름을 바꿔주었습니다.
PV 이름은 mysql-data-pv-volume 으로 바꿔주었고
폴더 또한 /tmp/mysql 로 바꿔주었습니다.
PVC 이름은 mysql-data-pv-claim 으로 바꿔주었습니다.
제대로 연결이 되었다면 STATUS 필드에 Bound 값이 뜹니다.
컨피그맵을 생성하였으니 거기에 맞게 deployment도 바꿔주어야합니다.
volumes에 configMap을 추가하고 volumeMounts에도 mount를 해줍니다.
kubectl apply -f "적용하고자 하는 yaml 파일"
위 명령어로 configmap과 deployment, volume까지 새로 적용시켜줍니다.
pod가 생성된 node의 위치를 확인합니다.
node3에 생성된 pod의 mysql 컨테이너를 확인을 해봅시다.
node3에 ssh를 이용해서 접속한 다음
mysql -u root -p
명령어로 mysql에 접속합니다 (password는 admin으로 설정해주었습니다.)
show databases;
생성된 database들을 확인해보면 "db"라는 이름의 데이터베이스가 정상적으로 자동생성 된것을 볼 수 있습니다.
"table1" 또한 잘 생성이 되어있는 것을 볼 수 있습니다.
그리고 docker-entrypoint-initdb.d 폴더에 initdb.sql 파일을 확인할 수 있습니다.
17. 현재 파일 구조와 오브젝트들 설명과 목표 짚고 가기.
폴더 구조
kubernetes 폴더
각종 yaml파일들이 들어있는 폴더입니다.
mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
labels:
app: database-deployment
spec:
replicas: 2
selector:
matchLabels:
app: database
template:
metadata:
labels:
app: database
spec:
restartPolicy: Always
containers:
- name: mysql
image: mysql
ports:
- containerPort: 8080
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: admin
volumeMounts:
- mountPath: /mysql-data
name: mysql-data-volume
- mountPath: /docker-entrypoint-initdb.d
name: mysql-init-config
volumes:
- name: mysql-data-volume
persistentVolumeClaim:
claimName: mysql-data-pv-claim
- name: mysql-init-config
configMap:
name: mysql-initdb-config
volumeMounts : 컨테이너 안에서 mount시켜줄 path와 name을 지정
volumes : configmap과 PV, PVC를 연결해주는 곳
volume.yaml
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: mysql-data-pv-volume
labels:
app: mysql
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/tmp/mysql"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-data-pv-claim
labels:
app: mysql
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
hostPath : 같은 노드에서 실행되는 파드끼리 공유할 폴더를 지정해줍니다.
Reclaim Policy
PV는 연결된 PVC가 삭제된 후 다시 다른 PVC에 의해서 재 사용이 가능한데, 재 사용시에 디스크의 내용을 지울지 유지할지에 대한 정책을 Reclaim Policy를 이용하여 설정이 가능하다.
-
Retain : 삭제하지 않고 PV의 내용을 유지한다.
-
Recycle : 재 사용이 가능하며, 재 사용시에는 데이타의 내용을 자동으로 rm -rf 로 삭제한 후 재사용이 된다.
-
Delete : 볼륨의 사용이 끝나면, 해당 볼륨은 삭제 된다. AWS EBS, GCE PD,Azure Disk등이 이에 해당한다.
AccessModeAccessMode는 PV에 대한 동시에 Pod에서 접근할 수 있는 정책을 정의한다.
-
ReadWriteOnce (RWO)해당 PV는 하나의 Pod에만 마운트되고 하나의 Pod에서만 읽고 쓰기가 가능하다.
-
ReadOnlyMany(ROX)여러개의 Pod에 마운트가 가능하며, 여러개의 Pod에서 동시에 읽기가 가능하다. 쓰기는 불가능하다.
-
ReadWriteMany(RWX)여러개의 Pod에 마운트가 가능하고, 동시에 여러개의 Pod에서 읽기와 쓰기가 가능하다.
출처: https://bcho.tistory.com/1259 [조대협의 블로그]
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-initdb-config
data:
initdb.sql: |
CREATE DATABASE db;
USE db;
CREATE TABLE table1(name char(20));
현재 구조
참고
https://tech.osci.kr/2019/04/15/71798599/
https://kubernetes.io/ko/docs/concepts/configuration/configmap/
'Kubernetes & Docker' 카테고리의 다른 글
[Kubernetes 공식문서 파헤치기] Redis를 사용한 PHP 방명록 애플리케이션 배포하기 + PV, PVC, Affinity 사용해보기 (0) | 2020.08.10 |
---|---|
[O'REILLY] 쿠버네티스 패턴 (Kuerbernetes Patterns) (0) | 2020.08.10 |
Kubespray와 Ansible을 이용한 Kubernetes 설치하기 - 3편 (0) | 2020.07.31 |
Kubespray와 Ansible을 이용한 Kubernetes 설치하기 - 2편 (0) | 2020.07.29 |
Kubespray와 Ansible을 이용한 Kubernetes 설치하기 - 1편 (2) | 2020.07.28 |