docker run --name myd my_daemon:0.1

nano save.dat => 100 (임의변경)

컨테이너는 기본적으로 휘발성(volatile) 저장 구조를 가진다.
이를 해결하는 방법이 바로 Persistent Volume(PV) 이다.
외부 디렉터리를 설정하여, 컨테이너 내부에서 생성한 값을 외부 디렉터리에 저장한다.
컨테이너 실행 시 환경변수(API)를 전달해본다.
/home/vagrant/apil 디렉터리를 만든다.Dockerfile과 my_daemon 파일을 복사해 사용한다.클라우드 환경에서는 여러 개발자와 여러 애플리케이션이 동시에 동작하기 때문에
사용자·프로세스별 권한 관리가 필수이다.
[SA] → 어떤 주체가 실행하는가?
[RBAC] → 무엇을 할 수 있는가?
SA는 “실행 주체”,
RBAC는 “권한 규칙”을 담당한다.
SA + RBAC = 쿠버네티스에서 권한을 체계적으로 관리하는 핵심 오브젝트 조합

ssh로 접속하지만, 이미 키들이 다 들어가 있어서,
인증 과정없이 접속이 가능함.
SA(Service Account)는 쿠버네티스에서 권한을 부여받아 동작하는 오브젝트로,
Pod 내부 애플리케이션이 API 서버에 접근할 수 있게 해주는 계정이다.
SA는 네임스페이스(NS) 단위에 속하는 리소스이며 기본적으로 default SA가 존재한다.
하지만 kubectl create sa kim 으로 새로운 SA를 만들어도,
권한이 없으면 아무것도 할 수 없다.
예를 들어:
cluster-adminRole과 ClusterRole은 모두 "권한의 범위(scope)"를 정의하는 쿠버네티스 RBAC 오브젝트지만
적용 범위가 다르다.
| 종류 | 설명 |
|---|---|
| Role | 네임스페이스 단위 권한을 정의. 특정 NS 내 리소스(Pod, Deployment, Service)의 조회/생성/삭제 권한만 설정 가능. → kubectl get role 로 확인 |
| ClusterRole | 클러스터 전체 단위의 권한을 정의. 네임스페이스에 속하지 않는 리소스(노드, PersistentVolume 등)까지 권한 부여 가능. 여러 네임스페이스에서 반복적으로 사용할 수 있음. → kubectl get clusterrole 로 확인 |
SA는 실행 계정이고, Role/ClusterRole은 권한 범위이며, 둘을 묶어줘야 실제로 Kubernetes 리소스를 조작할 수 있다.
권한 구조는 “주체 + 권한 정의 + 권한 연결”이라는 동일한 패턴으로 이루어진다.
Kubernetes에서도 SA가 “주체”, Role이 “권한”, RoleBinding이 “권한 연결”을 담당한다.
SA + Role + RoleBinding 구조는 쿠버네티스를 포함한 대부분의 시스템에서 공통적으로 사용하는 권한 관리 방식이다.

default namespace안에 있는 service 목록을 볼 수 있다.
kubectl get svc --as system:serviceaccount:default:alicek106
service에는 권한이 있지만, deploy, pod 에는 권한이 없다.

Aggregation


컨테이너가 사용할 수 있는 최대 자원량을 정의한다.
Kubernetes는 내부적으로 Docker와 동일하게 cGroup 기술을 활용하여
CPU·RAM 등의 최대 사용량을 제한한다.
리밋을 지정하지 않으면 컨테이너는 노드의 자원을 마음대로 모두 사용할 수도 있다.
—memory—cpus—cpu-shares—cpu-quota—cpu-runtime컨테이너가 최소한으로 보장받아야 하는 자원량이다.
Pod 스케줄러는 Requests 값을 기준으로
해당 Pod를 적절한 노드에 배치해 효율적으로 자원을 사용하도록 한다.
→ 두 컨테이너는 각각 최소 500MB가 필요하므로 노드 1GB에 정확히 맞게 배치된다.
예시:
→ 만약 Limits를 낮게 설정하면 충돌이 발생할 수 있음
→ Kubernetes는 Requests로 최소치만 보장하고,
Limits는 최대 경계선만 지정하기 때문
즉, Requests는 "최소 확보 자원",
Limits는 "최대 허용 자원"을 나타낸다.
메모리는 CPU와 다르게 압축하거나 되돌릴 수 없는 자원이다.
한번 메모리에 올라간 데이터는 즉시 줄일 수 없기 때문에
노드에서 메모리 경쟁이 발생하면 심각한 문제가 생길 수 있다.
Kubernetes는 설정된 Requests / Limits 값을 기준으로
Pod의 우선순위를 다음 3가지 QoS(Quality of Service) 로 분류한다.
우선순위 (높음 → 낮음)
BestEffort Pod → Burstable Pod → Guaranteed Pod 순으로 강제 종료(Eviction) 된다.
즉,
메모리를 가장 많이 쓰거나,
Requests·Limits 설정이 불완전한 Pod일수록
노드 메모리 부족 시 가장 먼저 희생된다.
메모리가 부족해지면 Kubernetes는 QoS가 가장 낮은 Pod부터 강제 종료시키며, 이를 Eviction이라고 한다.
클라우드 환경에서는 자원 제한뿐 아니라, 컨테이너를 어느 노드(node)에 배치할지 결정하는 기능이 매우 중요하다.
이 작업을 바로 스케줄링(Scheduling) 이라고 한다.
스케줄링은 다음을 결정한다:
즉, 컨테이너를 최적의 노드에 배치하는 전체 과정이 스케줄링이다.
사용자가 Pod를 생성 요청
ServiceAccount, Role, RoleBinding 등 인증/권한 검증
AdmissionController 가
검증 통과 시 Pod가 “스케줄링 대기 상태”에 놓임
kube-scheduler가 모든 노드를 탐색 후
→ 가장 조건이 맞는 노드에 Pod를 배치
최종적으로 kubelet이 해당 노드에서 컨테이너 실행
kube-apiserver
모든 요청의 입구. 인증·권한·검증 처리.
etcd
클러스터 상태 저장소. 어떤 Pod가 어디에 있는지 등의 정보를 저장함.
kube-scheduler
실제로 “어떤 노드에 Pod를 배치할지"를 결정하는 핵심 스케줄러.
스케줄링은 컨테이너를 어느 노드에 배치할지 결정하는 과정이며, kube-scheduler가 모든 노드의 상태를 고려해 가장 적합한 노드에 Pod를 자동으로 배치한다.
nodeSelector 를 사용하면키:값 형태 라벨만으로 노드를 선택하면Node Selector 기능을 확장한 라벨 기반 노드 선택 방법이다.
단순 “이 라벨을 가진 노드만”이 아니라,
하드 조건 (필수 조건)
requiredDuringSchedulingIgnoredDuringExecution
소프트 조건 (선호 조건)
preferredDuringSchedulingIgnoredDuringExecution
Node Affinity는 Node Selector보다 더 정교하게
“어떤 노드에 Pod를 배치할지”를 제어하기 위해
필수 조건 + 선호 조건을 라벨 기반으로 설정하는 스케줄링 방식이다.
노드를 선택 => 스케쥴
그리고 몇 가지 종류가 있다.
Pod 스케줄링에서 Label과 NodeSelector는
“이 노드에 배치되면 좋겠다”라는 선택 기준을 제공한다.
반면, Taint(테인트) 는 그 반대로 작동한다.
Taint는 특정 노드로의 Pod 배치를 막기 위한 설정이다.
노드에 Taint를 설정해두면,
해당 Taint를 허용(Toleration) 하지 않는 Pod는 절대 그 노드에 스케줄링되지 않는다.
즉:
이런 차이가 있다.
Pod에 Toleration이 지정되어 있으면
해당 Taint가 있어도 그 노드에서 실행될 수 있다.
master 노드에 다음과 같은 Taint를 설정:
kubectl taint nodes master node-role.kubernetes.io/master=:NoSchedule
→ Toleration이 없는 Pod들은
master 노드에 절대 배치되지 않음.
Taint는 노드에서 Pod를 쫓아내거나 막는 규칙이며,
Toleration은 그 규칙을 예외적으로 허용하는 설정이다.
(대표적인 동작: NoSchedule)
노드를 업데이트하거나 점검해야 할 때,
해당 노드의 Pod를 안전하게 이동시키고 스케줄링을 비활성화하는 과정에서
cordon, drain, PDB가 사용된다.
cordon 명령은 해당 노드에 앞으로 새로운 Pod가 배치되지 않도록
노드를 “스케줄 불가(NotSchedulable)” 상태로 만든다.
예)
kubectl cordon worker01
→ worker01 노드에는 새로운 Pod가 더 이상 스케줄되지 않음
→ 단, 이미 실행 중인 Pod는 그대로 실행됨
핵심: “더 이상 새로운 Pod는 못 들어오게 막음”
drain 명령은 노드를 완전히 비우기 위해
해당 노드의 Pod들을 다른 노드로 이동(Eviction) 시킨다.
kubectl drain worker01
동작 방식
유지보수 후 노드를 다시 클러스터에 복귀시키려면:
kubectl uncordon worker01
→ worker01이 정상 노드로 돌아오고,
다시 새로운 Pod가 스케줄링될 수 있음.
Drain 시 Pod가 너무 많이 빠지면 서비스 장애가 날 수 있다.
PDB(PodDisruptionBudget) 는 “최소 몇 개의 Pod는 반드시 유지되어야 한다”는 정책을 설정하여
Drain / Eviction 시 안정성을 보장한다.
예: replicas=3인 Deployment에서 최소 2개는 살아있게 하고 싶을 때
Cordon = 새로운 Pod 스케줄링 차단
Drain = 기존 Pod도 전부 다른 노드로 이동
Uncordon = 노드를 다시 활성화
PDB = Drain 시 서비스 중단 방지(최소 Pod 유지 정책)
--record 옵션을 쓰면 변경 이력이 남아서쿠버네티스에서는 일정 수의 Pod를 유지하면서 순차적으로 업데이트하는 방식을 사용한다.
예를 들어:
nginx Deployment에 replicas=3 으로 설정
nginx Pod가 3개 떠 있는 상태에서 이미지를 새 버전으로 변경하면,
이 과정에서 서비스는 계속 살아 있으므로 HA(고가용성) 이 유지된다.
Rolling Update는 Deployment를 업데이트할 때, 서비스 중단 없이 Pod를 순차적으로 새 버전으로 교체하는 방식이다.
Pod가 Running 상태가 되기 위해서는
이 과정 중 값이 비정상이라면 Kubernetes는 Probe를 통해 Pod의 상태를 확인하고,
필요하면 재시작시키거나 트래픽 전달을 막아 서비스 안정성을 보장한다.
| 종류 | 설명 |
|---|---|
| livenessProbe | 컨테이너 내부 애플이 살아있는지(정상 작동 중인지) 검사. 이 검사에 실패하면 restartPolicy 에 따라 컨테이너가 재시작됨. |
| readinessProbe | 컨테이너가 서비스 요청을 받을 준비가 되었는지 검사. 실패 시 해당 Pod는 Service 엔드포인트에서 제외되어 트래픽을 받지 않는다. |
| startupProbe | 애플이 시작되는 데 시간이 오래 걸리는 경우에 사용. startupProbe가 먼저 통과해야 livenessProbe/readinessProbe가 활성화됨. 실패하면 restartPolicy에 따라 재시작됨. |
Kubernetes에서는 사용자가 직접 새로운 리소스 타입을 정의할 수 있으며,
이때 사용하는 객체가 CRD(Custom Resource Definition) 이다.
예를 들어, Redis를 crd 형태의 리소스로 만들었다면,
사용자는 다음과 같이 Redis 커스텀 리소스를 생성하여 컨트롤러가 자동으로 관리하도록 만들 수 있다.
CRD 동작 방식
즉,
CRD = 새로운 리소스 타입 정의
Custom Resource = 그 타입의 객체 생성
이라고 이해하면 쉽다.
Job은 “특정 작업을 수행한 뒤 종료되어야 하는 작업”을 위한 K8s 객체이다.
Deployment처럼 계속 실행되는 서비스용이 아니라,
한 번 실행 → 정상 종료(Completed) → 끝
이 목적이다.
Job은 다음과 같은 작업에 적합하다:
Job이 생성되면 Pod가 실행되고,
해당 Pod가 정상적으로 작업을 끝내 0을 반환하면
Pod 상태가 Completed가 된다.
즉,
Job = “성공적으로 끝났는지 확인하고 종료시키는 실행 단위”
CronJob은 Job을 일정 주기로 실행시키는 K8s 객체이다.
UNIX/Linux의 Cron 개념과 동일하며,
*/5 * * * * 같은 스케줄 표현식으로 실행 시간을 정의한다.
CronJob의 특징:
예)
DaemonSet은 쿠버네티스 클러스터의 모든 노드(또는 지정된 노드)에 동일한 Pod를 하나씩 자동으로 배포하는 오브젝트이다.
노드가 추가되면 자동으로 해당 노드에도 Pod가 생성되고,
노드가 삭제되면 그 노드의 DaemonSet Pod도 함께 삭제된다.
DaemonSet은 주로 노드마다 실행되어야 하는 에이전트(Container) 를 배포할 때 사용한다.
대표적인 활용 예:
즉,
“각 노드마다 반드시 실행되어야 하는 Pod” → DaemonSet으로 배포해야 한다.
DaemonSet = 클러스터 내 모든 노드에서 동일한 Pod를 자동으로 실행시키는 오브젝트
노드 단위 로깅·모니터링·네트워킹 에이전트 배포에 필수적이다.
