도커, 컨테이너 빌드업!
클라우드 컴퓨팅 개요
클라우드는 인프라에 사용되는 서버, 저장소, 데이터베이스, 네트워크, 데이터베이스, 소프트웨어 데이터 분석등을 포함해 사용자가 언제든지 인터넷과 모바일 등을 통해 IT 서비스를 제공받을 수 있도록 하는 컴퓨팅 기술이다.
클라우드 컴퓨팅이란?
- 인터넷 기술을 사용해서 다수의 사용자에게 하나의 서비스로서 방대한 IT 능력을 제공하는 컴퓨팅 방식
특징
- 주문형 셀프 서비스 on demand self service
- 고객이 IT 서비스 제공자의 개입 없이 원하는 시점에 바로 서비스를 이용할 수 있다.
- 광대역 네트워크 접근 broad network access
- 각 클라우드 서비스 업체가 제공하는 광대역 네트워크를 이용하여 다양한 클라이언트 플랫폼이 빠르게 접속할 수 있다.
- 신속한 탄력성과 확장성, rapid elasticity and scalability
- 자동 조정 기능을 통해 몇 분 안에 신속한 확장과 축소를 조정할 수 있다.
- 자원의 공동관리, resource pooling
- 물리적 및 가상화된 자원을 풀로 관리하며, 탄력적으로 업무 상황에 맞게 사용자 요구에 따라 동적으로 할당 또는 재할당된다.
- 측정 가능한 서비스, measured service
- 자원 사용량이 실시간으로 수집되는 요금산정기능을 통해 비용이 발생한다.
클라우드 컴퓨팅 구조
물리적 시스템, 가상화, 프로비져닝 계층은 자원 활용과 관련되어있고 클라우드 컴퓨팅 서비스 관리 체계, 클라우드 서비스 계층은 클라우드 서비스와 관련있다.
- 물리적 계층 : 여러 형태의 서버 계열을 활용하여 서버에 탑재된 수평적으로 확장 가능한 스토리지 및 네트워크등의 물리적 요소
- 이를 기반으로 서버, 스토리지, 네트워크 가상화는 민첩성을 제공하고, IT 서비스 공급자는 클라우드 서버 프로비저닝 또는 프로비저닝 해제를 신속히 수행하여 서비스 사용자의 요구를 충족할 수 있다.
- 클라우드 컴퓨팅 서비스 관리 체계 계층
- 안정적인 클라우드 서비스를 위한 성능 및 고가용성, 소프트웨어 라이선스와 패치 관리, 사용량 요금 산정을 통한 과금 관리, 기본적인 클라우드 보안 관리 요소가 결합되어 있다.
- : 물리적 시스템 계층에서 제공되는 자원에 대한 전반적인 라이프사이클 관리와 모니터링을 지원한다.
컨테이너 기술과 도커
가상 머신과 컨테이너
가상화 : 물리적 구성은 은폐하고, 가상환경을 여러 개 만들어, 개별 가상머신이 자원을 갖추고 있게 만드는 기술
- 프로비저닝 : IT인프라 자원을 사용자의 니즈에 맞게 할당/배치/배포해서 시스템을 사용할 수 있도록 하는 기술
- 하이퍼바이저 : 물리서버 위에 존재하는 가상화 계층으로서, OS구동을 위한 HW환경을 가상으로 제공
하이퍼바이저
하드웨어 가상화
컨테이너
프로세스 가상화
- 컨테이너 기술의 장점
- 하이퍼바이저와 게스트 OS가 없어 가볍다.
- 경량이기 때문에 만들어진 이미지 복제, 이관, 배포가 쉽다.
- 게스트 OS를 부팅하지 않기 때문에 애플리케이션 시작 시간이 빠르다.
- 가상머신보다 경량이므로 더 많은 애플리케이션을 실행할 수 있다.
도커
컨테이너는 코드와 모든 종속성을 패키지화하는 표준 소프트웨어 단위로, 애플리케이션이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 한다.
도커 컨테이너 이미지는 애플리케이션을 실행하는 데 필요한 모든 것(코드, 런타임, 라이브러리 등)을 포함하는 경량의 독립형 실행 가능 소프트웨어 패키지라고 정의할 수 있다.
[ 도커 주요 기능 ]
- LXC(리눅스 컨테이너)를 이용한 컨테이너 구동
containerd는 리눅스 및 윈도우용 데몬으로, 이미지 전송 및 스토리지에서 컨테이너 실행 및 감독, 네트워크 연결까지 호스트 시스템 전체 컨테이너의 라이프사이클을 관리한다. - 통합 BuildKit
빌드킷은 도커파일의 설정 정보를 이용하여 도커 이미지를 빌드하는 오픈 소스 도구이며, 빠르고 정확하게 여러가지 아키텍처 향상 기능을 제공한다. - 도커 CLI 기반
도커 명령을 수행하는 기본적인 방법을 CLI로 제공한다.
도커를 사용하는 이유
예를 들어 node.js로 만든 애플리케이션을 테스트해야하는 상황에서 현재 로컬에 node.js를 실행하려면 npm이라는 모듈이 필요하다. 만약 이 애플리케이션이 하나의 모듈이 아니라 여러 가지 의존성이 있는 애플리케이션이며 데이터베이스까지 필요하다면? 환경설정과 애플리케이션을 설치하는 데 많은 시간을 투자해야한다. 만약 각각의 의존성이 다른 애플리케이션이 여러개라면 환경설정에 걸리는 시간은 배로 늘어난다. 이를 도커로 단축시킬 수 있다.
도커에 사전에 만들어진 이미지를 통해 컨테이너 안에서 테스트할 수 있다.
- 도커 엔진 : 도커를 이용한 애플리케이션 실행 환경 제공을 위한 핵심 요소
- 도커 허브 : 도커 사용자들과 함께 도커 컨테이너 이미지를 공유하는 클라우드 서비스
- docker-compose : 의존성 있는 독립된 컨테이너에 대한 구성 정보를 YAML코드로 작성하여 일원화된 애플리케이션 관리를 가능하게 하는 도구
- docker Kitematic : 컨테이너를 이용한 작업을 수행할 수 있는 GUI 제공
- docker registry :
- docker machine :
- docker swarm :
- docker ps -a : 실행된 모든 컨테이너의 정보를 제공
우리는 Nginx를 위한 환경 구성, 설치, 서비스 시작 그 어떤 것도 하지 않고 도커를 이용하여 컨테이너 nginx 서비스를 배포할 수 있다. - 도커의 민텁한 애플리케이션 배포 기능
도커 엔진은 서버와 클라이언트로 구분된다. 클라이언트는 도커의 명령을 받고 결과를 출력하고 서버는 도커 엔진, 도커 데몬을 이용하여 컨테이너 시작, 운영 , 정지등을 담당한다.
클라이언트는 도커 명령을 수행하는 명령줄을 제공 → 수행된 도커 명령은 서버의 도커 데몬으로 전달 → 도커 데몬은 docker socket이 보유한 도커 API를 이용해 컨테이너 생성 → 수행된 컨테이너에 포함된 서비스 결과를 클라이언트에 전달
docker system df
도커 시스템이 사용하는 디스크 사용량에 대한 현재 상태 조회
-v : 세부정보를 확인할 수 있다.
docker system events
도커 서버에서 발생하는 도커 관련 이벤트 정보를 표시하는 명령어
--filter 옵션을 이용해서 원하는 정보만 추출하여 볼 수 있다.
컨테이너 서비스
컨테이너에 서비스하고자 하는 애플리케이션 코드와 프로세스를 격리한다.
대부분의 개발자가 개발, 테스트, 배포, 운영의 컴퓨팅 환경 차이로 인한 시행착오 및 다양한 오류해결에 너무 많은 시간을 소비하는 공통적인 문제를 가지고 있어 이를 해결할 수 있는 도커 기반의 컨테이너 서비스 환경으로 전환하고 있다.
컨테이너 서비스는 기존 환경과 다르게 애플리케이션 실행에 필요한 바이너리, 라이브러리 및 구성 파일등을 패키지로 묶어 배포하는 방식으로 논리적 패키징 메커니즘을 제공한다. 애플리케이션이 가지고 있는 운영체제, 하드웨어에 대한 의존성 문제를 해결한 것이다. 따라서 어떤 환경에서든 컨테이너 기반의 애플리케이션을 개발하고 배포할 수 있다.
→ 이렇게 호스트 운영체제를 공유하고 애플리케이션에 필요한 환경을 패키징하는 것을 운영체제 레벨 가상화라고 부른다.
- 하드웨어 레벨 가상화 : 하이퍼바이저 등을 이용한 가상머신의 방식을 말한다.
- 운영체제 레벨 가상화 : 컨테이너 기반의 애플리케이션 서비스 방식
도커 기반 애플리케이션 개발의 라이프사이클
- 애플리케이션 코드 개발
- : 특정 서비스 구동을 위한 애플리케이션 코드 및 웹 화면 구성등을 위한 코드를 개발한다.
- 베이스 이미지를 이용한 Dockerfile 관리
- 개발에 필요한 인프라 구성 요소를 Dockerfile에 작성한다. 즉, 도커 허브를 통해 베이스 이미지를 다운로드하고 다양한 구동 명령어(FROM, RUN, CMD, ENDPOINT, ENV, ADD 등)와 1번에서 작성한 애플리케이션 코드, 라이브러리, 여러 도구를 Dockerfile에 포함시킨다.
- Dockerfile build를 통한 새로운 이미지 생성각 단계별로 실행되는 로그를 화면에서 확인하며 이때 오류 발생 내용도 확인할 수 있다.
- docker build 명령을 통해 작성한 Dockerfile을 실행한다.
- 생성된 이미지를 이용한 컨테이너 실행
- 도커 컴포즈를 이용한 다중 컨테이녀 실행도커 실행 옵션을 미리 작성한 docker-compose.yml을 통해 다중 컨테이너 간 실행 순서, 네트워크, 의존성 등을 통합 관리할 수 있고 마이크로서비스 개발에 활용한다. 예로 하나의 docker-compose.yml 파일이 아닌 여러 개의 yml파일로 구성된 서비스 개발도 가능하다.
- 도커 명령어 docker images를 통해 생성된 이미지를 확인하고 이미지를 통한 컨테이너를 구동(docker run)한다.
- 컨테이너 애플리케이션 서비스 테스트
- 예를 들어 Nginx를 이용한 웹 애플리케이션 컨테이너 서비스였다면 연결하는 IP와 포트 번호를 이용하여 웹 브라우저를 이용한 페이지 연결을 확인할 수 있다.
- 로컬 및 원격 저장소에 이미지 저장
- 깃허브 등을 활용한 Dockerfile 관리
- 동일 환경에서의 지속적 애플리케이션 개발 수행
- 1-7 과정을 통해 업무용 애플리케이션 이미지를 지속적으로 개발,운영 및 관리할 수 있다.
컨테이너 동작에 필요한 모든 내용을 사전에 코드로 작성하여 인프라 프로비저닝 도구로 자동화하게 되면 기업이 필요할 때마다 애플리케이션 및 서버 환경을 적은 비용으로 빠르게 개발, 배포, 확장할 수 있다는 것을 알아두자 → IaC
도커 명령어 활용
모든 명령어는 키워드로 docker를 맨 앞에 사용한다.
도커 컨테이너 명령어
도커 볼륨 활용
도커는 유니언 파일 시스템을 사용하여 하나의 이미지로부터 여러 컨테이너를 만들고 이미지에 변경된 내용을 저장할 수 있도록 한다.
도커 볼륨
→ 컨테이너에서 생성, 재사용할 수 있고 호스트 운영체제에서 직접 접근이 가능
→ 보존되어야 하는 데이터를 유지하기 위한 멬커니즘을 제공
일반적으로 컨테이너 내부의 데이터는 컨테이너의 라이프사이클에 의해 컨테이너 종료 시 삭제된다. 도커 볼륨을 사용하면 컨테이너가 삭제되어도 볼륨은 독립적으로 운영되어 데이터를 영속적으로 유지할 수 있다. → 호스트 파일 시스템의 특정 디렉터리와 컨테이너의 디렉터리를 연결하여 데이터를 저장할 수 있다.
- volume
- 도커에서 밀어주는 방식
- bind mount
- 도커 볼륨 기법에 비해 사용이 제한적이다.
- 호스트 파일 시스템 경로:컨테이너 내부 경로를 직접 마운트하여 사용한다.
- 사용자가 파일, 디렉토리를 생성하면 해당 호스트 파일 시스템의 소유자 권한으로 연결이 되고 존재하지 않는 경우 자동으로 생성된다(루트 소유).
- 컨테이너 실행 시 지정하여 사용하고 컨테이너 제거시 바인드 마운트는 해제되지만 호스트 디렉터리는 유지된다.
- tmpfs mount
- 컨테이너가 중지되면 tmpfs마운트가 제고되고 내부에 기록된 파일은 유지되지 않는다.
- 호스트 또는 컨테이너 쓰기 가능 계층에서 지속하지 않지만 중요한 파일을 임시로 사용하는 방법에 유용하다.
- 컨테이너 실행시 지정하여 사용하고 컨테이너 제거 시 자동 해제된다.
도커 네트워크
도커 컨테이너 및 서비스는 도커 네트워크를 통해 격리된 컨테이너 간의 네트워크 연결뿐만 아니라 도커 외의 다른 애플리케이션 워크로드와도 연결이 가능하다. 이때 도커 네트워크의 하위 시스템 연결을 위해 도커 네트워크 드라이버를 사용하여 상호간 통신을 할 수 있다.
- bridge
- 기본 네트워크 드라이버
- 컨테이너 실행 시 별도의 네트워크 지정 없이 독립적으로 실행되는 애플리케이션 컨테이너를 실행하는 경우 사용된다.
- → 단 브리지 모드는 동일 호스트상의 도커 컨테이너에만 적용된다.
- host
- 컨테이너와 호스트 간의 네트워크 격리를 제거하고 호스트의 네트워킹을 직접 사용할 수 있다.
- 컨테이너 애플리케이션에 별도의 포트 연결없이 호스트의 포트를 이용하여 바로 서비스할 수 있다.
- overlay
- 다중 호스트 도커 서버를 이용한 클러스터(도커 스웜)등을 이용할 경우 도커 데몬간의 연결을 통해 컨테이너 서비스를 수행할 수 있다.
- 컨테이너 간에 운영체제 수준의 라우팅을 사용하지 않아도 된다.
- 도커 클러스터인 도커 스웜 구축 시 호스트와 호스트 간의 컨테이너 연결에 사용된다.
- macvlan
- 물리적 네트워크에 컨테이너 mac 주소를 통한 직접 연결 구현시 사용된다.
- 도커 데몬은 mac 주소별로 트래픽을 라우팅하게 된다.
- none
- 컨테이너의 네트워크를 사용하지 않도록 설정
- 네트워크 인터페이스는 lo 인터페이스만 존재한다.
- 컨테이너가 호스트 네트워킹 스택에서 완전히 분리되어 외부와의 통신을 완전 단절한다.
- 컨테이너 네트워크
- container : 공유받을 컨테이너 이름
- 컨테이너의 네트워크 네임 스페이스 스택을 공유하여 같이 사용할 수 있게 한다.
- 사용자 정의 네트워크
- 사용자가 직접 생성한 네트워크로 아무런 옵션을 주지 않고 생성하면 docker0 IP 대역의 다른 CIDR을 지정하여 생성된다.
도커 기본 브리지 네트워크
도커의 기본 네트워크 구성은 브리지 모드로 도커 데몬을 통해 도커 컨테이너만의 네트워크를 실제 서버 네트워크와 분리해 독립적으로 구성하는 네트워크 방식이다.
Dockerfile
코드로 개발하는 컨테이너 인프라, Dockerfile
Dockerfile : 원하는 개발 환경을 코드로 구성하는 방법을 제공하는 것
- 필요성
- 커맨드 기반의 인프라 구성시 인적 오류 발생 가능성이 높다.
- Apache + PHP + MySQL 구축을 생각해보자. 설치 순서와 상호 연관성 등을 고려하여 각종 라이브러리와 함께 복잡한 명령어를 고민해야 한다.
- 각종 환경 설정 정보와 설치 프로그램을 요구사항에 맞게 따져봐야 한다.
- 만일 설치 이후에 잘못된 설정이 있다면 수정해야 하고, 때로는 재설치를 해야만 할 수도 있다.
애플리케이션에 적용되는 새로운 환경을 사용자가 직접 정의해서 아이디어를 실현할 수 있는 것이 바로 코드로서 인프라 환경을 프로비저닝하는 Dockerfile이다. 이렇게 만들어진 코드나 이미지를 다양한 공유 방식을 통해 언제 어디서든 컨테이너로 만들어낼 수 있다.
- 최적의 Dockerfile을 만들기 위해 고려할 점
- 경량의 컨테이너 서비스를 제공
- Dockerfile에 담기는 레이어를 최소화
- 도커파일 명령어의 수와 도커 이미지 레이어 수는 동일하다. 레이어 수가 많을수록 이미지를 빌드하는 시간은 길어지기 때문에 파일용량도 커진다. 따라서 명령어수를 최소화하는 방향으로 작성한다.
- 하나의 애플리케이션은 하나의 컨테이너에
- 캐시 기능을 활용
- IaC 환경 개발은 디렉터리 단위로
- 서버리스 환경으로 개발
Dockerfile 명령어
일반적으로 시작은 FROM으로 작성하지만 그 다음부터는 순서가 딱히 없다. 하지만 명령한 순서대로 빌드 캐시의 무효화와 연관되므로 변경 빈도수가 적은 명령을 먼저 배치하는 것을 권장한다. 무조건 OS 이미지를 선택하고 설치하는 것보다는 원하는 애플리케이션 패키지가 이미 설치된 이미지 선택을 권장한다.
FROM
생성하려는 이미지의 베이스 이미지 지정 명령어이다.
이미지를 선택할 때 작은 크기의 이미지와 리눅스 알파인 이미지를 권장하나 상황에 맞춰서 선택하면 된다. 예를 들어 파이썬 같은 경우 알파인 리눅스를 사용하면 파이썬 패키지에서 C코드를 컴파일을 통해 도커 이미지를 빌드하기 때문에 빌드 시간도 오래 걸리고 이미지 용량도 커질 수 있다. 파이썬 애플리케이션 도커 이미지를 선택하는 경우에는 Debian Buster 키워드 이미지가 유리하다.
태그를 넣지 않으면 latest로 지정된다.
MAINTAINER
일반적으로 이미지를 빌드한 작성자 이름과 이메일을 작성한다.
MAINTAINER san.An <san@42.kr>
LABEL
이미지 작성 목적으로 버전, 타이틀, 설명, 라이선스 정보등을 작성한다. 1개 이상 작성 가능
LABEL pupose = 'Nginx for webserver' \\
version = '1.0' \\
description = 'web service application using Nginx'
RUN
설정된 기본 이미지에 패키지 업데이트 각종 패키지 설치, 명령 실행 등을 작성한다. 1개 이상 작성 가능
레이어 저장
RUN apt update
RUN apt -y install nginx
#Shell
RUN apt update && apt install -y nginx \\
git \\
curl && \\
apt-get clean -y && \\
apt-get autoremove -y && \\
rm -rfv /tmp/* /var/lib/apt/lists/* /var/tmp/*
- 권장
- 다단계 빌드 사용 권장, 각 이미지별로 개별 Dockerfile로 빌드
- RUN 명령어의 개별 명령 수를 최소화하기 위해 여러 설치 명령을 연결하면 이미지의 레이어수가 감소한다.
- autoremove, autoclean, rm -rf/var/lib/apt/lists/* 을 사용하면 저장되어 있는 apt 캐시가 삭제되어 이미지 크기가 감소한다.
CMD
생성된 이미지를 컨테이너로 실행할 때 실행되는 명령이고, ENTRYPOINT 명령문으로 지정된 커맨드에 디폴트로 넘길 파라미터를 지정할 때 사용한다. 여러 개의 CMD를 작성해도 마지막 하나만 처리된다. 일반적으로 이미지의 컨테이너 실행 시 애플리케이션 데몬이 실행되도록 하는 경우 유용하다.
#shell
CMD apachectl -D FOREGROUND
#exec
CMD ["/usr/sbin/apachectl", "-D", "FOREGOUND"]
ENTRYPOINT
CMD와 마찬가지로 생성된 이미지가 컨테이너로 실행될 때 사용되지만 컨테이너가 실행될 때 명령어 및 인자 값을 전달하여 실행한다는 점이 다르다. 여러 개의 CMD를 사용하는 경우 ENTRYPOINT 명령문과 함께 사용한다. ENTRYPOINT는 커맨드를 지정하고 CMD는 기본 명령을 지정하면 탄력적으로 이미지를 실행할 ㅅ ㅜ있다. 예를 들어 python 명령을 기본으로 runapp.py 코드를 실행하면
ENTRYPOINT ["python"]
CMD ["runapp.py"]
# 동일 환경에 entrypoint.sh 를 이미지에 넣고 ADD 실행 권한 설정 후 컨테이너 실행 시 entrypoint.sh를 실행
...
ADD ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
- ENTRYPOINT : 도커 컨테이너 실행 시 항상 수행하야 하는 명령어를 지정 (웹 서버나 데이터베이스의 데몬을 실행)
- CMD : 도커 컨테이너 실행 시 다양한 명령어를 지정하는 경우 유용
COPY
호스트 환경의 파일, 디렉터리를 이미지 안에 복사하는 경우 작성한다.
단순한 복사 작업만 지원, 빌드 작업 디렉터리 외부의 파일은 카피할 수 없다.
레이어 저장
COPY index.html /usr/share/nginx/html
ADD
호스트 환경의 파일 디렉터리를 이미지 안에 복사하는 경우 뿐만아니라 URL 주소에서 직접 다운로드하여 이미지에 넣을수도 있다. 압축 파일의 경우 지정한 경로 안에 압축을 풀어서 추가한다.
빌드 작업 외부 파일은 ADD할 수 없고, 디렉터리 추가시에는 /로 끝나야 한다.
레이어 저장
ADD index.html /usr/share/nginx/html
ADD <http://example.com/view/customer.tar.gz> /workspace/data/
ENV
이미지 안에 각종 환경 변수를 지정하는 경우 작성한다. 애플리케이션 사용을 쉽게 하려면 사전에 구성되어야 하는 환경 변수들이 있다. 예를 들어 자바 홈디렉토리, 특정 실행 파일의 경로를 보장하기 위해 절대 경로 지정을 위한 PATH 설정, 프로그램 버전 등을 사전에 설정한다.
반복된 표현이 사용되는 경우에도 환경 변수 설정을 권장한다.
ENV PATH /usr/local/nginx/bin:$PATH
EXPOSE
컨테이너가 호스트 네트워크를 통해 들어오는 트래픽을 리스닝하는 포트와 프로토콜을 지정하기 위해 작성한다. nginx나 apache는 기본 포트로 HTTP 80번과 HTTPS 443번 포트를 사용하고, 컨테이너 모니터링 이미지로 사용하는 Cadvisor 컨테이너는 8080번 포트를 사용한다.
이미지 내에 애플리케이션이 사용하는 포트를 사전에 확인하고 호스트와 연결되도록 구성하는 경우에 설정하고 docker run 사용시 -p 옵션을 통해 사용한다.
EXPOSE 80
EXPOSE 80/tcp
VOLUME
볼륨을 이미지 빌드에 미리 설정하는 경우 작성한다.
도커 컨테이너에서 사용된 파일과 디렉터리는 컨테이너 삭제와 함께 사라지기 때문에 사용자 데이터의 보존과 지속성을 위해 볼륨 사용을 권장한다.
VOLUME으로 지정된 컨테이너의 경로는 볼륨의 기본 경로 /var/lib/docker와 자동으로 연결된다.
VOLUME /var/log
USER
컨테이너의 기본 사용자는 root이다. 애플리케이션이 권한 없이 서비스를 실행할 수 있다면 USER를 통해 다른 사용자로 변경하여 사용한다.
WORKDIR
컨테이너 상에서 작업할 경로 전환을 위해 작성한다. WORKDIR을 설정하면 RUN, ADD, CMD, ENTRYPOINT, COPY 명령문은 해당 디렉터리를 기준으로 실행된다.
ARG
ONBUILD
STOPSIGNAL
SHELL
HEALTHCHECK
이미지 생성을 위한 Dockerfile 빌드
docker build [옵션] 이미지명:[태그] 도커파일경로 | URL | 압축파일
도커 컴포즈 - 다중 컨테이너 애플리케이션
도커 컴포즈는 공통성을 갖는 컨테이너 애플리케이션 스택을 yaml 코드로 정의한 정의서이다. → 다중 컨테이너 실행 도구
이때 공통성이란 공통의 목적을 의미하며 그 예로 웹 애플리케이션을 생성하기 위해 필요한 MySQL 데이터베이스와 API 애플리케이션 설정을 위한 백엔드 환경(플라스크, node), 사용자 인터페이서 그성을 위한 웹 프레임워크 이 세가지는 공통의 목적을 가지며 각 스택을 도커 컴포즈를 통해 한번에 서비스를 올리고 관리할 수 있다.
도커 컴포즈로 실행된 컨테이너는 독립된 기능을 가지며 공통 네트워크로 구성되기 때문에 컨테이너간 통신이 쉽다. → 쉽고 빠른 런타임 환경 제공
docker-compose up
이라는 간단한 명령어로 컨테이너를 올릴 수 있다.
docker-compose ps
는 생성된 컨테이너 정보를 조회할 수 있다.
docker-compose down
은 생성했던 것과 반대로 서비스를 모두 내리고 네트워크도 회수한다.
docker-compose up -d
도커 컴포즈를 백그라운드로 실행한다.
도커 컴포즈 YAML 코드 작성법
야믈코드의 계층 구조는 부모-자식 간의 레벨을 들여쓰기로 구분한다.
큰 구조 →
version: "3.8"
services:
서비스명1:
# 설정
networks:
# 네트워크 설정, 미지정시 자동 설정
volumes:
# 볼룸 설정
일반적으로 가장 먼저 실행되어야 하는 애플리케이션을 먼저 작성하고 이와 의존성을 갖는 데이터베이스 및 하위 애플리케이션을 작성한다.
서비스 전체를 하나의 도커 컴포즈 야믈 코드로 작성할 수 있다.
- 버전 정의
야믈 코드 첫 줄은 버전을 명시한다.
version: "3"
- 서비스 정의
도커 컴포즈를 통해 실행할 서비스를 정의한다.
도커 컴포즈는 컨테이너 대신 서비스 개념을 사용한다. 서비스 하위에는 실행될 컨테이너 서비스를 작성하고 하위 레벨에 도커 명령 실행과 유사하게 컨테이너 실행에 필요한 옵션을 작성하면 된다.
image를 사용해도 되고 build옵션으로 도커 파일을 실행해도 된다.
- 그 외 옵션들
- container_name: 생략 시 자동으로 부여한다.
- ports: 서비스 내부 포트와 외부 호스트 포트를 지정하여 바인드, 외부 노출 포트를 지정한다.
- expose: 호스트 운영체제와 직접 연결하는 포트를 구성하지 않고 서비스만 포트를 노출, 필요 시 링크로 연결된 서비스와 서비스 간의 통신만 허용한다.
- networks: 최상위 레벨의 networks에 정의된 네트워크 이름을 작성
- volumes: 서비스 내부 디렉터리와 호스트 디렉터리를 연결하여 데이터 지속성 설정
- environment: 서비스 내부 환경 변수를 설정한다. 환경 변수가 많은 경우 *.env 파일로 만들어 env_file 옵션에 파일명을 지정할 수 있다.
- command: 서비스가 구동 후 실행할 명령어를 작성한다.
- restart: 서비스 재시작 옵션 지정, always의 경우 수동 제어를 제외하고 항상 재시작한다.
- depends_on: 서비스 간의 종속성을 의미하며 먼저 실행해야 하는 서비스를 지정하여 순서를 지정한다.
- 네트워크 정의
다중 컨테이너들이 사용할 최상위 네트워크 키를 정의하고 이하 하위 서비스 단위로 이 네트워크를 선택할 수 있다.
아무런 networks 옵션을 지정하지 않으면 자체 기본 네트워크가 자동으로 생성된다.
최상위 레벨에 networks 지정 시 해당 이름의 네트워크가 생성되고 대역은 172…….로 자동 할당되며 기본 드라이버는 브리지로 지정된다.
도커에서 생성한 기존 네트워크를 지정하는 경우에는 externel 옵션에 네트워크 이름을 작성한다.
- 데이터의 지속성을 유지하기 위해 최상위 레벨에 볼륨을 정의하고, 서비스 레벨에서 볼륨명과 서비스 내부의 디렉터리를 바인드한다. 도커가 관리하는 가상 영역 /var/lib/docker/volume에 자동 배치된다.
도커, 컨테이너 빌드업!
클라우드 컴퓨팅 개요
클라우드는 인프라에 사용되는 서버, 저장소, 데이터베이스, 네트워크, 데이터베이스, 소프트웨어 데이터 분석등을 포함해 사용자가 언제든지 인터넷과 모바일 등을 통해 IT 서비스를 제공받을 수 있도록 하는 컴퓨팅 기술이다.
클라우드 컴퓨팅이란?
- 인터넷 기술을 사용해서 다수의 사용자에게 하나의 서비스로서 방대한 IT 능력을 제공하는 컴퓨팅 방식
특징
- 주문형 셀프 서비스 on demand self service
- 고객이 IT 서비스 제공자의 개입 없이 원하는 시점에 바로 서비스를 이용할 수 있다.
- 광대역 네트워크 접근 broad network access
- 각 클라우드 서비스 업체가 제공하는 광대역 네트워크를 이용하여 다양한 클라이언트 플랫폼이 빠르게 접속할 수 있다.
- 신속한 탄력성과 확장성, rapid elasticity and scalability
- 자동 조정 기능을 통해 몇 분 안에 신속한 확장과 축소를 조정할 수 있다.
- 자원의 공동관리, resource pooling
- 물리적 및 가상화된 자원을 풀로 관리하며, 탄력적으로 업무 상황에 맞게 사용자 요구에 따라 동적으로 할당 또는 재할당된다.
- 측정 가능한 서비스, measured service
- 자원 사용량이 실시간으로 수집되는 요금산정기능을 통해 비용이 발생한다.
클라우드 컴퓨팅 구조
https://www.cloudhelp.kr/software/cloud-computing/outline/
물리적 시스템, 가상화, 프로비져닝 계층은 자원 활용과 관련되어있고 클라우드 컴퓨팅 서비스 관리 체계, 클라우드 서비스 계층은 클라우드 서비스와 관련있다.
- 물리적 계층 : 여러 형태의 서버 계열을 활용하여 서버에 탑재된 수평적으로 확장 가능한 스토리지 및 네트워크등의 물리적 요소
- 이를 기반으로 서버, 스토리지, 네트워크 가상화는 민첩성을 제공하고, IT 서비스 공급자는 클라우드 서버 프로비저닝 또는 프로비저닝 해제를 신속히 수행하여 서비스 사용자의 요구를 충족할 수 있다.
- 클라우드 컴퓨팅 서비스 관리 체계 계층
- 안정적인 클라우드 서비스를 위한 성능 및 고가용성, 소프트웨어 라이선스와 패치 관리, 사용량 요금 산정을 통한 과금 관리, 기본적인 클라우드 보안 관리 요소가 결합되어 있다.
- : 물리적 시스템 계층에서 제공되는 자원에 대한 전반적인 라이프사이클 관리와 모니터링을 지원한다.
클라우드 컴퓨팅 제공 방식
6페이지
컨테이너 기술과 도커
가상 머신과 컨테이너
가상화 : 물리적 구성은 은폐하고, 가상환경을 여러 개 만들어, 개별 가상머신이 자원을 갖추고 있게 만드는 기술
- 프로비저닝 : IT인프라 자원을 사용자의 니즈에 맞게 할당/배치/배포해서 시스템을 사용할 수 있도록 하는 기술
- 하이퍼바이저 : 물리서버 위에 존재하는 가상화 계층으로서, OS구동을 위한 HW환경을 가상으로 제공
하이퍼바이저
하드웨어 가상화
컨테이너
프로세스 가상화
- 컨테이너 기술의 장점
- 하이퍼바이저와 게스트 OS가 없어 가볍다.
- 경량이기 때문에 만들어진 이미지 복제, 이관, 배포가 쉽다.
- 게스트 OS를 부팅하지 않기 때문에 애플리케이션 시작 시간이 빠르다.
- 가상머신보다 경량이므로 더 많은 애플리케이션을 실행할 수 있다.
도커
컨테이너는 코드와 모든 종속성을 패키지화하는 표준 소프트웨어 단위로, 애플리케이션이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 한다.
도커 컨테이너 이미지는 애플리케이션을 실행하는 데 필요한 모든 것(코드, 런타임, 라이브러리 등)을 포함하는 경량의 독립형 실행 가능 소프트웨어 패키지라고 정의할 수 있다.
[ 도커 주요 기능 ]
- LXC(리눅스 컨테이너)를 이용한 컨테이너 구동
- containerd는 리눅스 및 윈도우용 데몬으로, 이미지 전송 및 스토리지에서 컨테이너 실행 및 감독, 네트워크 연결까지 호스트 시스템 전체 컨테이너의 라이프사이클을 관리한다.
- 통합 BuildKit
- 빌드킷은 도커파일의 설정 정보를 이용하여 도커 이미지를 빌드하는 오픈 소스 도구이며, 빠르고 정확하게 여러가지 아키텍처 향상 기능을 제공한다.
- 도커 CLI 기반
- 도커 명령을 수행하는 기본적인 방법을 CLI로 제공한다.
도커를 사용하는 이유
예를 들어 node.js로 만든 애플리케이션을 테스트해야하는 상황에서 현재 로컬에 node.js를 실행하려면 npm이라는 모듈이 필요하다. 만약 이 애플리케이션이 하나의 모듈이 아니라 여러 가지 의존성이 있는 애플리케이션이며 데이터베이스까지 필요하다면? 환경설정과 애플리케이션을 설치하는 데 많은 시간을 투자해야한다. 만약 각각의 의존성이 다른 애플리케이션이 여러개라면 환경설정에 걸리는 시간은 배로 늘어난다. 이를 도커로 단축시킬 수 있다.
도커에 사전에 만들어진 이미지를 통해 컨테이너 안에서 테스트할 수 있다.
- 도커 엔진 : 도커를 이용한 애플리케이션 실행 환경 제공을 위한 핵심 요소
- 도커 허브 : 도커 사용자들과 함께 도커 컨테이너 이미지를 공유하는 클라우드 서비스
- docker-compose : 의존성 있는 독립된 컨테이너에 대한 구성 정보를 YAML코드로 작성하여 일원화된 애플리케이션 관리를 가능하게 하는 도구
- docker Kitematic : 컨테이너를 이용한 작업을 수행할 수 있는 GUI 제공
- docker registry :
- docker machine :
- docker swarm :
- docker ps -a : 실행된 모든 컨테이너의 정보를 제공
우리는 Nginx를 위한 환경 구성, 설치, 서비스 시작 그 어떤 것도 하지 않고 도커를 이용하여 컨테이너 nginx 서비스를 배포할 수 있다. - 도커의 민텁한 애플리케이션 배포 기능
도커 엔진은 서버와 클라이언트로 구분된다. 클라이언트는 도커의 명령을 받고 결과를 출력하고 서버는 도커 엔진, 도커 데몬을 이용하여 컨테이너 시작, 운영 , 정지등을 담당한다.
클라이언트는 도커 명령을 수행하는 명령줄을 제공 → 수행된 도커 명령은 서버의 도커 데몬으로 전달 → 도커 데몬은 docker socket이 보유한 도커 API를 이용해 컨테이너 생성 → 수행된 컨테이너에 포함된 서비스 결과를 클라이언트에 전달
docker system df
도커 시스템이 사용하는 디스크 사용량에 대한 현재 상태 조회
-v : 세부정보를 확인할 수 있다.
docker system events
도커 서버에서 발생하는 도커 관련 이벤트 정보를 표시하는 명령어
--filter 옵션을 이용해서 원하는 정보만 추출하여 볼 수 있다.
컨테이너 서비스
컨테이너에 서비스하고자 하는 애플리케이션 코드와 프로세스를 격리한다.
대부분의 개발자가 개발, 테스트, 배포, 운영의 컴퓨팅 환경 차이로 인한 시행착오 및 다양한 오류해결에 너무 많은 시간을 소비하는 공통적인 문제를 가지고 있어 이를 해결할 수 있는 도커 기반의 컨테이너 서비스 환경으로 전환하고 있다.
컨테이너 서비스는 기존 환경과 다르게 애플리케이션 실행에 필요한 바이너리, 라이브러리 및 구성 파일등을 패키지로 묶어 배포하는 방식으로 논리적 패키징 메커니즘을 제공한다. 애플리케이션이 가지고 있는 운영체제, 하드웨어에 대한 의존성 문제를 해결한 것이다. 따라서 어떤 환경에서든 컨테이너 기반의 애플리케이션을 개발하고 배포할 수 있다.
→ 이렇게 호스트 운영체제를 공유하고 애플리케이션에 필요한 환경을 패키징하는 것을 운영체제 레벨 가상화라고 부른다.
- 하드웨어 레벨 가상화 : 하이퍼바이저 등을 이용한 가상머신의 방식을 말한다.
- 운영체제 레벨 가상화 : 컨테이너 기반의 애플리케이션 서비스 방식
도커 기반 애플리케이션 개발의 라이프사이클
- 애플리케이션 코드 개발
- : 특정 서비스 구동을 위한 애플리케이션 코드 및 웹 화면 구성등을 위한 코드를 개발한다.
- 베이스 이미지를 이용한 Dockerfile 관리
- 개발에 필요한 인프라 구성 요소를 Dockerfile에 작성한다. 즉, 도커 허브를 통해 베이스 이미지를 다운로드하고 다양한 구동 명령어(FROM, RUN, CMD, ENDPOINT, ENV, ADD 등)와 1번에서 작성한 애플리케이션 코드, 라이브러리, 여러 도구를 Dockerfile에 포함시킨다.
- Dockerfile build를 통한 새로운 이미지 생성각 단계별로 실행되는 로그를 화면에서 확인하며 이때 오류 발생 내용도 확인할 수 있다.
- docker build 명령을 통해 작성한 Dockerfile을 실행한다.
- 생성된 이미지를 이용한 컨테이너 실행
- 도커 컴포즈를 이용한 다중 컨테이녀 실행도커 실행 옵션을 미리 작성한 docker-compose.yml을 통해 다중 컨테이너 간 실행 순서, 네트워크, 의존성 등을 통합 관리할 수 있고 마이크로서비스 개발에 활용한다. 예로 하나의 docker-compose.yml 파일이 아닌 여러 개의 yml파일로 구성된 서비스 개발도 가능하다.
- 도커 명령어 docker images를 통해 생성된 이미지를 확인하고 이미지를 통한 컨테이너를 구동(docker run)한다.
- 컨테이너 애플리케이션 서비스 테스트
- 예를 들어 Nginx를 이용한 웹 애플리케이션 컨테이너 서비스였다면 연결하는 IP와 포트 번호를 이용하여 웹 브라우저를 이용한 페이지 연결을 확인할 수 있다.
- 로컬 및 원격 저장소에 이미지 저장
- 깃허브 등을 활용한 Dockerfile 관리
- 동일 환경에서의 지속적 애플리케이션 개발 수행
- 1-7 과정을 통해 업무용 애플리케이션 이미지를 지속적으로 개발,운영 및 관리할 수 있다.
컨테이너 동작에 필요한 모든 내용을 사전에 코드로 작성하여 인프라 프로비저닝 도구로 자동화하게 되면 기업이 필요할 때마다 애플리케이션 및 서버 환경을 적은 비용으로 빠르게 개발, 배포, 확장할 수 있다는 것을 알아두자 → IaC
도커 명령어 활용
모든 명령어는 키워드로 docker를 맨 앞에 사용한다.
도커 컨테이너 명령어
도커 볼륨 활용
도커는 유니언 파일 시스템을 사용하여 하나의 이미지로부터 여러 컨테이너를 만들고 이미지에 변경된 내용을 저장할 수 있도록 한다.
도커 볼륨
→ 컨테이너에서 생성, 재사용할 수 있고 호스트 운영체제에서 직접 접근이 가능
→ 보존되어야 하는 데이터를 유지하기 위한 멬커니즘을 제공
일반적으로 컨테이너 내부의 데이터는 컨테이너의 라이프사이클에 의해 컨테이너 종료 시 삭제된다. 도커 볼륨을 사용하면 컨테이너가 삭제되어도 볼륨은 독립적으로 운영되어 데이터를 영속적으로 유지할 수 있다. → 호스트 파일 시스템의 특정 디렉터리와 컨테이너의 디렉터리를 연결하여 데이터를 저장할 수 있다.
- volume
- 도커에서 밀어주는 방식
- bind mount
- 도커 볼륨 기법에 비해 사용이 제한적이다.
- 호스트 파일 시스템 경로:컨테이너 내부 경로를 직접 마운트하여 사용한다.
- 사용자가 파일, 디렉토리를 생성하면 해당 호스트 파일 시스템의 소유자 권한으로 연결이 되고 존재하지 않는 경우 자동으로 생성된다(루트 소유).
- 컨테이너 실행 시 지정하여 사용하고 컨테이너 제거시 바인드 마운트는 해제되지만 호스트 디렉터리는 유지된다.
- tmpfs mount
- 컨테이너가 중지되면 tmpfs마운트가 제고되고 내부에 기록된 파일은 유지되지 않는다.
- 호스트 또는 컨테이너 쓰기 가능 계층에서 지속하지 않지만 중요한 파일을 임시로 사용하는 방법에 유용하다.
- 컨테이너 실행시 지정하여 사용하고 컨테이너 제거 시 자동 해제된다.
도커 네트워크
도커 컨테이너 및 서비스는 도커 네트워크를 통해 격리된 컨테이너 간의 네트워크 연결뿐만 아니라 도커 외의 다른 애플리케이션 워크로드와도 연결이 가능하다. 이때 도커 네트워크의 하위 시스템 연결을 위해 도커 네트워크 드라이버를 사용하여 상호간 통신을 할 수 있다.
- bridge
- 기본 네트워크 드라이버
- 컨테이너 실행 시 별도의 네트워크 지정 없이 독립적으로 실행되는 애플리케이션 컨테이너를 실행하는 경우 사용된다.
- → 단 브리지 모드는 동일 호스트상의 도커 컨테이너에만 적용된다.
- host
- 컨테이너와 호스트 간의 네트워크 격리를 제거하고 호스트의 네트워킹을 직접 사용할 수 있다.
- 컨테이너 애플리케이션에 별도의 포트 연결없이 호스트의 포트를 이용하여 바로 서비스할 수 있다.
- overlay
- 다중 호스트 도커 서버를 이용한 클러스터(도커 스웜)등을 이용할 경우 도커 데몬간의 연결을 통해 컨테이너 서비스를 수행할 수 있다.
- 컨테이너 간에 운영체제 수준의 라우팅을 사용하지 않아도 된다.
- 도커 클러스터인 도커 스웜 구축 시 호스트와 호스트 간의 컨테이너 연결에 사용된다.
- macvlan
- 물리적 네트워크에 컨테이너 mac 주소를 통한 직접 연결 구현시 사용된다.
- 도커 데몬은 mac 주소별로 트래픽을 라우팅하게 된다.
- none
- 컨테이너의 네트워크를 사용하지 않도록 설정
- 네트워크 인터페이스는 lo 인터페이스만 존재한다.
- 컨테이너가 호스트 네트워킹 스택에서 완전히 분리되어 외부와의 통신을 완전 단절한다.
- 컨테이너 네트워크
- container : 공유받을 컨테이너 이름
- 컨테이너의 네트워크 네임 스페이스 스택을 공유하여 같이 사용할 수 있게 한다.
- 사용자 정의 네트워크
- 사용자가 직접 생성한 네트워크로 아무런 옵션을 주지 않고 생성하면 docker0 IP 대역의 다른 CIDR을 지정하여 생성된다.
도커 기본 브리지 네트워크
도커의 기본 네트워크 구성은 브리지 모드로 도커 데몬을 통해 도커 컨테이너만의 네트워크를 실제 서버 네트워크와 분리해 독립적으로 구성하는 네트워크 방식이다.
Dockerfile
코드로 개발하는 컨테이너 인프라, Dockerfile
Dockerfile : 원하는 개발 환경을 코드로 구성하는 방법을 제공하는 것
- 필요성
- 커맨드 기반의 인프라 구성시 인적 오류 발생 가능성이 높다.
- Apache + PHP + MySQL 구축을 생각해보자. 설치 순서와 상호 연관성 등을 고려하여 각종 라이브러리와 함께 복잡한 명령어를 고민해야 한다.
- 각종 환경 설정 정보와 설치 프로그램을 요구사항에 맞게 따져봐야 한다.
- 만일 설치 이후에 잘못된 설정이 있다면 수정해야 하고, 때로는 재설치를 해야만 할 수도 있다.
애플리케이션에 적용되는 새로운 환경을 사용자가 직접 정의해서 아이디어를 실현할 수 있는 것이 바로 코드로서 인프라 환경을 프로비저닝하는 Dockerfile이다. 이렇게 만들어진 코드나 이미지를 다양한 공유 방식을 통해 언제 어디서든 컨테이너로 만들어낼 수 있다.
- 최적의 Dockerfile을 만들기 위해 고려할 점
- 경량의 컨테이너 서비스를 제공
- Dockerfile에 담기는 레이어를 최소화
- 도커파일 명령어의 수와 도커 이미지 레이어 수는 동일하다. 레이어 수가 많을수록 이미지를 빌드하는 시간은 길어지기 때문에 파일용량도 커진다. 따라서 명령어수를 최소화하는 방향으로 작성한다.
- 하나의 애플리케이션은 하나의 컨테이너에
- 캐시 기능을 활용
- IaC 환경 개발은 디렉터리 단위로
- 서버리스 환경으로 개발
Dockerfile 명령어
일반적으로 시작은 FROM으로 작성하지만 그 다음부터는 순서가 딱히 없다. 하지만 명령한 순서대로 빌드 캐시의 무효화와 연관되므로 변경 빈도수가 적은 명령을 먼저 배치하는 것을 권장한다. 무조건 OS 이미지를 선택하고 설치하는 것보다는 원하는 애플리케이션 패키지가 이미 설치된 이미지 선택을 권장한다.
FROM
생성하려는 이미지의 베이스 이미지 지정 명령어이다.
이미지를 선택할 때 작은 크기의 이미지와 리눅스 알파인 이미지를 권장하나 상황에 맞춰서 선택하면 된다. 예를 들어 파이썬 같은 경우 알파인 리눅스를 사용하면 파이썬 패키지에서 C코드를 컴파일을 통해 도커 이미지를 빌드하기 때문에 빌드 시간도 오래 걸리고 이미지 용량도 커질 수 있다. 파이썬 애플리케이션 도커 이미지를 선택하는 경우에는 Debian Buster 키워드 이미지가 유리하다.
태그를 넣지 않으면 latest로 지정된다.
MAINTAINER
일반적으로 이미지를 빌드한 작성자 이름과 이메일을 작성한다.
MAINTAINER san.An <san@42.kr>
LABEL
이미지 작성 목적으로 버전, 타이틀, 설명, 라이선스 정보등을 작성한다. 1개 이상 작성 가능
LABEL pupose = 'Nginx for webserver' \\
version = '1.0' \\
description = 'web service application using Nginx'
RUN
설정된 기본 이미지에 패키지 업데이트 각종 패키지 설치, 명령 실행 등을 작성한다. 1개 이상 작성 가능
레이어 저장
RUN apt update
RUN apt -y install nginx
#Shell
RUN apt update && apt install -y nginx \\
git \\
curl && \\
apt-get clean -y && \\
apt-get autoremove -y && \\
rm -rfv /tmp/* /var/lib/apt/lists/* /var/tmp/*
- 권장
- 다단계 빌드 사용 권장, 각 이미지별로 개별 Dockerfile로 빌드
- RUN 명령어의 개별 명령 수를 최소화하기 위해 여러 설치 명령을 연결하면 이미지의 레이어수가 감소한다.
- autoremove, autoclean, rm -rf/var/lib/apt/lists/* 을 사용하면 저장되어 있는 apt 캐시가 삭제되어 이미지 크기가 감소한다.
CMD
생성된 이미지를 컨테이너로 실행할 때 실행되는 명령이고, ENTRYPOINT 명령문으로 지정된 커맨드에 디폴트로 넘길 파라미터를 지정할 때 사용한다. 여러 개의 CMD를 작성해도 마지막 하나만 처리된다. 일반적으로 이미지의 컨테이너 실행 시 애플리케이션 데몬이 실행되도록 하는 경우 유용하다.
#shell
CMD apachectl -D FOREGROUND
#exec
CMD ["/usr/sbin/apachectl", "-D", "FOREGOUND"]
ENTRYPOINT
CMD와 마찬가지로 생성된 이미지가 컨테이너로 실행될 때 사용되지만 컨테이너가 실행될 때 명령어 및 인자 값을 전달하여 실행한다는 점이 다르다. 여러 개의 CMD를 사용하는 경우 ENTRYPOINT 명령문과 함께 사용한다. ENTRYPOINT는 커맨드를 지정하고 CMD는 기본 명령을 지정하면 탄력적으로 이미지를 실행할 ㅅ ㅜ있다. 예를 들어 python 명령을 기본으로 runapp.py 코드를 실행하면
ENTRYPOINT ["python"]
CMD ["runapp.py"]
# 동일 환경에 entrypoint.sh 를 이미지에 넣고 ADD 실행 권한 설정 후 컨테이너 실행 시 entrypoint.sh를 실행
...
ADD ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
- ENTRYPOINT : 도커 컨테이너 실행 시 항상 수행하야 하는 명령어를 지정 (웹 서버나 데이터베이스의 데몬을 실행)
- CMD : 도커 컨테이너 실행 시 다양한 명령어를 지정하는 경우 유용
COPY
호스트 환경의 파일, 디렉터리를 이미지 안에 복사하는 경우 작성한다.
단순한 복사 작업만 지원, 빌드 작업 디렉터리 외부의 파일은 카피할 수 없다.
레이어 저장
COPY index.html /usr/share/nginx/html
ADD
호스트 환경의 파일 디렉터리를 이미지 안에 복사하는 경우 뿐만아니라 URL 주소에서 직접 다운로드하여 이미지에 넣을수도 있다. 압축 파일의 경우 지정한 경로 안에 압축을 풀어서 추가한다.
빌드 작업 외부 파일은 ADD할 수 없고, 디렉터리 추가시에는 /로 끝나야 한다.
레이어 저장
ADD index.html /usr/share/nginx/html
ADD <http://example.com/view/customer.tar.gz> /workspace/data/
ENV
이미지 안에 각종 환경 변수를 지정하는 경우 작성한다. 애플리케이션 사용을 쉽게 하려면 사전에 구성되어야 하는 환경 변수들이 있다. 예를 들어 자바 홈디렉토리, 특정 실행 파일의 경로를 보장하기 위해 절대 경로 지정을 위한 PATH 설정, 프로그램 버전 등을 사전에 설정한다.
반복된 표현이 사용되는 경우에도 환경 변수 설정을 권장한다.
ENV PATH /usr/local/nginx/bin:$PATH
EXPOSE
컨테이너가 호스트 네트워크를 통해 들어오는 트래픽을 리스닝하는 포트와 프로토콜을 지정하기 위해 작성한다. nginx나 apache는 기본 포트로 HTTP 80번과 HTTPS 443번 포트를 사용하고, 컨테이너 모니터링 이미지로 사용하는 Cadvisor 컨테이너는 8080번 포트를 사용한다.
이미지 내에 애플리케이션이 사용하는 포트를 사전에 확인하고 호스트와 연결되도록 구성하는 경우에 설정하고 docker run 사용시 -p 옵션을 통해 사용한다.
EXPOSE 80
EXPOSE 80/tcp
VOLUME
볼륨을 이미지 빌드에 미리 설정하는 경우 작성한다.
도커 컨테이너에서 사용된 파일과 디렉터리는 컨테이너 삭제와 함께 사라지기 때문에 사용자 데이터의 보존과 지속성을 위해 볼륨 사용을 권장한다.
VOLUME으로 지정된 컨테이너의 경로는 볼륨의 기본 경로 /var/lib/docker와 자동으로 연결된다.
VOLUME /var/log
USER
컨테이너의 기본 사용자는 root이다. 애플리케이션이 권한 없이 서비스를 실행할 수 있다면 USER를 통해 다른 사용자로 변경하여 사용한다.
WORKDIR
컨테이너 상에서 작업할 경로 전환을 위해 작성한다. WORKDIR을 설정하면 RUN, ADD, CMD, ENTRYPOINT, COPY 명령문은 해당 디렉터리를 기준으로 실행된다.
ARG
ONBUILD
STOPSIGNAL
SHELL
HEALTHCHECK
이미지 생성을 위한 Dockerfile 빌드
docker build [옵션] 이미지명:[태그] 도커파일경로 | URL | 압축파일
도커 컴포즈 - 다중 컨테이너 애플리케이션
도커 컴포즈는 공통성을 갖는 컨테이너 애플리케이션 스택을 yaml 코드로 정의한 정의서이다. → 다중 컨테이너 실행 도구
이때 공통성이란 공통의 목적을 의미하며 그 예로 웹 애플리케이션을 생성하기 위해 필요한 MySQL 데이터베이스와 API 애플리케이션 설정을 위한 백엔드 환경(플라스크, node), 사용자 인터페이서 그성을 위한 웹 프레임워크 이 세가지는 공통의 목적을 가지며 각 스택을 도커 컴포즈를 통해 한번에 서비스를 올리고 관리할 수 있다.
도커 컴포즈로 실행된 컨테이너는 독립된 기능을 가지며 공통 네트워크로 구성되기 때문에 컨테이너간 통신이 쉽다. → 쉽고 빠른 런타임 환경 제공
docker-compose up
이라는 간단한 명령어로 컨테이너를 올릴 수 있다.
docker-compose ps
는 생성된 컨테이너 정보를 조회할 수 있다.
docker-compose down
은 생성했던 것과 반대로 서비스를 모두 내리고 네트워크도 회수한다.
docker-compose up -d
도커 컴포즈를 백그라운드로 실행한다.
도커 컴포즈 YAML 코드 작성법
야믈코드의 계층 구조는 부모-자식 간의 레벨을 들여쓰기로 구분한다.
큰 구조 →
version: "3.8"
services:
서비스명1:
# 설정
networks:
# 네트워크 설정, 미지정시 자동 설정
volumes:
# 볼룸 설정
일반적으로 가장 먼저 실행되어야 하는 애플리케이션을 먼저 작성하고 이와 의존성을 갖는 데이터베이스 및 하위 애플리케이션을 작성한다.
서비스 전체를 하나의 도커 컴포즈 야믈 코드로 작성할 수 있다.
- 버전 정의
야믈 코드 첫 줄은 버전을 명시한다.
version: "3"
- 서비스 정의
도커 컴포즈를 통해 실행할 서비스를 정의한다.
도커 컴포즈는 컨테이너 대신 서비스 개념을 사용한다. 서비스 하위에는 실행될 컨테이너 서비스를 작성하고 하위 레벨에 도커 명령 실행과 유사하게 컨테이너 실행에 필요한 옵션을 작성하면 된다.
image를 사용해도 되고 build옵션으로 도커 파일을 실행해도 된다.
- 그 외 옵션들
- container_name: 생략 시 자동으로 부여한다.
- ports: 서비스 내부 포트와 외부 호스트 포트를 지정하여 바인드, 외부 노출 포트를 지정한다.
- expose: 호스트 운영체제와 직접 연결하는 포트를 구성하지 않고 서비스만 포트를 노출, 필요 시 링크로 연결된 서비스와 서비스 간의 통신만 허용한다.
- networks: 최상위 레벨의 networks에 정의된 네트워크 이름을 작성
- volumes: 서비스 내부 디렉터리와 호스트 디렉터리를 연결하여 데이터 지속성 설정
- environment: 서비스 내부 환경 변수를 설정한다. 환경 변수가 많은 경우 *.env 파일로 만들어 env_file 옵션에 파일명을 지정할 수 있다.
- command: 서비스가 구동 후 실행할 명령어를 작성한다.
- restart: 서비스 재시작 옵션 지정, always의 경우 수동 제어를 제외하고 항상 재시작한다.
- depends_on: 서비스 간의 종속성을 의미하며 먼저 실행해야 하는 서비스를 지정하여 순서를 지정한다.
- 네트워크 정의
다중 컨테이너들이 사용할 최상위 네트워크 키를 정의하고 이하 하위 서비스 단위로 이 네트워크를 선택할 수 있다.
아무런 networks 옵션을 지정하지 않으면 자체 기본 네트워크가 자동으로 생성된다.
최상위 레벨에 networks 지정 시 해당 이름의 네트워크가 생성되고 대역은 172…….로 자동 할당되며 기본 드라이버는 브리지로 지정된다.
도커에서 생성한 기존 네트워크를 지정하는 경우에는 externel 옵션에 네트워크 이름을 작성한다.
- 데이터의 지속성을 유지하기 위해 최상위 레벨에 볼륨을 정의하고, 서비스 레벨에서 볼륨명과 서비스 내부의 디렉터리를 바인드한다. 도커가 관리하는 가상 영역 /var/lib/docker/volume에 자동 배치된다.
도커, 컨테이너 빌드업!
클라우드 컴퓨팅 개요
클라우드는 인프라에 사용되는 서버, 저장소, 데이터베이스, 네트워크, 데이터베이스, 소프트웨어 데이터 분석등을 포함해 사용자가 언제든지 인터넷과 모바일 등을 통해 IT 서비스를 제공받을 수 있도록 하는 컴퓨팅 기술이다.
클라우드 컴퓨팅이란?
- 인터넷 기술을 사용해서 다수의 사용자에게 하나의 서비스로서 방대한 IT 능력을 제공하는 컴퓨팅 방식
특징
- 주문형 셀프 서비스 on demand self service
- 고객이 IT 서비스 제공자의 개입 없이 원하는 시점에 바로 서비스를 이용할 수 있다.
- 광대역 네트워크 접근 broad network access
- 각 클라우드 서비스 업체가 제공하는 광대역 네트워크를 이용하여 다양한 클라이언트 플랫폼이 빠르게 접속할 수 있다.
- 신속한 탄력성과 확장성, rapid elasticity and scalability
- 자동 조정 기능을 통해 몇 분 안에 신속한 확장과 축소를 조정할 수 있다.
- 자원의 공동관리, resource pooling
- 물리적 및 가상화된 자원을 풀로 관리하며, 탄력적으로 업무 상황에 맞게 사용자 요구에 따라 동적으로 할당 또는 재할당된다.
- 측정 가능한 서비스, measured service
- 자원 사용량이 실시간으로 수집되는 요금산정기능을 통해 비용이 발생한다.
클라우드 컴퓨팅 구조
https://www.cloudhelp.kr/software/cloud-computing/outline/
물리적 시스템, 가상화, 프로비져닝 계층은 자원 활용과 관련되어있고 클라우드 컴퓨팅 서비스 관리 체계, 클라우드 서비스 계층은 클라우드 서비스와 관련있다.
- 물리적 계층 : 여러 형태의 서버 계열을 활용하여 서버에 탑재된 수평적으로 확장 가능한 스토리지 및 네트워크등의 물리적 요소
- 이를 기반으로 서버, 스토리지, 네트워크 가상화는 민첩성을 제공하고, IT 서비스 공급자는 클라우드 서버 프로비저닝 또는 프로비저닝 해제를 신속히 수행하여 서비스 사용자의 요구를 충족할 수 있다.
- 클라우드 컴퓨팅 서비스 관리 체계 계층
- 안정적인 클라우드 서비스를 위한 성능 및 고가용성, 소프트웨어 라이선스와 패치 관리, 사용량 요금 산정을 통한 과금 관리, 기본적인 클라우드 보안 관리 요소가 결합되어 있다.
- : 물리적 시스템 계층에서 제공되는 자원에 대한 전반적인 라이프사이클 관리와 모니터링을 지원한다.
클라우드 컴퓨팅 제공 방식
6페이지
컨테이너 기술과 도커
가상 머신과 컨테이너
가상화 : 물리적 구성은 은폐하고, 가상환경을 여러 개 만들어, 개별 가상머신이 자원을 갖추고 있게 만드는 기술
- 프로비저닝 : IT인프라 자원을 사용자의 니즈에 맞게 할당/배치/배포해서 시스템을 사용할 수 있도록 하는 기술
- 하이퍼바이저 : 물리서버 위에 존재하는 가상화 계층으로서, OS구동을 위한 HW환경을 가상으로 제공
하이퍼바이저
하드웨어 가상화
컨테이너
프로세스 가상화
- 컨테이너 기술의 장점
- 하이퍼바이저와 게스트 OS가 없어 가볍다.
- 경량이기 때문에 만들어진 이미지 복제, 이관, 배포가 쉽다.
- 게스트 OS를 부팅하지 않기 때문에 애플리케이션 시작 시간이 빠르다.
- 가상머신보다 경량이므로 더 많은 애플리케이션을 실행할 수 있다.
도커
컨테이너는 코드와 모든 종속성을 패키지화하는 표준 소프트웨어 단위로, 애플리케이션이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 한다.
도커 컨테이너 이미지는 애플리케이션을 실행하는 데 필요한 모든 것(코드, 런타임, 라이브러리 등)을 포함하는 경량의 독립형 실행 가능 소프트웨어 패키지라고 정의할 수 있다.
[ 도커 주요 기능 ]
- LXC(리눅스 컨테이너)를 이용한 컨테이너 구동
- containerd는 리눅스 및 윈도우용 데몬으로, 이미지 전송 및 스토리지에서 컨테이너 실행 및 감독, 네트워크 연결까지 호스트 시스템 전체 컨테이너의 라이프사이클을 관리한다.
- 통합 BuildKit
- 빌드킷은 도커파일의 설정 정보를 이용하여 도커 이미지를 빌드하는 오픈 소스 도구이며, 빠르고 정확하게 여러가지 아키텍처 향상 기능을 제공한다.
- 도커 CLI 기반
- 도커 명령을 수행하는 기본적인 방법을 CLI로 제공한다.
도커를 사용하는 이유
예를 들어 node.js로 만든 애플리케이션을 테스트해야하는 상황에서 현재 로컬에 node.js를 실행하려면 npm이라는 모듈이 필요하다. 만약 이 애플리케이션이 하나의 모듈이 아니라 여러 가지 의존성이 있는 애플리케이션이며 데이터베이스까지 필요하다면? 환경설정과 애플리케이션을 설치하는 데 많은 시간을 투자해야한다. 만약 각각의 의존성이 다른 애플리케이션이 여러개라면 환경설정에 걸리는 시간은 배로 늘어난다. 이를 도커로 단축시킬 수 있다.
도커에 사전에 만들어진 이미지를 통해 컨테이너 안에서 테스트할 수 있다.
- 도커 엔진 : 도커를 이용한 애플리케이션 실행 환경 제공을 위한 핵심 요소
- 도커 허브 : 도커 사용자들과 함께 도커 컨테이너 이미지를 공유하는 클라우드 서비스
- docker-compose : 의존성 있는 독립된 컨테이너에 대한 구성 정보를 YAML코드로 작성하여 일원화된 애플리케이션 관리를 가능하게 하는 도구
- docker Kitematic : 컨테이너를 이용한 작업을 수행할 수 있는 GUI 제공
- docker registry :
- docker machine :
- docker swarm :
- docker ps -a : 실행된 모든 컨테이너의 정보를 제공
우리는 Nginx를 위한 환경 구성, 설치, 서비스 시작 그 어떤 것도 하지 않고 도커를 이용하여 컨테이너 nginx 서비스를 배포할 수 있다. - 도커의 민텁한 애플리케이션 배포 기능
도커 엔진은 서버와 클라이언트로 구분된다. 클라이언트는 도커의 명령을 받고 결과를 출력하고 서버는 도커 엔진, 도커 데몬을 이용하여 컨테이너 시작, 운영 , 정지등을 담당한다.
클라이언트는 도커 명령을 수행하는 명령줄을 제공 → 수행된 도커 명령은 서버의 도커 데몬으로 전달 → 도커 데몬은 docker socket이 보유한 도커 API를 이용해 컨테이너 생성 → 수행된 컨테이너에 포함된 서비스 결과를 클라이언트에 전달
docker system df
도커 시스템이 사용하는 디스크 사용량에 대한 현재 상태 조회
-v : 세부정보를 확인할 수 있다.
docker system events
도커 서버에서 발생하는 도커 관련 이벤트 정보를 표시하는 명령어
--filter 옵션을 이용해서 원하는 정보만 추출하여 볼 수 있다.
컨테이너 서비스
컨테이너에 서비스하고자 하는 애플리케이션 코드와 프로세스를 격리한다.
대부분의 개발자가 개발, 테스트, 배포, 운영의 컴퓨팅 환경 차이로 인한 시행착오 및 다양한 오류해결에 너무 많은 시간을 소비하는 공통적인 문제를 가지고 있어 이를 해결할 수 있는 도커 기반의 컨테이너 서비스 환경으로 전환하고 있다.
컨테이너 서비스는 기존 환경과 다르게 애플리케이션 실행에 필요한 바이너리, 라이브러리 및 구성 파일등을 패키지로 묶어 배포하는 방식으로 논리적 패키징 메커니즘을 제공한다. 애플리케이션이 가지고 있는 운영체제, 하드웨어에 대한 의존성 문제를 해결한 것이다. 따라서 어떤 환경에서든 컨테이너 기반의 애플리케이션을 개발하고 배포할 수 있다.
→ 이렇게 호스트 운영체제를 공유하고 애플리케이션에 필요한 환경을 패키징하는 것을 운영체제 레벨 가상화라고 부른다.
- 하드웨어 레벨 가상화 : 하이퍼바이저 등을 이용한 가상머신의 방식을 말한다.
- 운영체제 레벨 가상화 : 컨테이너 기반의 애플리케이션 서비스 방식
도커 기반 애플리케이션 개발의 라이프사이클
- 애플리케이션 코드 개발
- : 특정 서비스 구동을 위한 애플리케이션 코드 및 웹 화면 구성등을 위한 코드를 개발한다.
- 베이스 이미지를 이용한 Dockerfile 관리
- 개발에 필요한 인프라 구성 요소를 Dockerfile에 작성한다. 즉, 도커 허브를 통해 베이스 이미지를 다운로드하고 다양한 구동 명령어(FROM, RUN, CMD, ENDPOINT, ENV, ADD 등)와 1번에서 작성한 애플리케이션 코드, 라이브러리, 여러 도구를 Dockerfile에 포함시킨다.
- Dockerfile build를 통한 새로운 이미지 생성각 단계별로 실행되는 로그를 화면에서 확인하며 이때 오류 발생 내용도 확인할 수 있다.
- docker build 명령을 통해 작성한 Dockerfile을 실행한다.
- 생성된 이미지를 이용한 컨테이너 실행
- 도커 컴포즈를 이용한 다중 컨테이녀 실행도커 실행 옵션을 미리 작성한 docker-compose.yml을 통해 다중 컨테이너 간 실행 순서, 네트워크, 의존성 등을 통합 관리할 수 있고 마이크로서비스 개발에 활용한다. 예로 하나의 docker-compose.yml 파일이 아닌 여러 개의 yml파일로 구성된 서비스 개발도 가능하다.
- 도커 명령어 docker images를 통해 생성된 이미지를 확인하고 이미지를 통한 컨테이너를 구동(docker run)한다.
- 컨테이너 애플리케이션 서비스 테스트
- 예를 들어 Nginx를 이용한 웹 애플리케이션 컨테이너 서비스였다면 연결하는 IP와 포트 번호를 이용하여 웹 브라우저를 이용한 페이지 연결을 확인할 수 있다.
- 로컬 및 원격 저장소에 이미지 저장
- 깃허브 등을 활용한 Dockerfile 관리
- 동일 환경에서의 지속적 애플리케이션 개발 수행
- 1-7 과정을 통해 업무용 애플리케이션 이미지를 지속적으로 개발,운영 및 관리할 수 있다.
컨테이너 동작에 필요한 모든 내용을 사전에 코드로 작성하여 인프라 프로비저닝 도구로 자동화하게 되면 기업이 필요할 때마다 애플리케이션 및 서버 환경을 적은 비용으로 빠르게 개발, 배포, 확장할 수 있다는 것을 알아두자 → IaC
도커 명령어 활용
모든 명령어는 키워드로 docker를 맨 앞에 사용한다.
도커 컨테이너 명령어
도커 볼륨 활용
도커는 유니언 파일 시스템을 사용하여 하나의 이미지로부터 여러 컨테이너를 만들고 이미지에 변경된 내용을 저장할 수 있도록 한다.
도커 볼륨
→ 컨테이너에서 생성, 재사용할 수 있고 호스트 운영체제에서 직접 접근이 가능
→ 보존되어야 하는 데이터를 유지하기 위한 멬커니즘을 제공
일반적으로 컨테이너 내부의 데이터는 컨테이너의 라이프사이클에 의해 컨테이너 종료 시 삭제된다. 도커 볼륨을 사용하면 컨테이너가 삭제되어도 볼륨은 독립적으로 운영되어 데이터를 영속적으로 유지할 수 있다. → 호스트 파일 시스템의 특정 디렉터리와 컨테이너의 디렉터리를 연결하여 데이터를 저장할 수 있다.
- volume
- 도커에서 밀어주는 방식
- bind mount
- 도커 볼륨 기법에 비해 사용이 제한적이다.
- 호스트 파일 시스템 경로:컨테이너 내부 경로를 직접 마운트하여 사용한다.
- 사용자가 파일, 디렉토리를 생성하면 해당 호스트 파일 시스템의 소유자 권한으로 연결이 되고 존재하지 않는 경우 자동으로 생성된다(루트 소유).
- 컨테이너 실행 시 지정하여 사용하고 컨테이너 제거시 바인드 마운트는 해제되지만 호스트 디렉터리는 유지된다.
- tmpfs mount
- 컨테이너가 중지되면 tmpfs마운트가 제고되고 내부에 기록된 파일은 유지되지 않는다.
- 호스트 또는 컨테이너 쓰기 가능 계층에서 지속하지 않지만 중요한 파일을 임시로 사용하는 방법에 유용하다.
- 컨테이너 실행시 지정하여 사용하고 컨테이너 제거 시 자동 해제된다.
도커 네트워크
도커 컨테이너 및 서비스는 도커 네트워크를 통해 격리된 컨테이너 간의 네트워크 연결뿐만 아니라 도커 외의 다른 애플리케이션 워크로드와도 연결이 가능하다. 이때 도커 네트워크의 하위 시스템 연결을 위해 도커 네트워크 드라이버를 사용하여 상호간 통신을 할 수 있다.
- bridge
- 기본 네트워크 드라이버
- 컨테이너 실행 시 별도의 네트워크 지정 없이 독립적으로 실행되는 애플리케이션 컨테이너를 실행하는 경우 사용된다.
- → 단 브리지 모드는 동일 호스트상의 도커 컨테이너에만 적용된다.
- host
- 컨테이너와 호스트 간의 네트워크 격리를 제거하고 호스트의 네트워킹을 직접 사용할 수 있다.
- 컨테이너 애플리케이션에 별도의 포트 연결없이 호스트의 포트를 이용하여 바로 서비스할 수 있다.
- overlay
- 다중 호스트 도커 서버를 이용한 클러스터(도커 스웜)등을 이용할 경우 도커 데몬간의 연결을 통해 컨테이너 서비스를 수행할 수 있다.
- 컨테이너 간에 운영체제 수준의 라우팅을 사용하지 않아도 된다.
- 도커 클러스터인 도커 스웜 구축 시 호스트와 호스트 간의 컨테이너 연결에 사용된다.
- macvlan
- 물리적 네트워크에 컨테이너 mac 주소를 통한 직접 연결 구현시 사용된다.
- 도커 데몬은 mac 주소별로 트래픽을 라우팅하게 된다.
- none
- 컨테이너의 네트워크를 사용하지 않도록 설정
- 네트워크 인터페이스는 lo 인터페이스만 존재한다.
- 컨테이너가 호스트 네트워킹 스택에서 완전히 분리되어 외부와의 통신을 완전 단절한다.
- 컨테이너 네트워크
- container : 공유받을 컨테이너 이름
- 컨테이너의 네트워크 네임 스페이스 스택을 공유하여 같이 사용할 수 있게 한다.
- 사용자 정의 네트워크
- 사용자가 직접 생성한 네트워크로 아무런 옵션을 주지 않고 생성하면 docker0 IP 대역의 다른 CIDR을 지정하여 생성된다.
도커 기본 브리지 네트워크
도커의 기본 네트워크 구성은 브리지 모드로 도커 데몬을 통해 도커 컨테이너만의 네트워크를 실제 서버 네트워크와 분리해 독립적으로 구성하는 네트워크 방식이다.
Dockerfile
코드로 개발하는 컨테이너 인프라, Dockerfile
Dockerfile : 원하는 개발 환경을 코드로 구성하는 방법을 제공하는 것
- 필요성
- 커맨드 기반의 인프라 구성시 인적 오류 발생 가능성이 높다.
- Apache + PHP + MySQL 구축을 생각해보자. 설치 순서와 상호 연관성 등을 고려하여 각종 라이브러리와 함께 복잡한 명령어를 고민해야 한다.
- 각종 환경 설정 정보와 설치 프로그램을 요구사항에 맞게 따져봐야 한다.
- 만일 설치 이후에 잘못된 설정이 있다면 수정해야 하고, 때로는 재설치를 해야만 할 수도 있다.
애플리케이션에 적용되는 새로운 환경을 사용자가 직접 정의해서 아이디어를 실현할 수 있는 것이 바로 코드로서 인프라 환경을 프로비저닝하는 Dockerfile이다. 이렇게 만들어진 코드나 이미지를 다양한 공유 방식을 통해 언제 어디서든 컨테이너로 만들어낼 수 있다.
- 최적의 Dockerfile을 만들기 위해 고려할 점
- 경량의 컨테이너 서비스를 제공
- Dockerfile에 담기는 레이어를 최소화
- 도커파일 명령어의 수와 도커 이미지 레이어 수는 동일하다. 레이어 수가 많을수록 이미지를 빌드하는 시간은 길어지기 때문에 파일용량도 커진다. 따라서 명령어수를 최소화하는 방향으로 작성한다.
- 하나의 애플리케이션은 하나의 컨테이너에
- 캐시 기능을 활용
- IaC 환경 개발은 디렉터리 단위로
- 서버리스 환경으로 개발
Dockerfile 명령어
일반적으로 시작은 FROM으로 작성하지만 그 다음부터는 순서가 딱히 없다. 하지만 명령한 순서대로 빌드 캐시의 무효화와 연관되므로 변경 빈도수가 적은 명령을 먼저 배치하는 것을 권장한다. 무조건 OS 이미지를 선택하고 설치하는 것보다는 원하는 애플리케이션 패키지가 이미 설치된 이미지 선택을 권장한다.
FROM
생성하려는 이미지의 베이스 이미지 지정 명령어이다.
이미지를 선택할 때 작은 크기의 이미지와 리눅스 알파인 이미지를 권장하나 상황에 맞춰서 선택하면 된다. 예를 들어 파이썬 같은 경우 알파인 리눅스를 사용하면 파이썬 패키지에서 C코드를 컴파일을 통해 도커 이미지를 빌드하기 때문에 빌드 시간도 오래 걸리고 이미지 용량도 커질 수 있다. 파이썬 애플리케이션 도커 이미지를 선택하는 경우에는 Debian Buster 키워드 이미지가 유리하다.
태그를 넣지 않으면 latest로 지정된다.
MAINTAINER
일반적으로 이미지를 빌드한 작성자 이름과 이메일을 작성한다.
MAINTAINER san.An <san@42.kr>
LABEL
이미지 작성 목적으로 버전, 타이틀, 설명, 라이선스 정보등을 작성한다. 1개 이상 작성 가능
LABEL pupose = 'Nginx for webserver' \\
version = '1.0' \\
description = 'web service application using Nginx'
RUN
설정된 기본 이미지에 패키지 업데이트 각종 패키지 설치, 명령 실행 등을 작성한다. 1개 이상 작성 가능
레이어 저장
RUN apt update
RUN apt -y install nginx
#Shell
RUN apt update && apt install -y nginx \\
git \\
curl && \\
apt-get clean -y && \\
apt-get autoremove -y && \\
rm -rfv /tmp/* /var/lib/apt/lists/* /var/tmp/*
- 권장
- 다단계 빌드 사용 권장, 각 이미지별로 개별 Dockerfile로 빌드
- RUN 명령어의 개별 명령 수를 최소화하기 위해 여러 설치 명령을 연결하면 이미지의 레이어수가 감소한다.
- autoremove, autoclean, rm -rf/var/lib/apt/lists/* 을 사용하면 저장되어 있는 apt 캐시가 삭제되어 이미지 크기가 감소한다.
CMD
생성된 이미지를 컨테이너로 실행할 때 실행되는 명령이고, ENTRYPOINT 명령문으로 지정된 커맨드에 디폴트로 넘길 파라미터를 지정할 때 사용한다. 여러 개의 CMD를 작성해도 마지막 하나만 처리된다. 일반적으로 이미지의 컨테이너 실행 시 애플리케이션 데몬이 실행되도록 하는 경우 유용하다.
#shell
CMD apachectl -D FOREGROUND
#exec
CMD ["/usr/sbin/apachectl", "-D", "FOREGOUND"]
ENTRYPOINT
CMD와 마찬가지로 생성된 이미지가 컨테이너로 실행될 때 사용되지만 컨테이너가 실행될 때 명령어 및 인자 값을 전달하여 실행한다는 점이 다르다. 여러 개의 CMD를 사용하는 경우 ENTRYPOINT 명령문과 함께 사용한다. ENTRYPOINT는 커맨드를 지정하고 CMD는 기본 명령을 지정하면 탄력적으로 이미지를 실행할 ㅅ ㅜ있다. 예를 들어 python 명령을 기본으로 runapp.py 코드를 실행하면
ENTRYPOINT ["python"]
CMD ["runapp.py"]
# 동일 환경에 entrypoint.sh 를 이미지에 넣고 ADD 실행 권한 설정 후 컨테이너 실행 시 entrypoint.sh를 실행
...
ADD ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
- ENTRYPOINT : 도커 컨테이너 실행 시 항상 수행하야 하는 명령어를 지정 (웹 서버나 데이터베이스의 데몬을 실행)
- CMD : 도커 컨테이너 실행 시 다양한 명령어를 지정하는 경우 유용
COPY
호스트 환경의 파일, 디렉터리를 이미지 안에 복사하는 경우 작성한다.
단순한 복사 작업만 지원, 빌드 작업 디렉터리 외부의 파일은 카피할 수 없다.
레이어 저장
COPY index.html /usr/share/nginx/html
ADD
호스트 환경의 파일 디렉터리를 이미지 안에 복사하는 경우 뿐만아니라 URL 주소에서 직접 다운로드하여 이미지에 넣을수도 있다. 압축 파일의 경우 지정한 경로 안에 압축을 풀어서 추가한다.
빌드 작업 외부 파일은 ADD할 수 없고, 디렉터리 추가시에는 /로 끝나야 한다.
레이어 저장
ADD index.html /usr/share/nginx/html
ADD <http://example.com/view/customer.tar.gz> /workspace/data/
ENV
이미지 안에 각종 환경 변수를 지정하는 경우 작성한다. 애플리케이션 사용을 쉽게 하려면 사전에 구성되어야 하는 환경 변수들이 있다. 예를 들어 자바 홈디렉토리, 특정 실행 파일의 경로를 보장하기 위해 절대 경로 지정을 위한 PATH 설정, 프로그램 버전 등을 사전에 설정한다.
반복된 표현이 사용되는 경우에도 환경 변수 설정을 권장한다.
ENV PATH /usr/local/nginx/bin:$PATH
EXPOSE
컨테이너가 호스트 네트워크를 통해 들어오는 트래픽을 리스닝하는 포트와 프로토콜을 지정하기 위해 작성한다. nginx나 apache는 기본 포트로 HTTP 80번과 HTTPS 443번 포트를 사용하고, 컨테이너 모니터링 이미지로 사용하는 Cadvisor 컨테이너는 8080번 포트를 사용한다.
이미지 내에 애플리케이션이 사용하는 포트를 사전에 확인하고 호스트와 연결되도록 구성하는 경우에 설정하고 docker run 사용시 -p 옵션을 통해 사용한다.
EXPOSE 80
EXPOSE 80/tcp
VOLUME
볼륨을 이미지 빌드에 미리 설정하는 경우 작성한다.
도커 컨테이너에서 사용된 파일과 디렉터리는 컨테이너 삭제와 함께 사라지기 때문에 사용자 데이터의 보존과 지속성을 위해 볼륨 사용을 권장한다.
VOLUME으로 지정된 컨테이너의 경로는 볼륨의 기본 경로 /var/lib/docker와 자동으로 연결된다.
VOLUME /var/log
USER
컨테이너의 기본 사용자는 root이다. 애플리케이션이 권한 없이 서비스를 실행할 수 있다면 USER를 통해 다른 사용자로 변경하여 사용한다.
WORKDIR
컨테이너 상에서 작업할 경로 전환을 위해 작성한다. WORKDIR을 설정하면 RUN, ADD, CMD, ENTRYPOINT, COPY 명령문은 해당 디렉터리를 기준으로 실행된다.
ARG
ONBUILD
STOPSIGNAL
SHELL
HEALTHCHECK
이미지 생성을 위한 Dockerfile 빌드
docker build [옵션] 이미지명:[태그] 도커파일경로 | URL | 압축파일
도커 컴포즈 - 다중 컨테이너 애플리케이션
도커 컴포즈는 공통성을 갖는 컨테이너 애플리케이션 스택을 yaml 코드로 정의한 정의서이다. → 다중 컨테이너 실행 도구
이때 공통성이란 공통의 목적을 의미하며 그 예로 웹 애플리케이션을 생성하기 위해 필요한 MySQL 데이터베이스와 API 애플리케이션 설정을 위한 백엔드 환경(플라스크, node), 사용자 인터페이서 그성을 위한 웹 프레임워크 이 세가지는 공통의 목적을 가지며 각 스택을 도커 컴포즈를 통해 한번에 서비스를 올리고 관리할 수 있다.
도커 컴포즈로 실행된 컨테이너는 독립된 기능을 가지며 공통 네트워크로 구성되기 때문에 컨테이너간 통신이 쉽다. → 쉽고 빠른 런타임 환경 제공
docker-compose up
이라는 간단한 명령어로 컨테이너를 올릴 수 있다.
docker-compose ps
는 생성된 컨테이너 정보를 조회할 수 있다.
docker-compose down
은 생성했던 것과 반대로 서비스를 모두 내리고 네트워크도 회수한다.
docker-compose up -d
도커 컴포즈를 백그라운드로 실행한다.
도커 컴포즈 YAML 코드 작성법
야믈코드의 계층 구조는 부모-자식 간의 레벨을 들여쓰기로 구분한다.
큰 구조 →
version: "3.8"
services:
서비스명1:
# 설정
networks:
# 네트워크 설정, 미지정시 자동 설정
volumes:
# 볼룸 설정
일반적으로 가장 먼저 실행되어야 하는 애플리케이션을 먼저 작성하고 이와 의존성을 갖는 데이터베이스 및 하위 애플리케이션을 작성한다.
서비스 전체를 하나의 도커 컴포즈 야믈 코드로 작성할 수 있다.
- 버전 정의
야믈 코드 첫 줄은 버전을 명시한다.
version: "3"
- 서비스 정의
도커 컴포즈를 통해 실행할 서비스를 정의한다.
도커 컴포즈는 컨테이너 대신 서비스 개념을 사용한다. 서비스 하위에는 실행될 컨테이너 서비스를 작성하고 하위 레벨에 도커 명령 실행과 유사하게 컨테이너 실행에 필요한 옵션을 작성하면 된다.
image를 사용해도 되고 build옵션으로 도커 파일을 실행해도 된다.
- 그 외 옵션들
- container_name: 생략 시 자동으로 부여한다.
- ports: 서비스 내부 포트와 외부 호스트 포트를 지정하여 바인드, 외부 노출 포트를 지정한다.
- expose: 호스트 운영체제와 직접 연결하는 포트를 구성하지 않고 서비스만 포트를 노출, 필요 시 링크로 연결된 서비스와 서비스 간의 통신만 허용한다.
- networks: 최상위 레벨의 networks에 정의된 네트워크 이름을 작성
- volumes: 서비스 내부 디렉터리와 호스트 디렉터리를 연결하여 데이터 지속성 설정
- environment: 서비스 내부 환경 변수를 설정한다. 환경 변수가 많은 경우 *.env 파일로 만들어 env_file 옵션에 파일명을 지정할 수 있다.
- command: 서비스가 구동 후 실행할 명령어를 작성한다.
- restart: 서비스 재시작 옵션 지정, always의 경우 수동 제어를 제외하고 항상 재시작한다.
- depends_on: 서비스 간의 종속성을 의미하며 먼저 실행해야 하는 서비스를 지정하여 순서를 지정한다.
- 네트워크 정의
다중 컨테이너들이 사용할 최상위 네트워크 키를 정의하고 이하 하위 서비스 단위로 이 네트워크를 선택할 수 있다.
아무런 networks 옵션을 지정하지 않으면 자체 기본 네트워크가 자동으로 생성된다.
최상위 레벨에 networks 지정 시 해당 이름의 네트워크가 생성되고 대역은 172…….로 자동 할당되며 기본 드라이버는 브리지로 지정된다.
도커에서 생성한 기존 네트워크를 지정하는 경우에는 externel 옵션에 네트워크 이름을 작성한다.
- 데이터의 지속성을 유지하기 위해 최상위 레벨에 볼륨을 정의하고, 서비스 레벨에서 볼륨명과 서비스 내부의 디렉터리를 바인드한다. 도커가 관리하는 가상 영역 /var/lib/docker/volume에 자동 배치된다.
도커, 컨테이너 빌드업!
클라우드 컴퓨팅 개요
클라우드는 인프라에 사용되는 서버, 저장소, 데이터베이스, 네트워크, 데이터베이스, 소프트웨어 데이터 분석등을 포함해 사용자가 언제든지 인터넷과 모바일 등을 통해 IT 서비스를 제공받을 수 있도록 하는 컴퓨팅 기술이다.
클라우드 컴퓨팅이란?
- 인터넷 기술을 사용해서 다수의 사용자에게 하나의 서비스로서 방대한 IT 능력을 제공하는 컴퓨팅 방식
특징
- 주문형 셀프 서비스 on demand self service
- 고객이 IT 서비스 제공자의 개입 없이 원하는 시점에 바로 서비스를 이용할 수 있다.
- 광대역 네트워크 접근 broad network access
- 각 클라우드 서비스 업체가 제공하는 광대역 네트워크를 이용하여 다양한 클라이언트 플랫폼이 빠르게 접속할 수 있다.
- 신속한 탄력성과 확장성, rapid elasticity and scalability
- 자동 조정 기능을 통해 몇 분 안에 신속한 확장과 축소를 조정할 수 있다.
- 자원의 공동관리, resource pooling
- 물리적 및 가상화된 자원을 풀로 관리하며, 탄력적으로 업무 상황에 맞게 사용자 요구에 따라 동적으로 할당 또는 재할당된다.
- 측정 가능한 서비스, measured service
- 자원 사용량이 실시간으로 수집되는 요금산정기능을 통해 비용이 발생한다.
클라우드 컴퓨팅 구조
https://www.cloudhelp.kr/software/cloud-computing/outline/
물리적 시스템, 가상화, 프로비져닝 계층은 자원 활용과 관련되어있고 클라우드 컴퓨팅 서비스 관리 체계, 클라우드 서비스 계층은 클라우드 서비스와 관련있다.
- 물리적 계층 : 여러 형태의 서버 계열을 활용하여 서버에 탑재된 수평적으로 확장 가능한 스토리지 및 네트워크등의 물리적 요소
- 이를 기반으로 서버, 스토리지, 네트워크 가상화는 민첩성을 제공하고, IT 서비스 공급자는 클라우드 서버 프로비저닝 또는 프로비저닝 해제를 신속히 수행하여 서비스 사용자의 요구를 충족할 수 있다.
- 클라우드 컴퓨팅 서비스 관리 체계 계층
- 안정적인 클라우드 서비스를 위한 성능 및 고가용성, 소프트웨어 라이선스와 패치 관리, 사용량 요금 산정을 통한 과금 관리, 기본적인 클라우드 보안 관리 요소가 결합되어 있다.
- : 물리적 시스템 계층에서 제공되는 자원에 대한 전반적인 라이프사이클 관리와 모니터링을 지원한다.
클라우드 컴퓨팅 제공 방식
6페이지
컨테이너 기술과 도커
가상 머신과 컨테이너
가상화 : 물리적 구성은 은폐하고, 가상환경을 여러 개 만들어, 개별 가상머신이 자원을 갖추고 있게 만드는 기술
- 프로비저닝 : IT인프라 자원을 사용자의 니즈에 맞게 할당/배치/배포해서 시스템을 사용할 수 있도록 하는 기술
- 하이퍼바이저 : 물리서버 위에 존재하는 가상화 계층으로서, OS구동을 위한 HW환경을 가상으로 제공
하이퍼바이저
하드웨어 가상화
컨테이너
프로세스 가상화
- 컨테이너 기술의 장점
- 하이퍼바이저와 게스트 OS가 없어 가볍다.
- 경량이기 때문에 만들어진 이미지 복제, 이관, 배포가 쉽다.
- 게스트 OS를 부팅하지 않기 때문에 애플리케이션 시작 시간이 빠르다.
- 가상머신보다 경량이므로 더 많은 애플리케이션을 실행할 수 있다.
도커
컨테이너는 코드와 모든 종속성을 패키지화하는 표준 소프트웨어 단위로, 애플리케이션이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 한다.
도커 컨테이너 이미지는 애플리케이션을 실행하는 데 필요한 모든 것(코드, 런타임, 라이브러리 등)을 포함하는 경량의 독립형 실행 가능 소프트웨어 패키지라고 정의할 수 있다.
[ 도커 주요 기능 ]
- LXC(리눅스 컨테이너)를 이용한 컨테이너 구동
- containerd는 리눅스 및 윈도우용 데몬으로, 이미지 전송 및 스토리지에서 컨테이너 실행 및 감독, 네트워크 연결까지 호스트 시스템 전체 컨테이너의 라이프사이클을 관리한다.
- 통합 BuildKit
- 빌드킷은 도커파일의 설정 정보를 이용하여 도커 이미지를 빌드하는 오픈 소스 도구이며, 빠르고 정확하게 여러가지 아키텍처 향상 기능을 제공한다.
- 도커 CLI 기반
- 도커 명령을 수행하는 기본적인 방법을 CLI로 제공한다.
도커를 사용하는 이유
예를 들어 node.js로 만든 애플리케이션을 테스트해야하는 상황에서 현재 로컬에 node.js를 실행하려면 npm이라는 모듈이 필요하다. 만약 이 애플리케이션이 하나의 모듈이 아니라 여러 가지 의존성이 있는 애플리케이션이며 데이터베이스까지 필요하다면? 환경설정과 애플리케이션을 설치하는 데 많은 시간을 투자해야한다. 만약 각각의 의존성이 다른 애플리케이션이 여러개라면 환경설정에 걸리는 시간은 배로 늘어난다. 이를 도커로 단축시킬 수 있다.
도커에 사전에 만들어진 이미지를 통해 컨테이너 안에서 테스트할 수 있다.
- 도커 엔진 : 도커를 이용한 애플리케이션 실행 환경 제공을 위한 핵심 요소
- 도커 허브 : 도커 사용자들과 함께 도커 컨테이너 이미지를 공유하는 클라우드 서비스
- docker-compose : 의존성 있는 독립된 컨테이너에 대한 구성 정보를 YAML코드로 작성하여 일원화된 애플리케이션 관리를 가능하게 하는 도구
- docker Kitematic : 컨테이너를 이용한 작업을 수행할 수 있는 GUI 제공
- docker registry :
- docker machine :
- docker swarm :
- docker ps -a : 실행된 모든 컨테이너의 정보를 제공
우리는 Nginx를 위한 환경 구성, 설치, 서비스 시작 그 어떤 것도 하지 않고 도커를 이용하여 컨테이너 nginx 서비스를 배포할 수 있다. - 도커의 민텁한 애플리케이션 배포 기능
도커 엔진은 서버와 클라이언트로 구분된다. 클라이언트는 도커의 명령을 받고 결과를 출력하고 서버는 도커 엔진, 도커 데몬을 이용하여 컨테이너 시작, 운영 , 정지등을 담당한다.
클라이언트는 도커 명령을 수행하는 명령줄을 제공 → 수행된 도커 명령은 서버의 도커 데몬으로 전달 → 도커 데몬은 docker socket이 보유한 도커 API를 이용해 컨테이너 생성 → 수행된 컨테이너에 포함된 서비스 결과를 클라이언트에 전달
docker system df
도커 시스템이 사용하는 디스크 사용량에 대한 현재 상태 조회
-v : 세부정보를 확인할 수 있다.
docker system events
도커 서버에서 발생하는 도커 관련 이벤트 정보를 표시하는 명령어
--filter 옵션을 이용해서 원하는 정보만 추출하여 볼 수 있다.
컨테이너 서비스
컨테이너에 서비스하고자 하는 애플리케이션 코드와 프로세스를 격리한다.
대부분의 개발자가 개발, 테스트, 배포, 운영의 컴퓨팅 환경 차이로 인한 시행착오 및 다양한 오류해결에 너무 많은 시간을 소비하는 공통적인 문제를 가지고 있어 이를 해결할 수 있는 도커 기반의 컨테이너 서비스 환경으로 전환하고 있다.
컨테이너 서비스는 기존 환경과 다르게 애플리케이션 실행에 필요한 바이너리, 라이브러리 및 구성 파일등을 패키지로 묶어 배포하는 방식으로 논리적 패키징 메커니즘을 제공한다. 애플리케이션이 가지고 있는 운영체제, 하드웨어에 대한 의존성 문제를 해결한 것이다. 따라서 어떤 환경에서든 컨테이너 기반의 애플리케이션을 개발하고 배포할 수 있다.
→ 이렇게 호스트 운영체제를 공유하고 애플리케이션에 필요한 환경을 패키징하는 것을 운영체제 레벨 가상화라고 부른다.
- 하드웨어 레벨 가상화 : 하이퍼바이저 등을 이용한 가상머신의 방식을 말한다.
- 운영체제 레벨 가상화 : 컨테이너 기반의 애플리케이션 서비스 방식
도커 기반 애플리케이션 개발의 라이프사이클
- 애플리케이션 코드 개발
- : 특정 서비스 구동을 위한 애플리케이션 코드 및 웹 화면 구성등을 위한 코드를 개발한다.
- 베이스 이미지를 이용한 Dockerfile 관리
- 개발에 필요한 인프라 구성 요소를 Dockerfile에 작성한다. 즉, 도커 허브를 통해 베이스 이미지를 다운로드하고 다양한 구동 명령어(FROM, RUN, CMD, ENDPOINT, ENV, ADD 등)와 1번에서 작성한 애플리케이션 코드, 라이브러리, 여러 도구를 Dockerfile에 포함시킨다.
- Dockerfile build를 통한 새로운 이미지 생성각 단계별로 실행되는 로그를 화면에서 확인하며 이때 오류 발생 내용도 확인할 수 있다.
- docker build 명령을 통해 작성한 Dockerfile을 실행한다.
- 생성된 이미지를 이용한 컨테이너 실행
- 도커 컴포즈를 이용한 다중 컨테이녀 실행도커 실행 옵션을 미리 작성한 docker-compose.yml을 통해 다중 컨테이너 간 실행 순서, 네트워크, 의존성 등을 통합 관리할 수 있고 마이크로서비스 개발에 활용한다. 예로 하나의 docker-compose.yml 파일이 아닌 여러 개의 yml파일로 구성된 서비스 개발도 가능하다.
- 도커 명령어 docker images를 통해 생성된 이미지를 확인하고 이미지를 통한 컨테이너를 구동(docker run)한다.
- 컨테이너 애플리케이션 서비스 테스트
- 예를 들어 Nginx를 이용한 웹 애플리케이션 컨테이너 서비스였다면 연결하는 IP와 포트 번호를 이용하여 웹 브라우저를 이용한 페이지 연결을 확인할 수 있다.
- 로컬 및 원격 저장소에 이미지 저장
- 깃허브 등을 활용한 Dockerfile 관리
- 동일 환경에서의 지속적 애플리케이션 개발 수행
- 1-7 과정을 통해 업무용 애플리케이션 이미지를 지속적으로 개발,운영 및 관리할 수 있다.
컨테이너 동작에 필요한 모든 내용을 사전에 코드로 작성하여 인프라 프로비저닝 도구로 자동화하게 되면 기업이 필요할 때마다 애플리케이션 및 서버 환경을 적은 비용으로 빠르게 개발, 배포, 확장할 수 있다는 것을 알아두자 → IaC
도커 명령어 활용
모든 명령어는 키워드로 docker를 맨 앞에 사용한다.
도커 컨테이너 명령어
도커 볼륨 활용
도커는 유니언 파일 시스템을 사용하여 하나의 이미지로부터 여러 컨테이너를 만들고 이미지에 변경된 내용을 저장할 수 있도록 한다.
도커 볼륨
→ 컨테이너에서 생성, 재사용할 수 있고 호스트 운영체제에서 직접 접근이 가능
→ 보존되어야 하는 데이터를 유지하기 위한 멬커니즘을 제공
일반적으로 컨테이너 내부의 데이터는 컨테이너의 라이프사이클에 의해 컨테이너 종료 시 삭제된다. 도커 볼륨을 사용하면 컨테이너가 삭제되어도 볼륨은 독립적으로 운영되어 데이터를 영속적으로 유지할 수 있다. → 호스트 파일 시스템의 특정 디렉터리와 컨테이너의 디렉터리를 연결하여 데이터를 저장할 수 있다.
- volume
- 도커에서 밀어주는 방식
- bind mount
- 도커 볼륨 기법에 비해 사용이 제한적이다.
- 호스트 파일 시스템 경로:컨테이너 내부 경로를 직접 마운트하여 사용한다.
- 사용자가 파일, 디렉토리를 생성하면 해당 호스트 파일 시스템의 소유자 권한으로 연결이 되고 존재하지 않는 경우 자동으로 생성된다(루트 소유).
- 컨테이너 실행 시 지정하여 사용하고 컨테이너 제거시 바인드 마운트는 해제되지만 호스트 디렉터리는 유지된다.
- tmpfs mount
- 컨테이너가 중지되면 tmpfs마운트가 제고되고 내부에 기록된 파일은 유지되지 않는다.
- 호스트 또는 컨테이너 쓰기 가능 계층에서 지속하지 않지만 중요한 파일을 임시로 사용하는 방법에 유용하다.
- 컨테이너 실행시 지정하여 사용하고 컨테이너 제거 시 자동 해제된다.
도커 네트워크
도커 컨테이너 및 서비스는 도커 네트워크를 통해 격리된 컨테이너 간의 네트워크 연결뿐만 아니라 도커 외의 다른 애플리케이션 워크로드와도 연결이 가능하다. 이때 도커 네트워크의 하위 시스템 연결을 위해 도커 네트워크 드라이버를 사용하여 상호간 통신을 할 수 있다.
- bridge
- 기본 네트워크 드라이버
- 컨테이너 실행 시 별도의 네트워크 지정 없이 독립적으로 실행되는 애플리케이션 컨테이너를 실행하는 경우 사용된다.
- → 단 브리지 모드는 동일 호스트상의 도커 컨테이너에만 적용된다.
- host
- 컨테이너와 호스트 간의 네트워크 격리를 제거하고 호스트의 네트워킹을 직접 사용할 수 있다.
- 컨테이너 애플리케이션에 별도의 포트 연결없이 호스트의 포트를 이용하여 바로 서비스할 수 있다.
- overlay
- 다중 호스트 도커 서버를 이용한 클러스터(도커 스웜)등을 이용할 경우 도커 데몬간의 연결을 통해 컨테이너 서비스를 수행할 수 있다.
- 컨테이너 간에 운영체제 수준의 라우팅을 사용하지 않아도 된다.
- 도커 클러스터인 도커 스웜 구축 시 호스트와 호스트 간의 컨테이너 연결에 사용된다.
- macvlan
- 물리적 네트워크에 컨테이너 mac 주소를 통한 직접 연결 구현시 사용된다.
- 도커 데몬은 mac 주소별로 트래픽을 라우팅하게 된다.
- none
- 컨테이너의 네트워크를 사용하지 않도록 설정
- 네트워크 인터페이스는 lo 인터페이스만 존재한다.
- 컨테이너가 호스트 네트워킹 스택에서 완전히 분리되어 외부와의 통신을 완전 단절한다.
- 컨테이너 네트워크
- container : 공유받을 컨테이너 이름
- 컨테이너의 네트워크 네임 스페이스 스택을 공유하여 같이 사용할 수 있게 한다.
- 사용자 정의 네트워크
- 사용자가 직접 생성한 네트워크로 아무런 옵션을 주지 않고 생성하면 docker0 IP 대역의 다른 CIDR을 지정하여 생성된다.
도커 기본 브리지 네트워크
도커의 기본 네트워크 구성은 브리지 모드로 도커 데몬을 통해 도커 컨테이너만의 네트워크를 실제 서버 네트워크와 분리해 독립적으로 구성하는 네트워크 방식이다.
Dockerfile
코드로 개발하는 컨테이너 인프라, Dockerfile
Dockerfile : 원하는 개발 환경을 코드로 구성하는 방법을 제공하는 것
- 필요성
- 커맨드 기반의 인프라 구성시 인적 오류 발생 가능성이 높다.
- Apache + PHP + MySQL 구축을 생각해보자. 설치 순서와 상호 연관성 등을 고려하여 각종 라이브러리와 함께 복잡한 명령어를 고민해야 한다.
- 각종 환경 설정 정보와 설치 프로그램을 요구사항에 맞게 따져봐야 한다.
- 만일 설치 이후에 잘못된 설정이 있다면 수정해야 하고, 때로는 재설치를 해야만 할 수도 있다.
애플리케이션에 적용되는 새로운 환경을 사용자가 직접 정의해서 아이디어를 실현할 수 있는 것이 바로 코드로서 인프라 환경을 프로비저닝하는 Dockerfile이다. 이렇게 만들어진 코드나 이미지를 다양한 공유 방식을 통해 언제 어디서든 컨테이너로 만들어낼 수 있다.
- 최적의 Dockerfile을 만들기 위해 고려할 점
- 경량의 컨테이너 서비스를 제공
- Dockerfile에 담기는 레이어를 최소화
- 도커파일 명령어의 수와 도커 이미지 레이어 수는 동일하다. 레이어 수가 많을수록 이미지를 빌드하는 시간은 길어지기 때문에 파일용량도 커진다. 따라서 명령어수를 최소화하는 방향으로 작성한다.
- 하나의 애플리케이션은 하나의 컨테이너에
- 캐시 기능을 활용
- IaC 환경 개발은 디렉터리 단위로
- 서버리스 환경으로 개발
Dockerfile 명령어
일반적으로 시작은 FROM으로 작성하지만 그 다음부터는 순서가 딱히 없다. 하지만 명령한 순서대로 빌드 캐시의 무효화와 연관되므로 변경 빈도수가 적은 명령을 먼저 배치하는 것을 권장한다. 무조건 OS 이미지를 선택하고 설치하는 것보다는 원하는 애플리케이션 패키지가 이미 설치된 이미지 선택을 권장한다.
FROM
생성하려는 이미지의 베이스 이미지 지정 명령어이다.
이미지를 선택할 때 작은 크기의 이미지와 리눅스 알파인 이미지를 권장하나 상황에 맞춰서 선택하면 된다. 예를 들어 파이썬 같은 경우 알파인 리눅스를 사용하면 파이썬 패키지에서 C코드를 컴파일을 통해 도커 이미지를 빌드하기 때문에 빌드 시간도 오래 걸리고 이미지 용량도 커질 수 있다. 파이썬 애플리케이션 도커 이미지를 선택하는 경우에는 Debian Buster 키워드 이미지가 유리하다.
태그를 넣지 않으면 latest로 지정된다.
MAINTAINER
일반적으로 이미지를 빌드한 작성자 이름과 이메일을 작성한다.
MAINTAINER san.An <san@42.kr>
LABEL
이미지 작성 목적으로 버전, 타이틀, 설명, 라이선스 정보등을 작성한다. 1개 이상 작성 가능
LABEL pupose = 'Nginx for webserver' \\
version = '1.0' \\
description = 'web service application using Nginx'
RUN
설정된 기본 이미지에 패키지 업데이트 각종 패키지 설치, 명령 실행 등을 작성한다. 1개 이상 작성 가능
레이어 저장
RUN apt update
RUN apt -y install nginx
#Shell
RUN apt update && apt install -y nginx \\
git \\
curl && \\
apt-get clean -y && \\
apt-get autoremove -y && \\
rm -rfv /tmp/* /var/lib/apt/lists/* /var/tmp/*
- 권장
- 다단계 빌드 사용 권장, 각 이미지별로 개별 Dockerfile로 빌드
- RUN 명령어의 개별 명령 수를 최소화하기 위해 여러 설치 명령을 연결하면 이미지의 레이어수가 감소한다.
- autoremove, autoclean, rm -rf/var/lib/apt/lists/* 을 사용하면 저장되어 있는 apt 캐시가 삭제되어 이미지 크기가 감소한다.
CMD
생성된 이미지를 컨테이너로 실행할 때 실행되는 명령이고, ENTRYPOINT 명령문으로 지정된 커맨드에 디폴트로 넘길 파라미터를 지정할 때 사용한다. 여러 개의 CMD를 작성해도 마지막 하나만 처리된다. 일반적으로 이미지의 컨테이너 실행 시 애플리케이션 데몬이 실행되도록 하는 경우 유용하다.
#shell
CMD apachectl -D FOREGROUND
#exec
CMD ["/usr/sbin/apachectl", "-D", "FOREGOUND"]
ENTRYPOINT
CMD와 마찬가지로 생성된 이미지가 컨테이너로 실행될 때 사용되지만 컨테이너가 실행될 때 명령어 및 인자 값을 전달하여 실행한다는 점이 다르다. 여러 개의 CMD를 사용하는 경우 ENTRYPOINT 명령문과 함께 사용한다. ENTRYPOINT는 커맨드를 지정하고 CMD는 기본 명령을 지정하면 탄력적으로 이미지를 실행할 ㅅ ㅜ있다. 예를 들어 python 명령을 기본으로 runapp.py 코드를 실행하면
ENTRYPOINT ["python"]
CMD ["runapp.py"]
# 동일 환경에 entrypoint.sh 를 이미지에 넣고 ADD 실행 권한 설정 후 컨테이너 실행 시 entrypoint.sh를 실행
...
ADD ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
- ENTRYPOINT : 도커 컨테이너 실행 시 항상 수행하야 하는 명령어를 지정 (웹 서버나 데이터베이스의 데몬을 실행)
- CMD : 도커 컨테이너 실행 시 다양한 명령어를 지정하는 경우 유용
COPY
호스트 환경의 파일, 디렉터리를 이미지 안에 복사하는 경우 작성한다.
단순한 복사 작업만 지원, 빌드 작업 디렉터리 외부의 파일은 카피할 수 없다.
레이어 저장
COPY index.html /usr/share/nginx/html
ADD
호스트 환경의 파일 디렉터리를 이미지 안에 복사하는 경우 뿐만아니라 URL 주소에서 직접 다운로드하여 이미지에 넣을수도 있다. 압축 파일의 경우 지정한 경로 안에 압축을 풀어서 추가한다.
빌드 작업 외부 파일은 ADD할 수 없고, 디렉터리 추가시에는 /로 끝나야 한다.
레이어 저장
ADD index.html /usr/share/nginx/html
ADD <http://example.com/view/customer.tar.gz> /workspace/data/
ENV
이미지 안에 각종 환경 변수를 지정하는 경우 작성한다. 애플리케이션 사용을 쉽게 하려면 사전에 구성되어야 하는 환경 변수들이 있다. 예를 들어 자바 홈디렉토리, 특정 실행 파일의 경로를 보장하기 위해 절대 경로 지정을 위한 PATH 설정, 프로그램 버전 등을 사전에 설정한다.
반복된 표현이 사용되는 경우에도 환경 변수 설정을 권장한다.
ENV PATH /usr/local/nginx/bin:$PATH
EXPOSE
컨테이너가 호스트 네트워크를 통해 들어오는 트래픽을 리스닝하는 포트와 프로토콜을 지정하기 위해 작성한다. nginx나 apache는 기본 포트로 HTTP 80번과 HTTPS 443번 포트를 사용하고, 컨테이너 모니터링 이미지로 사용하는 Cadvisor 컨테이너는 8080번 포트를 사용한다.
이미지 내에 애플리케이션이 사용하는 포트를 사전에 확인하고 호스트와 연결되도록 구성하는 경우에 설정하고 docker run 사용시 -p 옵션을 통해 사용한다.
EXPOSE 80
EXPOSE 80/tcp
VOLUME
볼륨을 이미지 빌드에 미리 설정하는 경우 작성한다.
도커 컨테이너에서 사용된 파일과 디렉터리는 컨테이너 삭제와 함께 사라지기 때문에 사용자 데이터의 보존과 지속성을 위해 볼륨 사용을 권장한다.
VOLUME으로 지정된 컨테이너의 경로는 볼륨의 기본 경로 /var/lib/docker와 자동으로 연결된다.
VOLUME /var/log
USER
컨테이너의 기본 사용자는 root이다. 애플리케이션이 권한 없이 서비스를 실행할 수 있다면 USER를 통해 다른 사용자로 변경하여 사용한다.
WORKDIR
컨테이너 상에서 작업할 경로 전환을 위해 작성한다. WORKDIR을 설정하면 RUN, ADD, CMD, ENTRYPOINT, COPY 명령문은 해당 디렉터리를 기준으로 실행된다.
ARG
ONBUILD
STOPSIGNAL
SHELL
HEALTHCHECK
이미지 생성을 위한 Dockerfile 빌드
docker build [옵션] 이미지명:[태그] 도커파일경로 | URL | 압축파일
도커 컴포즈 - 다중 컨테이너 애플리케이션
도커 컴포즈는 공통성을 갖는 컨테이너 애플리케이션 스택을 yaml 코드로 정의한 정의서이다. → 다중 컨테이너 실행 도구
이때 공통성이란 공통의 목적을 의미하며 그 예로 웹 애플리케이션을 생성하기 위해 필요한 MySQL 데이터베이스와 API 애플리케이션 설정을 위한 백엔드 환경(플라스크, node), 사용자 인터페이서 그성을 위한 웹 프레임워크 이 세가지는 공통의 목적을 가지며 각 스택을 도커 컴포즈를 통해 한번에 서비스를 올리고 관리할 수 있다.
도커 컴포즈로 실행된 컨테이너는 독립된 기능을 가지며 공통 네트워크로 구성되기 때문에 컨테이너간 통신이 쉽다. → 쉽고 빠른 런타임 환경 제공
docker-compose up
이라는 간단한 명령어로 컨테이너를 올릴 수 있다.
docker-compose ps
는 생성된 컨테이너 정보를 조회할 수 있다.
docker-compose down
은 생성했던 것과 반대로 서비스를 모두 내리고 네트워크도 회수한다.
docker-compose up -d
도커 컴포즈를 백그라운드로 실행한다.
도커 컴포즈 YAML 코드 작성법
야믈코드의 계층 구조는 부모-자식 간의 레벨을 들여쓰기로 구분한다.
큰 구조 →
version: "3.8"
services:
서비스명1:
# 설정
networks:
# 네트워크 설정, 미지정시 자동 설정
volumes:
# 볼룸 설정
일반적으로 가장 먼저 실행되어야 하는 애플리케이션을 먼저 작성하고 이와 의존성을 갖는 데이터베이스 및 하위 애플리케이션을 작성한다.
서비스 전체를 하나의 도커 컴포즈 야믈 코드로 작성할 수 있다.
- 버전 정의
야믈 코드 첫 줄은 버전을 명시한다.
version: "3"
- 서비스 정의
도커 컴포즈를 통해 실행할 서비스를 정의한다.
도커 컴포즈는 컨테이너 대신 서비스 개념을 사용한다. 서비스 하위에는 실행될 컨테이너 서비스를 작성하고 하위 레벨에 도커 명령 실행과 유사하게 컨테이너 실행에 필요한 옵션을 작성하면 된다.
image를 사용해도 되고 build옵션으로 도커 파일을 실행해도 된다.
- 그 외 옵션들
- container_name: 생략 시 자동으로 부여한다.
- ports: 서비스 내부 포트와 외부 호스트 포트를 지정하여 바인드, 외부 노출 포트를 지정한다.
- expose: 호스트 운영체제와 직접 연결하는 포트를 구성하지 않고 서비스만 포트를 노출, 필요 시 링크로 연결된 서비스와 서비스 간의 통신만 허용한다.
- networks: 최상위 레벨의 networks에 정의된 네트워크 이름을 작성
- volumes: 서비스 내부 디렉터리와 호스트 디렉터리를 연결하여 데이터 지속성 설정
- environment: 서비스 내부 환경 변수를 설정한다. 환경 변수가 많은 경우 *.env 파일로 만들어 env_file 옵션에 파일명을 지정할 수 있다.
- command: 서비스가 구동 후 실행할 명령어를 작성한다.
- restart: 서비스 재시작 옵션 지정, always의 경우 수동 제어를 제외하고 항상 재시작한다.
- depends_on: 서비스 간의 종속성을 의미하며 먼저 실행해야 하는 서비스를 지정하여 순서를 지정한다.
- 네트워크 정의
다중 컨테이너들이 사용할 최상위 네트워크 키를 정의하고 이하 하위 서비스 단위로 이 네트워크를 선택할 수 있다.
아무런 networks 옵션을 지정하지 않으면 자체 기본 네트워크가 자동으로 생성된다.
최상위 레벨에 networks 지정 시 해당 이름의 네트워크가 생성되고 대역은 172…….로 자동 할당되며 기본 드라이버는 브리지로 지정된다.
도커에서 생성한 기존 네트워크를 지정하는 경우에는 externel 옵션에 네트워크 이름을 작성한다.
- 데이터의 지속성을 유지하기 위해 최상위 레벨에 볼륨을 정의하고, 서비스 레벨에서 볼륨명과 서비스 내부의 디렉터리를 바인드한다. 도커가 관리하는 가상 영역 /var/lib/docker/volume에 자동 배치된다.
도커, 컨테이너 빌드업!
클라우드 컴퓨팅 개요
클라우드는 인프라에 사용되는 서버, 저장소, 데이터베이스, 네트워크, 데이터베이스, 소프트웨어 데이터 분석등을 포함해 사용자가 언제든지 인터넷과 모바일 등을 통해 IT 서비스를 제공받을 수 있도록 하는 컴퓨팅 기술이다.
클라우드 컴퓨팅이란?
- 인터넷 기술을 사용해서 다수의 사용자에게 하나의 서비스로서 방대한 IT 능력을 제공하는 컴퓨팅 방식
특징
- 주문형 셀프 서비스 on demand self service
- 고객이 IT 서비스 제공자의 개입 없이 원하는 시점에 바로 서비스를 이용할 수 있다.
- 광대역 네트워크 접근 broad network access
- 각 클라우드 서비스 업체가 제공하는 광대역 네트워크를 이용하여 다양한 클라이언트 플랫폼이 빠르게 접속할 수 있다.
- 신속한 탄력성과 확장성, rapid elasticity and scalability
- 자동 조정 기능을 통해 몇 분 안에 신속한 확장과 축소를 조정할 수 있다.
- 자원의 공동관리, resource pooling
- 물리적 및 가상화된 자원을 풀로 관리하며, 탄력적으로 업무 상황에 맞게 사용자 요구에 따라 동적으로 할당 또는 재할당된다.
- 측정 가능한 서비스, measured service
- 자원 사용량이 실시간으로 수집되는 요금산정기능을 통해 비용이 발생한다.
클라우드 컴퓨팅 구조
https://www.cloudhelp.kr/software/cloud-computing/outline/
물리적 시스템, 가상화, 프로비져닝 계층은 자원 활용과 관련되어있고 클라우드 컴퓨팅 서비스 관리 체계, 클라우드 서비스 계층은 클라우드 서비스와 관련있다.
- 물리적 계층 : 여러 형태의 서버 계열을 활용하여 서버에 탑재된 수평적으로 확장 가능한 스토리지 및 네트워크등의 물리적 요소
- 이를 기반으로 서버, 스토리지, 네트워크 가상화는 민첩성을 제공하고, IT 서비스 공급자는 클라우드 서버 프로비저닝 또는 프로비저닝 해제를 신속히 수행하여 서비스 사용자의 요구를 충족할 수 있다.
- 클라우드 컴퓨팅 서비스 관리 체계 계층
- 안정적인 클라우드 서비스를 위한 성능 및 고가용성, 소프트웨어 라이선스와 패치 관리, 사용량 요금 산정을 통한 과금 관리, 기본적인 클라우드 보안 관리 요소가 결합되어 있다.
- : 물리적 시스템 계층에서 제공되는 자원에 대한 전반적인 라이프사이클 관리와 모니터링을 지원한다.
클라우드 컴퓨팅 제공 방식
6페이지
컨테이너 기술과 도커
가상 머신과 컨테이너
가상화 : 물리적 구성은 은폐하고, 가상환경을 여러 개 만들어, 개별 가상머신이 자원을 갖추고 있게 만드는 기술
- 프로비저닝 : IT인프라 자원을 사용자의 니즈에 맞게 할당/배치/배포해서 시스템을 사용할 수 있도록 하는 기술
- 하이퍼바이저 : 물리서버 위에 존재하는 가상화 계층으로서, OS구동을 위한 HW환경을 가상으로 제공
하이퍼바이저
- 하드웨어 가상화
컨테이너
- 프로세스 가상화
- 컨테이너 기술의 장점
- 하이퍼바이저와 게스트 OS가 없어 가볍다.
- 경량이기 때문에 만들어진 이미지 복제, 이관, 배포가 쉽다.
- 게스트 OS를 부팅하지 않기 때문에 애플리케이션 시작 시간이 빠르다.
- 가상머신보다 경량이므로 더 많은 애플리케이션을 실행할 수 있다.
도커
컨테이너는 코드와 모든 종속성을 패키지화하는 표준 소프트웨어 단위로, 애플리케이션이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 한다.
도커 컨테이너 이미지는 애플리케이션을 실행하는 데 필요한 모든 것(코드, 런타임, 라이브러리 등)을 포함하는 경량의 독립형 실행 가능 소프트웨어 패키지라고 정의할 수 있다.
[ 도커 주요 기능 ]
- LXC(리눅스 컨테이너)를 이용한 컨테이너 구동
containerd는 리눅스 및 윈도우용 데몬으로, 이미지 전송 및 스토리지에서 컨테이너 실행 및 감독, 네트워크 연결까지 호스트 시스템 전체 컨테이너의 라이프사이클을 관리한다. - 통합 BuildKit
빌드킷은 도커파일의 설정 정보를 이용하여 도커 이미지를 빌드하는 오픈 소스 도구이며, 빠르고 정확하게 여러가지 아키텍처 향상 기능을 제공한다. - 도커 CLI 기반
도커 명령을 수행하는 기본적인 방법을 CLI로 제공한다.
도커를 사용하는 이유
예를 들어 node.js로 만든 애플리케이션을 테스트해야하는 상황에서 현재 로컬에 node.js를 실행하려면 npm이라는 모듈이 필요하다. 만약 이 애플리케이션이 하나의 모듈이 아니라 여러 가지 의존성이 있는 애플리케이션이며 데이터베이스까지 필요하다면? 환경설정과 애플리케이션을 설치하는 데 많은 시간을 투자해야한다. 만약 각각의 의존성이 다른 애플리케이션이 여러개라면 환경설정에 걸리는 시간은 배로 늘어난다. 이를 도커로 단축시킬 수 있다.
도커에 사전에 만들어진 이미지를 통해 컨테이너 안에서 테스트할 수 있다.
- 도커 엔진 : 도커를 이용한 애플리케이션 실행 환경 제공을 위한 핵심 요소
- 도커 허브 : 도커 사용자들과 함께 도커 컨테이너 이미지를 공유하는 클라우드 서비스
- docker-compose : 의존성 있는 독립된 컨테이너에 대한 구성 정보를 YAML코드로 작성하여 일원화된 애플리케이션 관리를 가능하게 하는 도구
- docker Kitematic : 컨테이너를 이용한 작업을 수행할 수 있는 GUI 제공
- docker registry :
- docker machine :
- docker swarm :
- docker ps -a : 실행된 모든 컨테이너의 정보를 제공
우리는 Nginx를 위한 환경 구성, 설치, 서비스 시작 그 어떤 것도 하지 않고 도커를 이용하여 컨테이너 nginx 서비스를 배포할 수 있다. - 도커의 민텁한 애플리케이션 배포 기능
도커 엔진은 서버와 클라이언트로 구분된다. 클라이언트는 도커의 명령을 받고 결과를 출력하고 서버는 도커 엔진, 도커 데몬을 이용하여 컨테이너 시작, 운영 , 정지등을 담당한다.
클라이언트는 도커 명령을 수행하는 명령줄을 제공 → 수행된 도커 명령은 서버의 도커 데몬으로 전달 → 도커 데몬은 docker socket이 보유한 도커 API를 이용해 컨테이너 생성 → 수행된 컨테이너에 포함된 서비스 결과를 클라이언트에 전달
docker system df
도커 시스템이 사용하는 디스크 사용량에 대한 현재 상태 조회
-v : 세부정보를 확인할 수 있다.
docker system events
도커 서버에서 발생하는 도커 관련 이벤트 정보를 표시하는 명령어
--filter 옵션을 이용해서 원하는 정보만 추출하여 볼 수 있다.
컨테이너 서비스
컨테이너에 서비스하고자 하는 애플리케이션 코드와 프로세스를 격리한다.
대부분의 개발자가 개발, 테스트, 배포, 운영의 컴퓨팅 환경 차이로 인한 시행착오 및 다양한 오류해결에 너무 많은 시간을 소비하는 공통적인 문제를 가지고 있어 이를 해결할 수 있는 도커 기반의 컨테이너 서비스 환경으로 전환하고 있다.
컨테이너 서비스는 기존 환경과 다르게 애플리케이션 실행에 필요한 바이너리, 라이브러리 및 구성 파일등을 패키지로 묶어 배포하는 방식으로 논리적 패키징 메커니즘을 제공한다. 애플리케이션이 가지고 있는 운영체제, 하드웨어에 대한 의존성 문제를 해결한 것이다. 따라서 어떤 환경에서든 컨테이너 기반의 애플리케이션을 개발하고 배포할 수 있다.
→ 이렇게 호스트 운영체제를 공유하고 애플리케이션에 필요한 환경을 패키징하는 것을 운영체제 레벨 가상화라고 부른다.
- 하드웨어 레벨 가상화 : 하이퍼바이저 등을 이용한 가상머신의 방식을 말한다.
- 운영체제 레벨 가상화 : 컨테이너 기반의 애플리케이션 서비스 방식
도커 기반 애플리케이션 개발의 라이프사이클
- 애플리케이션 코드 개발
- : 특정 서비스 구동을 위한 애플리케이션 코드 및 웹 화면 구성등을 위한 코드를 개발한다.
- 베이스 이미지를 이용한 Dockerfile 관리
- 개발에 필요한 인프라 구성 요소를 Dockerfile에 작성한다. 즉, 도커 허브를 통해 베이스 이미지를 다운로드하고 다양한 구동 명령어(FROM, RUN, CMD, ENDPOINT, ENV, ADD 등)와 1번에서 작성한 애플리케이션 코드, 라이브러리, 여러 도구를 Dockerfile에 포함시킨다.
- Dockerfile build를 통한 새로운 이미지 생성각 단계별로 실행되는 로그를 화면에서 확인하며 이때 오류 발생 내용도 확인할 수 있다.
- docker build 명령을 통해 작성한 Dockerfile을 실행한다.
- 생성된 이미지를 이용한 컨테이너 실행
- 도커 컴포즈를 이용한 다중 컨테이녀 실행도커 실행 옵션을 미리 작성한 docker-compose.yml을 통해 다중 컨테이너 간 실행 순서, 네트워크, 의존성 등을 통합 관리할 수 있고 마이크로서비스 개발에 활용한다. 예로 하나의 docker-compose.yml 파일이 아닌 여러 개의 yml파일로 구성된 서비스 개발도 가능하다.
- 도커 명령어 docker images를 통해 생성된 이미지를 확인하고 이미지를 통한 컨테이너를 구동(docker run)한다.
- 컨테이너 애플리케이션 서비스 테스트
- 예를 들어 Nginx를 이용한 웹 애플리케이션 컨테이너 서비스였다면 연결하는 IP와 포트 번호를 이용하여 웹 브라우저를 이용한 페이지 연결을 확인할 수 있다.
- 로컬 및 원격 저장소에 이미지 저장
- 깃허브 등을 활용한 Dockerfile 관리
- 동일 환경에서의 지속적 애플리케이션 개발 수행
- 1-7 과정을 통해 업무용 애플리케이션 이미지를 지속적으로 개발,운영 및 관리할 수 있다.
컨테이너 동작에 필요한 모든 내용을 사전에 코드로 작성하여 인프라 프로비저닝 도구로 자동화하게 되면 기업이 필요할 때마다 애플리케이션 및 서버 환경을 적은 비용으로 빠르게 개발, 배포, 확장할 수 있다는 것을 알아두자 → IaC
도커 명령어 활용
모든 명령어는 키워드로 docker를 맨 앞에 사용한다.
도커 컨테이너 명령어
도커 볼륨 활용
도커는 유니언 파일 시스템을 사용하여 하나의 이미지로부터 여러 컨테이너를 만들고 이미지에 변경된 내용을 저장할 수 있도록 한다.
도커 볼륨
→ 컨테이너에서 생성, 재사용할 수 있고 호스트 운영체제에서 직접 접근이 가능
→ 보존되어야 하는 데이터를 유지하기 위한 멬커니즘을 제공
일반적으로 컨테이너 내부의 데이터는 컨테이너의 라이프사이클에 의해 컨테이너 종료 시 삭제된다. 도커 볼륨을 사용하면 컨테이너가 삭제되어도 볼륨은 독립적으로 운영되어 데이터를 영속적으로 유지할 수 있다. → 호스트 파일 시스템의 특정 디렉터리와 컨테이너의 디렉터리를 연결하여 데이터를 저장할 수 있다.
- volume
- 도커에서 밀어주는 방식
- bind mount
- 도커 볼륨 기법에 비해 사용이 제한적이다.
- 호스트 파일 시스템 경로:컨테이너 내부 경로를 직접 마운트하여 사용한다.
- 사용자가 파일, 디렉토리를 생성하면 해당 호스트 파일 시스템의 소유자 권한으로 연결이 되고 존재하지 않는 경우 자동으로 생성된다(루트 소유).
- 컨테이너 실행 시 지정하여 사용하고 컨테이너 제거시 바인드 마운트는 해제되지만 호스트 디렉터리는 유지된다.
- tmpfs mount
- 컨테이너가 중지되면 tmpfs마운트가 제고되고 내부에 기록된 파일은 유지되지 않는다.
- 호스트 또는 컨테이너 쓰기 가능 계층에서 지속하지 않지만 중요한 파일을 임시로 사용하는 방법에 유용하다.
- 컨테이너 실행시 지정하여 사용하고 컨테이너 제거 시 자동 해제된다.
도커 네트워크
도커 컨테이너 및 서비스는 도커 네트워크를 통해 격리된 컨테이너 간의 네트워크 연결뿐만 아니라 도커 외의 다른 애플리케이션 워크로드와도 연결이 가능하다. 이때 도커 네트워크의 하위 시스템 연결을 위해 도커 네트워크 드라이버를 사용하여 상호간 통신을 할 수 있다.
💡 도커 설치 시 기본적으로 제공되는 docker0은 가상 이더넷 브릿지 네트워크이고 이것을 통해 격리된 컨테이너들의 상호 간 통신을 제공한다.
- bridge
- 기본 네트워크 드라이버
- 컨테이너 실행 시 별도의 네트워크 지정 없이 독립적으로 실행되는 애플리케이션 컨테이너를 실행하는 경우 사용된다.
- → 단 브리지 모드는 동일 호스트상의 도커 컨테이너에만 적용된다.
- host
- 컨테이너와 호스트 간의 네트워크 격리를 제거하고 호스트의 네트워킹을 직접 사용할 수 있다.
- 컨테이너 애플리케이션에 별도의 포트 연결없이 호스트의 포트를 이용하여 바로 서비스할 수 있다.
- overlay
- 다중 호스트 도커 서버를 이용한 클러스터(도커 스웜)등을 이용할 경우 도커 데몬간의 연결을 통해 컨테이너 서비스를 수행할 수 있다.
- 컨테이너 간에 운영체제 수준의 라우팅을 사용하지 않아도 된다.
- 도커 클러스터인 도커 스웜 구축 시 호스트와 호스트 간의 컨테이너 연결에 사용된다.
- macvlan
- 물리적 네트워크에 컨테이너 mac 주소를 통한 직접 연결 구현시 사용된다.
- 도커 데몬은 mac 주소별로 트래픽을 라우팅하게 된다.
- none
- 컨테이너의 네트워크를 사용하지 않도록 설정
- 네트워크 인터페이스는 lo 인터페이스만 존재한다.
- 컨테이너가 호스트 네트워킹 스택에서 완전히 분리되어 외부와의 통신을 완전 단절한다.
- 컨테이너 네트워크
- container : 공유받을 컨테이너 이름
- 컨테이너의 네트워크 네임 스페이스 스택을 공유하여 같이 사용할 수 있게 한다.
- 사용자 정의 네트워크
- 사용자가 직접 생성한 네트워크로 아무런 옵션을 주지 않고 생성하면 docker0 IP 대역의 다른 CIDR을 지정하여 생성된다.
도커 기본 브리지 네트워크
도커의 기본 네트워크 구성은 브리지 모드로 도커 데몬을 통해 도커 컨테이너만의 네트워크를 실제 서버 네트워크와 분리해 독립적으로 구성하는 네트워크 방식이다.
Dockerfile
코드로 개발하는 컨테이너 인프라, Dockerfile
Dockerfile : 원하는 개발 환경을 코드로 구성하는 방법을 제공하는 것
- 필요성
- 커맨드 기반의 인프라 구성시 인적 오류 발생 가능성이 높다.
- Apache + PHP + MySQL 구축을 생각해보자. 설치 순서와 상호 연관성 등을 고려하여 각종 라이브러리와 함께 복잡한 명령어를 고민해야 한다.
- 각종 환경 설정 정보와 설치 프로그램을 요구사항에 맞게 따져봐야 한다.
- 만일 설치 이후에 잘못된 설정이 있다면 수정해야 하고, 때로는 재설치를 해야만 할 수도 있다.
애플리케이션에 적용되는 새로운 환경을 사용자가 직접 정의해서 아이디어를 실현할 수 있는 것이 바로 코드로서 인프라 환경을 프로비저닝하는 Dockerfile이다. 이렇게 만들어진 코드나 이미지를 다양한 공유 방식을 통해 언제 어디서든 컨테이너로 만들어낼 수 있다.
- 최적의 Dockerfile을 만들기 위해 고려할 점
- 경량의 컨테이너 서비스를 제공
- Dockerfile에 담기는 레이어를 최소화
- 도커파일 명령어의 수와 도커 이미지 레이어 수는 동일하다. 레이어 수가 많을수록 이미지를 빌드하는 시간은 길어지기 때문에 파일용량도 커진다. 따라서 명령어수를 최소화하는 방향으로 작성한다.
- 하나의 애플리케이션은 하나의 컨테이너에
- 캐시 기능을 활용
- IaC 환경 개발은 디렉터리 단위로
- 서버리스 환경으로 개발
Dockerfile 명령어
일반적으로 시작은 FROM으로 작성하지만 그 다음부터는 순서가 딱히 없다. 하지만 명령한 순서대로 빌드 캐시의 무효화와 연관되므로 변경 빈도수가 적은 명령을 먼저 배치하는 것을 권장한다. 무조건 OS 이미지를 선택하고 설치하는 것보다는 원하는 애플리케이션 패키지가 이미 설치된 이미지 선택을 권장한다.
FROM
생성하려는 이미지의 베이스 이미지 지정 명령어이다.
이미지를 선택할 때 작은 크기의 이미지와 리눅스 알파인 이미지를 권장하나 상황에 맞춰서 선택하면 된다. 예를 들어 파이썬 같은 경우 알파인 리눅스를 사용하면 파이썬 패키지에서 C코드를 컴파일을 통해 도커 이미지를 빌드하기 때문에 빌드 시간도 오래 걸리고 이미지 용량도 커질 수 있다. 파이썬 애플리케이션 도커 이미지를 선택하는 경우에는 Debian Buster 키워드 이미지가 유리하다.
태그를 넣지 않으면 latest로 지정된다.
MAINTAINER
일반적으로 이미지를 빌드한 작성자 이름과 이메일을 작성한다.
MAINTAINER san.An <san@42.kr>
LABEL
이미지 작성 목적으로 버전, 타이틀, 설명, 라이선스 정보등을 작성한다. 1개 이상 작성 가능
LABEL pupose = 'Nginx for webserver' \\
version = '1.0' \\
description = 'web service application using Nginx'
RUN
설정된 기본 이미지에 패키지 업데이트 각종 패키지 설치, 명령 실행 등을 작성한다. 1개 이상 작성 가능
레이어 저장
RUN apt update
RUN apt -y install nginx
#Shell
RUN apt update && apt install -y nginx \\
git \\
curl && \\
apt-get clean -y && \\
apt-get autoremove -y && \\
rm -rfv /tmp/* /var/lib/apt/lists/* /var/tmp/*
- 권장
- 다단계 빌드 사용 권장, 각 이미지별로 개별 Dockerfile로 빌드
- RUN 명령어의 개별 명령 수를 최소화하기 위해 여러 설치 명령을 연결하면 이미지의 레이어수가 감소한다.
- autoremove, autoclean, rm -rf/var/lib/apt/lists/* 을 사용하면 저장되어 있는 apt 캐시가 삭제되어 이미지 크기가 감소한다.
CMD
생성된 이미지를 컨테이너로 실행할 때 실행되는 명령이고, ENTRYPOINT 명령문으로 지정된 커맨드에 디폴트로 넘길 파라미터를 지정할 때 사용한다. 여러 개의 CMD를 작성해도 마지막 하나만 처리된다. 일반적으로 이미지의 컨테이너 실행 시 애플리케이션 데몬이 실행되도록 하는 경우 유용하다.
#shell
CMD apachectl -D FOREGROUND
#exec
CMD ["/usr/sbin/apachectl", "-D", "FOREGOUND"]
ENTRYPOINT
CMD와 마찬가지로 생성된 이미지가 컨테이너로 실행될 때 사용되지만 컨테이너가 실행될 때 명령어 및 인자 값을 전달하여 실행한다는 점이 다르다. 여러 개의 CMD를 사용하는 경우 ENTRYPOINT 명령문과 함께 사용한다. ENTRYPOINT는 커맨드를 지정하고 CMD는 기본 명령을 지정하면 탄력적으로 이미지를 실행할 ㅅ ㅜ있다. 예를 들어 python 명령을 기본으로 runapp.py 코드를 실행하면
ENTRYPOINT ["python"]
CMD ["runapp.py"]
# 동일 환경에 entrypoint.sh 를 이미지에 넣고 ADD 실행 권한 설정 후 컨테이너 실행 시 entrypoint.sh를 실행
...
ADD ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
- ENTRYPOINT : 도커 컨테이너 실행 시 항상 수행하야 하는 명령어를 지정 (웹 서버나 데이터베이스의 데몬을 실행)
- CMD : 도커 컨테이너 실행 시 다양한 명령어를 지정하는 경우 유용
COPY
호스트 환경의 파일, 디렉터리를 이미지 안에 복사하는 경우 작성한다.
단순한 복사 작업만 지원, 빌드 작업 디렉터리 외부의 파일은 카피할 수 없다.
레이어 저장
COPY index.html /usr/share/nginx/html
ADD
호스트 환경의 파일 디렉터리를 이미지 안에 복사하는 경우 뿐만아니라 URL 주소에서 직접 다운로드하여 이미지에 넣을수도 있다. 압축 파일의 경우 지정한 경로 안에 압축을 풀어서 추가한다.
빌드 작업 외부 파일은 ADD할 수 없고, 디렉터리 추가시에는 /로 끝나야 한다.
레이어 저장
ADD index.html /usr/share/nginx/html
ADD <http://example.com/view/customer.tar.gz> /workspace/data/
ENV
이미지 안에 각종 환경 변수를 지정하는 경우 작성한다. 애플리케이션 사용을 쉽게 하려면 사전에 구성되어야 하는 환경 변수들이 있다. 예를 들어 자바 홈디렉토리, 특정 실행 파일의 경로를 보장하기 위해 절대 경로 지정을 위한 PATH 설정, 프로그램 버전 등을 사전에 설정한다.
반복된 표현이 사용되는 경우에도 환경 변수 설정을 권장한다.
ENV PATH /usr/local/nginx/bin:$PATH
EXPOSE
컨테이너가 호스트 네트워크를 통해 들어오는 트래픽을 리스닝하는 포트와 프로토콜을 지정하기 위해 작성한다. nginx나 apache는 기본 포트로 HTTP 80번과 HTTPS 443번 포트를 사용하고, 컨테이너 모니터링 이미지로 사용하는 Cadvisor 컨테이너는 8080번 포트를 사용한다.
이미지 내에 애플리케이션이 사용하는 포트를 사전에 확인하고 호스트와 연결되도록 구성하는 경우에 설정하고 docker run 사용시 -p 옵션을 통해 사용한다.
EXPOSE 80
EXPOSE 80/tcp
VOLUME
볼륨을 이미지 빌드에 미리 설정하는 경우 작성한다.
도커 컨테이너에서 사용된 파일과 디렉터리는 컨테이너 삭제와 함께 사라지기 때문에 사용자 데이터의 보존과 지속성을 위해 볼륨 사용을 권장한다.
VOLUME으로 지정된 컨테이너의 경로는 볼륨의 기본 경로 /var/lib/docker와 자동으로 연결된다.
VOLUME /var/log
USER
컨테이너의 기본 사용자는 root이다. 애플리케이션이 권한 없이 서비스를 실행할 수 있다면 USER를 통해 다른 사용자로 변경하여 사용한다.
WORKDIR
컨테이너 상에서 작업할 경로 전환을 위해 작성한다. WORKDIR을 설정하면 RUN, ADD, CMD, ENTRYPOINT, COPY 명령문은 해당 디렉터리를 기준으로 실행된다.
ARG
ONBUILD
STOPSIGNAL
SHELL
HEALTHCHECK
이미지 생성을 위한 Dockerfile 빌드
docker build [옵션] 이미지명:[태그] 도커파일경로 | URL | 압축파일
도커 컴포즈 - 다중 컨테이너 애플리케이션
도커 컴포즈는 공통성을 갖는 컨테이너 애플리케이션 스택을 yaml 코드로 정의한 정의서이다. → 다중 컨테이너 실행 도구
이때 공통성이란 공통의 목적을 의미하며 그 예로 웹 애플리케이션을 생성하기 위해 필요한 MySQL 데이터베이스와 API 애플리케이션 설정을 위한 백엔드 환경(플라스크, node), 사용자 인터페이서 그성을 위한 웹 프레임워크 이 세가지는 공통의 목적을 가지며 각 스택을 도커 컴포즈를 통해 한번에 서비스를 올리고 관리할 수 있다.
도커 컴포즈로 실행된 컨테이너는 독립된 기능을 가지며 공통 네트워크로 구성되기 때문에 컨테이너간 통신이 쉽다. → 쉽고 빠른 런타임 환경 제공
docker-compose up
이라는 간단한 명령어로 컨테이너를 올릴 수 있다.
docker-compose ps
는 생성된 컨테이너 정보를 조회할 수 있다.
docker-compose down
은 생성했던 것과 반대로 서비스를 모두 내리고 네트워크도 회수한다.
docker-compose up -d
도커 컴포즈를 백그라운드로 실행한다.
도커 컴포즈 YAML 코드 작성법
야믈코드의 계층 구조는 부모-자식 간의 레벨을 들여쓰기로 구분한다.
큰 구조 →
version: "3.8"
services:
서비스명1:
# 설정
networks:
# 네트워크 설정, 미지정시 자동 설정
volumes:
# 볼룸 설정
일반적으로 가장 먼저 실행되어야 하는 애플리케이션을 먼저 작성하고 이와 의존성을 갖는 데이터베이스 및 하위 애플리케이션을 작성한다.
서비스 전체를 하나의 도커 컴포즈 야믈 코드로 작성할 수 있다.
- 버전 정의
야믈 코드 첫 줄은 버전을 명시한다.
version: "3"
- 서비스 정의
도커 컴포즈를 통해 실행할 서비스를 정의한다.
도커 컴포즈는 컨테이너 대신 서비스 개념을 사용한다. 서비스 하위에는 실행될 컨테이너 서비스를 작성하고 하위 레벨에 도커 명령 실행과 유사하게 컨테이너 실행에 필요한 옵션을 작성하면 된다.
image를 사용해도 되고 build옵션으로 도커 파일을 실행해도 된다.
- 그 외 옵션들
- container_name: 생략 시 자동으로 부여한다.
- ports: 서비스 내부 포트와 외부 호스트 포트를 지정하여 바인드, 외부 노출 포트를 지정한다.
- expose: 호스트 운영체제와 직접 연결하는 포트를 구성하지 않고 서비스만 포트를 노출, 필요 시 링크로 연결된 서비스와 서비스 간의 통신만 허용한다.
- networks: 최상위 레벨의 networks에 정의된 네트워크 이름을 작성
- volumes: 서비스 내부 디렉터리와 호스트 디렉터리를 연결하여 데이터 지속성 설정
- environment: 서비스 내부 환경 변수를 설정한다. 환경 변수가 많은 경우 *.env 파일로 만들어 env_file 옵션에 파일명을 지정할 수 있다.
- command: 서비스가 구동 후 실행할 명령어를 작성한다.
- restart: 서비스 재시작 옵션 지정, always의 경우 수동 제어를 제외하고 항상 재시작한다.
- depends_on: 서비스 간의 종속성을 의미하며 먼저 실행해야 하는 서비스를 지정하여 순서를 지정한다.
- 네트워크 정의
다중 컨테이너들이 사용할 최상위 네트워크 키를 정의하고 이하 하위 서비스 단위로 이 네트워크를 선택할 수 있다.
아무런 networks 옵션을 지정하지 않으면 자체 기본 네트워크가 자동으로 생성된다.
최상위 레벨에 networks 지정 시 해당 이름의 네트워크가 생성되고 대역은 172…….로 자동 할당되며 기본 드라이버는 브리지로 지정된다.
도커에서 생성한 기존 네트워크를 지정하는 경우에는 externel 옵션에 네트워크 이름을 작성한다.
- 데이터의 지속성을 유지하기 위해 최상위 레벨에 볼륨을 정의하고, 서비스 레벨에서 볼륨명과 서비스 내부의 디렉터리를 바인드한다. 도커가 관리하는 가상 영역 /var/lib/docker/volume에 자동 배치된다.
[참고를 넘어선 참참고]
도커, 컨테이너 빌드업! 라는 책을 보면서 정리했습니다. (따라쳤습니다.)
'42seoul > circle-5' 카테고리의 다른 글
[Inception] 0. 과제 이해하기 (2) | 2022.11.15 |
---|
댓글