이 글을 작성한 시점의 저는 아직 k8s에 대해 깊게 알지 못합니다,
Backend 부분에 비해 틀린점이 있을 수 있습니다
또, 위 그림은 실제 진행한 설계의 일부분입니다.
특히 StatefulSet과 DB의 관계가 적절한지 아직 확실히 검증되지 않았습니다(구상하다보니 애틋해져서 넣었습니다)
이 글을 보고 클론 코딩을 하며 배우겠다는 느낌보다는, (아마 그렇게 할 수 없을거에요...)
이런 기능이 있고 어떤 식으로 구성되어있구나란 것을 개략적으로 같이 느끼셨으면 좋겠습니다 :)
k8s는 과제를 준비하면서 급하게 공부하게 되었는데,
아주 좋은 기술이라 느껴졌다 (구글이 그 동안의 노하우를 담아서 만들었다는게 잘 느껴졌다)
쿠버를 사용하면 인프라 구성도를 코드로 쉽게 관리할 수 있다는 장점이 있다
또 코드(yaml)로 되어있어 재사용 가능하고 노하우를 쌓으면서 발전시킬 수 있다
Just 1 WAS
가장 간단한 경우부터 시작을 해 보면
Namespace는 작업을 할 수 있는 공간이다
이 공간에 Pod란 것을 배치할 수 있는데, 쿠버에서 관리하는 최소 단위이다
마치 도커의 컨테이너와 같다
컨테이너 내부에 여러 앱을 넣을 수 있듯이,
쿠버 또한 Pod내에 여러 컨테이너를 넣을 수 있다
도커와 마찬가지로 이 Pod는 단독으로 외부와 통신할 수 없는데,
쿠버에서는 서비스라는 객체로 외부와 통신을 중계한다 (우선은 포트포워딩이라고 봐도 된다)
이 서비스의 타입을 NodePort타입으로 만들어야 하는데... 이 부분은 넘어가도록 하자
(궁금하시다면)
서비스에는 크게 ClientIp, NodePort, LoadBalancer가 있는데
기본 값은 ClientIp로, 쿠버 클러스터 내부에서만 사용한다
NodePort는 클러스터 외부에서 접근할 수 있고 주로 내부망에서 개발 환경등에 사용한다
여기서의 Node의 뜻은 클러스터 노드의 노드이다
즉 노드의 포트
LoadBalancer는 운영환경에서 정식으로 배포를 할 때 사용하는 타입이다
쿠버를 배포한 환경인 클라우드 공급사에서 지원이 되어야 한다
아래의 yaml 명세를 통해서 배포를 하면되는데,
네임스페이스
apiVersion: v1
kind: Namespace
metadata:
name: ns-sample
파드
apiVersion: v1
kind: Pod
metadata:
name: pod-was
namespace: ns-sample
labels:
pod-type: was
spec:
containers:
- name: container
image: progress0407/app
ports:
- containerPort: 8000
서비스
apiVersion: v1
kind: Service
metadata:
name: svc-nodeport
namespace: ns-sample
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30000
selector:
pod-type: was
배포 방법은
kubectl apply -f {파일 이름}
을 적용하면 할 수있다
혹은 미니쿠버를 사용한다면 아래와 같다
minikube kubectl apply -f {파일 이름}
그리고
확인은 아래처럼 각각의 오브젝트를 조회하거나
(오브젝트는 pod, service, namespace와 같은 것이다)
kubectl get pod
아니면 대시보드에서 볼 수 있다 (대시보드 접근 법은 생략한다... ㅠ)
1 WAS 1 DB
이제 DB를 추가해보자
apiVersion: v1
kind: Pod
metadata:
name: pod-db
namespace: ns-sample
spec:
selector:
matchLabels:
pod-type: db
containers:
- name: container
image: mysql:8.0.3
ports:
- containerPort: 3306
단, 여기서 우리는 추가만 하지 말고 Headless Service란 걸 넣도록 하자
어렵게 보일 수 있는데, 이해하기 쉽게 설명해보면...
쿠버네티스에서 파드(Pod)는 본디 어느때든 문제가 생길 수 있다는 것을 가정하고 설계되었다
문제는 문제가 생긴 이 파드가 재기동되면 IP가 변경된다
만일 그 파드가 DB라면, 이 DB를 참조하는 WAS는 장애가 난다
이를 해결하는 방법 중 하나가 Headless Service이다
IP가 아니라 파드를 label(라벨)로 간접적으로 식별하기 때문에 DNS처럼 타겟 파드에 라벨로 접근할 수 있다
즉, 느슨히 결합할 수 있게 도와준다
헤드리스 서비스
apiVersion: v1
kind: Service
metadata:
name: svc-db-router
namespace: ns-sample
spec:
clusterIP: None
selector:
pod-type: db
ports:
- protocol: TCP
port: 3306
targetPort: 3306
위 속성에서 selector.pod-type과 DB 파드의 matchesLabels의 라벨이 매칭이 되면,
해당 서비스는 파드의 위치를 중계한다
이때 WAS는 이 헤드리스 서비스를 바라보게 하면 된다
apiVersion: v1
kind: Pod
metadata:
name: pod-was
namespace: ns-sample
spec:
selector:
matchLabels:
pod-type: was
containers:
- name: container
image: progress0407/app
ports:
- containerPort: 8080
env:
- name: SPRING_DATASOURCE_URL
value: 'jdbc:mysql://svc-db-router:3306/sample_app?useSSL=false&allowPublicKeyRetrieval=true'
- name: SPRING_DATASOURCE_USERNAME
value: root
- name: SPRING_DATASOURCE_PASSWORD
value: 1234
이때 `SPRING_DATASOURCE_URL`값에 `svc-db-router`가 헤드리스 서비스를 가리키면 된다!
그리고 해당 부분은 스프링의 yaml처럼 config과 secret 으로 뺄 수 있다 (생략)
또한 DB의 경우 영구 저장이 되어야 하는데,
이 부분 또한 도커의 볼륨처럼 마운트 설정을 할 수 있다
다만 쿠버의 경우 이 볼륨이 PVC와 PV 두 부분으로 나뉜다
PV가 실제로 물리적인 볼륨을 설정하는 부분이고
PVC는 PV를 가리키는데, 인터페이스와 구현체의 관계라고 보면 된다 (이런 예시를 본 적은 없는데 현재로써는 이렇게 해석해도 오해의 소지가 없는 걸로 보인다)
2 WAS 1 DB, Rolling Deploy + Auto Scailing
WAS의 경우 배포를 할 때
쿠버의 롤링 배포로 쉽게 무중단 배포를 구현할 수 있다
아래에서 롤링 배포을 참고하면 된다!
다음은 HPA를 추가해보자
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: hpa-was
namespace: ns-sample
spec:
maxReplicas: 6
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: deploy-was
namespace: ns-sample
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
위와 같이 설정하면 처음에는 2개의 pod로 시작해서 부하 정도에 따라 따라 6개까지 늘어난다
위에서 설정한 부하의 기준은 평균CPU 사용량이다 (보통의 경우 해당 설정으로 한다고 한다)
현재 pod들의 평균 CPU가 50%를 기준으로 동작한다
늘어나는 pod의 갯수는 현재 pod 갯수 * (평균 CPU / HPA의 기준 CPU ) 이다
예를들어
2개의 pod의 평균 CPU가 75%일 경우 3개로 늘어난다 // 2개 * (75% / 50%)
만일 Deployment의 replicas 갯수가 HPA의 min 갯수와 다를 경우 HPA의 설정이 덮어쓴다고 한다
작성 후기
사실 이 지식은 이미 1월 중순에 습득을 했고 2월 5일에 거의 작성을 다했었다
근데 일들이 겹쳐서 끝끝내 퍼블리시는 현재한다 ㅠ
PVC, PV 설명은 다소 아쉬운 점이 많은 것 같다...
이 글은 이쯤에서 마무리한다 ㅎㅎ,,
'Infra, DevOps > Kubernetes, Docker' 카테고리의 다른 글
[k8s] 쿠버로 무중단 배포 3종 모두 해보자 (argo없는 Blue Green) (0) | 2024.01.30 |
---|---|
[배포 기록] 도커 역사 및 빠른 재정리 (feat. 삽질 ..) (0) | 2024.01.20 |
따끈따끈 쿠버네티스 기초 개념 요약 (0) | 2024.01.17 |
윈도우에서 쿠버네티스 긴급 사용 후기 (2) | 2024.01.16 |
순전히 GPT의 도움으로 Docker기반 MySQL 셋업하기 (0) | 2023.07.08 |
hi hello... World >< 가장 아름다운 하나의 해답이 존재한다
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!