* 본 게시물은 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2 강의와 강의 자료를 바탕으로 작성되었습니다.
강의 내용
- PVC/PV의 필요성
- Pod의 업데이트 동작 (Rolling Update, Recreate 등)
- Service가 제공하는 기능 (Publishing, Discovery, Registry, LoadBalancing)
- HPA 설정에 따른 Pod 증감
PVC/PV

PVC
- 속성
- resource (필수)
- accessModes (필수)
PV
- 속성
- capacity (필수)
- accessModes (필수)
- local
- path: Node의 Path
- nodeAffinity: 어느 Node에 Pod를 생성할 지 정의
* PVC의 selector와 PV의 labels를 통해 연결되지만, 위의 속성 값이 다르면 연결되지 않음
* PVC/PV를 사용하는 방법도 있지만, Deployment의 hostPath 속성을 이용하여 Node의 Volume과 연결할 수 있음
+ nodeSelector를 이용해 어떤 Node와 연결될 지 정의
Deployment
- strategy:
- type: 어떤 방식으로 업데이트 할 지 선택
- RollingUpdate:
- maxUnavailable: 업데이트 동안 유지할 서비스 상태를 정의
- maxSurge: 새로운 Pod를 한 번에 몇 개를 만들지 정의
- RollingUpdate:
- type: 어떤 방식으로 업데이트 할 지 선택
- template: Pod에 대한 내용을 정의한 속성으로, 이 속성 아래에 내용이 하나라도 수정되면 업데이트를 유발
업데이트 동작
- 업데이트 시, 새로운 ReplicaSet을 만들어 그에 대한 Pod도 새로 생성된다. 기존의 ReplicaSet의 replicas 속성 값은 0으로 바꾸고 Roll Back을 위해 남겨둔다.
- Recreate
- 기존 Pod를 모두 삭제하고 동시에 새로운 파드를 모두 동시에 생성
- App마다 기동 시간이 다르기 때문에 그 시간만큼 서비스가 중단
- Rolling Update
- maxSurge 속성에 정의된 값에 따라 새로운 Pod를 먼저 생성한다.
- 새로운 Pod의 기동이 완료되면 maxUnavailalbe에 따라 기존의 Pod를 삭제시켜 그 비율을 유지
- 덕분에 업데이트 중 서비스 중단이 발생하지 않지만, 다른 버전의 Pod가 동시에 실행되기 때문에 그 만큼 자원이 증가하고 두 가지 버전이 동시에 호출될 수 있다.
- 두 버전이 동시에 호출되는 문제에 대한 대안으로 Blue/Green 배포를 사용하는 방법이 있지만, 자원 사용량이 200% 증가하게 된다.

Service
- Service의 selector와 Pod의 labels가 연결되어 사용
Publishing (외부에서 Pod로 접근할 수 있도록 만드는 작업)

- 속성
- type: NodePort (Default: ClusterIP)
Node의 Port와 연결되어 외부 트래픽을 받을 수 있게 됨- ClusterIP는 k8s 내부 Pod에서만 접근하는 용도로 사용
- ports:
- protocol
- targetPort: Container의 Port를 가리킴
- port: 80
k8s 내부 통신을 위한 port - nodePort: 여기에 정의된 값으로 외부 Port가 만들어짐
- type: NodePort (Default: ClusterIP)
Discovery (내부 통신을 가능하도록 만드는 작업)
- 내부 DNS를 이용하여 Object의 name으로 API를 호출
- 위의 과정에서 port 속성을 80으로 정의한 덕분에, k8s 내부에서 특별한 포트 입력없이 내부 DNS 서버에 등록된 Object의 name만으로 통신이 가능해짐 (http://{object_name}.{namespace}/)
* 같은 namespace일 경우, namespace는 생략 가능 - 각 Pod와 Service는 생성 시 IP가 할당되지만, 사용자가 외우기 힘들 뿐더러 재생성되면 IP가 바뀌므로 DNS를 이용하여 통신
- 위의 과정에서 port 속성을 80으로 정의한 덕분에, k8s 내부에서 특별한 포트 입력없이 내부 DNS 서버에 등록된 Object의 name만으로 통신이 가능해짐 (http://{object_name}.{namespace}/)
Registry (Pod의 IP를 자동으로 관리해주는 작업)

- Pod에 Service를 연결해놓기만 하는 것으로, k8s는 알아서 제거된 Pod는 Service에서 해당 IP를 제거하고
- 새로 만들어진 Pod의 IP를 Service에 등록하는 작업을 수행
LoadBalancing
- Service로 들어온 트래픽을 자동으로 각 Pod에 분산해주는 역할을 수행
[미션 4]
1. PV, PVC
▶ 1~4. local 동작 확인
(API를 통해 파일을 생성한 후)

각 경로에 파일이 정상적으로 생성된 것을 확인
(기존의 Pod를 삭제하고)

`/usr/src/myapp/files/dev` 디렉터리는 Volume을 Mount 시켰기 때문에 Pod가 종료되어도 파일이 유지되지만,
`/usr/src/myapp/tmp` 디렉터리는 Container에서만 유지되는 파일 경로로 Pod 제거 시, Container도 종료되어 파일이 삭제
▶ 5. hostPath 동작 확인 - Deployment 수정 후 [1~4] 실행
# PVC/PC와 연결을 끊고 hostPath를 사용
volumes:
- name: files
# persistentVolumeClaim:
# claimName: api-tester-1231-files
hostPath:
path: /root/k8s-local-volume/1231
- name: secret-datasource
secret:
secretName: api-tester-1231-postgresql
defaultMode: 420
Deployment에서 hostPath를 이용할 경우

위 처럼 파일이 동일하게 생성되지만,

여전히 `/usr/src/myapp/tmp`은 Container의 내부에만 존재하므로 Pod가 종료되는 순간 내부의 파일은 삭제된다.
2. Deployment
▶ 1. RollingUpdate 하기
kubectl set image -n anotherclass-123 deployment/api-tester-1231 api-tester-1231=1pro/api-tester:v2.0.0
App의 버전을 바꾸는 것으로 Deployment의 업데이트를 유발

업데이트가 진행되는 동안에는 두 가지의 버전이 공존하여 트래픽이 분산되어 출력되는 것을 볼 수 있음

업데이트 완료 후에는 기존의 Pod는 모두 종료되어 동일 버전만 출력됨
▶ 2. RollingUpdate (maxUnavailable: 0%, maxSurge: 100%) 하기
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0%
maxSurge: 100%
maxUnavailable과 maxSurge를 수정 (모든 Pod를 사용할 수 있어야 하고, 한 번에 업데이트를 올리겠다는 의미)

기존 Pod는 계속 실행되고 새로운 Pod 2개가 한 번에 올라옴


때문에, 계속해서 동일한 버전이 출력되다 기동이 완료되면 기존의 Pod가 순차적으로 종료되어 로그에 출력
▶ 3. Recreate 하기
# type 속성을 Recreate로 수정
strategy:
type: Recreate
Deployment에서 type을 Recreate로 수정

업데이트를 시작하자 모든 Pod를 종료해 응답이 없다.

기동이 완료되고 업데이트 버전이 적용되어 다시 로그에 출력
▶ 4. Rollback
# 이전 버전으로 롤백
kubectl rollout undo -n anotherclass-123 deployment/api-tester-1231

여전히 Recreate 방식이라 모든 Pod 삭제 후, 이전 버전으로 다시 출력되는 것을 확인
3. Service
▶ 1. Pod 내부에서 Service 명으로 API 호출 [서비스 디스커버리]

Pod 내부에서 Obejct name으로 API 호출을 해 출력
▶ 2. Deployment에서 Pod의 ports 전체 삭제, Service targetPort를 http -> 8080으로 수정
# Deployment 일부 수정
containers:
- name: api-tester-1231
image: 1pro/api-tester:v2.0.0
# ports:
# - name: http
# containerPort: 8080
# protocol: TCP
---
# Service port 수정
spec:
ports:
- protocol: TCP
port: 80
# targetPort: http
targetPort: 8080
nodePort: 31231
기존에는 Deployment와 Service의 포트가 name으로 연결되어 있어, 이것을 targetPort로 연결되도록 수정

정상적으로 포워딩되어 API가 호출된다.
4. HPA
▶ 1. 부하 발생

부하가 발생하자 Pod가 1개 증가해 총 3개가 됨
▶ 2. [behavior] 미사용으로 적용
# behavior 수정
kubectl edit -n anotherclass-123 hpa api-tester-1231-default

behavior 아래 속성을 모두 주석처리

부하가 올라가자 새로운 Pod 2개가 함께 생성되어 총 4개

부하가 내려가니 바로 2개로 줄었다.
'Tech > Kubernetes(K8s)' 카테고리의 다른 글
잘못된 정보가 있다면 말씀해주세요!