2. 컨테이너 개발을 익히기 위한 5단계

김하영·2021년 9월 22일
0
post-custom-banner

'15단계로 배우는 도커와 쿠버네티스' 기반으로 내용 정리하였습니다.

  • 컨테이너 첫걸음
    hello-world 컨테이너 둘러보기

1.1 hello-world 실행

  1. 터미널 혹은 커맨드 프롬프트에서 'docker run hello-world'를 실행하면 도커 데몬에 접속한다.

  2. 커맨드 중 'hello-world'는 리포지터리의 이름이다. 도커 엔진은 도커 허브의 리포지터리에서 컨터이너를 위한 이미지를 로컬에 다운로드한다.

  3. 도커 엔진이 이미지로 부터 컨테이너를 생성한다. 그러면 컨테이너상의 프로세스가 메시지를 표준 출력에 쓰기 시작한다.

  4. 도커 엔진은 컨테이너의 표준 출력을 도커 커맨드에 보내고 터미널에 표시된다.

[ 도커 고유의 용어 ]

  • 도커의 '이미지;는 운영체제와 소프트웨어를 담고 있는 컨테이너 실행 이전의 상태다.
    각 이미지는 '리포지터리:태그'로 식별된다.

  • 도커의 리포지터리는 이미지 보관소를 말한다. 리포지터리의 이름에 버전등을 의미하는 태그를 붙여서
    각각의 이미지를 구별하여 보관할 수 있다. 태그를 생략하면 최신을 의미하는 latest가 사용된다.
    클라우드 서비스의 문서등에서는 리포지터리대신 레지스트리란 표현을 쓰이기도 한다.

  • 레지스트리는 리포지터리의 집합체로서 리포지터리를 제공하는 서버를 말한다. (이미지 저장소)

1.2 컨테이너의 생명 주기와 도커 커맨드

컨테이너는 이미지, 실행, 정지의 세 가지 상태로 있을 수 있다.
그리고 도커 커맨드에 따라 컨테이너의 상태가 변한다.

  • 이미지 : 컨테이너의 모형이 되는 것으로 실행되기 전의 상태다.
  • 실행 : 컨테이너 위에서 프로세스가 실행 중인 상태를 의미한다.
  • 정지 : 프로세스의 종료코드, 로그가 보존된 채 정지한 상태다.

(1) 이미지 다운로드 : docker pull 리포지터리명:태그

(2) 컨테이너 실행 : docker run [옵션] 리포지터리명:태그 [커맨드][인자]

[ 자주 사용하는 docker run 옵션 ]

-i : 키보드 입력을 컨테이너의 표준 입력에 연결하여 키보드 입력을 컨테이너의 셀 등에 보낸다.
-t : 터미널을 통해 대화형 조작이 가능하게 한다.
-d : 백그라운드로 컨테이너를 돌려 터미널과 연결하지 않는다.
--name : 컨테이너에 이름을 설정한다. 시스템에서 유일한 이름이어야 하며,
옵션을 생략하면 자동으로 만들어진 이름이 부여된다.
--rm : 컨테이너가 종료하면 종료 상태의 컨테이너를 자동으로 삭제한다.

(3) 컨테이너의 상태 출력 : docker ps

(4) 로그 출력 : docker logs

(5) 컨테이너 정지 : docker stop / docker kill

실행 중인 컨테이너를 정지시키는 방법은 다음가 같이 세가지가 있다.

  1. 컨테이너의 PID=1인 프로세스가 종요한다.
  2. 'docker stop 컨테이너 ID | 컨테이너 명'을 실행한다.
  3. 'docker kill 컨테이너 ID | 컨테이너 명'을 실행한다.

(6) 컨테이너 재기동 : docker start [옵션] 컨테이너ID | 컨테이너명

(7) 컨테이너의 변경 사항을 리포지터리에 저장 : docker commit

(8) 이미지를 원격 리포지터리에 보관 : docker push

(9) 종료한 컨테이너 제거 : docker rm

(10) 필요 없어진 이미지를 로컬 리포지터리에서 삭제 : docker rmi

  • 컨테이너 개발
    간단한 애플리케이션의 컨테이너를 빌드하고 실행하기

3.1 이미지 빌드 개요

'docker build [옵션] 경로 [URL] -' 을 사용하면 도커 이미지가 만들어진다.

(1) 베이스 이미지 선택
: 이미지를 만들 때 바탕이 되는 이미지를 베이스 이미지라고 한다.
베이스 이미지에는 리눅스의 공유 라이브러리, 동적 링크나 로드에 필요한 기초적인 파일들이 포함되며,
이를 기반으로 사용자의 이미지를 만들게 된다.

(2) 소프트웨어 패키지 설치

(3) 애플리케이션 소스 코드
: 깃헙 혹은 로컬에 있는 소스 코드를 이미지에 복사한다.

(4) Dockerfile
: 이미지를 빌드하는 스크립트가 기재된 파일로서, 다음과 같은 내용을 담고 있다.

  1. 베이스 이미지의 리포지터리
  2. 설치할 패키지
  3. 애플리케이션 코드와 설정파일
  4. 컨테이너 기동 시 실행될 명령어

3.2 빌드 실행 순서

  1. 디렉토리를 준비하여 이미지에 포함시킬 파일들을 모은다.
  2. Dockerfile을 작성한다.
  3. 컨테이너에서 실행할 어플리케이션 코드를 작설하고 유닛 테스트를 실행한다.
  4. 이미지를 빌드한다.
  5. 컨테이너를 실행하고 동작을 확인한다.

Dockerfile

[ Dockerfile 설명 ]

  • FROM alpine:latest
    : FROM으로 베이스 이미지를 지정. 이미지가 로컬에 없으면 도커 허브에서 다운로드 한다.

  • RUN apk update && apk add figlet
    : RUN으로 컨테이너를 실행할 명령어를 지정한다.
    apk를 업데이트하고 figlet이란 커멘드를 설치하고 있다.

  • ADD ./message /message
    : ADD로 컨테이너에 배치할 파일이나 디렉터리를 지정한다.

  • CMD cat /message | figlet
    : CMD로 컨테이너가 가동한 직후에 실행하는 커맨드를 지정한다.

3.3 Dockerfile 작성법

  • FROM <이미지>[:태그] : 컨테이너의 베이스 이미지를 지정

  • RUN <커맨드> : FROM의 베이스 이미지에서 커맨드를 실행

  • ADD <소스><컨테이너 내 경로> : 소스를 컨테이너 내 경로에 복사

  • COPY <소스><컨테이너 내 경로> : 소스를 컨테이너 내 경로에 복사

  • ENTRYPOINT ["실행가능한 것","파라미터1","파라미터2"] : 컨테이너가 실행하는 파일을 설정

  • CMD ["실행 바이너리","파라미터1","파라미터2"] : 컨테이너 기동 시 실행될 커맨드를 지정

  • ENV key value : 환경 변수 설정

  • EXPOSE port : 공개 포트 설정

  • USER <유저명> | UID : RUN, CMD, ENRTYPOINT 실행 유저 지정

  • VOLUME ["/path"] : 공유 가능한 볼륨을 마운트

  • WORKDIR /path : 작업 디렉터리 지정

  • ARG <이름>[=<디폴트 값>] : 빌드할 때 넘길 인자를 정의. --build-arg <변수명>=<값>

  • LABEL key=value : 이미지의 메타데이터에 라벨을 추가

  • MAINTAINER <이름> : 이미지의 메타데이터에 저작권을 추가

  • 컨테이너와 네트워크
    컨테이너 네트워크와 포트 공개 방법

4.1 컨테이너 네트워크

[ 컨테이너 네트워크 커맨드 ]

  • docker network ls : 컨테이너 네트워크를 리스트로 표시
  • docker network inspect : 네트워크 명을 지정해서 자세한 내용을 표시
  • docker network create : 컨테이너 네트워크를 생성
  • docker network rm : 컨테이너 네트워크를 삭제
  • docker network connect : 컨테이너를 컨테이너 네트워크에 접속
  • docker network disconnect : 컨테이너를 컨테이너 네트워크에서 분리

4.2 외부에 포트를 공개하기

' docker run [옵션] 리포지터리[:태그] 커맨드 인자' 의 옵션으로 '-p 공개_포트번호:컨테이너
내 포트번호'를 지정하면 컨테이너 내 포트를 호스트의 IP 주소상의 포트번호로 매핑한다.

  • 컨테이너 API
    컨테이너 API의 역할과 사용법 이해

컨테이너 API는 컨테이너를 블랙박스처럼 다룰 수 있게 해주는 인테페이스다.
이는 쿠베네티스 환경에서도 사용된다.

5.1 컨테이너 API의 종류와 개요

  • 컨테이너 기동
    : 컨테이너 내의 애플리케이션은 기동 시에 환경 변수나 실행 인자를 읽어서 그에 맞게 동작하게 만들 수 있다.

  • 헬스 체크 (쿠버네티스 환경)
    : 준비 완료 프로브는 컨테이너의 애플리케이션이 초기화가 완료되어 외부로부터의 요청을 받을 수 있게 되었음을 알리는 인터페이스다. 로드밸런서가 컨테이너에 요청을 전달하기 시작해도 될지 확인하기 위한 목적으로 사용된다.
    한편, 활성 프로브는 애플리케이션의 기동상태를 알리는 인터페이스다. 이를 통해 비정상이 감지되면
    쿠버네티스가 컨테이너를 재기동하여 복구를 시도한다.

  • 컨테이너 종료
    : 컨테이너 내의 애플리케이션은 종료 요청 시그널(SIGTERM)에 대한 종료 처리를 구현하는 것이 좋다.
    여기서 종료처리란 메모리의 값을 보존하거나 데이터베이스와의 세션을 종료한 뒤 종료하는 것을 말한다.
    한편, 강제 종료 시그널(SIGKILL)은 제한 시간 내에 종료 처리가 완료되지 않은 경우, 컨테이너를 강제 종료하기 위해 사용된다. 애플리케이션이 강제 종료를 막을 수 있는 방법은 없다.

  • 서비스
    : 컨테이너 위에서 돌아가는 서버 애플리케이션은 특정 포트를 통해 클라이언트로부터의 요청을 받아드린다. 특정 포트번호로 클라이언트로부터의 요청을 받고, 처리 결과를 반환하는 역할을 수행한다.
    이를 위해서는 컨테이너의 포트를 호스트의 IP 주소에 포트 포워딩을 하여 외부에서의 요청을 받아들여야 한다.

  • 로그
    : 로그를 일관되게 관리하여 컨테이너의 표준 출력과 표준 오류를 로그로 간직한다.

  • 후크 (쿠버네티스 환경)
    : 컨테이너가 기동하고 종료할 때 컨테이너 내에서 특정 처리를 실행시킬 수 있다.
    컨테이너에는 후크에 의해 실행될 스크립트, 혹은 HTTP 요청 처리를 구현해야 한다.
    이때 Dockerfile의 ENRTYPOINT나 CMD로 지정한 명령어와 후크는 비동기적으로 실행되어
    실행순서가 보장되지 않는다.

  • 퍼시스턴트 볼륨
    : 퍼시스턴트 볼륨을 사용하는 대표적인 경우는 설정 파일을 외부에서 주입하는 경우와 발생 데이터를 보존하는 경우 두 가지가 있다. 두 경우 다 호스트의 디렉터리를 컨테이너의 파일 시스템에 마운트하여 사용한다.

  • 종료 상태
    : PID가 1인 프로세스의 Exit 코드가 컨테이너의 종료 코드로 설정된다.

profile
Back-end Developer
post-custom-banner

0개의 댓글