컨테이너/도커

Build : 도커 이미지 생성

비니화이팅 2022. 10. 19. 22:38

도커 이미지

- 애플리케이션의 실행에 필요한 프로그램 본체, 라이브러리, 미들웨어, OS, 네트워크 설정, 파일과 설정값(서버 기능을 작동시키기 위해 필요한 /etc, /bin 등 디렉터리 및 파일 등) 등을 하나로 모아 도커 이미지를 만듬

- 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 의존성 파일을 컴파일하고 이것저것 설치할 필요가 없음

- 도커에서는 하나의 이미지에는 하나의 애플리케이션만 넣어 두고 여러 개의 컨테이너를 조합하여 서비스를 구축하는 방법을 권장함

- OS용 이미지에 애플리케이션용 이미지를 겹쳐서 다른 새로운 이미지 생성 가능

- 이미지를 만들기 위해 Dockerfile을 사용함

 

Dockerfile

- 컨테이너 구성 정보를 기술하기 위한 파일

 

Dockerfile 명령어

FROM - 베이스 이미지 지정 [이미지명]
[이미지명:태그]
[이미지명@다이제스트]
WORKDIR - 작업 디렉터리(디렉터리가 존재하지 않으면 새로 작성됨) 1) 절대경로 지정 WORKDIR /first 2) 상대경로 지정 WORKDIR /first WORKDIR second WORKDIR third → 상대경로 지정 시 이전 경로에 대한 상대 경로가 되므로 /first/secod/third 경로 지정  
RUN - 이미지를 작성하기 위한 명령 실행 1) shell 형식 지정 RUN echo 안녕하세요 shell 형식입니다. 2) exec 형식 지정 → shell 경유하여 실행하지 않음 RUN [”echo”. “안녕하세요 EXEC 형식입니다.”] [명령]
CMD - 이미지를 바탕으로 생성된 컨테이너 안에서 명령 실행 * 도커파일에는 하나의 CMD 명령만 기술 가능(여러 개 지정 시 마지막 명령만 유효) 1) shell 형식 지정 CMD nginx -g ‘daemon off;’ 2) exec 형식 지정 → shell 경유하여 실행하지 않음 CMD [”nginx”, “-g”, “daemon off;”] [명령]
ENTRYPOINT - docer container run 명령을 실행했을 때 실행할 명령 1) shell 형식 지정 ENTRYPOINTnginx -g ‘daemon off;’ 2) exec 형식 지정 → shell 경유하여 실행하지 않음 ENTRYPOINT [”nginx”, “-g”, “daemon off;”] [명령]
ONBUILD - 다음 빌드에서 실행할 명령을 설정 [명령]
COPY - 파일 복사  
ADD - 파일/디렉터리 추가 - .tar, .gzip 등 일때는 디렉터리로 압축해제(원격 파일일 경우 압축 풀리지 않음) - 와일드카드 사용 가능 - 원격 파일 URL로 추가할 경우 퍼미션이 600으로 추가 - 인증을 지원하지 않기 때문에 원격 파일의 다운로드에 인증이 필요한 경우 RUN명령에서 wget 또는 curl 명령 사용 [호스트 파일 경로] [도커 이미지 파일 경로]
HEALTHCHECK - 컨테이너 안의 프로세스가 정상적으로 작동하고 있는지 체크 - 체크 결과는 docker container inspect 명령으로 확인 가능

[옵션]
--interval=n : 헬스체크 간격(default : 30s)
--timeout=n : 헬스체크 타임아웃(default : 30s)
--retries=N : 타임아웃 횟수(default : 3)

[예시]
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost || exit 1
- 5분마다 가동중인 웹 서버의 페이지를 3초안에 표시할 수 있는지 없는지 확인
[옵션] CMD [명령]
STOPSIGNAL - 컨테이너 종료 시 송신할 시그널 설정
1) 시그널 번호 지정 9
2) 시그널명 지정 SIGKILL
[시그널]
ENV - 환경변수 설정 [KEY] [VALUE] [KEY]=[VALUE]
USER - 사용자 지정(RUN 명령으로 미리 작성해야 함) [사용자명] [UID]
LABEL - 이미지에 코멘트 작성
- docker image inspect 명령으로 확인 가능
[키 명]=[값]
EXPOSE - 공개 포트 번호 지정 [포트번호]
ARG - 도커파일 내 변수 설정
- docker build . --build-arg 명령으로 값 변경 가능
[이름]=[기본값]
SHELL - 기본 쉘 지정 [쉘 경로, 파라미터]
VOLUME - 볼륨 할당
- 호스트나 다른 컨테이너로부터 마운트
- 컨테이너는 영구 데이터를 저장하는 데는 적합하지 않으므로 컨테이너 밖의 스토리지에 마운트하거나 공유 스토리지를 볼륨으로 마운트하는 것이 좋음
[/마운트 포인트]

 

RUN vs CMD

- Nginx를 설치하는 명령은 run, 설치한 nginx를 데몬으로서 컨테이너 안에서 상시 작동시키기 위해서는 CMD 사용

 

도커파일 빌드(docker build)

- docker build -t [생성할 이미지명:태그] [도커파일경로]

- 빌드 시 디렉터리 아래에 있는 모든 파일이 Docker 데몬으로 전송되므로 빌드에서 제외하고 싶은 파일이 있는 경우 .dockerignore라는 이름의 파일 안에 해당 파일명 기술

 

옵션

  • --build-arg [변수]=[값]
  • ARG 명령으로 지정한 변수에 값 지정
hbeen@DESKTOP-EDC39JU:~$ mkdir sample
hbeen@DESKTOP-EDC39JU:~$ cd sample
hbeen@DESKTOP-EDC39JU:~/sample$ touch Dockerfile
hbeen@DESKTOP-EDC39JU:~/sample$ vi Dockerfile
																FROM centos:centos7

**hbeen@DESKTOP-EDC39JU:~/sample$ docker build -t sample:1.0 /home/hbeen/sample**
[+] Building 29.7s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                       0.1s
 => => transferring dockerfile: 63B                                        0.0s
 => [internal] load .dockerignore                                          0.1s
 => => transferring context: 2B                                            0.0s
 => [internal] load metadata for docker.io/library/centos:centos7         14.9s
 => [auth] library/centos:pull token for registry-1.docker.io              0.0s
 => [1/1] FROM docker.io/library/centos:centos7@sha256:9d4bcbbb213dfd745  14.6s
 => => resolve docker.io/library/centos:centos7@sha256:9d4bcbbb213dfd745b  0.0s
 => => sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db 76.10MB / 76.10MB  8.5s
 => => sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe7 1.20kB / 1.20kB  0.0s
 => => sha256:dead07b4d8ed7e29e98de0f4504d87e8880d4347859d839 529B / 529B  0.0s
 => => sha256:eeb6ee3f44bd0b5103bb561b4c16bcb82328cfe5809 2.75kB / 2.75kB  0.0s
 => => extracting sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43  5.7s
 => exporting to image                                                     0.0s
 => => exporting layers                                                    0.0s
 => => writing image sha256:72b64f44af7b171e762593a7834a88ba13c30b6f349c7  0.0s
 => => naming to docker.io/library/sample:1.0                              0.0s

hbeen@DESKTOP-EDC39JU:~/sample$ docker image ls
REPOSITORY             TAG       IMAGE ID       CREATED         SIZE
sample                 1.0       72b64f44af7b   5 months ago    204MB

 

도커 이미지 레이어 구조

- 도커파일 빌드 시 도커파일의 명령별로 이미지를 작성

Ex) 명령어가 3개라면 3개의 도커 이미지를 겹쳐서 이미지를 생성

 

멀티스테이지 빌드를 사용한 애플리케이션 개발

→ 멀티스테이지 빌드 : 실행 바이너리만 제품 환경용 이미지에 심어 넣을 수 있는 기능

- 개발 환경에서 사용한 라이브러리나 개발 지원 툴이 제품 환경에서 반드시 사용되는 것은 아

- 제품환경에는 애플리케이션을 실행하기 위해 최소한으로 필요한 실행 모듈만 배치하는 것이 컴퓨팅 리소스를 효율적으로 활용할 수 있고 보안관점에서 볼 때 바람직

 

도커파일 생성 및 빌드

hbeen@DESKTOP-EDC39JU:~/sample/dockertext2/chap05/multi-stage$ ls
Dockerfile  main.go
hbeen@DESKTOP-EDC39JU:~/sample/dockertext2/chap05/multi-stage$ vi Dockerfile

# 1. Build Image
FROM golang:1.13 AS builder   #golang을 베이스 이미지로 하여 builder라는 별명을 붙임

# Install dependencies
WORKDIR /go/src/github.com/asashiho/dockertext-greet
RUN go get -d -v github.com/urfave/cli

# Build modules
COPY main.go .   # 로컬 환경에 있는 소스코드를 컨테이너 안으로 복사
RUN GOOS=linux go build -a -o greet .  # 소스코드를 go build로 빌드하여 greet라는 실행 가능 바이러니 파일 작성

# ------------------------------
# 2. Production Image
FROM busybox   # busybox(기본적인 리눅스 명령들을 하나의 파일로 모아놓은 것으로 최소한으로 필요한 리눅스 쉘 환경 제공)를 베이스 이미지로 사용
WORKDIR /opt/greet/bin   

# Deploy modules
COPY --from=builder /go/src/github.com/asashiho/dockertext-greet/ .   # greet이라는 이름의 실행 가능 바이너리 파일을 제품 환경용 도커 이미지로 복사(--from 옵션알 사용하여 builder라는 이름의 이미지로부터 복사한다는 것을 선언)
ENTRYPOINT ["./greet"]   # 복사한 실행 가능 바이너리 파일 실행

hbeen@DESKTOP-EDC39JU:~/sample/dockertext2/chap05/multi-stage$ docker build -t greet .
  • 총 두 개의 도커 이미지를 생성
  • 도커 허브에서 베이스 이미지인 golang을 다운로드하고 그것을 바탕으로 builder 이미지를 생성 후 builder 이미지로 소스코드를 빌드하여 실행가능 바이너리 파일을 생성하고 제품 환경용 이미지에 실행 가능 바이너리 파일이 복사

 

도커 컨테이너 시작

hbeen@DESKTOP-EDC39JU:~/sample/dockertext2/chap05/multi-stage$ docker container run -it --rm greet asa
Hello asa
hbeen@DESKTOP-EDC39JU:~/sample/dockertext2/chap05/multi-stage$ docker container run -it --rm greet --lang=es asa
Hola asa

 

ONBUILD를 사용한 애플리케이션 개발

hbeen@DESKTOP-EDC39JU:~/sample$ cat Dockerfile.base
#베이스 이미지 설정
FROM ubuntu:16.04

#Nginx 설치
RUN apt-get -y update && apt-get -y upgrade
RUN apt-get -y install nginx

#포트 지정
EXPOSE 80

#웹 콘텐츠 배치
ONBUILD ADD website.tar /var/www/html/

#Nginx 실행
CMD ["nginx", "-g", "daemon off;"]

hbeen@DESKTOP-EDC39JU:~/sample$ docker build -t web-base -f Dockerfile.base .
[+] Building 162.9s (8/8) FINISHED
 => [internal] load build definition from Dockerfile.base                                          0.0s
 => => transferring dockerfile: 322B                                                               0.0s
 => [internal] load .dockerignore                                                                  0.0s
 => => transferring context: 2B                                                                    0.0s
 => [internal] load metadata for docker.io/library/ubuntu:16.04                                   13.5s
 => [auth] library/ubuntu:pull token for registry-1.docker.io                                      0.0s
 => [1/3] FROM docker.io/library/ubuntu:16.04@sha256:0f71fa8d4d2d4292c3c617fda2b36f6dabe5c8b6e34c  9.7s
 => => resolve docker.io/library/ubuntu:16.04@sha256:0f71fa8d4d2d4292c3c617fda2b36f6dabe5c8b6e34c  0.0s
 => => sha256:58690f9b18fca6469a14da4e212c96849469f9b1be6661d2342a4bf01774aa50 46.50MB / 46.50MB   5.6s
 => => sha256:b51569e7c50720acf6860327847fe342a1afbe148d24c529fb81df105e3eed01 857B / 857B         0.2s
 => => sha256:da8ef40b9ecabc2679fe2419957220c0272a965c5cf7e0269fa1aeeb8c56f2e1 528B / 528B         0.7s
 => => sha256:0f71fa8d4d2d4292c3c617fda2b36f6dabe5c8b6e34c3dc5b0d17d4e704bd39c 1.42kB / 1.42kB     0.0s
 => => sha256:a3785f78ab8547ae2710c89e627783cfa7ee7824d3468cae6835c9f4eae23ff7 1.15kB / 1.15kB     0.0s
 => => sha256:b6f50765242581c887ff1acc2511fa2d885c52d8fb3ac8c4bba131fd86567f2e 3.36kB / 3.36kB     0.0s
 => => sha256:fb15d46c38dcd1ea0b1990006c3366ecd10c79d374f341687eb2cb23a2c8672e 170B / 170B         0.9s
 => => extracting sha256:58690f9b18fca6469a14da4e212c96849469f9b1be6661d2342a4bf01774aa50          3.5s
 => => extracting sha256:b51569e7c50720acf6860327847fe342a1afbe148d24c529fb81df105e3eed01          0.0s
 => => extracting sha256:da8ef40b9ecabc2679fe2419957220c0272a965c5cf7e0269fa1aeeb8c56f2e1          0.0s
 => => extracting sha256:fb15d46c38dcd1ea0b1990006c3366ecd10c79d374f341687eb2cb23a2c8672e          0.0s
 => [2/3] RUN apt-get -y update && apt-get -y upgrade                                             69.2s
 => [3/3] RUN apt-get -y install nginx                                                            69.7s
 => exporting to image                                                                             0.5s
 => => exporting layers                                                                            0.5s
 => => writing image sha256:2bb890af42c7e84efd40248d8b3bafaacece65cd9ddec1872168d57e2fef38a3       0.0s
 => => naming to docker.io/library/web-base                                                        0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

hbeen@DESKTOP-EDC39JU:~/sample$ docker image ls
REPOSITORY             TAG       IMAGE ID       CREATED         SIZE
web-base               latest    2bb890af42c7   2 minutes ago   222MB

hbeen@DESKTOP-EDC39JU:~/sample$ ls
Dockerfile  website.tar

hbeen@DESKTOP-EDC39JU:~/sample$ cat Dockerfile
#도커 이미지 취득
FROM web-base

hbeen@DESKTOP-EDC39JU:~/sample$ docker build -t photoview-image .
[+] Building 0.5s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                                               0.0s
 => => transferring dockerfile: 82B                                                                0.0s
 => [internal] load .dockerignore                                                                  0.0s
 => => transferring context: 2B                                                                    0.0s
 => [internal] load metadata for docker.io/library/web-base:latest                                 0.0s
 => [internal] load build context                                                                  0.0s
 => => transferring context: 356.45kB                                                              0.0s
 => [1/1] FROM docker.io/library/web-base                                                          0.1s
 => [2/1] ADD website.tar /var/www/html/                                                           0.1s
 => exporting to image                                                                             0.1s
 => => exporting layers                                                                            0.1s
 => => writing image sha256:503e5fd9d6a30a028cceb50b9707c543e7394bfd28efb6429848e8867e896b18       0.0s
 => => naming to docker.io/library/photoview-image                                                 0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

  • 베이스 이미지 작성 → 웹 콘텐츠 개발 → 웹 서버용 이미지 작성 순으로 작업
  1. 실행환경 작성 담당자 : OS/미들웨어 설치, 라이브러리 도입을 하여 베이스가 되는 도커 이미지 작성
  2. 개발자들 : 도커 베이스 이미지를 바탕으로 각자 개발한 소스코드를 전개하여 테스트

 

도커 이미지 생성

컨테이너로부터 이미지 작성(docker container commit)

  • docker container commit [옵션] [컨테이너ID] [이미지명:태그]
    • 컨테이너는 이미지를 바탕으로 작성하지만 반대로 컨테이너를 바탕으로 이미지를 작성할 수 있음
    • 리포지토리에서 취득한 공식 이미지를 바탕으로 컨테이너를 만들고 환경에 맞도록 설정을 변경한 컨테이너로부터 다시 이미지 생성 가능

옵션

  • -a : 작성자 지정
  • -m : 메시지 지정
  • -c : 커밋 시 dockerfile 명령을 지정
  • -p : 컨테이너를 일시 정지하고 커밋
hbeen@DESKTOP-EDC39JU:~$ docker container commit -a "leehyebeen" centos hyebeen/centos_test:1.0
sha256:2245b47ce1348137b007288b695af086427c9cada7e78a23ccf9b136ebdc4d82
hbeen@DESKTOP-EDC39JU:~$ docker image ls
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
hyebeen/centos_test   1.0       2245b47ce134   6 seconds ago   215MB

 

컨테이너를 tar 파일로 출력(docker container export)

  • docker container export [컨테이너ID]
    • 가동중인 컨테이너의 디렉터리/파일들을 모아서 tar 파일 생성
    • 생성한 tar 파일을 바탕으로 다른 서버에서 컨테이너를 기동시킬 수 있음
hbeen@DESKTOP-EDC39JU:~$ docker container export nginxserver > latest.tar
hbeen@DESKTOP-EDC39JU:~$ ls -la
total 132492
drwxr-xr-x 4 hbeen hbeen      4096 Feb 13 17:50 .
drwxr-xr-x 3 root  root       4096 Feb 12 19:45 ..
lrwxrwxrwx 1 hbeen hbeen        23 Feb 12 19:46 .aws -> /mnt/c/Users/llhb3/.aws
lrwxrwxrwx 1 hbeen hbeen        25 Feb 12 19:46 .azure -> /mnt/c/Users/llhb3/.azure
-rw-r--r-- 1 hbeen hbeen       220 Feb 12 19:45 .bash_logout
-rw-r--r-- 1 hbeen hbeen      3771 Feb 12 19:45 .bashrc
drwxr-xr-x 6 hbeen hbeen      4096 Feb 13 02:05 .docker
drwxr-xr-x 2 hbeen hbeen      4096 Feb 12 19:46 .landscape
-rw-r--r-- 1 hbeen hbeen         0 Feb 13 01:13 .motd_shown
-rw-r--r-- 1 hbeen hbeen       807 Feb 12 19:45 .profile
-rw-r--r-- 1 hbeen hbeen 135641600 Feb 13 17:50 latest.tar
hbeen@DESKTOP-EDC39JU:~$ tar tf latest.tar | more
.dockerenv
bin/
bin/bash
bin/cat
bin/chgrp
bin/chmod
bin/chown
bin/cp
bin/dash

 

tar 파일로부터 이미지 작성(docker image import)

  • docker image import [파일 또는 URL] | - [이미지명:태그]
    • 리눅스 OS 이미지의 디렉터리/파일로부터 도커 이미지 생성
    • root 권한으로 실행하지 않으면 액세스 권한이 없는 파일이 포함되지 않음
hbeen@DESKTOP-EDC39JU:~$ ls -al
total 132492
drwxr-xr-x 4 hbeen hbeen      4096 Feb 13 17:50 .
drwxr-xr-x 3 root  root       4096 Feb 12 19:45 ..
lrwxrwxrwx 1 hbeen hbeen        23 Feb 12 19:46 .aws -> /mnt/c/Users/llhb3/.aws
lrwxrwxrwx 1 hbeen hbeen        25 Feb 12 19:46 .azure -> /mnt/c/Users/llhb3/.azure
-rw-r--r-- 1 hbeen hbeen       220 Feb 12 19:45 .bash_logout
-rw-r--r-- 1 hbeen hbeen      3771 Feb 12 19:45 .bashrc
drwxr-xr-x 6 hbeen hbeen      4096 Feb 13 02:05 .docker
drwxr-xr-x 2 hbeen hbeen      4096 Feb 12 19:46 .landscape
-rw-r--r-- 1 hbeen hbeen         0 Feb 13 01:13 .motd_shown
-rw-r--r-- 1 hbeen hbeen       807 Feb 12 19:45 .profile
-rw-r--r-- 1 hbeen hbeen 135641600 Feb 13 17:50 latest.tar
hbeen@DESKTOP-EDC39JU:~$ cat latest.tar | docker image import - hyebeen/centos_test2
sha256:af615bc2338b7caadb868e926f86eba7b281f5f22ce97804d646b3ada9805f7f
hbeen@DESKTOP-EDC39JU:~$ docker image ls
REPOSITORY             TAG       IMAGE ID       CREATED         SIZE
hyebeen/centos_test2   latest    af615bc2338b   7 seconds ago   132MB
hyebeen/centos_test    1.0       2245b47ce134   5 minutes ago   215MB
ubuntu                 <none>    54c9d81cbb44   11 days ago     72.8MB
ubuntu                 latest    f643c72bc252   14 months ago   72.9MB
nginx                  latest    bc9a0695f571   14 months ago   133MB
centos                 latest    0d120b6ccaa8   18 months ago   215MB

 

이미지를 tar 파일로 저장(docker image save)

  • docker image save -o [저장 파일명] [이미지명]
    • 도커 이미지를 tar 파일로 저장
hbeen@DESKTOP-EDC39JU:~$ docker image save -o saveimage.tar hyebeen/centos_test
hbeen@DESKTOP-EDC39JU:~$ ls -l
total 349932
-rw-r--r-- 1 hbeen hbeen 135641600 Feb 13 17:50 latest.tar
-rw------- 1 hbeen hbeen 222685696 Feb 13 17:56 saveimage.tar

 

tar 파일로부터 이미지 읽어 들이기(docker image load)

  • docker image load -i [파일명]
hbeen@DESKTOP-EDC39JU:~$ docker image load -i saveimage.tar
'Loaded image: hyebeen/centos_test:1.0