훈훈훈
Kubernetes :: 로컬 환경에서 웹 서버 구축하기 본문
이번에는 쿠버네티스를 사용해서 웹 서버를 구축하려고 한다.
사실 AWS와 같은 클라우드 벤더사를 사용할 경우 로컬 내에서 웹 서버랑 데이터 베이스 서버를 동시에 실행 시킬 일은 없지만,
쿠버네티스에 대한 개념도 잡을 겸 해보았다.
예제로 사용한 웹 서버는 이전 글에서 Spring boot와 코틀린으로 작성한 코드를 사용하였다.
사용한 기술은 아래와 같다.
- Spring boot
- Postgresql
- Docker
- Kubernetes
- Helm
구성도는 아래와 같다.
웹 서버(Spring boot)와 DB서버(Postgresql) 컨테이너를 각각 파드로 나누었다.
그 다음 서비스도 서로 다른 포트로 통신하기 때문에 서로 다른 서비스로 나누었다.
Service까지 설정이 되면 이제 파드에 접근할 수 있게 웹 서버 파드를 가지고 있는 서비스로 포트 포워딩 설정만 해주면 끝난다.
여담이지만, 실제 서버를 운영할 때 DB서버를 파드로 배포할 일은 흔치 않다.
왜냐하면 DB서버는 절대로 중단되서는 안되는 서버이기 때문이다.
AWS 운영 시 디비 서버는 RDS를 사용하고 그 외 서버들은 EKS와 같은 서비스로 운영하는게 좋다.
이제 각각의 코드들을 살펴보자.
프로젝트 구성
프로젝트 구성은 위와 같으며 kubernetes 관련 파일들은 devops 하위 디렉터리에 생성하였고, Helm으로 관리하였다.
Helm Create로 만든 파일 중 사용하지 않은 파일들은 모두 삭제했다,
DockerFile
FROM java:8
EXPOSE 8080
ARG JAR_FILE=build/libs/rest-exam-0.0.1.jar
ADD ${JAR_FILE} rest-exam.jar
ENTRYPOINT ["java","-jar", "/rest-exam.jar"]
- 도커 파일 빌드 및 레포지토리 푸쉬
아래 명령어는 본인 환경에 맞게 수정해서 사용하면 된다.
❯ docker build -t kk03187693/rest-exam:0.6 .
❯ docker push kk03187693/rest-exam:0.6
위 명령어를 사용하고 도커 허브로 들어가면 아래와 같이 푸쉬가 정상적으로 된 것을 볼 수 있다.
deployment-postgresql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-server-deployment
labels:
app: postgres-server
spec:
replicas: 1
selector:
matchLabels:
app: postgres-server
template:
metadata:
labels:
app: postgres-server
spec:
containers:
- name: postgresql
image: postgres
ports:
- containerPort: 5432
env:
- name: POSTGRES_USER
value: kwanghoon.kim
- name: POSTGRES_DB
value: springexam
- name: POSTGRES_PASSWORD
value: password
테스트용으로 작성한 코드이기 때문에 replicas 는 1로 설정하였다.
containers 설정을 살펴보면 container port는 postgresql 디폴트 포트로 잡았고 env 설정은 application.yaml 설정과 동일하게 했다.
deployment-server.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-server-deployment
labels:
app: spring-server
spec:
replicas: 1
selector:
matchLabels:
app: spring-server
template:
metadata:
labels:
app: spring-server
spec:
restartPolicy: Always
containers:
- name: spring
image: kk03187693/rest-exam:0.6
imagePullPolicy: Always
ports:
- containerPort: 8080
서버 파일도 위에서 작성한 postgresql 파일과 거의 동일하게 작성하였다.
service-postgres.yaml
apiVersion: v1
kind: Service
metadata:
name: postgres-server-service
spec:
clusterIP: None
ports:
- port: 8080
targetPort: 5432
protocol: TCP
name: db-port
selector:
app: postgres-server
service-postgresql 파일은 위에서 작성한 deployment-postgresql 에서 설정한 label 을 selector로 설정하였다.
그리고 외부에서 로드 밸런싱을 할 필요가 없고 내부 Cluster IP도 필요하지 않아 headless service로 작성하였다.
포트는 web-server port는 8080 이고 DB port는 5432이기 때문에 위와 같이 작성하였다.
service-server.yaml
apiVersion: v1
kind: Service
metadata:
name: spring-server-service
spec:
clusterIP: None
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: server-port
selector:
app: spring-server
서버 파일도 위에서 작성한 postgresql 파일과 거의 동일하게 작성하였다.
application.yaml
spring:
datasource:
url: jdbc:postgresql://postgres-server-service.default.svc.cluster.local:5432/springexam
username: kwanghoon.kim
password: password
driverClassName: org.postgresql.Driver
마지막으로 application.yaml에서 DB 서버에 관한 설정을 하였다.
쿠버네티스에서 파드는 영속적인 객체가 아니기 때문에 재시작 하는 경우가 생기는데 이때 IP가 바뀌게 된다.
이에 대한 해결책은 쿠버네티스에서 제공하는 DNS를 사용하여 URL을 만들었다.
파일이 세팅이 되었다면 이제 아래 명령어로 실행시켜 보자
helm install product-api .
이제 생성된 svc, deployment, pod를 조회해보자
❯ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 none 443/TCP 19m
postgres-server-service ClusterIP None none 8080/TCP 18m
spring-server-service ClusterIP None none 8080/TCP 18m
❯ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
postgres-server-deployment 1/1 1 1 19m
spring-server-deployment 1/1 1 1 19m
❯ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
postgres-server-deployment-6887b5cdcb-r9ff4 1/1 Running 0 19m 10.1.1.50 docker-desktop <none> <none>
spring-server-deployment-5fcc9df984-4svf6 1/1 Running 0 19m 10.1.1.51 docker-desktop <none> <none>
웹 서버가 정상적으로 실행되었는데 웹 서버 컨테이너를 담고 있는 파드 로그를 조회해보았다.
❯ kubectl logs -f [PodName]
아래와 같이 정상적으로 실행된 것을 확인할 수 있다.
그 다음 DB가 정상적으로 생성되었는지 확인해보자.
❯ kubectl exec -it [PodName] bash
아래와 같이 정상적으로 생성된 것을 알 수 있다.
마지막으로 파드 끼리는 통신할 수 있지만 파드로 접근하기 위해서는 별로 설정이 필요하기 때문에
127.0.0.1:8080으로 접근할때 웹 서버 파드를 가지고 있는 서비스로 포트 포워딩 설정을 해주었다,
❯ kubectl port-forward [ServieName] 8080 8080
실행 결과는 아래와 같다.
- post 요청
- get 요청
'인프라 > Kubernetes' 카테고리의 다른 글
Kubernetes :: 외부 클라이언트 노출을 위한 Service 타입 정리 (0) | 2020.09.15 |
---|---|
Kubernetes :: Iiveness probe 정리 (0) | 2020.09.06 |
Kubernetes :: HPA(Horizontal Pod Autoscaler) 정리 (0) | 2020.08.23 |