source : https://github.com/brendandburns/kbp-sample
- apiVersion issue :
- Deployment : extensions/v1beta1 -> apps/v1, request -> requests
- Ingress : extensions/v1beta1
[%] 의 표시 : 필자의 의견
kubernetes 에서 관리하는 Object 들(kind:[~])은 kubernetes Object로 표시
Chapter 1. 기본 서비스 설치
앱 개요
- redis 에 기록하는 journal service product
- component 종류
- restful api (frontend)
- file server (정적 파일 서버)
- ssl : ‘let’s encrypt’
- 본 Chapter 에서 사용하는 방법
- .yaml 선언
- helm chart 사용
설정 파일 관리
- 일반적인 선언적 방법 : .yaml 사용
[%].yaml 은 indentation 에 민감하다. - 선언적 상태의 변경과 감시, 롤백을 이행 할 수 있어야 한다. : 보통 git으로 관리 (cluster에 적용되어 내용과 git으로 확인하는 내용이 일치해야 한다.)
[%] git과 cluster 를 동기화 시켜놓으면 git 관리를 통해서 rollback 도 가능 할 것 같다. - app을 파일 시스템으로 관리 할 때는 directory를 사용하여 component를 분리하여 관리하는게 좋다.
-
1 2 3 4
journal/ frontend/ redis/ fileserver/
-
이미지 관리 모범 사례
- 믿을 수 있는 공급자를 기반으로 하는 image 를 base로 해야한다. : 그렇지 않으면 보안에 취약하다 (조대협님 강의)
- 네이밍
- 이미지가 빌드된 커밋의 SHA hash 와 결합하여 네이밍 하는것을 권장한다. ex) v1.0.1-bff02d
실습 Product Application Diagram
Product 배포 시작
Application Replica 생성
- Front End (API Server)
- FE App 은
Stateless이다. - State 는 Redis 에서 전적으로 관리한다.
- 그렇기 때문에, traffic 에 영향을 주지 않고 임의로
복제가 가능하다.
- 그렇기 때문에, traffic 에 영향을 주지 않고 임의로
- App의 규모가 커질 가능성은 낮지만,
장애 대응,rollout 시에 downtime 방지를 위해서 최소 두개의 replica를 실행하는 것이 좋다. -
1
TIP : Replica를 관리하는 `ReplicaSet`이란 k8s Object 가 있지만, 이것 대신 `Deployment`를 사용하는 것을 권장한다. : 레플리카 복제 + 버전관리, 단계적 롤아웃 기능까지 지원한다.
- FE App 은
- frontend.yaml
- 유의 사항 : pod를 찾을 수 있도록 label 을 설정해야함
- resource 의 requests, limits : 최적의 효율을 위해 두 옵션을 차등 관리하면 더 좋지만, 보통 유저들은
저조한 사용률 < 예측 가능성으로 부터 얻는 안정성을 택한다. (requests, limits 를 같이 둔다.)
CI/CD Setting 의 필요성
- 책에서는 .yaml 의 파일을 수정/추가/삭제 시에는 바로바로 git 에 update 하여 version control 하도록 유도하고 있다. ([%]cmd 로 apply -f 전에 commit 하는 정도..: 물론 자동화 시키면 더 좋겠지?)
- 프로젝트 초반부터 완벽한 CI/CD Pipeline 을 만드는 것이 부담스럽게 느껴질 수 있지만,
- return : 이것이 주는
신뢰성이라는 항목을 제쳐두고라도자동화라는 항목을 통해 세이브 되는 시간만 생각하더라도 자동화 pipeline 구축은 매우 중요하다. - 또한 이미 명령적으로 배포된 app에 CI/CD Pipeline 을 다시 끼워넣는 것은 굉장히 어렵다.
- return : 이것이 주는
Ingress 설정 (외부 Traffic 수용)
- traffic 이 Cluster 내부의 Component 까지 들어오기 위해서는 두가지의 k8s Object 가 필요하다. ([%] 보편적인 구조를 가져가려면.. 물론 Service 로만 externalIP 를 노출시킬수 있다.)
-
- Service : L4 LB
- 해당 예제에서는 ClusterIP Type 으로 사용하고 있다.
- Service : L4 LB
-
- Ingress : L7 LB
Http PathorHost기반으로 Routing 이 가능하다.- 앞단에 Ingress 를 배치하면 향후 서비스 확장 측면에서 유연성을 확보할 수 있다.
- 앞단의 Ingress 를 통해서 추가하는 Component로 Routing 만 해주면 되니까
- [%] Ingress 의 routing rules
- examples
- http://*/api ⇢ frontend:8080 (들어오는 host 를 설정 하지 않을 수도 있다. (‘[ip address]/api’ 로도 타고 들어올 수 가 있다.))
- http://ingress.jhpark.testing.com/ ⇢ frontend:8080 (L7 LB 이니 만큼 host-domain 을 설정하는 것이 좋다. )
- 해당 Ingress 에 붙는 IP (보통 VIP나 물리 LB가 될듯)는 각각 설정이 가능하다.
- Ingress : L7 LB
-
Appication Setting Using ConfigMap
- [%] 앱 서비스에 관련된 설정들 ex) 한 페이지에 노출할 저널 항목 수, 특정 배경색, 공휴일 화면 등..
- 보통 Application 과 Setting 은 분리하는게 좋다.
- 동일한 App Binary 환경에 따라 달라지는 설정을 적용하고 싶을 때 활용 (spring 의 profile 처럼)
configMap은K:V 형식으로 Value 에 '설정 정보'|'파일'을 나타낸다.-
$ kubectl create configmap frontend-config --from-literal-journalEntries=10 - 적용한 configMap은
환경 변수를 이용하여 App에 설정 정보 적용- issue : configMap으로 설정을 관리한다고 했을 때 configMap 을 update 해도 pod는 재시작 하지 않는다. -> update 한 내용 적용x
- 이를 해결하기 좋은 방법 : conigMap 의 네이밍에서 버전을 달아주는 것이다. : ex) frontend-config-v1
- 이렇게 하면 Deployment 에 key 이름을 수정해야 할 것이고 -> 이는 Deployment 의 update 이므로 health checking 을 하면서 알아서 변경이 될 것이기 때문이다. -> 이전 버전으로의 롤백도 Deployment만 바꿔주면 되므로 app을 관리하기 수월하다.
Secret 인증 관리
- config 와 거의 동일한 개념
- 활용의 차이를 두기위해 존재하는 Object
-
$ kubectl create secret generic redis-passwd --from-literal=passwd=${RANDOM}- Secret Volume 을 Mount 하기 위해서는 두가지 설정이 필요하다.
- 1. Pod에 Volume을 추가하는 항목 :
containers와 대등하게 들어간다. - 2. 특정 conainer 에 Volume을 Mount 한다. :containers안에 들어간다. - 이렇게 하면 client service app 에서 redis secret 을 사용할 수 있게 된다.
- Secret Volume 을 Mount 하기 위해서는 두가지 설정이 필요하다.
- 1. Pod에 Volume을 추가하는 항목 :
Deploy Stateful DB
- State 가 존재하는 App을 배포하는 일은 개념적으로는 Stateless App 배포와 비슷하지만, 더 복잫ㅂ나다.
- k8s에서는
Node 상태,업그레이드,리밸런싱등의 이유로 pod가 reschedule 된다. -> 이때, pod 가 다른 서버로 옮겨지면 redis instance 와 연관된 data가 특정 장비나 container 자체에 존재하는 경우 container 가 이관되거나 재시작 될 때, 해당 data 는 날라갈것이다. ->PersistendVolume을 그래서 사용한다.
- k8s에서는
[아주 중요 - 배경 지식]
앞서 설명한 Secret Volume 과 마찬가지로 pod와 연계되어 있으며 `특정 위치의 container`에 마운트 된다.
하지만 PV는 일반적으로 `원격스토리지`에 저장이 된다. (NFS, SMB, iSCSI, 클라우드 기반 디스크 등 다양한 Network Protocol 을 통해서)
일반적으로 DB와 같은 App의 경우 `성능`이 더 좋은 `Block 기반 디스크`를 선호하지만
성능이 주요 고려 대상이 아니라면 `유연성`이 더 높은 `파일 디스크`를 더 선호한다.
StatefulSet으로 Redis 배포
- PVC로
PV 리소스 요청하면 k8s 는 적절한 PV를 제공할 방법을 결정한다.- PVC 가 존재하는 이유는 두가지가 잇다.
-
- 디스크 명세가 다를 수 있다. : 여러 클라우드나 on-prem 사이에서 이식할 수 있도록 StatefulSet 작성이 가능하다.
-
- PV 는 오직 하나의 Pod에 Mount 될 수 있지만, PVC 를 통해 작성한 template 은 복제가 가능하다.
-
- PVC 가 존재하는 이유는 두가지가 잇다.
- [#] 만약 읽기 scale-out 이나 장애 탄력성을 위해서 redis-cluster 를 복제한다고 가정해보면
- replica 1 -> 3
- 두개의 새로운 replica 를 redis의 master에 연결해야 한다.
- redis statefulSet 서비스를 생성하면 dns (redis-0.redis)도 생성된다. : 이것은 첫번째 replica의 ip주소이다.
-> 요걸 활용해서 모든 container에서 사용 가능한 간단한 스크립트를 만들어보자
launch.sh
#!/bin/sh PASSWORD=$(cat /etc/redis-passwd/passwd) if [[ "${HOSTNAME}" == "redis-0" ]]; then redis-server --requirepass ${PASSWORD} else redis-server --slaveof redis-0.redis 6379 --masterauth ${PASSWORD} --requirepass ${PASSWORD} fi- 이 launch.sh를 file로 만들어서 configMap 으로 등록도 가능하다.
-
$ kubectl create configmap redis-config --from-file=./launch.sh - Service 두개 생성
- redis read
- redis write (headless service : cluster ip 가 존재하지 x)
- 대신 statefulSet 안의 모든 pod에 대한 dns를 설정
Product 배포 끝
Helm을 이용한 Product Applications 파라미터화
- 보통 같은 product 라도 다양한 환경에서 돌리게 된다.
- dev, cp-dev, prod
- k8s cluster 의 version control이 필요한 상황이 된다. :
템플릿 시스템을 사용한다.- 가장 대중적인게 바로
Helm
- 가장 대중적인게 바로
- helm 에서 product 는
chart라는 파일 집합으로 패키징 된다. - chart 는 자신의 Metadata를 정의한 chart.yaml 파일로 시작한다.
-
1 2 3 4 5
apiVersion: v1 appVersion: "1.0" description: A Helm chart for our frontend journal server. name: frontend version: 0.1.0
- 이 파일은
chart dir의 최상위 (ex: frontend/)에 위치한다. - 이 dir 안에는
templates dir이 있습니다. 이 template 파일들은파라미터 참조로 대체된다.-
1 2 3 4
... spec: replicas: ...
-
파라미터 값은 values.yaml 파일에 정의된다.- 모두 한곳에 둔 다음에, helm 도구를 이용하여 이 차트를 배포할 수 있다.
-
1
helm install path/to/chart --values path/to/environment/values.yaml
- 해당 예제의 file 구조
journal/ frontend/ chart.yaml templates/ frontend-deployment.yaml frontend-service.yaml frontend-configMap.yaml frontend-secret.yaml ... ... values.yaml - helm 정리 : Application 설정을 다양한 환경에서 재사용하려면 Application을 파라미터화 해야 합니다.
마치며 : 실습 K8S Cluster Setting Info with LENS
- Pod
- Service
- ingresse