2일 차 2장 Container Podman, K8S 이해

jhin·2025년 3월 10일
0

K-PaaS

목록 보기
7/16

Container 이해

Container

  • 가상화된 OS 위에서 애플리케이션의 독립적인 실행에 필요한 파일(소스코드, 라이브러리 등)을 모은 패키지
  • 애플리케이션의 코드를 관련 구성 파일, 라이브러리 및 앱 실행에 필요한 종속성과 함께 번들로 제공하는 SW 패키지

Hypervisor 기술과 Container 기술

항목Hypervisor (VM)Container
가상화 방식하드웨어 가상화 (Guest OS 포함)OS 가상화 (커널 공유)
성능무거움, 부팅 속도 느림✔ 가벼움, 빠른 실행
격리 수준✔ 강한 격리 (보안성 높음)약한 격리 (보안 고려 필요)
리소스 사용량상대적으로 높음✔ 상대적으로 낮음
배포 속도느림 (OS 부팅 필요)✔ 빠름 (이미지 실행)
주요 활용 분야데이터센터, 서버 가상화클라우드, DevOps, MSA
  • Hyperviosr 기술은 물리적인 서버 위에서 각각의 OS를 구성하여 그 위에 애플리케이션을 운영하는 구조
  • Container 기술은 OS 레벨에서 프로세스를 격리하는 가상화 기술
  • 안전성이 중요한 환경에서는 Hypervisor (VM)
  • 빠른 배포와 경량 운영이 필요한 환경에서는 Container
  • 최근에는 하이브리드 환경(VM + Container)도 많이 사용됨 (예: Kubernetes on VMware)

Container 특징

  • 개발과 운영의 관심사 분리
  • 지속적인 개발, 통합 및 배포
  • 기민한 앱 생성과 배포
  • 가시성(observability)
  • 개발, 테스팅 및 운영 환경에 걸친 일관성
  • 클라우드 및 OS 배포판 간 이식성
  • 앱 중심 관리

Container Engine

  • 컨테이너를 관리하기 위한 API나 CLI 도구를 제공하는 SW
  • 사용자 입력을 받고, 컨테이너 이미지를 꺼내고(pull), 컨테이너 실행 방법을 명시한 메타데이터를 만든 다음, 컨테이너 런타임에 이 정보들을 전달

Container Runtime

  • 루트 파일시스템과 메타 데이터(spec file)를 받아 컨테이너를 실행하는 도구

Podman 이해

Podman

  • 리눅스 시스템에서 컨테이너 및 컨테이너 이미지를 실행, 관리, 배포할 수 있도록 설계된 Daemonless 컨테이너 엔진

Podman과 Docker의 차이

항목PodmanDocker
데몬 (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 rundocker ps, docker run
  1. Podman은 데몬이 없고(Daemonless), Docker는 데몬(dockerd)이 항상 실행됨.
  2. Podman은 rootless 모드를 기본 지원하여 보안성이 더 뛰어남.
  3. Docker는 docker-compose 기본 지원, Podman은 podman-compose를 추가 설치해야 함.
  4. Podman은 Kubernetes YAML을 쉽게 생성 가능 (podman generate kube).
  5. Podman과 Docker는 거의 동일한 명령어를 사용하며, Docker 이미지를 그대로 사용할 수 있음.

Docker는 익숙한 환경, Podman은 보안성과 유연성이 중요한 환경에서 사용하면 좋음! 🚀

Podman CLI

  • Podman 명령은 Docker-CLI와 유사한 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 컨테이너 삭제

Kubernetes 이해

쿠버네티스

  • 컨테이너화된 애플리케이션을 자동으로 배포, 스케일링 및 관리해 주는 오픈소스 시스템
  • 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장가능한 오픈소스 플랫폼

쿠버네티스 특징

  • 서비스 디스커버리와 로드 밸런싱
  • 스토리지 오케스트레이션
  • 자동화된 롤아웃과 롤백
  • 자동화된 빈 패킹(bin packing)
  • 자동화된 복구(self-healing)
  • 시크릿과 구성 관리

쿠버네티스 클러스터 구성

  • Cluster
    컨테이너화된 앱을 실행하기 위한 일련의 노드 머신의 집합
  • Master
    클러스터 전체를 컨트롤하며 내부에 있는 모든 노드를 관리하는 가상 머신
  • Worker
    마스터에 의해 명령을 받고 실제 컨테이너들이 생성되고 일을 하는 가상 머신

Container Runtime Interface (CRI)

  • 컨테이너 런타임 인터페이스는 쿠버네티스에서 다양한 컨테이너 런타임을 사용할 수 있게 해주는 API

Kubernetes 배포 도구

  • kubeadm
    일반적인 서버 클러스터 환경에서도 쿠버네티스를 쉽게 설치할 수 있게 해주는 관리 툴로서 클러스터를 빠르고 일관되게 설정할 수 있음
  • kops
    자동화된 프로비저닝 시스템으로 AWS에 쉽고 빠르게 쿠버네티스 클러스터를 설치 가능
  • Kubespray
    Ansible을 통해 쿠버네티스 클러스터를 유연하고 쉽게 배포 및 관리할 수 있는 강력한 오픈 소스 툴

Kubernetes 리소스 개념

Namespace

  • 클러스터를 논리적으로 분리하여 사용하는 것을 의미

Deployment

  • 레플리카셋을 관리하면서 실행시켜야 할 파드의 배포 및 관리를 하는 리소스
  • 상태가 없는 앱을 배포할 때 사용되는 가장 기본적인 컨트롤러
  • 파드 개수 유지
  • 배포 시 롤링 업데이트 발생

ReplicaSet

  • 파드의 개수를 유지하고 관리하는 리소스
  • 실행되는 파드를 안정적으로 유지
  • 파드 개수에 대한 가용성 보장

Pod

  • 실제로 컨테이너가 파드에서 실행되며 컨테이너를 돌리는 최소한의 단위
  • 컨테이너가 직접 실행되는 장소
  • 하나 이상의 컨테이너 그룹
  • 컨테이너를 직접 관리하지 않고 파드 단위로 관리

Service

  • 클러스터 외부에서 클러스터 내부 파드에 접근할 수 있도록 IP를 제공하는 리소스
  • 고정된 IP주소 할당
  • 파드 간의 로드 밸런싱 지원
  • 하나 또는 여러 개의 포트 지원

Volume

  • 파드의 일부분으로 동일한 파드 내의 컨테이너끼리는 볼륨 공유가 가능하며 컨테이너의 데이터를 보관하여 유지시키는 역할

Ingress

  • 클러스터 외부로부터 클러스터 내부로 들어오는 네트워크 트래픽을 로드밸런싱
  • L7 로드밸런싱 기능을 수행
  • Service에 외부 URL을 제공
  • 클러스터로 접근하는 URL 별로 다른 서비스에 트래픽을 분산
  • TLS/SSL 인증서 처리
  • 도메인 기반의 Virtual hosting을 지정

StatefulSet

  • 동일한 컨테이너 스펙을 가진 파드들을 관리하며 각 파드들은 각각의 식별자를 가지기 때문에 독자성을 유지
  • 파드들의 순서 및 고유성을 보장
  • 식별자를 가지고 있어 재스케줄링 간에도 지속적인 유지
  • 내부 파드마다 고유한 pvc를 갖도록 설정이 가능하여, 스케일 확장 시 PV를 유지 가능

Deployment vs StatefulSet

항목DeploymentStatefulSet
주요 목적Stateless 애플리케이션 관리Stateful 애플리케이션 관리
Pod 이름랜덤 생성 (nginx-abcde)고정된 이름 (web-0, web-1)
Pod 순서 보장❌ 순서 보장 안 됨✅ 순서 보장 (web-0web-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

  • JOB을 실행하는데 스케줄러 역할

DaemonSet

  • 클러스터 전체에 특정 파드를 실행할 때 사용하거나 특정 노드 또는 모든 노드에 항상 실행되어야 할 특정 파드들을 관리

Persistent Volume

  • 특정 파드와 상관없이 별도의 생명주기를 가지는 독립적인 볼륨

Persistent Volume Claim

  • 사용자가 PV(Persistent Volume)에 하는 요청
  • 파드와 PV를 연결

StorageClass

  • PV로 확보한 스토리지 종류를 정의하는 리소스

PV, PVC 생명주기
1. 생성 (Provisioning)
2. 연결 (Binding)
3. 사용 (Using)
4. 삭제 (Reclaiming)

💻 Kubectl

  • 쿠버네티스 API를 사용하여 쿠버네티스 클러스터의 컨트롤 플레인과 통신하기 위한 CLI
  • kubectl apply -f FILENAME 파일이나 표준입력(stdin)으로부터 리소스에 구성 변경 사항을 적용
  • kubectl create -f FILENAME 파일이나 표준입력에서 하나 이상의 리소스를 생성
  • kubectl get 하나 이상의 리소스를 조회
  • kubectl describe -f FILENAME 하나 이상의 리소스의 상세한 상태 조회
  • kubectl logs 특정 이름을 가진 리소스의 로그 정보 출력
  • kubectl edit 특정 이름을 가진 리소스 정보 수정

Kubernetes 리소스 관리

📝 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 파일을 하나의 파일로 작성하기 위해서는 중간에 ---로 구분 지어 작성

0개의 댓글