이 글을 보는 사람은 도커와 쿠버네티스에 대한 기본적인 지식이 있다고 생각할 것입니다.
도커는 알겠는데 쿠버네티스는 처음이라면 아래 동영상을 보고 진행하시기 바랍니다.
https://www.youtube.com/watch?v=s_o8dwzRlu4&ab_channel=TechWorldwithNana
쿠버네티스 컨테이너에 외부에서 접속하는 과정은 일반적으로 다음과 같습니다.
외부 → nginx → minikube → ingress controller → service → pod
각각이 잘 동작하는지 확인하려면 거꾸로 구현해야 합니다.
여기서는 서비스와 파드를 구현해보고 외부에서 접속하는 과정은 ingress 대신 포트포워딩을 이용해 간단히 구현해볼 것입니다.
쿠버네티스에 스프링 프로젝트 배포하기
1. EC2에 Minicube 설치하기
1.1. EC2 생성하기
ARM 버전으로 진행하면 이슈가 많아서 x86으로 진행하는 것을 추천합니다.
인스턴스는 미니큐브 조건 때문에 t2 미디엄을 사용합니다.
프리티어 사용하면 미니큐브 설치 에러가 발생합니다.
SSH로 접속합니다.
프리티어가 아니니까 주의하시기 바랍니다.
1.2. 도커 설치하기
두 단계로 나누어서 설치할 것입니다.
docker info를 입력해서 잘 나오면 설치가 잘 된 것입니다.
1.3. 미니큐브 설치하기
공식 홈페이지에서 환경에 맞춰서 설치할 것입니다.
minikube version을 입력해서 잘 나오면 설치가 잘 된 것입니다.
1.4. kubectl 설치하기
환경에 맞춰서 설치할 것입니다.
kubectl version --short를 입력해서 잘 나오면 설치가 잘 된 것입니다.
2. 샘플 프로젝트 만들기
테스트를 위해서는 Spring과 MySQL을 사용하는 샘플 프로젝트를 만들어야 합니다.
이 부분을 뛰어넘고 싶은 분은 그냥 3번부터 시작하시면 됩니다. 제가 미리 만들어둔 프로젝트를 사용할 것입니다.
참고로 제 프로젝트는 /으로 GET 요청을 받으면 HelloEntity라는 인스턴스를 만들어서 DB에 저장하고 결과를 반환해주는 단순한 것입니다.
3. 샘플 프로젝트 배포하기
3.1. ConfigMap 작성
https://kubernetes.io/docs/concepts/configuration/configmap/
vim config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
data:
# property-like keys; each key maps to a simple value
mysql-url : mysql-service
환경 변수에 세팅해줄 URL 주소를 입력합니다.
아래 커맨드를 입력하고 잘 되면 된 것입니다.
kubectl apply -f config.yaml
kubectl describe configMap mysql-config을 입력하면 들어가 있는 값이 나옵니다.
[ec2-user@ip-172-31-42-29 spring-test]$ kubectl describe configMap mysql-config
Name: mysql-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
mysql-url:
----
mysql-service
BinaryData
====
Events: <none>
3.2. Secret 작성
아이디와 비밀번호 등 민감한 정보는 config에 그대로 노출되면 안 됩니다.
Secret은 암호화된 상태로 저장하기 때문에 털려도 그나마 괜찮습니다.
그러나 설정하지 않으면 기본적으로 암호화 상태로 저장되지 않습니다.
그래서 쿠버네티스에 배포할 수 있는 권한을 가진 사람이 간접적으로 접근 가능합니다.
암호화하려면 따로 설정이 필요합니다.
하지만 우리는 테스트니까 하지 않을 것입니다.
https://kubernetes.io/docs/concepts/configuration/secret/#basic-authentication-secret
echo -n mysql-user | base64 # bXlzcWwtdXNlcg==
stringData 옵션을 사용하면 data 옵션을 대체할 수 있습니다. 하지만 특수문자를 포함한 문자열은 사용할 수 없습니다.
저희는 stringData 옵션을 사용할 예정입니다.
아래 커맨드를 입력하여 mysql-secret.yaml 파일을 적용합니다.
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
type: kubernetes.io/basic-auth
stringData:
password: mysql-password
kubectl describe secret secret-basic-auth 를 입력하면 아래와 같은 결과가 나타납니다.
Name: secret-basic-auth
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/basic-auth
Data
====
password: 14 bytes
3.3 MySQL Deployment & Service 작성하기
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ 에서 예시를 확인할 수 있습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
아래와 같이 수정해봅시다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
labels:
app: mysql
tier: database
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: 'mysql:8.0.26'
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: secret-basic-auth
key: password
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
이후 kubectl apply -f mysql-deployment.yaml 를 입력합니다.
kubectl get all 로 파드, 서비스, 배포 그리고 레플리카셋을 확인할 수 있습니다.
아래와 같이 파드가 잘 동작하면 성공입니다.
NAME READY STATUS RESTARTS AGE
pod/mysql-deploy-847cd594ff-8hkkc 1/1 Running 0 5s
로그를 자세히 확인하려면 아래의 커맨드를 입력합니다.
kubectl logs -f pod/mysql-deploy-847cd594ff-8hkkc
아래와 같은 로그가 나타나면 준비가 완료된 상태입니다.
2023-02-22T04:59:55.553138Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.26' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
배시 쉘에서 직접 접속하려면 아래의 커맨드를 입력합니다.
kubectl exec -it pod/mysql-deploy-847cd594ff-8hkkc bash
패스워드는 아까 시크릿에서 명시한 mysql-password 입니다. exit 두 번 입력하여 콘솔로 나옵니다.
3.4 Spring 배포와 Service 작성하기
MySQL 배포와 형식이 비슷하기 때문에, 일단 아래와 같이 복사합니다.
cp mysql-deployment.yaml spring-deployment.yaml
그리고 수정을 좀 해줄 겁니다. 저희가 만든 테스트 프로젝트는 환경 변수가 3개이고, 사용자는 그냥 root를 넣고, 비밀번호는 시크릿, URL은 config를 참조할 겁니다.
MYSQL_USER
MYSQL_PWD
MYSQL_URL
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-demo-deploy # 이름을 바꿔줍니다.
labels:
app: spring-demo # 레이블을 바꿔줍니다.
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: spring-demo # 당연히 바꿔줍니다.
template:
metadata:
labels:
app: spring-demo # 당연히 바꿔줍니다.
spec:
containers:
- name: spring-demo # 당연히 바꿔줍니다.
image: 'lee01042000/k8s-auto-deployment-test:main-2023-02-21T11-36-33'
ports:
- containerPort: 8080 # Spring은 8080 포트를 사용하므로 바꿔줍니다.
env:
- name: MYSQL_USER
value: root
- name: MYSQL_PWD
valueFrom:
secretKeyRef:
name: secret-basic-auth
key: password
- name: MYSQL_URL
valueFrom:
configMapKeyRef:
name: mysql-config
key: mysql-url
서비스도 추가해 줄 겁니다. 나중에 외부에서 이 파드에 접속하려면 서비스가 있어야 합니다.
apiVersion: v1
kind: Service
metadata:
name: spring-service
spec:
selector:
app: spring-demo
ports:
- protocol: TCP
port: 8080
targetPort: 8080
정갈한 버전은 아래와 같습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-demo-deploy
labels:
app: spring-demo
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: spring-demo
template:
metadata:
labels:
app: spring-demo
spec:
containers:
- name: spring-demo
image: 'lee01042000/k8s-auto-deployment-test:main-2023-02-21T11-36-33'
ports:
- containerPort: 8080
env:
- name: MYSQL_USER
value: root
- name: MYSQL_PWD
valueFrom:
secretKeyRef:
name: secret-basic-auth
key: password
- name: MYSQL_URL
valueFrom:
configMapKeyRef:
name: mysql-config
key: mysql-url
---
apiVersion: v1
kind: Service
metadata:
name: spring-service
spec:
selector:
app: spring-demo
ports:
- protocol: TCP
port: 8080
targetPort: 8080
kubectl get all을 실행해 보세요. 아래와 같이 잘 나오면 성공입니다.
NAME READY STATUS RESTARTS AGE
pod/mysql-deploy-847cd594ff-8hkkc 1/1 Running 0 52m
pod/spring-demo-deploy-c9798b78d-bs5c7 1/1 Running 0 4s
로그를 찍어 보세요.
kubectl logs -f pod/spring-demo-deploy-c9798b78d-bs5c7
로그가 잘 찍히면 실행된 것입니다. 굿굿!
3. 요청해보기
모든 파드와 서비스는 미니큐브 안에 있으므로, 현재는 ec2 로컬에서 요청할 수 없습니다. 스프링 서비스를 미니큐브 바깥으로 연결해야 합니다. 이를 위해서는 로드밸런서나 노드포트를 이용해서 구현할 수 있습니다. 이전에 작성한 서비스를 수정해 봅시다.
apiVersion: v1
kind: Service
metadata:
name: spring-service
spec:
type: NodePort #스펙에 노드포트 추가
selector:
app: spring-demo
ports:
- protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30007 # 미니큐브 바깥으로 연결할 포트번호 미니큐프ip:30007로 서비스에 연결가능
기존 파일을 수정한 코드는 아래와 같습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-demo-deploy
labels:
app: spring-demo
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: spring-demo
template:
metadata:
labels:
app: spring-demo
spec:
containers:
- name: spring-demo
image: 'lee01042000/k8s-auto-deployment-test:main-2023-02-21T11-36-33'
ports:
- containerPort: 8080
env:
- name: MYSQL_USER
value: root
- name: MYSQL_PWD
valueFrom:
secretKeyRef:
name: secret-basic-auth
key: password
- name: MYSQL_URL
valueFrom:
configMapKeyRef:
name: mysql-config
key: mysql-url
---
apiVersion: v1
kind: Service
metadata:
name: spring-service
spec:
type: NodePort
selector:
app: spring-demo
ports:
- protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30007
명령어를 실행한 결과를 확인해 봅시다.
kubectl get svc
위 명령어를 실행한 결과가 아래와 같으면 성공입니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 103m
mysql-service ClusterIP 10.110.69.196 <none> 3306/TCP 7m19s
spring-service NodePort 10.104.52.108 <none> 8080:30007/TCP 5m37s
이제 콘솔에서 minikube ip를 입력하면, 미니큐브에 할당된 로컬 아이피가 나옵니다. curl 192.168.49.2:30007을 입력하면, 아래와 같이 응답을 받을 수 있습니다.
HelloEntity(id=0, name=Hello)
데이터베이스에 데이터가 잘 저장되어 있는지 확인해 봅시다. MySQL에 접속하고 데이터베이스들을 확인합니다.
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| k8s_test |
| mysql |
| performance_schema |
| sys |
+--------------------+
데이터베이스가 생성되어 있습니다. use k8s_test;로 데이터베이스를 선택하고, show tables;로 테이블을 확인합니다.
mysql> show tables;
+--------------------+
| Tables_in_k8s_test |
+--------------------+
| hello_entity |
+--------------------+
1 row in set (0.00 sec)
테이블도 잘 생성되어 있습니다. select * from hello_entity;를 실행하면, 데이터가 잘 저장되어 있는 것을 확인할 수 있습니다.
mysql> select * from hello_entity;
+----+-------+
| id | name |
+----+-------+
| 0 | Hello |
+----+-------+
1 row in set (0.00 sec)
4. 외부와 연결하기
이제 minikube ip 를 외부에서 들어오는 요청과 매핑해야 합니다.
포트포워딩 방법은 여러 가지가 있습니다. kubectl에서는 다음과 같은 명령어를 사용하여 포트포워딩이 가능합니다.
kubectl port-forward --address 0.0.0.0 service/spring-service 8080:8080
위와 같이 포워딩이 수행되면 다음과 같은 메시지가 출력됩니다.
Forwarding from 0.0.0.0:8080 -> 8080
Handling connection for 8080
Handling connection for 8080
이제 웹 페이지에서 EC2 인스턴스로 요청하면 결과를 잘 받을 수 있습니다.
쿠버네틱스 외부 연결
이 글을 보는 사람은 도커와 쿠버네티스에 대한 기본적인 지식이 있다고 생각할 것입니다.
도커는 알겠는데 쿠버네티스는 처음이라면 아래 동영상을 보고 진행하시기 바랍니다.
https://www.youtube.com/watch?v=s_o8dwzRlu4&ab_channel=TechWorldwithNana
쿠버네티스 컨테이너에 외부에서 접속하는 과정은 다음과 같습니다.
외부 → nginx → minikube → ingress controller → service → pod
각각이 잘 동작하는지 확인하려면 거꾸로 구현해야 합니다.
여기서는 서비스와 파드를 구현해 볼 것입니다.
쿠버네티스에 스프링 프로젝트 배포하기
1. EC2에 Minicube 설치하기
1.1. EC2 생성하기
ARM 버전으로 진행하면 이슈가 많아서 x86으로 진행하는 것을 추천합니다.
인스턴스는 미니큐브 조건 때문에 t2 미디엄을 사용합니다.
프리티어 사용하면 미니큐브 설치 에러가 발생합니다.
SSH로 접속합니다.
프리티어가 아니니까 주의하시기 바랍니다.
1.2. 도커 설치하기
두 단계로 나누어서 설치할 것입니다.
docker info를 입력해서 잘 나오면 설치가 잘 된 것입니다.
1.3. 미니큐브 설치하기
공식 홈페이지에서 환경에 맞춰서 설치할 것입니다.
minikube version을 입력해서 잘 나오면 설치가 잘 된 것입니다.
1.4. kubectl 설치하기
환경에 맞춰서 설치할 것입니다.
kubectl version --short를 입력해서 잘 나오면 설치가 잘 된 것입니다.
2. 샘플 프로젝트 만들기
MySQL과 연결되는 샘플 프로젝트를 만들 것입니다.
이 부분을 뛰어넘고 싶은 분은 그냥 3번부터 시작하시면 됩니다. 제가 미리 만들어둔 프로젝트를 사용할 것입니다.
참고로 제 프로젝트는 /으로 GET 요청을 받으면 HelloEntity라는 인스턴스를 만들어서 DB에 저장하고 결과를 반환해주는 단순한 것입니다.
코드 블라블라
3. 샘플 프로젝트 배포하기
3.1. ConfigMap 작성
https://kubernetes.io/docs/concepts/configuration/configmap/
vim config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
data:
# property-like keys; each key maps to a simple value
mysql-url : mysql-service
환경 변수에 세팅해줄 URL 주소를 입력합니다.
아래 커맨드를 입력하고 잘 되면 된 것입니다.
kubectl apply -f config.yaml
kubectl describe configMap mysql-config을 입력하면 들어가 있는 값이 나옵니다.
[ec2-user@ip-172-31-42-29 spring-test]$ kubectl describe configMap mysql-config
Name: mysql-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
mysql-url:
----
mysql-service
BinaryData
====
Events: <none>
3.2. Secret 작성
아이디와 비밀번호 등 민감한 정보는 config에 그대로 노출되면 안 됩니다.
Secret은 암호화된 상태로 저장하기 때문에 털려도 그나마 괜찮습니다.
그러나 설정하지 않으면 암호화 상태로 저장되지 않습니다.
그래서 쿠버네티스에 배포할 수 있는 권한을 가진 사람이 간접적으로 접근 가능합니다.
암호화하려면 따로 설정이 필요합니다.
하지만 우리는 테스트니까 하지 않을 것입니다.
https://kubernetes.io/docs/concepts/configuration/secret/#basic-authentication-secret
echo -n mysql-user | base64 # bXlzcWwtdXNlcg==
stringData 옵션을 사용하면 data 옵션을 대체할 수 있습니다. 하지만 특수문자를 포함한 문자열은 사용할 수 없습니다.
저희는 stringData 옵션을 사용할 예정입니다.
아래 커맨드를 입력하여 mysql-secret.yaml 파일을 적용합니다.
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
type: kubernetes.io/basic-auth
stringData:
password: mysql-password
kubectl describe secret secret-basic-auth 를 입력하면 아래와 같은 결과가 나타납니다.
Name: secret-basic-auth
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/basic-auth
Data
====
password: 14 bytes
3.3 MySQL Deployment & Service 작성하기
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ 에서 예시를 확인할 수 있습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
아래와 같이 수정해봅시다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
labels:
app: mysql
tier: database
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: 'mysql:8.0.26'
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: secret-basic-auth
key: password
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
이후 kubectl apply -f mysql-deployment.yaml 를 입력합니다.
kubectl get all 로 파드, 서비스, 배포 그리고 레플리카셋을 확인할 수 있습니다.
아래와 같이 파드가 잘 동작하면 성공입니다.
NAME READY STATUS RESTARTS AGE
pod/mysql-deploy-847cd594ff-8hkkc 1/1 Running 0 5s
로그를 자세히 확인하려면 아래의 커맨드를 입력합니다.
kubectl logs -f pod/mysql-deploy-847cd594ff-8hkkc
아래와 같은 로그가 나타나면 준비가 완료된 상태입니다.
2023-02-22T04:59:55.553138Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.26' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
배시 쉘에서 직접 접속하려면 아래의 커맨드를 입력합니다.
kubectl exec -it pod/mysql-deploy-847cd594ff-8hkkc bash
패스워드는 아까 시크릿에서 명시한 mysql-password 입니다. exit 두 번 입력하여 콘솔로 나옵니다.
3.4 Spring 배포와 Service 작성하기
MySQL 배포와 형식이 비슷하기 때문에, 일단 아래와 같이 복사합니다.
cp mysql-deployment.yaml spring-deployment.yaml
그리고 수정을 좀 해줄 겁니다. 저희가 만든 테스트 프로젝트는 환경 변수가 3개이고, 사용자는 그냥 root를 넣고, 비밀번호는 시크릿, URL은 config를 참조할 겁니다.
MYSQL_USER
MYSQL_PWD
MYSQL_URL
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-demo-deploy # 이름을 바꿔줍니다.
labels:
app: spring-demo # 레이블을 바꿔줍니다.
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: spring-demo # 당연히 바꿔줍니다.
template:
metadata:
labels:
app: spring-demo # 당연히 바꿔줍니다.
spec:
containers:
- name: spring-demo # 당연히 바꿔줍니다.
image: 'lee01042000/k8s-auto-deployment-test:main-2023-02-21T11-36-33'
ports:
- containerPort: 8080 # Spring은 8080 포트를 사용하므로 바꿔줍니다.
env:
- name: MYSQL_USER
value: root
- name: MYSQL_PWD
valueFrom:
secretKeyRef:
name: secret-basic-auth
key: password
- name: MYSQL_URL
valueFrom:
configMapKeyRef:
name: mysql-config
key: mysql-url
서비스도 추가해 줄 겁니다. 나중에 외부에서 이 파드에 접속하려면 서비스가 있어야 합니다.
apiVersion: v1
kind: Service
metadata:
name: spring-service
spec:
selector:
app: spring-demo
ports:
- protocol: TCP
port: 8080
targetPort: 8080
정갈한 버전은 아래와 같습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-demo-deploy
labels:
app: spring-demo
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: spring-demo
template:
metadata:
labels:
app: spring-demo
spec:
containers:
- name: spring-demo
image: 'lee01042000/k8s-auto-deployment-test:main-2023-02-21T11-36-33'
ports:
- containerPort: 8080
env:
- name: MYSQL_USER
value: root
- name: MYSQL_PWD
valueFrom:
secretKeyRef:
name: secret-basic-auth
key: password
- name: MYSQL_URL
valueFrom:
configMapKeyRef:
name: mysql-config
key: mysql-url
---
apiVersion: v1
kind: Service
metadata:
name: spring-service
spec:
selector:
app: spring-demo
ports:
- protocol: TCP
port: 8080
targetPort: 8080
kubectl get all을 실행해 보세요. 아래와 같이 잘 나오면 성공입니다.
NAME READY STATUS RESTARTS AGE
pod/mysql-deploy-847cd594ff-8hkkc 1/1 Running 0 52m
pod/spring-demo-deploy-c9798b78d-bs5c7 1/1 Running 0 4s
로그를 찍어 보세요.
kubectl logs -f pod/spring-demo-deploy-c9798b78d-bs5c7
로그가 잘 찍히면 실행된 것입니다. 굿굿!
3. 요청해보기
모든 파드와 서비스는 미니큐브 안에 있으므로, 현재는 ec2 로컬에서 요청할 수 없습니다. 스프링 서비스를 미니큐브 바깥으로 연결해야 합니다. 이를 위해서는 로드밸런서나 노드포트를 이용해서 구현할 수 있습니다. 이전에 작성한 서비스를 수정해 봅시다.
apiVersion: v1
kind: Service
metadata:
name: spring-service
spec:
type: NodePort #스펙에 노드포트 추가
selector:
app: spring-demo
ports:
- protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30007 # 미니큐브 바깥으로 연결할 포트번호 미니큐프ip:30007로 서비스에 연결가능
기존 파일을 수정한 코드는 아래와 같습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-demo-deploy
labels:
app: spring-demo
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: spring-demo
template:
metadata:
labels:
app: spring-demo
spec:
containers:
- name: spring-demo
image: 'lee01042000/k8s-auto-deployment-test:main-2023-02-21T11-36-33'
ports:
- containerPort: 8080
env:
- name: MYSQL_USER
value: root
- name: MYSQL_PWD
valueFrom:
secretKeyRef:
name: secret-basic-auth
key: password
- name: MYSQL_URL
valueFrom:
configMapKeyRef:
name: mysql-config
key: mysql-url
---
apiVersion: v1
kind: Service
metadata:
name: spring-service
spec:
type: NodePort
selector:
app: spring-demo
ports:
- protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30007
명령어를 실행한 결과를 확인해 봅시다.
kubectl get svc
위 명령어를 실행한 결과가 아래와 같으면 성공입니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 103m
mysql-service ClusterIP 10.110.69.196 <none> 3306/TCP 7m19s
spring-service NodePort 10.104.52.108 <none> 8080:30007/TCP 5m37s
이제 콘솔에서 minikube ip를 입력하면, 미니큐브에 할당된 로컬 아이피가 나옵니다. curl 192.168.49.2:30007을 입력하면, 아래와 같이 응답을 받을 수 있습니다.
HelloEntity(id=0, name=Hello)
데이터베이스에 데이터가 잘 저장되어 있는지 확인해 봅시다. MySQL에 접속하고 데이터베이스들을 확인합니다.
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| k8s_test |
| mysql |
| performance_schema |
| sys |
+--------------------+
데이터베이스가 생성되어 있습니다. use k8s_test;로 데이터베이스를 선택하고, show tables;로 테이블을 확인합니다.
mysql> show tables;
+--------------------+
| Tables_in_k8s_test |
+--------------------+
| hello_entity |
+--------------------+
1 row in set (0.00 sec)
테이블도 잘 생성되어 있습니다. select * from hello_entity;를 실행하면, 데이터가 잘 저장되어 있는 것을 확인할 수 있습니다.
mysql> select * from hello_entity;
+----+-------+
| id | name |
+----+-------+
| 0 | Hello |
+----+-------+
1 row in set (0.00 sec)
4. 외부와 연결하기
이제 minikube ip 를 외부에서 들어오는 요청과 매핑해야 합니다.
포트포워딩 방법은 여러 가지가 있습니다. kubectl에서는 다음과 같은 명령어를 사용하여 포트포워딩이 가능합니다.
kubectl port-forward --address 0.0.0.0 service/spring-service 8080:8080
위와 같이 포워딩이 수행되면 다음과 같은 메시지가 출력됩니다.
Forwarding from 0.0.0.0:8080 -> 8080
Handling connection for 8080
Handling connection for 8080
이제 웹 페이지에서 EC2 인스턴스로 요청하면 결과를 잘 받을 수 있습니다.