ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kubernetes] 도커와 컨테이너
    Engineering/DevOps 2022. 1. 30. 09:42
    반응형

    도커와 컨테이너

    파드, 컨테이너, 쿠버네티스

    • 파드는 워커 노드라는 노드 단위로 관리된다.
    • 워커 노드와 마스터 노드가 모여서 쿠버네티스 클러스터가 된다.
    • 파드는 1개 이상의 컨테이너로 구성되어 있다.

    컨테이너

    • 컨테이너는 하나의 운영 체제 안에서 커널을 공유하며 개별적인 실행 환경을 제공하는 격리된 공간이다.
    • 컨테이너 기술의 핵심은 다음 세 가지다.
      • 컨트롤 그룹 (cgroup)
      • 네임스페이스
      • 통합 파일 시스템 (Union filesystem)

    컨트롤 그룹

    • 프로세스들의 리소스 사용(CPU, 메모리, 디스크 입출력, 네트워크 등)을 제한하고 격리시키는 리눅스 커널 기능이다.
    • 컨테이너는 미리 정의된 제약 조건 하에 CPU와 메모리를 공유할 수 있다.
    • 컨트롤 그룹을 사용하여 컨테이너가 메모리, 디스크 I/O, 네트워크, CPU에 대한 접근을 프로비저닝하고 디바이스에 접근한다.

    주요 7가지 컨트롤 그룹

    • memory cgroup
      • 페이지 접근을 그룹별로 추적하며 물리 메모리, 커널 메모리, 전체 메모리에 대한 제한을 정의할 수 있다.
    • Blkio cgroup
      • 물리 드라이브(ex: 디스크, 솔리드 스테이트, USB 등)와 간ㅌ은 블록 장치에 대한 I/O 액세스에 제한을 설정한다.
    • CPU cgroup
      • CPU당 사용자 및 시스템의 CPU 시간 및 사용량을 추적한다.
    • Freezer cgroup
      • cgroup의 작업을 일시 중지하거나 다시 시작한다.
    • CPUset cgroup
      • 개별 CPU(멀티코어 시스템에서) 및 메모리 노드를 croup의 작업에 할당한다.
      • 멀티 코어 CPU 아키텍처 내의 특정 CPU에 그룹을 고정할 수 있다.
      • 애플리케이션별로 CPU를 고정하면 CPU 사이에서 이동하지 않게 해 로컬 메모리 접근량을 늘리거나 스레드 전환을 최소화해 코드의 성능을 향상시킬 수 있다.
    • Net_cls/net_prio cgroup
      • Linux 트래픽 컨트롤러(tc)가 특정 cgroup 작업에서 발생하는 패킷을 식별하게 하는 클래식 식별자(classid)를 사용하여 네크워크 패킷에 태그를 지정한다.
      • cgroup 내의 프로세스에서 생성되는 송신 트래픽 클래스(cls)나 우선순위(net_prio)를 감시한다.
    • devices cgroup
      • cgroup의 작업 단위로 장치에 대한 액세스 권한을 제어한다.

    네임스페이스

    • VM에서는 각 게스트 머신별로 독립적인 공간을 제공하고 서로가 충돌하지 않도록 하는 기능이 있는데, 리눅스에서는 동일한 역할을 하는 namespace 기능을 커널에 내장하고 있다.
    • 리눅스 네임스페이스는 unshare라는 시스템 호출(syscall)로 생성하며, clone과 setns를 사용하면 unshare 과는 다른 방식으로 네임스페이스를 조작할 수 있다.
      • unshare() - 현재 프로세스를 새로 지정된 네임스페이스에 연결
      • clone() - 새로운 프로세스를 만들고 이를 새로 지정된 네임스페이스에 연결
      • setns() - 이미 존재하는 네임스페이스에 프로세스를 연결
    • 리눅스 커널에서 지원하는 namespace
      • mnt namespace (마운트 네임스페이스)
        • 파일 시스템 마운트 포인트를 격리한다.
        • 호스트 파일 시스템에 영향을 주지 않고, 독립적으로 파일 시스템을 마운트하거나 언마운트 할 수 있다.
      • pid namespace (프로세스)
        • pid namespace 는 PID 집합을 다른 네임스페이스의 PID 집합과 독립적인 프로세스에 할당한다.
        • PID 1인 새로운 네임스페이스인 첫 번째 프로세스가 생성되고, 자식 프로세스는 그 다음 PID를 갖는다.
        • 자식 프로세스가 자신의 PID 네임스페이스를 사용하여 생성된 경우, PID 1을 가지고 있고, 부모 프로세스의 네임스페이스에도 PID가 있다.
      • net namespace (네트워크 네임스페이스)
        • 독립적인 네트워크 스택을 가지며, namespace 간에 network 충돌을 방지한다.
      • ipc namespace (interprocess communication namesapce)
        • 프로세스간의 독립적인 통신통로를 할당한다.
      • uts namespace (UNIX Time-sharing)
        • 단일 시스템이 다른 호스트와 도메인 이름 스키마를 다른 프로세스에 제공할 수 있게 한다.
      • user namespace (UID)
        • user namespace 는 프로세스가 외부에서 허용되는 것과 다른 사용자 식별자 및 권한으로 해당 namespace 내부에서 실행될 수 있도록 격리한다.
        • 프로세스는 네임스페이스 외부에서 0이 아닌 UID를 가질 수 있는 동시에 네임스페이스 내부에 0인 UID를 가질 수 있다. 즉, 프로세스는 user namespace 외부의 작업에 대해 권한이 없지만 namespace 내부에서는 루트권한이 있다.

    통합 파일시스템 (UFS: Union Filesystem)

    • 도커 컨테이너는 UFS 기반으로 동작한다.
    • 복수의 파일시스템을 하나의 파일시스템으로 마운트한다.
    • 두 파일 시스템에서 동일한 파일이 있다면 나중에 마운트된 파일 시스템의 파일을 오버레이한다.
    • UFS 에서는 기존 레이어(하위 레이어) 위에 새로운 레이어(상위 레이어)가 쌓일 경우, 하위 레이어는 읽기 전용 상태가 된다.
    • 하위 파일 시스템에 대한 쓰기 작업은 Cow(Copy On Write) 전략에 따라 복사본을 생성하여 수행하므로 원본 파일 시스템은 변하지 않는다.
    • 레이어화된 파일시스템이 효율적인 이유는 처음 빌드할 때 레이어를 도커가 캐싱하기 때문이다.
      • 예를 들어 우분투 이미지에 아파치 이미지를 추가하여 이미지를 빌드한 후에 다시 우분투 이미지를 기반으로 다시 MySQL 이미지를 빌드한다고 가정할 때, 우분투 레이어가 미리 캐싱되어 있으므로 두 번째 빌드는 훨씬 빠르다.

    이미지 검색 및 내려받기

    • 이미지는 레지스트리(registry)라고 하는 저장소에 저장되어 있다.
    • 레지스트리는 도커 허브처럼 공개된 레지스트리일 수도 있고, 내부에서 직접 구축한 레지스트리일 수도 있다.

    이미지 검색하기

    > docker search <검색어>
    • 검색어를 포함하는 이미지를 찾는다.
    • 이미지는 애플리케이션, 미들웨어 등 고유한 목적에 맞게 패키지되어 있다.
    • docker search 로 찾은 이미지는 docker pull 로 내려받을 수 있다.
    > docker pull <이미지>
    • 이미지를 내려받을 때 사용하는 태그, 레이어, 이미지의 고유 식별 값 등을 볼 수 있다.
    • 태그(tag)
      • Using default tag와 함께 뒤에 따라오는 태그 이름을 통해 이미지를 내려받을 때 사용한 이미지를 알 수 있다.
      • 아무런 값을 주지 않고, 이미지 이름만으로 pull 하면 latest 태그가 적용된다. latest 태그는 가장 최신 이미지를 의미한다.
    • 레이어(layer)
      • 하나의 이미지는 여러 레이어로 이루어져 있어서 레이어마다 Pull complete 메시지가 발생한다.
    • 다이제스트(digest)
      • 이미지의 고유 식별자로, 이미지에 포함된 내용과 이미지의 생성 환경을 식별할 수 있다.
      • 식별자는 해시 함수로 생성되며, 이미지가 동일한지 검증하는 데 사용한다.
    • 상태(status)
      • 이미지를 내려받은 레지스트리, 이미지, 태그 등의 상태 정보를 확인할 수 있다.
      • 형식은 '레지스트리 이름/이미지 이름 이름:태그' 이다.

    컨테이너 실행

    > docker run -d --restart always nginx
    • -d (--detach): 컨테이너를 백그라운드에서 실행
    • --restart always: 예상치 못한 오류가 발생하거나 리눅스 시스템에서 도커 서비스가 중지되는 경우에 컨테이너도 중지되는데, 이때 중지된 컨테이너를 즉시 재시작 하거나 리눅스 시스템에서 도커 서비스가 작동할 때 컨테이너를 자동으로 시작한다.
    • 도커에서 실행한 컨테이너는 호스트 네트워크와 도커 네트워크를 연결하기 위해 포트를 열어주어야 한다.
    • 아래의 명령어와 같이 -p 옵션을 통해 '호스트 네트워크:도커 네트워크'로 요청을 전달하도록 설정할 수 있다.
      > docker run -p 8080:80 --name named-nginx --restart always nginx
      # 호스트 네트워크 8080 포트로 요청이 들어오면 named-nginx 라는 이름을 가진 nginx 컨테이너의 80 포트로 요청을 전달한다.

    컨테이너 볼륨

    • 도커는 컨테이너 내부에서 컨테이너 외부 파일을 사용할 수 있는 방법으로 크게 4가지를 제공한다.
    docker cp 명령어
    # 호스트에 위치한 파일을 구동중인 컨테이너 내부에 복사
    > docker cp <호스트 경로> <컨테이너 이름>:<컨테이너 내부경로>
    Dockerfile ADD
    • 이미지는 Dockerfile을 기반으로 만들어지는데, Dockerfile에 ADD라는 구문으로 컨테이너 내부로 복사할 파일을 지정하면 이미지를 빌드할 때 지정한 파일이 이미지 내부로 복사된다.
    바인드 마운트
    • 호스트의 파일 시스템과 컨테이너 내부를 연결하여 어느 한쪽에서 작업한 내용이 동시에 반영되도록 할 수 있다.
    • 호스트 디렉터리의 내용을 그대로 컨테이너 디렉터리에 덮어쓰므로 주의해야한다.
    볼륨
    • 호스트의 파일 시스템과 컨테이너 내부를 연결하는 것은 바인드 마운트와 동일하지만, 호스트의 특정 디렉토리가 아닌 도커에서 관리하는 볼륨을 컨테이너와 연결한다.
    • 바인드 마운트와 달리 호스트 디렉토리를 컨테이너 디렉토리에 덮어쓰는 구조가 아니라 서로 동기화하는 구조이기 때문에 기존의 컨테이너 디렉토리에 있는 파일들이 보존된다.
    • 다만, 볼륨에 컨테이너 디렉토리와 동일한 파일이 존재한 상태로 연결되는 경우엔 덮어쓰기가 되므로 주의해야한다.

    컨테이너 정지, 삭제

    # 컨테이너 정지
    > docker stop <컨테이너 이름 | ID>
    
    # 컨테이너 삭제
    > docker rm <컨테이너 이름 | ID>
    # 컨테이너가 실행중이어서 삭제 명령이 실패하면 -f(--force) 옵션을 주어 실행중인 컨테이너를 강제로 삭제할 수 있다.

    참고자료

    컨트롤 그룹
    네임스페이스와 cgroup
    Docker volumnes

    컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커

    반응형

    댓글

Designed by Tistory.