Minikube 란 ?
Kubernetes는 크게 Master Node와 Worker Node 여러 개로 구성되어 있다.
이때, 여기서 말하는 Node들은 하나의 물리 서버 혹은 VM이다.
Minikube 는 이러한 물리 서버 혹은 VM 을 구축할 필요 없이 단일 노드에서 쿠버네티스 환경을 구성해주는 툴이다.
지금부터 로컬 환경에서 minikube 를 통해 쿠버네티스 클러스터를 생성하고 TODO 애플리케이션을 구축해볼 것이다.
Minikube 설치
https://kubernetes.io/ko/docs/tasks/tools/install-minikube/
클러스터 생성
다음 명령어로 간단히 생성 가능하다.
minikube start
이전에 실행한 적이 있다면, 다음과 같은 에러가 뜰 것이다.
machine does not exist
다음 명령어를 통해 구성을 삭제한 후 다시 생성해준다.
minikube delete
DB 설정
minikube 클러스터를 생성하면 standard 라는 이름의 기본 storageClass 가 생성되어 있다.
기본 storageClass 를 사용하지 말아야 하는 특별한 경우가 아니라면 해당 storageClass 를 사용하면 된다.
*만약 직접 정의한 storageClass 를 사용하고 싶다면, 다음 링크 참고
기본 storageClass 및 생성한 storgaClass 는 다음 명령어로 조회할 수 있다.
kubectl get storageclass
DB 서비스 (master, slave) 실행
데이터를 지속적으로 유지하기 위해 statefulSet 를 사용한다.
kubectl apply -f mysql-master.yaml kubectl apply -f mysql-slave.yaml
apiVersion: v1 kind: Service metadata: name: mysql-master labels: app: mysql-master spec: ports: - port: 3306 name: mysql clusterIP: None selector: app: mysql-master --- apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql-master labels: app: mysql-master spec: serviceName: "mysql-master" selector: matchLabels: app: mysql-master replicas: 1 template: metadata: labels: app: mysql-master spec: terminationGracePeriodSeconds: 60 containers: - name: mysql image: gihyodocker/tododb:latest imagePullPolicy: Always args: - "--ignore-db-dir=lost+found" ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "gihyo" - name: MYSQL_DATABASE value: "tododb" - name: MYSQL_USER value: "gihyo" - name: MYSQL_PASSWORD value: "gihyo" - name: MYSQL_MASTER value: "true" volumeMounts: - name: mysql-data mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: standard # minikube 의 기본 storageClass 를 사용한다 resources: requests: storage: 4Gi
apiVersion: v1 kind: Service metadata: name: mysql-slave labels: app: mysql-slave spec: ports: - port: 3306 name: mysql clusterIP: None selector: app: mysql-slave --- apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql-slave labels: app: mysql-slave spec: serviceName: "mysql-slave" selector: matchLabels: app: mysql-slave replicas: 2 updateStrategy: type: OnDelete template: metadata: labels: app: mysql-slave spec: terminationGracePeriodSeconds: 60 containers: - name: mysql image: gihyodocker/tododb:latest imagePullPolicy: Always args: - "--ignore-db-dir=lost+found" ports: - containerPort: 3306 env: - name: MYSQL_MASTER_HOST value: "mysql-master" - name: MYSQL_ROOT_PASSWORD value: "gihyo" - name: MYSQL_DATABASE value: "tododb" - name: MYSQL_USER value: "gihyo" - name: MYSQL_PASSWORD value: "gihyo" - name: MYSQL_REPL_USER value: "repl" - name: MYSQL_REPL_PASSWORD value: "gihyo" volumeMounts: - name: mysql-data mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: standard resources: requests: storage: 4Gi
기본 테이블 생성 및 확인
생성한 DB master 서비스에 테이블을 생성해보고, slave 에서 조회하여 master-slave 구성이 제대로 되었는지 확인한다.
kubectl exec -it mysql-master-0 init-data.sh kubectl exec -it mysql-slave-0 bash mysql -u root -pgihyo tododb -e "SHOW TABLES;"
#!/bin/bash -e for SQL in `ls /sql/*.sql` do mysql -u root -p$MYSQL_ROOT_PASSWORD $MYSQL_DATABASE < $SQL > /dev/null 2>&1 done
TODO API
kubectl apply -f todo-api.yaml
apiVersion: v1 kind: Service metadata: name: todoapi labels: app: todoapi spec: selector: app: todoapi ports: - name: http port: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: todoapi labels: app: todoapi spec: replicas: 2 selector: matchLabels: app: todoapi template: metadata: labels: app: todoapi spec: containers: - name: nginx image: gihyodocker/nginx:latest imagePullPolicy: Always ports: - containerPort: 80 env: - name: WORKER_PROCESSES value: "2" - name: WORKER_CONNECTIONS value: "1024" - name: LOG_STDOUT value: "true" - name: BACKEND_HOST value: "localhost:8080" - name: api image: gihyodocker/todoapi:latest imagePullPolicy: Always ports: - containerPort: 8080 env: - name: TODO_BIND value: ":8080" - name: TODO_MASTER_URL value: "gihyo:gihyo@tcp(mysql-master:3306)/tododb?parseTime=true" - name: TODO_SLAVE_URL value: "gihyo:gihyo@tcp(mysql-slave:3306)/tododb?parseTime=true"
확인
kubectl get pod -l app=todoapi
TODO WEB
kubectl apply -f todo-web.yaml
apiVersion: v1 kind: Service metadata: name: todoweb labels: app: todoweb spec: selector: app: todoweb ports: - name: http port: 80 type: NodePort --- apiVersion: apps/v1 kind: Deployment metadata: name: todoweb labels: name: todoweb spec: replicas: 2 selector: matchLabels: app: todoweb template: metadata: labels: app: todoweb spec: volumes: - name: assets emptyDir: {} containers: - name: nginx image: gihyodocker/nginx-nuxt:latest imagePullPolicy: Always ports: - containerPort: 80 env: - name: WORKER_PROCESSES value: "2" - name: WORKER_CONNECTIONS value: "1024" - name: LOG_STDOUT value: "true" - name: BACKEND_HOST value: "localhost:3000" volumeMounts: # 정적 파일은 Node.jst 서버를 거치지 않고 Nginx 에서 바로 제공할 수 있도록 가상 볼륨 공유 - mountPath: /var/www/_nuxt name: assets - name: web image: gihyodocker/todoweb:latest imagePullPolicy: Always lifecycle: postStart: exec: # 마운트 된 경로에 있는 파일을 복사해준다 command: - cp - -R - /todoweb/.nuxt/dist - / ports: - containerPort: 3000 env: - name: TODO_API_URL value: http://todoapi volumeMounts: # 정적 파일은 Node.jst 서버를 거치지 않고 Nginx 에서 바로 제공할 수 있도록 가상 볼륨 공유 - mountPath: /dist name: assets
INGRESS 로 노출하기
minikube 에서 ingress 를 사용하기 위해서는 다음 명령어를 통해 ingress 를 활성화 해주어야 한다.
minikube addons enable ingress
확인
kubectl get pods -n kube-system
kubectl apply -f ingress.yaml
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress spec: rules: - http: paths: - path: /* backend: serviceName: todoweb servicePort: 80
아래 명령어를 통해 얻은 url 로 접속 가능하다.
minikube service todoweb --url
*minikube 사용 시, kubectl get ingress
를 통해 얻는 주소는 internal IP 주소이다. minikube ip
를 통해 external IP 주소를 얻을 수 있다.
https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/
해당 url 로 접속해보면 다음과 같은 화면을 볼 수 있다.