Rolling update and Rollback
Deployment를 생성하거나 변경하면 rollout 이벤트가 발생한다.
Kubernetes는 Deployment마다 변경 이력을 관리합니다.
kubectl rollout status deployment/myapp-deployment # 현재 롤아웃 진행 상태 확인
kubectl rollout history deployment/myapp-deployment # 배포 이력 (리비전) 확인
rollout 은 새로운 애플리케이션 버전을 단계적으로 배포해나가는 과정을 말한다
(내가 배포한 애플리케이션이 클러스터에 반영되고 있는 과정)
배포 전략
Recreate 전략
모든 기존 Pod을 먼저 종료한 후 → 새로운 버전 Pod을 생성
다운타임이 발생 할 수 있기때문에 일반적으로 사용하지 않는다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-recreate
labels:
app: myapp
spec:
replicas: 3
strategy:
type: Recreate # 👈 Recreate 전략
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: nginx:1.21
ports:
- containerPort: 80
RollingUpdate 전략 (기본값)
신규 버전 Pod을 하나씩 추가하고 동시에 구버전 Pod을 하나씩 제거
애플리케이션을 계속 유지하면서 점진적으로 배포됨
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-rolling
labels:
app: myapp
spec:
replicas: 3
strategy:
type: RollingUpdate # 👈 RollingUpdate 전략 (안써도 기본값)
rollingUpdate:
maxSurge: 1 # 새 파드를 최대 몇 개까지 더 띄울 수 있는가 (기본값 : 25%)
maxUnavailable: 1 # 동시에 몇 개까지 내려도 괜찮은가 (기본값 : 25%)
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: nginx:1.21
ports:
- containerPort: 80
업그레이드 동작 확인
kubectl apply -f 로 Deployment를 변경하면,
Kubernetes는 새로운 ReplicaSet을 생성하고,
- 기존 ReplicaSet: Pod 수 줄임
- 신규 ReplicaSet: Pod 수 늘림
kubectl get replicaset
롤백
변경이 잘못되었거나 문제가 생긴 경우, 이전 리비전으로 되돌릴 수 있음
kubectl rollout undo deployment/myapp-deployment
ps
이미지 배포 관련
kubectl set image deploy <배포이름> <컨테이너이름>=<이미지:태그>
ex) kubectl set image deploy myapp-deployment simple-webapp=kodekloud/webapp-color:v3
Commands / Arguments
컨테이너는 OS 전체를 실행하는것이 아니라 단일 프로세스를 실행하는것이 목적이다.
그래서 컨테이너 내부에서 실행되는 프로세스가 종료되면 컨테이너도 같이 종료된다
ex) 구동중이던 웹서버 멈추면 컨테이너도 종료된다
도커 명령어
CMD : 기본 실행 명령어 또는 인수 , docker run 시 명령어 주면 덮어 써진다
ENTRYPOINT : 실행 대상 명령어 지정 , 무조건 실행되고 인수만 변경이 가능하다
CMD + ENTRYPOINT : ENTRYPOINT에 인수를 추가한다, docker run시 인수만 교체 가능하다
#기본 cmd만 정의
FROM ubuntu
CMD ["sleep", "5"] # 여기서 "sleep 5" 이렇게 x
# 아래와 같이 호출시 결과값
docker run ubuntu-sleeper # sleep 5
docker run ubuntu-sleeper sleep 10 # sleep 10 (CMD 전체 덮어씀)
# ENTRYPOINT만 정의한 경우
FROM ubuntu
ENTRYPOINT ["sleep"]
# 아래와 같이 호출시 결과값
docker run ubuntu-sleeper 10 # 실행: sleep 10
#ENTRYPOINT + CMD 같이 쓴 경우
FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]
# 아래와 같이 호출시 결과값
docker run ubuntu-sleeper # sleep 5
docker run ubuntu-sleeper 10 # sleep 10 (CMD 무시됨)
#실행중인 ENTRYPOINT 변경
docker run --entrypoint sleep ubuntu-sleeper 10
pod yaml에서의 적용
Kubernetes에서는 Dockerfile
ENTRYPOINT → command,
CMD → args 로 대응된다
#단순히 args만 지정 (기존 ENTRYPOINT 사용)
spec:
containers:
- name: ubuntu-sleeper
image: ubuntu
args: ["10"]
#command와 args 모두 지정 (ENTRYPOINT + CMD 효과)
spec:
containers:
- name: ubuntu-sleeper
image: ubuntu
command: ["sleep"] # ENTRYPOINT
args: ["10"] # CMD
# 위랑 다르게 아래 형태로도 쓸 수 있음
spec:
containers:
- name: ubuntu
image: ubuntu
command:
- "sleep"
- "5000"
ps
#생성시 바로 명령어 줄 수 있음 이거는 인자만 준거
kubectl run webapp-green --image=kodekloud/webapp-color -- --color green
#이렇게 하는것도 있음 --<command> <arg>
kubectl run webapp-green --image=kodekloud/webapp-color --command --python --color green
Environment Variables (시험 중요) / ConfigMap/ Secret
Pod에서 환경변수 설정하기
spec:
containers:
- name: my-container
image: my-image
env:
- name: APP_MODE
value: "production"
env는 배열의 형태로 여러개의 환경변수를 지정할 수 있다
가장 기본적인 방법으로 값을 명시하는 방법이다.
ConfigMap/Secret 을 통한 설정값 분리
ConfigMap이나 Secret을 사용하면 환경 변수나 설정 값을 Pod 외부에서 관리할 수 있다.
ConfigMap
- Key-Value 쌍으로 구성된 설정 데이터
- 코드와 설정을 분리하여 유지 보수성과 재사용성 향상
#명령어로생성
kubectl create configmap app-config --from-literal=APP_COLOR=blue --from-literal=APP_MODE=prod
여러개 할떄는 --from-literal 여러번 쓰면된다
#파일로 생성
kubectl create configmap app-config --from-file=config.properties
#yaml로 선언형 생성
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_COLOR: blue
APP_MODE: prod
# 조회는 기본적으로 아래 명령어 쓰면된다
kubectl get configmaps
kubectl describe configmap app-config
Pod에서 configMap을 사용하는 3가지 방법
1. envFrom
모든 키를 환경 변수로 주입
envFrom:
- configMapRef:
name: app-config
configmap의 모든 key들이 각각의 환경변수로 자동 설정
2. env + valueForm.configMapKeyRef
env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: app-config
key: APP_COLOR
configmap에서 특정 key만 선택해서 주입하고 싶을때 사용
3. volum으로 마운트 (파일처럼 사용)
volumes:
- name: app-config-volume
configMap:
name: app-config
volumeMounts:
- name: app-config-volume
mountPath: /etc/config
ConfigMap 안의 key-value 데이터를 “파일”로 바꿔서 Pod 내부 디렉토리에 자동으로 넣어주는 것
즉, 환경 변수로 넣는 게 아니라 → 실제 파일처럼 사용할 수 있게 되는 방식
(ConfigMap의 각 key가 파일 이름이 되고, value는 파일 내용으로 마운트됨)
위의 기준으로 설명하면 컨테이너 안에서 /etc/config 디렉토리를 보면
/etc/config/APP_COLOR ← 이 파일 내용은 "blue"
/etc/config/APP_MODE ← 이 파일 내용은 "production"
이렇게 된다고 보면된다.
애플리케이션이 설정 파일을 읽게 설정되어있을때 (ex properties등) 사용하고
쉘스크립트나 템플릿 파일이 필요할떄 등에 사용한다.
Secrets
사용자체는 위와 동일하게 사용 가능하다
#환경변수 사용
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-secret
key: password
#envFrom으로 한번에 사용
envFrom:
- secretRef:
name: my-secret
#volum으로 마운트
volumes:
- name: secret-volume
secret:
secretName: my-secret
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
Secret은 언제 쓸까?
기본적으로 쿠버네티스에서 설정 값을 저장할때 configmap을 사용하는데
db의 비밀번호나 api 키와같은 민감한 정보를 저장할때는 Secret을 사용한다
configmap은 평문으로 저장되기 때문에 보안에 취약하다
특징
- Secret은 configmap과 같이 key value 형태
- Configmap과 유사하지만 내부 데이터는 기본적으로 base64로 인코딩 되어 저장된다
- base64는 암호화아니다 보안에 안전한건 아님
- 기본적으로 secret을 암호화하지 않고 etcd에 저장하기 떄문에 etcd접근 권한이 있으면 인코딩 풀어서 누구나 볼 수 있다
- etcd저장시 암호화를 위해서는 EncryptionConfiguration을 설정하여 Encryption at Rest를 활성화 필요
- 쿠버네티스는 secret을 pod가 필요할떄만 해당 노드로 전달하며, 노드의 메모리 상에 저장된다 (디스크상에 평문으로 기록 x)
- pod가 삭제되면 해당 노드의 secret데이터도 삭제된다
생성방법
# 명령어기반
kubectl create secret generic <이름> --from-literal=key=value
kubectl create secret generic <이름> --from-file=key=파일경로
# Yaml 파일 (data필드에 들어가는 값은 base64로 인코딩된 값)
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
username: YWRtaW4= # admin
password: MWYyZDFlMmU2N2Rm # mypassword
# 조회 명령어
kubectl get secrets
kubectl describe secret <이름> # value는 숨겨져 있음
kubectl get secret <이름> -o yaml # Base64 인코딩된 값 확인 가능
#인코딩/디코딩 명령어
# Base64 디코딩 (복호화)
echo -n 'YWRtaW4=' | base64 --decode
# Base64 인코딩
echo -n 'admin' | base64
Encrypting Secret Data
secret 을 암호화해서 사용하는 방법
etcd 서버에 암호화 해서 보관을 해야한다
수행을 하기 위해서는 etcdctl 이설치되어야하고 인증서 파일도 필요하다
(etcd에 저장된 특정 secret의 원본데이터 호가인을 위한거, 쿠버네티스 api서버를 거치지 않고 raw데이터를 직접 조회하기 위한 목적)
ETCDCTL_API=3 etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
get /registry/secrets/default/secret1 | hexdump -C
위의 명령어의 위치에 해당하는 파일들이 있어야한다 (클러스터 접근에 필요한 인증서들)
secret1 은 내가 설정한 시크릿 명으로하면된다
hexdump -C로 하면 결과값도 암호화된 형태로 출력된다
(안 붙이면 그냥 암호화 안된 결과값 콘솔에서 보인다)
저장시 암호화 활성화 되어있는지 확인하는 명령어
ps -aux | grep kube-api | gep "--encryption-provider-config"
요게 설정이 되어있어야한다 설정이 안되어있으면
EncryptionConfiguration 을 생성해서 해당 옵션에 전달해주면 된다
(kube-api 에서 command option과 마운트를 활용해서)
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
# See the following text for more details about the secret value
secret: <BASE 64 ENCODED SECRET>
- identity: {} # this fallback allows reading unencrypted secrets;
# for example, during initial migration
resources는 암호화하는걸 선택하는데 secrets말고도 다른것들도 선택이 가능하다
provider는 다양한 종류가 있다 원하는걸 선택하면된다 (다양한 알고리즘 정보 있다)
기존에 저장했던것들은 암호화 안되고 위의 설정이 끝나고 생성한것들에 대해서 암호화가 설정된다
kubectl get secrets --all-namespaces -o json | kubectl replace -f - (전달받은 json을 다시 클러스터로 덮어 씌운다는것)
요거 쓰면 기존것도 전체 다 암호화가 가능해진다
공식 문서 :
https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
Muti Container Pod (시험 중요)
하나의 pod안에 두개 이상의 각각 기능을 담당하는 컨테이너를 배포할 수 있다.
보통 서로 밀접하게 협력해야하는 기능을 같이 배포할 때 사용한다
(Web server + Log Agent)
특징
- 같이 생성되고 같이 삭제된다(생명 주기 공유)
- 같이 스케일 업 /다운 된다
- 같은 네트워크 공간을 공유한다 (서로를 localhost로 참조 가능)
- 같은 스토리지 볼륨 공유한다 (emptyDir 등으로 데이터 공유 가능)
- 별도로 pod간 service연결이나 volum 공유 설정 없이 협력 가능
구성방법
# 파드 구성할때 각 컨테이너의 설정을 containers 배열안에 나란히 추가하면 된다
spec:
containers:
- name: web-server
image: nginx
- name: log-agent
image: log-agent-image
. tip
# 멀티 컨테이너 만들기
run활용해서 yaml만들고 해당 yaml 수정해서 다른 container정보 입력하는 방법으로해야함
#로그보는 명령어
kubectl logs <pod name> -n <namespace>
#로그 중 특정 컨테이너를 보려는 경우
kubectl logs <pod name> -c <containerName>
# 파드 내부로 들어가는 명령어 (exec)
kubectl -n elastic-stack exec -it <pod name> -- cat /log/app.log
multi container에서 볼륨 마운트 하는방법
spec:
containers:
- name: web-server
image: nginx
volumeMounts:
- name: shared-volume
mountPath: /log
- name: log-agent
image: log-agent-image
volumeMounts:
- name: shared-volume
mountPath: /log
volumes:
- name: shared-volume
emptyDir: {}
- volumeMounts.name이 같으면 동일한 Volume을 마운트한 것
- emptyDir는 Pod 생애 주기 동안 존재하는 비어 있는 디스크를 의미하며, 모든 컨테이너가 해당 디렉토리에 접근하고 내용을 공유할 수 있다
- 마운트 경로(mountPath)는 각 컨테이너 내에서의 접근 위치이며, 필요에 따라 다르게 설정할 수도 있다
Design Pattern
Sidecar 패턴
보조 역할을 하는 컨테이너
• 주 컨테이너와 함께 동작하며 기능을 확장하거나 보완함
• 예: 로그 수집기, 프록시, 인증 토큰 자동 갱신기
Adapter 패턴
형식을 변환해주는 컨테이너
• 외부 시스템과의 인터페이스를 주 컨테이너가 이해할 수 있게 가공
• 주로 포맷 변환, API 변환에 사용됨
(재사용성도 가능하다는 장점이 있음, 형식 변환 로직만 바꾼다면 adapter만 교체하면된다)
ex) 외부에서 XML 데이터를 받아 JSON으로 변환해 주는 컨테이너
Ambassador 패턴
외부와의 통신을 대신 처리하는 컨테이너
• 주 컨테이너 대신 외부와 연결, 프록시 역할을 함
• 네트워크 트래픽 제어, 보안, 라우팅 등에 활용
ex) 외부 DB와 통신하는 프록시를 두고, 주 컨테이너는 로컬호스트만 바라보게 구성
InitContainers
pod안에서 메인 컨테이너가 시작되기 전에 실행되는 일회성 작업을 수행하는 컨테이너
용도
- 코드나 바이너리 다운로드
- 환경 설정 또는 사전 체크 작업
작동방식
- spec.initContainers섹션에 정의
- 메인 컨테이너는 initContainer가 모두 성공적으로 완료되어야만 실행된다.
- 여러개 정의를 하는경우 순차적으로 하나씩 실행된다
- 하나라도 실패하면 pod가 반복적으로 재시작되며 initcontainer부터 다시 실행된다
initContainers:
- name: init-mydb
image: busybox
command: ['sh', '-c', 'until nslookup mydb; do sleep 2; done;']
Self-Healing Applications
쿠버네티스의 자가 치유기능
-> 애플리케이션이 비정상 종료되거나 crash 해도 자동으로 복구되도록 지원하는 기능
ReplicationController / ReplicaSet
- 지정한 개수만큼 pod 복제본 유지
- pod가 죽거나 삭제되면 자동을 새로 생성
Liveness/Readiness Probe
애플리케이션 상태를 세밀하게 확인하고 필요시 재시작 또는 트래픽 차단 하는 매커니즘
Autoscaling
HPA (시험 중요)
pod의 수를 자동으로 늘리거나 줄이는 기능
cpu, 메모리 , 사용자 정의 지표 (metric server 필요)등을 기반으로 동작한다
주로 웹앱이나 마이크로서비스와 같은 stateless 서비스에 적합하다
# 명령어 예시
kubectl autoscale deployment app --cpu-percent=50 --min=1 --max=10
# yaml 예시
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 스케일 다운시 최근 5분간의 메트릭 고려해서 급격한 감소 방지 할것
VPA
pod의 cpu/메모리 리소스를 자동으로 조정한다
pod를 재시작해서 resource의 request/limit 를 조정한다
쿠버네티스에 기본 내장되어 있지 않아서 별도 설치가 필요하다
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-up.sh
필요한 vpa 구성요소들
kubectl get deployments -n kube-system | grep vpa
- vpa-recommender
- vpa-updater
- vpa-admission-controller
주로 CPU/메모리 사용량이 큰 작업에 적합하다 (e.g. DB, ML workloads)
• 초기 과부하 → 점차 자원 감소하는 시스템에 유용
VPA가 리소스 추천을 할 때 사용할 수 있는 최소/최대 한계를 지정하는 것이고, 그 범위 내에서만 추천값이 생성되고 적용
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: myapp-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: myapp
updatePolicy:
updateMode: "Auto" # Auto | Recreate | Initial | Off
resourcePolicy:
containerPolicies:
- containerName: "*"
minAllowed:
cpu: "100m"
memory: "256Mi"
maxAllowed:
cpu: "1"
memory: "2Gi"
Auto : VPA가 리소스를 자동으로 분석하고, 필요 시 Pod을 재시작해서 리소스를 조정
Recreate : 리소스 조정이 필요할 때마다 전체 Pod을 종료하고 새로 만듦
Initial: 처음 Pod이 생성될 때만 VPA 추천 리소스 반영 그 이후에는 리소스 조정 없음
Off : VPA는 리소스를 분석하고 추천만 제공 실제 리소스 조정은 없음
Cluster Autoscaler
노드 수를 자동으로 늘리거나 줄인다
스케줄 불가능한 Pod이 있으면 노드 추가, 유휴 노드는 제거
In-place Pod Resize (1.27+ 알파 기능)
Pod는 재시작해야 리소스 변경 적용됨
InPlacePodVerticalScaling 를 쓰면
• Pod을 재시작하지 않고 CPU/메모리 변경 가능
(아직 완전하게 제공되는 기능은 아니라 알파단계 )
# feature 활성화 필요
--feature-gates=InPlacePodVerticalScaling=true
# 적용 yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: myapp-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: myapp
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: "*"
minAllowed:
cpu: "100m"
memory: "256Mi"
maxAllowed:
cpu: "2"
memory: "4Gi"
# ✅ CPU는 in-place(재시작 없이)로 리사이징 가능 (Kubernetes 1.27+)
- resourceName: cpu
restartPolicy: NotRequired
# ⚠️ 메모리는 반드시 컨테이너 재시작 필요 (현재까지는 재시작 방식만 지원됨)
- resourceName: memory
restartPolicy: RestartContainer
'자격증 > CKA' 카테고리의 다른 글
쿠버네티스 보안 (0) | 2025.04.13 |
---|---|
cluster 관리 (0) | 2025.04.12 |
Logging & Monitoring (0) | 2025.04.06 |
쿠버네티스 Scheduling (0) | 2025.03.31 |
구성 요소 설계 및 생성 (0) | 2025.03.08 |