티스토리 뷰
반응형
[시작하세요! 도커/쿠버네티스 - www.yes24.com/Product/Goods/93765519]
1. 도커 이미지와 컨테이너
- 도커 이미지
- 컨테이너를 생성할 때 필요한 요소
- 여러 개의 계층으로 된 바이너리 파일로 존재하고 컨테이너를 생성하고 실행할 때 읽기 전용으로 사용
- 이미지 이름의 형식 : [저장소 이름]/[이미지 이름]:[태그]
- 저장소(Repository) : 이미지가 저장된 장소
명시되지 않으면 도커에서 기본적으로 제공하는 도커허브의 공식 이미지라는 뜻이지만 생성할 때 생략하는 경우도 있음 - 이미지 이름 : 해당 이미지가 어떤 역할을 하는지, 생략 불가능
- 태그 : 이미지의 버전 관리 혹은 리비전(revision) 관리에 사용, 생략시 latest로 인식
- 저장소(Repository) : 이미지가 저장된 장소
- 도커 컨테이너
- 이미지로 컨테이너를 생성하면 해당 이미지의 목적에 맞는 파일이 들어 있는 파일시스템과 격리된 시스템 자원 및 네트워크를 사요할 수 있는 독립된 공간이 생성됨
- 컨테이너는 이미지를 읽기 전용으로 사용하되 이미지에서 변경된 사항만 컨테이너 계층에 저장하므로 컨테이너에서 무엇을 하든지 원래 이미지는 영향을 받지 않음
- 생성된 각 컨테이너는 독립된 파일시스템을 제공받으며 호스트와 분리되어 있음
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)한 설계
- 컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하도록 설계하는 것
- 컨테이너 자체는 상태가 없고 상태를 결정하는 데이터는 외부로부터 제공받음
- 컨테이너가 삭제돼도 데이터는 보존되므로 도커를 사용할 때 매우 바람직한 설계
- 스테이트풀(stateful)한 설계
2.7 도커 네트워크
- 도커 네트워크 구조
- 도커는 컨테이너 내부 IP를 순차적으로 할당하며 컨테이너를 재시작할 때마다 변경될 수 있음
- 내부망에서만 쓸 수 있는 IP임
- 도커는 각 컨테이너에 외부와의 네트워크를 제공하기 위해 각 컨테이너마다 veth로 시작하는 가상 네트워크 인터페이스를 호스트에 자동으로 생성함
- 호스트에서 ifconfig 명령어를 실행했을 때
- eth0 : 공인 ip 또는 내부 ip가 할당되어 실제로 외부와 통신할 수 있는 호스트이 네트워크 인터페이스
- veth_____ : 컨테이너를 시작할 때 생성, 각 컨테이너의 eth0와 연결
- docker0 : 브리지, 각 veth 인터페이스와 바인딩돼 호스트의 eth0 인터페이스와 이어주는 역할
- 컨테이너의 eth0 인터페이스는 호스트의 veth____ 라는 인터페이스와 연결됐으며 veth 인터페이스는 docker0 브리지와 바인딩돼 외부와 통신할 수 있습니다
- 도커는 컨테이너 내부 IP를 순차적으로 할당하며 컨테이너를 재시작할 때마다 변경될 수 있음
- 도커 네트워크 기능
- 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 리스트를 반환함
- --link : 컨테이너의 IP가 변경돼도 별명으로 컨테이너를 찾을 수 있게 DNS에 의해 자동으로 관리됨
- MacVLAN 네트워크
- 호스트의 네트워크 인터페이스 카드를 가상화해 물리 네트워크 환경을 컨테이너에게 동일하게 제공
- 컨테이너는 물리 네트워크상에서 가상의 맥(MAC) 주소를 가지며 해당 네트워크에 연결된 다른 장치와의 통신이 가능해짐
- 여기에 연결된 컨테이너는 기본적으로 할당되는 IP 대역인 172.17.X.X 대신 네트워크 장비의 IP를 할당 받음
- MacVLAN을 사용하는 컨테이너들과 동일한 IP 대역을 사용하는 서버 및 컨테이너들은 서로 통신이 가능함
- 호스트와는 통신 불가능
- docker0 브리지로 외부와 통신할 수 있지만 다른 여러 네트워크 드라이버를 쓸 수도 있음
2.8 컨테이너 로깅
- 도커는 컨테이너의 표준출력(StdOut)과 에러(StdErr) 로그를 별도의 메타데이터 파일로 저장하며 이를 확인하는 명령어를 제공한다
- json-file 로그 사용하기
- docker logs 명령어로 컨테이너의 표준 출력 확인
- 컨테이너 로그는 JSON 형태로 도커 내부에 컨테이너의 ID로 시작하는 파일명으로 저장됨
2.9 컨테이너 자원 할당 제한
- 컨테이너에 자원 할당 옵션을 설정하지 않으면 호스트의 자원을 전부 점유해 다른 컨테이너들뿐 아니라 호스트 자체의 동작이 멈출 수도 있다
- 컨테이너 메모리 제한
- docker run 명령어에 --memory를 지정해 컨테이너의 메모리를 제한할 수 있음
- 컨테이너 내에서 동작하는 프로세스가 컨테이너에 할당된 메모리를 초과하면 컨테이너는 자동으로 종료됨
- 기본적으로 컨테이너의 swap 메모리는 메모리의 2배로 설정되지만 별도로 지정할 수 있음
- docker run 명령어에 --memory를 지정해 컨테이너의 메모리를 제한할 수 있음
- 컨테이너 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는 상대적인 값 입력해서 제한
- 스토리지 공간 제한은 스토리지 드라이버마다 가능한지 안한지 다른데 안하는게 좋을 수도 있음
- --cpu-shares 옵션으로 컨테이너에 가중치를 설정해 해당 컨테이너가 CPU를 상대적으로 얼마나 사용할 수 있는지를 나타낼 수 있음
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으로 여러 개의 명령어를 실행하도록 작성하면
이미지 레이어의 개수가 하나로 줄어든다
- 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를 호출함
- 도커 클라이언트가 사용하는 유닉스 소켓은 같은 호스트 내에 있는 도커 데몬에게 명령을 전달할 때 사용됨
- 컨테이너나 이미지를 다루는 명령어는 /usr/bin/docker에서 실행되지만
- 서버로서의 도커
- 실제로 컨테이너를 생성하고 실행하며 이미지를 관리하는 주체는 도커 서버
- 도커서버는 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
링크
TAG
- k8s
- kotlin
- 도커
- QuickTimePlayer
- 도메인주도설계
- linuxkit
- back merge
- docker pull limit
- Spring
- springboot
- docker for mac
- IntelliJ
- java
- clean code
- 자바
- 스프링부트
- gasmask
- 코틀린
- JavaScript
- 쿠버네티스
- ImagePullBackOff
- 스프링
- 자바스크립트
- cacheable
- kotlin In Action
- ddd
- gradle
- Kubernetes
- 클린코드
- docker
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함