티스토리 뷰

반응형

[시작하세요! 도커/쿠버네티스 - www.yes24.com/Product/Goods/93765519]

 

1. 도커 이미지와 컨테이너

  • 도커 이미지
    • 컨테이너를 생성할 때 필요한 요소
    • 여러 개의 계층으로 된 바이너리 파일로 존재하고 컨테이너를 생성하고 실행할 때 읽기 전용으로 사용
    • 이미지 이름의 형식 : [저장소 이름]/[이미지 이름]:[태그]
      • 저장소(Repository) : 이미지가 저장된 장소
        명시되지 않으면 도커에서 기본적으로 제공하는 도커허브의 공식 이미지라는 뜻이지만 생성할 때 생략하는 경우도 있음
      • 이미지 이름 : 해당 이미지가 어떤 역할을 하는지, 생략 불가능
      • 태그 : 이미지의 버전 관리 혹은 리비전(revision) 관리에 사용, 생략시 latest로 인식
  • 도커 컨테이너
    • 이미지로 컨테이너를 생성하면 해당 이미지의 목적에 맞는 파일이 들어 있는 파일시스템과 격리된 시스템 자원 및 네트워크를 사요할 수 있는 독립된 공간이 생성됨
    • 컨테이너는 이미지를 읽기 전용으로 사용하되 이미지에서 변경된 사항만 컨테이너 계층에 저장하므로 컨테이너에서 무엇을 하든지 원래 이미지는 영향을 받지 않음
    • 생성된 각 컨테이너는 독립된 파일시스템을 제공받으며 호스트와 분리되어 있음

2. 도커 컨테이너 다루기

(명령어는 다른글에 정리)

  • 기본적으로 도커는 컨테이너에 172.17.0.x의 IP를 순차적으로 할당

2.5 컨테이너 애플리케이션 구축

  • 컨테이너에 애플리케이션을 하나만 동작시키면 컨테이너 간의 독립성을 보장함과 동시에 애플리케이션의 버전 관리, 소스코드 모듈화 등이 더욱 쉬워진다
  • 한 컨테이너에 프로세스 하나만 실행하는 것이 도커의 철학

2.6 도커 볼륨

  • 이미 생성된 이미지는 어떠한 경우로도 변경되지 않으며, 컨테이너 계층에 원래 이미지에서 변경된 파일시스템 등을 저장한다
  • 컨테이너의 데이터를 영속적(persistent) 데이터로 활용할 수 있는 방법 -> 볼륨을 활용
  • 볼륨을 활용하는 방법
    • 호스트와 볼륨을 공유
      • 컨테이너를 삭제해도 데이터는 삭제되지 않음
      • -v 옵션을 사용해서 호스트의 디렉터리와 컨테이너의 디렉터리 공유
      • 호스트의 디렉터리를 컨테이너의 디렉터리에 마운트함
    • 볼륨 컨테이너를 활용
      • -v 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유하는 것
      • 컨테이너를 생성할 때 --volumes-from 옵션을 설정하면 -v 또는 --volume 옵션을 적용한 컨테이너의 볼륨 디렉터리를 공유할 수 있음
      • 여러 개의 컨테이너가 동일한 컨테이너에 --volumes-from 옵션을 사용함으로써 볼륨을 공유해 사용할 수도 있음
      • 호스트에서 볼륨만 공유하고 별도의 역할을 담당하지 않는 '볼륨 컨테이너'로 활용도 가능
    • 도커가 관리하는 볼륨을 생성
      • docker volume 명령어 활용
      • 볼륨 생성할 때 플러그인 드라이버를 설정해 여러 종류의 스토리지 백엔드를 사용할 수 있음
      • 여러 개의 컨테이너에 공유되어 활용될 수 있음
      • 볼륨은 디렉터리 하나에 상응하는 단위로 도커 엔진에서 관리
      • 호스트에 저장함으로써 데이터를 보존하지만 파일이 실제로 어디에 저장되는지 사용자는 알 필요가 없음
        • docker inspect 명령어로 실제로 어디에 저장되는지 알 수 있음
      • 도커 볼륨을 사용하고 있는 컨테이너를 삭제해도 볼륨이 자동으로 삭제되지는 않음
        • docker volume prune : 사용되지 않는 볼륨을 한꺼번에 삭제
  • stateful/stateless
    • 스테이트풀(stateful)한 설계
      • 컨테이너가 데이터를 저장하고 있어 상태가 있는 경우
      • 컨테이너 자체에서 데이터를 보관하므로 지양하는 것이 좋음
    • 스테이트리스(stateless)한 설계
      • 컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하도록 설계하는 것
      • 컨테이너 자체는 상태가 없고 상태를 결정하는 데이터는 외부로부터 제공받음
      • 컨테이너가 삭제돼도 데이터는 보존되므로 도커를 사용할 때 매우 바람직한 설계

2.7 도커 네트워크

  • 도커 네트워크 구조
    • 도커는 컨테이너 내부 IP를 순차적으로 할당하며 컨테이너를 재시작할 때마다 변경될 수 있음
      • 내부망에서만 쓸 수 있는 IP임
    • 도커는 각 컨테이너에 외부와의 네트워크를 제공하기 위해 각 컨테이너마다 veth로 시작하는 가상 네트워크 인터페이스를 호스트에 자동으로 생성함
    • 호스트에서 ifconfig 명령어를 실행했을 때
      • eth0 : 공인 ip 또는 내부 ip가 할당되어 실제로 외부와 통신할 수 있는 호스트이 네트워크 인터페이스
      • veth_____ : 컨테이너를 시작할 때 생성, 각 컨테이너의 eth0와 연결
      • docker0 : 브리지, 각 veth 인터페이스와 바인딩돼 호스트의 eth0 인터페이스와 이어주는 역할
    • 컨테이너의 eth0 인터페이스는 호스트의 veth____ 라는 인터페이스와 연결됐으며 veth 인터페이스는 docker0 브리지와 바인딩돼 외부와 통신할 수 있습니다
  • 도커 네트워크 기능
    • docker0 브리지로 외부와 통신할 수 있지만 다른 여러 네트워크 드라이버를 쓸 수도 있음
      • 도커에서 제공 : 브리지(bridge), 호스트(host), 논(none), 컨테이너(container), 오버레이(overlay)
      • 서드파티(third-party) : weave, falnnel, openvswitch
    • 브리지 네트워크
      • 사용자 정의 브리지를 새로 생성해 각 컨테이너에 연결하는 네트워크 구조
      • docker0이 아닌 새로운 브리지 타입의 네트워크를 생성할 수 있음
      • docker network create 명령어로 생성, docker network disconnect/connect 명령어로 붙이고 떼기 가능
      • --net-alias : 브리지 타입의 네트워크와 이 옵션을 함께 쓰면 특정 호스트 이름으로 컨테이너 여러 개에 접근할 수 있음
        • 예를 들어 --net A --net-alias B라는 옵션을 준 컨테이너 3개를 생성했을 때 --net A 옵션을 준 새로운 컨테이너 생성해서 ping을 B로 보내면 이전에 생성한 컨테이너 3개가 라운드로빈으로 돌아가며 ping이 전송이된걸 확인 할 수 있다
        • 도커 엔진에 내장된 DNS가 B라는 호스트 이름을 --net-alis 옵션으로 B를 설정한 컨테이너로 변환(resolve)함
    • 호스트 네트워크
      • 네트워크를 호스트로 설정하면 호스트의 네트워크 환경을 그대로 쓸 수 있음
      • 호스트 드라이버의 네트워크는 별도로 생성할 필요 없이 기존의 host라는 이름의 네트워크 사용
      • 컨테이너의 호스트 이름은 도커 엔진이 설치된 호스트 머신의 호스트 이름으로 설정됨
      • 컨테이너의 네트워크를 호스트 모드로 설정하면 컨테이너 내부의 애플리케이션을 별도의 포트 포워딩 없이 바로 서비스할 수 있음
    • 논 네트워크
      • 아무런 네트워크를 쓰지 않는 것
      • 외부와의 연결이 단절됨
      • 컨테이너 내부에서 네트워크 인터페이스를 확인하면 로컬호스트(lo) 외에 존재하지 않음
    • 컨테이너 네트워크
      • --net 옵션으로 container를 입력하면 다른 컨테이너의 네트워크 네임스페이스 환경을 공유
      • 내부 IP를 새로 할당받지 않으며 호스트에 veth로 시작하는 가상 네트워크 인터페이스도 생성되지 않음
    • 도커 DNS : 호스트 이름으로 유동적인 컨테이너를 찾을 때 주로 사용됨
      • --link : 컨테이너의 IP가 변경돼도 별명으로 컨테이너를 찾을 수 있게 DNS에 의해 자동으로 관리됨
        • 디폴트 브리지 네트워크 컨테이너의 DNS 사용
      • --net-alias : 사용자가 정의한 브리지 네트워크에 사용되는 내장 DNS 서버 사용
        • DNS 서버는 라운드 로빈 방식을 이용해 컨테이너의 IP 리스트를 반환함
    • MacVLAN 네트워크
      • 호스트의 네트워크 인터페이스 카드를 가상화해 물리 네트워크 환경을 컨테이너에게 동일하게 제공
      • 컨테이너는 물리 네트워크상에서 가상의 맥(MAC) 주소를 가지며 해당 네트워크에 연결된 다른 장치와의 통신이 가능해짐
      • 여기에 연결된 컨테이너는 기본적으로 할당되는 IP 대역인 172.17.X.X 대신 네트워크 장비의 IP를 할당 받음
      • MacVLAN을 사용하는 컨테이너들과 동일한 IP 대역을 사용하는 서버 및 컨테이너들은 서로 통신이 가능함
        • 호스트와는 통신 불가능

2.8 컨테이너 로깅

  • 도커는 컨테이너의 표준출력(StdOut)과 에러(StdErr) 로그를 별도의 메타데이터 파일로 저장하며 이를 확인하는 명령어를 제공한다
  • json-file 로그 사용하기
    • docker logs 명령어로 컨테이너의 표준 출력 확인
    • 컨테이너 로그는 JSON 형태로 도커 내부에 컨테이너의 ID로 시작하는 파일명으로 저장됨

2.9 컨테이너 자원 할당 제한

  • 컨테이너에 자원 할당 옵션을 설정하지 않으면 호스트의 자원을 전부 점유해 다른 컨테이너들뿐 아니라 호스트 자체의 동작이 멈출 수도 있다
  • 컨테이너 메모리 제한
    • docker run 명령어에 --memory를 지정해 컨테이너의 메모리를 제한할 수 있음
      • 컨테이너 내에서 동작하는 프로세스가 컨테이너에 할당된 메모리를 초과하면 컨테이너는 자동으로 종료됨
    • 기본적으로 컨테이너의 swap 메모리는 메모리의 2배로 설정되지만 별도로 지정할 수 있음
  • 컨테이너 CPU 제한
    • --cpu-shares 옵션으로 컨테이너에 가중치를 설정해 해당 컨테이너가 CPU를 상대적으로 얼마나 사용할 수 있는지를 나타낼 수 있음
      • 기본값은 1024로 CPU 할당에서 1의 비중을 뜻함
    • --cpuset-cpus 옵션으로 호스트에 CPU가 여러 개 있을 때 컨테이너가 특정 CPU만 사용하도록 설정할 수 있음
    • --cpu-peroid, --cpu-quota 옵션으로 컨테이너의 CFS(Completely Fair Scheduler) 주기를 변경할 수 있다
      • --cpu-period의 기본값은 100000(100ms)
      • --cpu-quota는 --cpu-peroid에 설정된 시간 중 CPU 스케줄링에 얼마나 할당할 것인지를 정함
    • --cpus 옵션은 --cpu-period, --cpu-quota와 동일한 기능을 하며 CPU의 개수를 직접 지정할 수 있음
    • Block I/O 제한
      • run 명령어의 옵션들로 블록 입출력을 제한할 수 있음
      • Direct I/O인 경우에만 블록 입출력이 제한되고 Buffered I/O는 제한되지 않음
      • --device-write-bps, --device-read-bps로 쓰고 읽는 작업의 초당 제한을 설정할 수 있음
      • --device-write-iops, --deivce-read-iops는 상대적인 값 입력해서 제한
    • 스토리지 공간 제한은 스토리지 드라이버마다 가능한지 안한지 다른데 안하는게 좋을 수도 있음

 

3. 도커 이미지

  • 도커 허브(Docker Hub) : 도커가 공식적으로 제공하고 있는 중앙 이미지 저장소
    • 도커는 기본적으로 이 곳에서 이미지를 내려받음

3.1 도커 이미지 생성

  • docker commit 명령어로 컨테이너를 이미지로 만들 수 있음

3.2 이미지 구조 이해

  • 이미지를 커밋할 때 컨테이너에서 변경된 사항만 새로운 레이어로 저장하고, 그 레이어를 포함해 새로운 이미지를 만듦
  • docker rmi : 이미지 삭제
    • 삭제되는 이미지의 부모 이미지가 존재하지 않아야만 해당 이미지의 파일이 실제로 삭제됨

3.3 이미지 추출

  • docker save
    • 컨테이너의 커맨드, 이미지 이름과 태그 등 이미지의 모든 메타데이터를 포함해 하나의 파일로 추출할 수 있음
  • docker load
    • docker save로 저장한 데이터를 다시 도커에 로드
    • 이전의 이미지와 완전히 동일한 이미지가 도커 엔진에 생성됨
  • docker export 와 docker import 
    • 이미지를 레이어 구조가 아닌 단일 파일로 저장하기 때문에 여러 버전의 이미지를 추출하면 용량을 각기 차지함

3.4 이미지 배포

  • 도커허브
  • 도커 사설 레지스트리(Docker private Registry)
    • 컨테이너로서 구현됨(이미지는 도커에서 공식적으로 제공)
    • 기본적으로 5000 포트 사용

 

4. Dockerfile

4.1 이미지를 생성하는 방법

  • 컨테이너로 이미지 생성
    • 아무것도 존재하지 않는 이미지로 컨테이너를 생성
    • 애플리케이션을 위한 환경을 설치하고 소스코드 등을 복사해 잘 동작하는 것을 확인
    • 컨테이너를 이미지로 커밋(commit)
  • Dockerfile로 이미지 생성
    • 완성된 이미지를 생성하기 위해 컨테이너에 설치해야 하는 패키지, 추가해야 하는 소스코드, 실행해야 하는 며령어와 셸 스크립트 등을 하나의 파일에 기록
    • 도커는 이 파일을 읽어 컨테이너에서 작업을 수행한 뒤 이미지로 만들어냄

4.2 Doclerfile 작성

  • Dockerfile에는 컨테이너에서 수행해야 할 작업을 명시함
  • 도커 엔진은 Dockerfile을 읽어 들일 때 기본적으로 현재 디렉터리에 있는 Dockerfile이라는 이름을 가진 파일을 선택함
  • Dockerfile은 빈 디렉터리에 저장하는 것이 좋음
  • Dockefile은 한 줄이 하나의 명령어가 되고 명령어(Instruction)를 명시한 뒤에 옵션을 추가하는 방식
  • Dockerfile의 명령어는 위에서 한 줄 씩 실행됨

4.3 Dockerfile 빌드

4.3.1 이미지 생성

  • docker build 명령어로 이미지 생성

4.3.2 빌드 과정 살펴보기

  • 빌드 컨텍스트
    • 이미지 빌드를 시작하면 도커는 가장 먼저 빌드 컨텍스트를 읽어 들임
      • 빌드 컨텍스트 : 이미지를 생성하는 데 필요한 각종 파일, 소스코드, 메타데이터 등을 담고 있는 디렉터리
        • Dockerfile이 위치한 디렉터리가 빌드 컨텍스트가 됨
        • Dockerfile에서 빌드될 이미지에 파일을 추가할 때 사용됨
        • 컨텍스트는 build 명령어의 맨 마지막에 지정된 위치에 있는 파일을 전부 포함함
      • .dockerignore : 빌드 시 이 파일에 명시된 이름의 파일을 컨텍스트에서 제외함
        • 컨텍스트의 최상위 경로, 즉 build 명령어에서 맨 마지막에 오는 경로인 Dockerfile이 위치한 경로와 같은 곳에 위치해야 함
        • 컨텍스트에서 제외할 파일의 경로는 Dockerfile이 존재하는 경로를 기준으로 함
        • '!'로 특정 파일을 제외하지 않음을 나타낼 수 있음
  • Dockerfile을 이용한 컨테이너 생성과 커밋
    • build 명령어는 Dockerfile에 기록된 대로 컨테이너를 실행한 뒤 완성된 이미지를 만들어 냄
    • Dockerfile의 명령어 한 줄이 실행될 때마다 이전 Step에서 생성된 이미지에 의해 새로운 컨테이너가 하나씩 생성되며
      Dockerfile에 적힌 명령어를 수행하고 이를 새로운 이미지 레이어로 저장함
    • 이미지 빌드가 완료되면 Dockerfile의 명령어 줄 수 만큼의 레이어가 존재하게 되며
      중간에 컨테이너도 같은 수만큼 생성되고 삭제됨
  • 캐시를 이용한 이미지 빌드
    • 한 번 이미지 빌드를 마치고 난 뒤 다시 같은 빌드를 진행하면 이전의 이미지 빌드에서 사용했던 캐시를 사용함
    • 이전에 빌드했던 Dockerfile에 같은 내용이 있다면 build 명령어는 이를 새로 빌드하지 않고
      같은 명령어 줄까지 이전에 사용한 이미지 레이어를 활용해 이미지를 생성함
    • 캐시를 사용하지 않으려면 build 명령어에 --no-cache 옵션 추가
    • --cache-from 옵션으로 캐시로 사용할 이미지를 직접 지정할 수도 있음

4.3.3 멀티 스테이지를 이용한 Dockerfile 빌드하기

  • 하나의 Dockerfile 안에 여러 개의 FROM 이미지를 정의함으로써 빌드 완료 시 최종적으로 생성될 이미지의 크기를 줄이는 역할
  • 반드시 필요한 실행 파일만 최종 이미지 결과물에 포함시킴으로써 이미지 크기를 줄일 때 유용하게 사용할 수 있음

4.4 기타 Dockerfile 명령어

(dockerfile 정리한 글 참고)

 

4.5 Dockerfile로 빌드할 때 주의할 점

  • Dockerfile을 작성할 때 좋은 습관(practice)
    • 하나의 명령어를 \(역슬래시)로 나눠서 가독성을 높일 수 있도록 작성
    • .dockerignore 파일을 작성해 불필요한 파일을 빌드 컨텍스트에 포함하지 않음
    • 빌드 캐시를 이용해 기존에 사용했던 이미지 레이어를 재사용
  • Dockerfile을 아무렇게나 작성하면 저장 공간을 불필요하게 차지하는 이미지나 레이어가 너무 많은 이미지가 생성될 수 있음
    • Dockerfile을 작성할 때 &&로 각 RUN 명령어를 하나로 묶어 하나의 RUN으로 여러 개의 명령어를 실행하도록 작성하면
      이미지 레이어의 개수가 하나로 줄어든다
  • 다른 사람이 빌드한 이미지에 불필요한 이미지 레이어가 들어있다면 해당 이미지로 컨테이너를 생성하고 docker export, import 명령어를 사용해 컨테이너를 이미지로 만들어서 이미지의 크기를 줄일 수 있음
    • 익스포트된 파일을 임포트해서 다시 도커에 저장하면 레이어가 한 개로 줄어듦
    • 이전 이미지에 저장돼 있던 각종 이미지 설정은 잃어버리게 되므로 조심해야 됨

 

5. 도커 데몬

5.1 도커의 구조

  • 클라이언트로서의 도커와 서버로서의 도커
    • 클라이언트로서의 도커
      • 컨테이너나 이미지를 다루는 명령어는 /usr/bin/docker에서 실행되지만
        도커 엔진의 프로세스는 /usr/bin/dockerd 파일로 실행됨
      • docker 명령어가 실제 도커 엔진이 아닌 클라이언트로서의 도커이기 때문
      • 도커 서버의 API를 사용할 수 있도록 CLI(Command Line Interface)를 제공하는 것
      • 사용자가 docker로 시작하는 명령어를 입력하면 도커 클라이언트를 사용하는 것이며
        도커 클라이언트는 입력된 명령어를 로컬에 존재하는 도커 데몬에게 API로서 전달함
      • 도커 클라이언트는 /var/run/docker.sock에 위치한 유닉스 소켓을 통해 도커 데몬의 API를 호출함
        • 도커 클라이언트가 사용하는 유닉스 소켓은 같은 호스트 내에 있는 도커 데몬에게 명령을 전달할 때 사용됨
    • 서버로서의 도커
      • 실제로 컨테이너를 생성하고 실행하며 이미지를 관리하는 주체는 도커 서버
      • 도커서버는 dockerd 프로세스로 동작
      • 도커 엔진은 외부에서 API 입력을 받아 도커 엔진의 기능을 수행하는데
        도커 프로세스가 실행되어 서버로서 입력을 받을 준비가 된 상태를 도커 데몬이라고 이야기함
  • docker 명령어를 입력했을 때 실제로 도커게 제어되는 순서
    • 1. 사용자가 docker ps 같은 도커 명령어를 입력한다
    • 2. /usr/bin/docker는 /var/run/docker.sock 유닉스 소켓을 사용해 도커 데몬에게 명령어를 전달한다
    • 3. 도커 데몬은 이 명령어를 파싱하고 명령어에 해당하는 작업을 수행
    • 4. 수행 결과를 도커 클라이언트에게 반환하고 사용자에게 결과를 출력

5.2 도커 데몬 실행

  • 도커 데몬은 일반적으로 아래와 같은 명령어로 시작, 정지할 수 있음
# service docker start
# service docker stop
  • "dockerd"로 바로 도커 데몬을 실행할 수도 있음
반응형

'study > 시작하세요! 도커 쿠버네티스' 카테고리의 다른 글

05. 쿠버네티스  (0) 2021.07.26
01. 도커란?  (0) 2020.12.26
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함