Container
Hypervisor 기술과 Container 기술
항목 | Hypervisor (VM) | Container |
---|---|---|
가상화 방식 | 하드웨어 가상화 (Guest OS 포함) | OS 가상화 (커널 공유) |
성능 | 무거움, 부팅 속도 느림 | ✔ 가벼움, 빠른 실행 |
격리 수준 | ✔ 강한 격리 (보안성 높음) | 약한 격리 (보안 고려 필요) |
리소스 사용량 | 상대적으로 높음 | ✔ 상대적으로 낮음 |
배포 속도 | 느림 (OS 부팅 필요) | ✔ 빠름 (이미지 실행) |
주요 활용 분야 | 데이터센터, 서버 가상화 | 클라우드, DevOps, MSA |
Container 특징
Container Engine
Container Runtime
Podman
Podman과 Docker의 차이
항목 | Podman | Docker |
---|---|---|
데몬 (Daemon) | ❌ 없음 (데몬리스) | ✅ 있음 (dockerd 항상 실행) |
Rootless 모드 | ✅ 기본 지원 | ⚠️ 제한적 (설정 필요) |
보안성 | 🔒 더 안전함 (root 권한 불필요) | 🔓 root 권한 필요 (보안 위험) |
OCI 호환성 | ✅ 완전한 OCI 호환 | ✅ OCI 호환 (containerd 사용) |
Compose 지원 | ⚠️ podman-compose 별도 설치 필요 | ✅ docker-compose 기본 지원 |
Kubernetes 연동 | ✅ podman generate kube 지원 | ✅ docker stack 사용 가능 |
이미지 호환성 | ✅ Docker 이미지 그대로 사용 가능 | ✅ Docker Hub 사용 가능 |
컨테이너 관리 | ✅ podman ps , podman run | ✅ docker ps , docker run |
docker-compose
기본 지원, Podman은 podman-compose
를 추가 설치해야 함.podman generate kube
).✅ Docker는 익숙한 환경, Podman은 보안성과 유연성이 중요한 환경에서 사용하면 좋음! 🚀
Podman CLI
podman version
Podman 버전 정보 표시podman login(또는 logout)
컨테이너 레지스트리에 로그인/로그아웃podman build
컨테이너 파일을 사용하여 컨테이너 이미지 빌드podman tag
로컬 이미지에 새로운 이름 추가podman pull
레지스트리에서 이미지 가져오기podman push
이미지, 매니페스트 목록 또는 이미지 인덱스를 로컬 스토리지에서 다른 곳으로 보내기podman run
컨테이너 이미지로 새 컨테이너 실행podman exec
실행 중인 컨테이너에서 명령 실행podman stop
실행 중인 컨테이너 중지podman kill
실행 중인 컨테이너 즉시 종료podman ps
컨테이너에 대한 정보 출력podman rm
컨테이너 삭제쿠버네티스
쿠버네티스 특징
쿠버네티스 클러스터 구성
Container Runtime Interface (CRI)
Kubernetes 배포 도구
Namespace
Deployment
ReplicaSet
Pod
Service
Volume
Ingress
StatefulSet
Deployment vs StatefulSet
항목 | Deployment | StatefulSet |
---|---|---|
주요 목적 | Stateless 애플리케이션 관리 | Stateful 애플리케이션 관리 |
Pod 이름 | 랜덤 생성 (nginx-abcde ) | 고정된 이름 (web-0 , web-1 ) |
Pod 순서 보장 | ❌ 순서 보장 안 됨 | ✅ 순서 보장 (web-0 → web-1 ) |
네트워크 ID | 변경될 수 있음 | Stable Hostname 유지 |
스토리지 | 임시 볼륨 사용 가능 | Persistent Volume 유지 (PVC 개별 할당) |
롤링 업데이트 | ✅ 빠르게 수행 | ⚠️ 한 개씩 차례로 수행 |
사용 사례 | 웹 서버, API 서버, 백엔드 서비스 등 | 데이터베이스(MySQL, PostgreSQL), Kafka, Zookeeper |
Deployment (무상태, Stateless) | StatefulSet (유상태, Stateful) |
---|---|
Stateless 방식의 Pod 배포 상태가 없는 앱 배포 | Stateful한 방식의 Pod 관리 상태가 있는 앱 배포 |
Service를 통한 외부 노출 | Headless Service를 통한 외부 노출 |
Service 요청 시 랜덤한 Pod 선택 | 요청 시 원하는 Pod 선택 가능 (단, Service 요청 불가능) |
ReplicaSet을 가지고 있으며 rollback 가능 | ReplicaSet이 없으며 rollback 불가능 |
모든 Pod가 1개의 PVC에 모두 연결 | Pod마다 각각의 고유한 PVC를 생성하여 고유한 PV를 가짐 |
Job
CronJob
DaemonSet
Persistent Volume
Persistent Volume Claim
StorageClass
PV, PVC 생명주기
1. 생성 (Provisioning)
2. 연결 (Binding)
3. 사용 (Using)
4. 삭제 (Reclaiming)
💻 Kubectl
kubectl apply -f FILENAME
파일이나 표준입력(stdin)으로부터 리소스에 구성 변경 사항을 적용kubectl create -f FILENAME
파일이나 표준입력에서 하나 이상의 리소스를 생성kubectl get
하나 이상의 리소스를 조회kubectl describe -f FILENAME
하나 이상의 리소스의 상세한 상태 조회kubectl logs
특정 이름을 가진 리소스의 로그 정보 출력kubectl edit
특정 이름을 가진 리소스 정보 수정📝 Deployment yaml 파일 작성 방법
apiVersion: v1 # Kubernetes API 버전
kind: Pod # 생성할 오브젝트 종류 (Pod)
metadata: # 리소스에 이름을 부여하고 구분
name: my-pod # Pod의 이름
labels: # 키-값 쌍으로 구성
app: my-app # 라벨 (Pod 식별용)
spec: # 생성하고자 하는 리소스에 대한 내용 구체적 정의
replicas: 3 # 띄우고자 하는 파드 개수
selector: # 어떤 파드를 컨트롤하고 감시해야 하는지 정의
matchLabels: # metadata.labels와 동일한 설정으로 맵핑. 동일한 레이블 가진 파드의 컨테이너를 카운팅하여 현재 상태를 측정
app: my-app # 레이블 셀렉터: app이 'my-app'인 Pod들만 선택
template: # 어떤 파드를 실행할지에 대한 정보 설정
metadata: # metadata.labels와 동일한 설정으로 맵핑. 동일한 레이블 가진 파드 실행
labels:
app: my-app # Pod에 붙일 레이블
spec: # 실행시킬 컨테이너에 대한 설정
containers: # 실행시킬 컨테이너의 이름, 이미지, 포트 번호 등을 설정
- name: my-container
image: nginx:latest # 컨테이너로 배포할 이미지 지정
imagePullPolicy: Always # 이미지 다운로드 정책 지정
ports:
- containerPort: 80 # 컨테이너에서 노출할 포트
imagePullSecrets: # 이미지 저장소에 접근하기 위한 인증정보
- name: edu-msa-secret
nodeSelector: kubernetes.io/hostname: paas-ta-worker-1 # 파드를 배포할 특정 노드 지정
📝 서비스 yaml 파일 작성 방법
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app # 이 서비스가 연결할 Pod의 레이블
ports:
- nodePort: ${EDU_MSA_BOARD} # 외부에서 접근 가능한 포트 번호 설정 (외부 포트)
port: 80 # 서비스가 클러스터 내에서 사용하는 포트 (내부 포트)
protocol: TCP # 프로토콜 방식 설정
targetPort: 8080 # 접근하고자 하는 컨테이너 포트 번호를 설정
type: NodePort # 외부에 노출하고자 하는 방식 설정 (NodePort는 포트 번호를 통해 외부에서 접근할 수 있는 방법)
🔔 서로 연관된 여러 yaml 파일을 하나의 파일로 작성하기 위해서는 중간에 ---
로 구분 지어 작성