반응형
Application Lifecycle Management
강의 개요
- 응용 프로그램 수명 주기 관리에 대해 생각해보자.
- 업데이트와 롤백에서 시작해 응용 프로그램을 구성하는 다양한 방법
- Self-Healing Application
Rolling Update & Rollbacks
- 먼저 배포 시 롤아웃과 버전 관리를 이해해보자
- 처음 배포를 실행하게 되면 새로운 롤아웃으로 인해 새로운 배포 Revision을 생성하게 된다.
- 새로 앱이 업그레이드 되면 컨테이너 버전이 새 것으로 업데이트 되면 새 롤아웃이 트리거되고 새 배포 Revision이 생성된다.
- 배포 과정 중 일어난 변화를 추적할 수 있게 해주고 필요하다면 배포의 이전 버전으로 되돌릴 수 있게 해준다.
kubectl rollout status deployment/myapp-deployment
- 위 명령어를 입력하게 되면 해당 deploy에 대한 rollout을 확인할 수 있다.
- 또한 deployment에 대한 기록과 개정 이록을 확인할 수도 있다.
kubectl rollout hisroty deployment/myapp-deployment
- 사실 배포 전략은 두 가지 유형이 있다.
- 1번은 새로운 버전으로 업그레이드 할 때 기존에 있던 애플리케이션 인스턴스를 모조리 없애고 다시 새 인스턴스를 생성하는 방법
- 1번의 경우 구 버전이 다운되고 새 버전이 업 되기까지 애플리케이션은 Down되고 User들은 해당 애플리케이션에 접근이 불가 할 것이다.
- 2번의 경우 한꺼번에 없애고 다시 생성하는 것 보다 차례차례로 Down Up을 반복하는 Rolling update 방식이다.
- 2번의 경우 앱이 다운되지 않고 업그레이드도 원활해진다.
- rollout 명령어를 사용해 업데이트를 진행하게 되면 2번의 경우로 업데이트를 진행하게 된다.
- 그리고 Deployment 파일을 수정하거나 레이블을 업데이트 하거나 하게되면 기본적으로 Rolling update를 하게된다.
- 만약 deployment의 이미지를 수정한다고 했을 때
- 기존의 매니페스트 파일로 apply 명령어를 수행하여 하는 방법이 있다.
- kube set image deployment/myapp-deployment nginx-container=nginx:1.9.1 이와 같이 set image 명령어를 이용해서도 변경이 가능하다.
- 그런데 set 명령어를 사용해서 이미지를 업데이트할 경우 매니페스트 파일 구성이 달라지기 때문에 조심해야함.
- rollout 명령어 취소하기
- rollout 명령어로 적용했던 배포를 취소하기 위해선 rollout undo 명령어를 이용해야함.
kubectl rollout undo deployment/myapp-deployment
명령어 정리
# 파일 기반 deployment 생성
kubectl create -f deployment-definition.yml
# deployment get
kubectl get deployments
# deployment 변경사항 적용
kubectl apply -f deployment-definition.yml
# deployment 컨테이너 이미지 변경
kubectl set image deployment/myapp-deployment nginx=nginx:1.9.1
# rollout 상태 확인
kubectl rollout status deployment/myapp-deployment
# rollout 리비젼 세부 사항 확인
kubectl rollout history deploytment/myapp-deployment
# rollout 했던 결과 되돌리기
kubectl rollout undo deployment/myapp-deploymnet
# 특정 리비젼으로 되돌리기
kubectl rollout undo deployment/myapp-deploymnet --to-revision=3
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 10
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: nginx
spec:
containers:
—name: nginx
image: nginx:1.14.2
ports:
—containerPort: 80
- type 항목은 RollingUpdate 항목과 Recreate 항목이 있음
- 만약 strategy를 입력하지 않으면 기본적으로 RollingUpdate가 되게 된다.
- type을 RollingUpdate로 지정하게 되면 maxSurge와 maxUnavailable 필드를 설정할 수 있음.
- maxSurge : 디플로이먼트가 배포 시 한 번에 생성할 수 있는 최대 파드의 수. 정수형으로 입력하거나 백분율로 입력하면 된다. 예를 들어 maxSurge가 15로 되어있고 기존 디플로이먼트가 10으로 되어있다고 가정하면, 롤링 업데이트 시 기존 디플로이먼트(10) + 롤링 업데이트 될 파드(5) 총합 15로 파드 수가 유지 되면서 롤링 업데이트를 진행함.
- maxUnavailable : 디플로이먼트가 배포 시 사용할 수 없는 Pod의 최대 수 또는 비율을 지정. 예를 들어 maxUnavailable을 2로 설정하면 롤링 업데이트 중에 Kubernetes는 최대 2개의 포드가 동시에 종료되도록 한다.
Application Commands (도커) (시험에는 포함X)
- 나중에 정리 하도록 함!
Application Commands & Arguments (쿠버네티스)
- 위 Docker 경우에서 sleep 명령어를 사용하는 컨테이너를 생성했었다.
- 이 컨테이너로 이미지를 생성하고 쿠버네티스에서 사용하고자 한다.
- 위와 같이 docker 이미지를 만들어서 pod의 매니페스트 파일에 참조하게 만들었다.
- 근데 docker의 경우에서 확인 했듯이 sleep 명령어는 옵션 값 즉 arguments가 필요하다. 쿠버네티스에서는 어떻게 하는가?
- spec.containers.args 필드를 이용하면 된다.
- 배열의 형태로 작성해야 한다.
- 도커파일과 비교하여 설명하자면 Dockerfile은 ENTRYPOINT와 CMD를 이용해서 명령어와 인자 값을 결정하게 된다.
- 위에서는 args를 이용해서 매개 변수 값을 변경해주었는데 그럼 ENTRYPOINT는 어떻게 쿠버네티스에서 사용해야하는가?
- spec.containers.command 필드를 이용하면 된다.
- 배열의 형태로 작성해야 한다.
- Docker에서 와 Kubernetes 의 경우를 비교하자면 이렇다.
- ENTRYPOINT == command
- CMD == args
Configure Environment Variables in Applications
- 쿠버네티스의 환경 변수를 설정하는 법을 알아보자
- 쿠버네티스에서 환경 변수를 설정하기 위해서는 어떻게 해야 하는가?
- spec.containers.env 속성을 사용하면 된다.
- env는 배열이다.
- - (대시)를 기준으로 하나의 env라고 인식하게 된다.
- 환경변수를 설정하는 다른 방법도 있다.
- ConfigMap
- Secrets
- 자세한 설명은 다음 강의에서.
Configuring ConfigMaps in Applications
- 쿠버네티스의 데이터 활용법을 배워보도록 하겠다.
- 위에서 파드 매니페스트 파일에 환경 변수를 정의하는 법을 배웠을 것이다.
- 파드 매니페스트 파일이 많아지면 동일한 환경 변수를 사용하는 경우도 있을 것이고, 환경 변수를 관리하기가 어려워질 것이다.
- 그래서 ConfigMap을 이용해서 중앙에서 관리하도록 해준것이다.
- ConfigMap은 Key-Value 쌍의 구성 데이터를 전달하는 데 사용된다.
- 파드를 생성할 때 파드에 ConfigMap을 삽입해 키 값 쌍이 환경 변수로 사용될 수 있게 한다.
- ConfigMap 구성에는 두 단계가 있다.
- ConfigMap을 생성하고
- Pod에 주입
- ConfigMap을 만드는 방법은 명령적, 선언적 방법이 있다.
- 명령적 : kubectl create configmap
- 선언적 : kubectl create -f ~~~.yaml
- 명령적으로 만드는 기본 방법은 아래와 같다.
kubectl create configmap <config name> --from-literal=<key>=<value>
- 여러 개의 환경 변수를 만들기 위해서는 --from-literal 옵션을 여러 번 지정해주면 된다.
kubectl create configmap <config name> --from-literal=APP_COLOR=blue --from-literal=APP_MOD=prod
- 또한 파일을 기준으로 config를 만드는 방법도 있다.
- 대신 파일은 아래와 같은 내용으로 구성해야한다.
- 선언적 접근은 definition 파일을 생성한다.
- 위와 같이 yaml 파일을 구성하고 data 아래에 환경 변수들을 구성해주면 된다.
- 다른 리소스와 동일하게 아래와 같이 configmap에 대한 정보를 출력할 수 있다.
kubectl get configmaps
kubectl describe configmaps
- 파드에서 ConfigMap을 참조하고 싶으면 어떻게 해야 하는가?
- 위와 같이 pod를 생성할 때 spec.envFrom.configMapRef 필드를 이용해서 미리 만들어 두었던 ConfigMap을 참조하도록 해주면된다.
- ConfigMap 전체를 참조하거나, ConfigMap안에 있는 특정 key만 참조하거나 volume 전체를 참조할 수도 있다.
Configure Secrets in Applications
- Secret은 이름, 사용자 이름, 패스워드 등의 민감한 정보들을 애플리케이션 안에 포함시키지 않으려고 사용한다.
- 이 경우 app.py 파일에 mysql과 연결하는 과정에서 사용하는 user name과 password 모두 노출되게 된다.
- ConfigMap의 경우 일반 텍스트 형식으로 구성 데이터를 저장해서 위와 같은 경우에 configmap을 이용해 중앙 관리를 할 수도 있다.
- 근데 그렇게 하는게 민감한 정보를 숨기는 데 도움이 되지는 않는다.
- Secrets은 민감한 정보를 저장하는데 쓰인다. 인코딩 된 형식으로 저장된다는 점만 빼면 ConfigMap과 동일하다.
- Secrets은 ConfigMap과 마찬가지로 두 단계가 있다.
- 시크릿을 생성하고
- 파드에 주입
- 그리고 Secret은 명력적, 선언적으로 생성할 수 있다.
- ConfigMap과 동일하게 명령적은 아래와 같이 생성한다.
- kubectl create secret 명령어를 이용해서 --from-literal 옵션을 이용해 key value 값도 지정 해준다.
- ConfigMap과 동일하게 여러 key value를 등록하려면 --from-literal 옵션을 여러번 입력하면 된다.
- 선언적도 ConfigMap과 유사한 방법으로 생성할 수 있다.
- 그런데 Secret의 경우 일반 텍스트로 지정하면 안전할까? 아니다. 그래서 인코딩된 형식의 비밀 값을 지정해야한다.
# 인코딩
echo -n 'mysql' | base64
# 디코딩
echo -n 'bXlzcWw=' | base64 --decode
- n 옵션을 붙이는 이유는 개행을 없애줘야 원문 그대로 나오기 때문에
kubectl get secrets
kubectl describe secrets
- 위와 같은 명령어로 secret을 확인할 수 있다.
- Secret은 ConfigMap과 비슷하게 spec.envFrom 에 정의 가능하다.
- 주의해야할 점은 secretRef 및에 name은 공백을 2 가 아니라 4로 해야함
- 위와같이 ConfigMap과 유사하게 다양한 경우에서 사용 가능하다.
- Secret은 사용시 유의사항이 있다.
- Secret은 암호화 되지 않았다. 단순히 인코딩 됐을 뿐이다.
- 암호화 되어 있지 않기 때문에 누구든 기밀문서로 만든 파일을 볼 수 있고, 기밀 개체를 얻을 수 있다. 누구든지 디코딩만하면 데이터를 볼 수 있다는 말이다. Github나 외부로 푸시할 경우 Secret 파일이 노출되어 위험이 발생할 수 있다.
- ETCD 안에있는 Secret은 암호화되지 않는다.
- ETCD의 어떤 데이터도 기본적으로 암호화되어 있지 않는다. 그래서 "Encryption at rest" 를 즉시 사용해야 한다.
- Encryption at rest는 클러스터에서 사용하는 디스크 또는 볼륨과 같은 영구 저장 장치에 데이터가 저장될 때 데이터를 암호화하는 방식을 나타낸다.
- EncryptionConfiguration이라는 리소스를 사용해서 파드를 생성할 때 --encryption-provider-config 커맨드를 이용하면 인증을 통과해 특정 secret을 사용할 수 있게끔 하는 방식인듯하다.
- https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/ 링크 참조하면 될듯
- 동일한 이름의 네임스페이스에서 파드를 만들거나 디플로이먼트를 생성할수 있는 누구나는 secret에 접근 가능하다.
- 누군가가 파드나 디플로이먼트를 생성하고 Secret을 사용하게되면 파드에 탑재된 Secret을 볼수 있기 때문에 RBAC을 이용해서 액세스 제한을 고려해야한다.
- 서드파티 암호 공급자를 고려해야한다.
- AWS, Azure, GCP, Vault 같이 외부 비밀 공급자에 저장해서 Etcd가 아니라 외부에서 Secret을 불러올 수 있도록 하면 훨씬 안전하다.
- Secret은 암호화 되지 않았다. 단순히 인코딩 됐을 뿐이다.
Multi Container Pod
- 파드 안에 웹 서버와 로깅 서비스처럼 두 가지 서비스가 필요할 수도 있다.
- 함께 장착된 웹 서버 인스턴스 당 에이전트 인스턴스 하나가 필요하다.
- 코드로서 웹 서버 인스턴스와 에이전트 인스턴스를 병합 해 하나의 컨테이너로 올리는 것은 바람직하지 않다.
- 그래서 다중 컨테이너로 된 파드 하나를 배포하는 게 낫다.
- 두 컨테이너는 로컬 호스트라는 같은 네트워크 공간을 공유하기 때문에 같은 저장소 볼륨에도 액세스할 수 있다.
- 아래 그림과 같이 두 개의 컨테이너를 단일 manifest 파일에 구성해주면 된다.
- 멀티 컨테이너 Pod를 설계할 때는 3가지의 일반적인 패턴이 있다. (CKAD 내용)
- 사이드카 (sidecar) 패턴
- 어댑터 (adapter) 패턴
- 앰배서더 (ambassador) 패턴
InitContainers
- 멀티 컨테이너 파드에서 각 컨테이너는 Pod의 라이프사이클 기간 동안 활성 상태로 유지되는 프로세스를 실행해야 한다.
- 예를 들어 앞서 설명한 웹 애플리케이션과 로깅 에이전트는 두 컨테이너가 항상 활성 상태를 유지해야 한다.
- 둘 중 하나라도 실패하면 Pod가 다시 시작된다.
- 그러나 때로는 컨테이너에서 완료까지 실행되는 프로세스를 실행하고 싶을 수도 있다.
- 예를 들어 메인 웹 애플리케이션에서 사용할 리포지토리에서 코드나 바이너리를 가져오는 프로세스가 있다고 가정해보자. 이는 파드가 처음 생성될 때 한 번만 실행되는 작업이다. 또는 실제 애플리케이션이 시작되기 전에 외부 서비스나 데이터베이스가 가동될 때까지 기다리는 프로세스이다. 이것이 바로 InitContainers가 필요한 이유이다.
- InitContainers는 다른 모든 컨테이너와 마찬가지로 파드에서 구성되지만, 파드 내의 spec.initContainers 항목으로 구성된다는 점에서 기존의 containers와 다르다.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox
command: ['sh', '-c', 'git clone <some-repository-that-will-be-used-by-application> ; done;']
Self Healing Application
- 쿠버네티스는 레플리카셋과 레플리케이션 컨트롤러를 통해 자가 복구 애플리케이션을 지원한다.
- 레플리카셋은 Pod 내의 애플리케이션이 Crash 될때 Pod가 자동으로 다시 생성되도록 돕는다.
- 이는 애플리케이션의 충분한 복제본이 항상 실행되도록 하는 데 도움이 된다.
- 쿠버네티스는 라이브니스 및 레디니스 프로브를 통해 Pod 내에서 실행중인 애플리케이션의 상태를 확인하고 필요한 조치를 취할 수 있도록 추가 지원을 제공한다. (CKAD 관련 내용)
[참조] :
https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests/
반응형
'자격증 > Kubernetes CKA' 카테고리의 다른 글
[CKA] Cluster Maintenance (0) | 2023.12.04 |
---|---|
[CKA] Practice Test - Rolling Updates And Rollbacks (0) | 2023.12.03 |
[CKA] Practice Test - Monitor Cluster Components, Managing Application Logs (0) | 2023.12.03 |
[CKA] Logging & Monotoring (0) | 2023.12.03 |
[CKA] Practice Test - Static Pods (0) | 2023.12.02 |