728x90

vagrant를 이용한 vm 준비


버추얼 박스 환경 설정

Virtualbox - 환경 설정

  • 입력 > 가상 머신 > 호스트 키 조합

 

  • 네트워크 > NatNetwork 확인

 

호스트 네트워크 관리자

  • 192.168.56.1/24

 


 

가상 머신 배포

운영 체제에 맞도록 vagrant 설치

https://www.vagrantup.com/

플러그인 설치

  • vagrant-hostmanager, vagrant-disksize
vagrant plugin install vagrant-hostmanager  
vagrant plugin install vagrant-disksize
vagrant plugin list

 

가상 머신 추가

  • ubuntu/bionic64 이미지를 이용한 가상 머신 추가
vagrant box add ubuntu/bionic64
vagrant box list

 

Vagrantfile 생성

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.define "kube-master1" do |config|
    config.vm.box = "ubuntu/bionic64"
    config.vm.provider "virtualbox" do |vb|
      vb.name = "kube-master1"
      vb.cpus = 2
      vb.memory = 3072
    end
    config.vm.hostname = "kube-master1"
    config.vm.network "private_network", ip: "192.168.56.11"
    config.disksize.size = "30GB"
  end
  config.vm.define "kube-node1" do |config|
    config.vm.box = "ubuntu/bionic64"
    config.vm.provider "virtualbox" do |vb|
      vb.name = "kube-node1"
      vb.cpus = 2
      vb.memory = 3072
    end
    config.vm.hostname = "kube-node1"
    config.vm.network "private_network", ip: "192.168.56.21"
    config.disksize.size = "30GB"
  end
  config.vm.define "kube-node2" do |config|
    config.vm.box = "ubuntu/bionic64"
    config.vm.provider "virtualbox" do |vb|
      vb.name = "kube-node2"
      vb.cpus = 2
      vb.memory = 3072
    end
    config.vm.hostname = "kube-node2"
    config.vm.network "private_network", ip: "192.168.56.22"
    config.disksize.size = "30GB"
  end
  config.vm.define "kube-node3" do |config|
    config.vm.box = "ubuntu/bionic64"
    config.vm.provider "virtualbox" do |vb|
     vb.name = "kube-node3"
      vb.cpus = 2
      vb.memory = 3072
    end
    config.vm.hostname = "kube-node3"
    config.vm.network "private_network", ip: "192.168.56.23"
    config.disksize.size = "30GB"
  end

  # Hostmanager plugin
  config.hostmanager.enabled = true
  config.hostmanager.manage_guest = true

  # Enable SSH Password Authentication
  config.vm.provision "shell", inline: <<-SHELL
    sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
    sed -i 's/archive.ubuntu.com/ftp.daum.net/g' /etc/apt/sources.list
    sed -i 's/security.ubuntu.com/ftp.daum.net/g' /etc/apt/sources.list
    systemctl restart ssh
  SHELL
end

 

가상 머신 생성

  • Vagrantfile이 있는 경로에서 명령 실행
  • Vagrantfile에 정의된 내용으로 가상 머신 생성
  • 총 4대의 가상 머신 (마스터 노드 1대, 워커 노드 3대)
vagrant up

 

가상 머신 접속

  • kube-master1에 vagrant 사용자 계정으로 ssh 접속
  • 패스워드: vagrant
ssh vagrant@192.168.56.11
Password: vagrant

728x90
728x90

Docker Compose란


Docker Compose

여러 컨테이너를 모아 관리하는 툴

  • docker-compose.yml 파일에 컨테이너의 구성 정보를 정의하여 동일 호스트상의 여러 컨테이너를 일괄적으로 관리할 수 있음
  • compose 정의 파일은 웹 애플리케이션의 의존 관계를 모아서 설정할 수 있음
  • 정의 파일을 기반으로 docker-compose 명령을 실행하면 여러 개의 컨테이너를 모아서 시작하거나 정지할 수 있음
  • 컨테이너 구성 정보를 YAML 형식의 파일로 관리할 수 있음
  • CI/CD 프로세스에서 자동 테스트를 할 때 환경 구축에 그대로 이용할 수 있음

 


 

Compose 구성 파일 작성

Docker Compose는 구성 정보를 정의 파일에서 설정함

  • Compose 정의 파일 확인
  • 'webserver'와 'redis'라는 이름의 서비스 2개 정의
  • webserver 서비스는 커런트 디렉토리에 있는 Dockerfile에 정의한 구성의 이미지를 빌드( build: . )하고, 외부에 대해 80번 포트를 공개( port: )하여 컨테이너 시작
  • 컨테이너는 redis 서비스에 의존( depends_on: )함
  • redis 서비스는 Docker Hub에 공개되어 있는 Redis의 공식 이미지인 'redis'의 버전 4.0을 베이스 이미지( image: )로 하여 컨테이너 시작
[root@localhost compose]# cat docker-compose.yml
version: '3.3'
services:
  # WebServer config
  webserver:
    build: .
    ports:
      - "80:80"
    depends_on:
      - redis

  # Redis config
  redis:
    image: redis

 


 

Docker Compose 명령

주요 서브 명령

  • docker-compose 명령은 docker-compose.yml을 저장한 디렉토리에서 실행됨
명령 설명
up 여러 Docker 컨테이너 생성/시작
stop 여러 Docker 컨테이너 정지
down 리소스 삭제
ps 컨테이너 목록 표시
logs 컨테이너 로그 출력
run 컨테이너 실행
start 컨테이너 시작
restart 컨테이너 재시작
pause 컨테이너 일시 정지
unpause 컨테이너 재개
port 공개 포트 번호 표시
config 구성 확인
kill 실행 중인 컨테이너 강제 정지
rm 컨테이너 삭제

 


 

docker-compose.yml 작성

image: 이미지 지정

  • Docker 컨테이너의 베이스 이미지 지정
  • 이미지 이름 또는 이미지 ID 지정
  • 로컬 환경에 없는 경우 Docker Hub로부터 자동 다운로드
  • 태그를 지정하지 않는 경우 최신 버전 다운로드
services:
webserver:
    image: khj/imagetest:1.0 # 태그 지정 또는
    image: ubuntu # 태그를 지정하지 않음

 

 

build: 이미지 빌드

  • 이미지의 작성을 Dockerfile에 기술하고 자동 빌드하여 베이스 이미지로 지정할 때 사용
  • Dockerfile의 파일 경로 지정
  • docker-compose.yml 파일이 있는 디렉토리를 커런트 디렉토리로 했을 때 Dockerfile의 위치를 지정함
  • build 지정
sevices:
  webserver:
    build: .

 

  • Dockerfile 작성
FROM ubuntu

 

  • 컨테이너 생성
docker-compose up --build

 

 

  • Dockerfile과 컨텍스트 지정
  • /compose에 저장되어 있는 Dockerfile-com이라는 이름의 Dockerfile을 빌드함
  • 파일 경로는 상대/절대 모두 지정 가능
services:
  webserver:
    build:
      context: /compose
      dockerfile: Dockerfile-com

 

 

 

command/entrypoint: 컨테이너 안에서 작동하는 명령 지정

  • 컨테이너 안에서 작동하는 명령 지정
command: /bin/bash

 

  • entrypoint 지정
entrypoint:
  - php
  - -d
  - memory_limit=-1

 

 

ports/expose: 컨테이너 간 통신

  • 공개 포트 지정
ports:
  - "3000"
  - "8000:8000"
  - "49100:22"
  - "127.0.0.1:8001:8001"

 

  • 컨테이너 내부에만 공개하는 포트 지정
expose:
  - "3000"
  - "8000"

 

 

 

depends_on: 서비스의 의존 관계 정의

  • 주의: 컨테이너의 시작 순서만 제어할 뿐 컨테이너상의 애플리케이션이 이용 가능해질 때까지는 제어하지 않음

 

volumes/volumes_from: 컨테이너 데이터 관리

  • 컨테이너에 볼륨을 마운트할 때 사용
  • 볼륨 지정
volumes:
  - /var/lib/mysql
  - cache/:/tmp/cache

 

  • 읽기 전용 볼륨 지정 (ro)
volumes:
  - ~/configs:/etc/configs/:ro

 

  • 볼륨 마운트 지정
  • 다른 컨테이너로부터 모든 볼륨을 마운트할 경우 사용
  • log라는 이름의 컨테이너로 마운트
volumes_from:
  - log
728x90
728x90

실습 환경 리소스 정리


컨테이너 & 이미지 모두 삭제

도커 컨테이너 모두 삭제

  • 구동 중인 모든 컨테이너 중지, 삭제
docker stop $(docker ps -aq) 
docker rm $(docker ps -aq)

 

도커 이미지 모두 삭제

docker rmi $(docker images -q)

 

  • 에러 발생: IMAGE ID 가 동일하여 충돌이 일어나 삭제할 수 없음
  • Error response from daemon: conflict: unable to delete e66264b98777 (must be forced) - image is referenced in multiple repositories
  • 해결: 강제 삭제
docker rmi -f $(docker ps -aq)

 


 

Docker Registry를 사용한 프라이빗 레지스트리 구축


 

로컬 환경에 Docker 레지스트리 구축

  • Docker 레지스트리는 프라이빗 네트워크 안에서만 이미지를 공개할 수 있음
  • registry 검색
[root@localhost ~]# docker search registry
NAME                            DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
registry                        The Docker Registry 2.0 implementation for s…   3614      [OK]
~

 

  • registry 다운로드
[root@localhost ~]# docker image pull registry

 

  • registry 이미지 확인
[root@localhost ~]# docker image ls
REPOSITORY     TAG       IMAGE ID       CREATED       SIZE
registry       latest    773dbf02e42e   3 weeks ago   24.1MB

 

  • registry 컨테이너 시작
  • 레지스트리는 5000번 포트를 사용함
[root@localhost ~]# docker container run -d -p 5000:5000 --name registry registry
09ad150b0b06f7e8407ae64893b1f38189eda07af8507b0e857c85df2c5e91fc

 

  • registry 컨테이너 확인
[root@localhost ~]# docker container ls
CONTAINER ID   IMAGE      COMMAND                  CREATED              STATUS              PORTS                                       NAMES
09ad150b0b06   registry   "/entrypoint.sh /etc…"   About a minute ago   Up About a minute   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   registry

 

Docker 이미지 업로드

  • Dockerfile.base 베이스 이미지 작성 후 빌드
# Dockerfile.base 작성
[root@localhost Dockerfile]# vi Dockerfile.base

FROM ubuntu:16.04

RUN apt-get -y update && apt-get -y upgrade
RUN apt-get -y install nginx

EXPOSE 80

ONBUILD ADD website.tar /var/www/html/

CMD ["nginx", "-g", "daemon off;"]

# web-base 이미지 빌드
[root@localhost Dockerfile]# docker build -t web-base -f Dockerfile.base .

 

  • index.html 작성 후 tar 파일로 저장
[root@localhost Dockerfile]# vi index.html

<!doctype html>
<html>
  <head>
    <h1>Private Registry</h1>
  </head>
  <body>
    <img src="https://miro.medium.com/max/560/1*0DFwvFiEE0BiSG6hC8Q-8Q.png">
  </body>
</html>


[root@localhost Dockerfile]# tar -cvf website.tar index.html

 

  • Dockerfile 작성
[root@localhost Dockerfile]# vi Dockerfile

FROM web-base

 

  • webpage 이미지 빌드
[root@localhost Dockerfile]# docker build -t webpage .

 

  • webpage 이미지 태그 설정
  • 로컬 이미지명: webpage
  • localhost의 5000번 포트에서 작동
  • 레지스트리에 업로드할 이미지명: rg-webpage
  • webpage와 rg-webpage의 IMAGE ID는 동일함 => 동일한 이미지임을 알 수 있음
[root@localhost Dockerfile]# docker image tag webpage localhost:5000/rg-webpage

[root@localhost Dockerfile]# docker image ls
REPOSITORY                  TAG       IMAGE ID       CREATED          SIZE
webpage                     latest    38288fd45692   3 minutes ago    222MB
localhost:5000/rg-webpage   latest    38288fd45692   3 minutes ago    222MB

 

  • 이미지 업로드
[root@localhost Dockerfile]# docker image push localhost:5000/rg-webpage
~
sha256:d4013a81e4478edbc5cda16ee11e92fb556f95a3f155edaa00245c6ae2df29bc size: 1781

 

  • 로컬 이미지 삭제
[root@localhost Dockerfile]# docker image rm localhost:5000/rg-webpage:latest
[root@localhost Dockerfile]# docker image rm webpage

 

 

 

Docker 이미지 다운로드와 작동 확인

  • 프라이빗 레지스트리에서 이미지 다운로드
[root@localhost Dockerfile]# docker image pull localhost:5000/rg-webpage
~
sha256:d4013a81e4478edbc5cda16ee11e92fb556f95a3f155edaa00245c6ae2df29bc
Status: Downloaded newer image for localhost:5000/rg-webpage:latest
localhost:5000/rg-webpage:latest

 

 

  • 이미지 목록 표시
[root@localhost Dockerfile]# docker image ls
REPOSITORY                  TAG       IMAGE ID       CREATED          SIZE
localhost:5000/rg-webpage   latest    38288fd45692   10 minutes ago   222MB

 

  • 작동 확인
  • 웹 브라우저에서 localhost IP:80로 접속
[root@localhost Dockerfile]# docker container run -d -p 80:80 localhost:5000/rg-webpage
d50b9e8f1baa1bfbb41cac59ffd20308f3760e781045891819710f96943be16c

 

  • 웹 브라우저에서 localhost IP:8888로 접속
[root@localhost Dockerfile]# docker container run -d -p 8888:80 localhost:5000/rg-webpage
c39e04736962f7c5ece162681557d5123e25c9fd69420bd4e44cf0371fcbf429

728x90
728x90

파일 설정


ADD: 파일 및 디렉토리 추가

이미지에 호스트상의 파일이나 디렉토리를 추가할 때 사용

ADD <호스트 파일 경로> <Docker 이미지 파일 경로>ADD ["<호스트 파일 경로>" "<Docker 이미지 파일 경로>"]

  • 호스트상의 파일이나 디렉토리, 원격 파일을 Docker 이미지 안으로 복사

 

  • 호스트 상의 host.html 파일을 이미지 안의 /docker_dir/에 추가
  • Dockerfile이 있는 경로에 host.html 파일 생성
# host.html 파일 생성
[root@localhost Dockerfile]# touch host.html
[root@localhost Dockerfile]# ls
Dockerfile  Dockerfile.base  host.html  index.html  website.tar

 

 

  • Dockerfile 작성
[root@localhost Dockerfile]# vi Dockerfile
FROM centos:7

ADD host.html /docker_dir/

 

  • add 이미지 빌드
[root@localhost Dockerfile]# docker build -t add .
Sending build context to Docker daemon  15.36kB
Step 1/2 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/2 : ADD host.html /docker_dir/
 ---> Using cache
 ---> 8d416c2d5b91
Successfully built 8d416c2d5b91
Successfully tagged add:latest

 

 

  • 생성한 add 이미지를 이용한 컨테이너 실행
[root@localhost Dockerfile]# docker run -it add

 

  • 실행된 컨테이너의 /docker_dir/ 경로에서 복사된 host.html 파일 확인
[root@0f90594633cd /]# ls /docker_dir/
host.html

 


 

COPY: 파일 복사

이미지에 호스트상의 파일이나 디렉토리를 복사할 때 사용

COPY <호스트 파일 경로> <Docker 이미지 파일 경로>

COPY ["<호스트 파일 경로>" "<Docker 이미지 파일 경로>"]

  • ADD 명령과 유사함
  • ADD 명령: 원격 파일의 다운로드나 아카이브 압축 해제 등과 같은 기능이 있음
  • COPY 명령: 호스트상의 파일을 이미지 안으로 복사하는 처리만 함

 


 

VOLUME: 볼륨 마운트

이미지에 볼륨 할당

VOLUME ["/마운트 포인트"]

  • 지정한 이름의 마운트 포인트 작성
  • 호스트나 그 외 다른 컨테이너로부터 볼륨의 외부 마운트를 수행함
  • 영구 데이터 저장이 필요한 경우 컨테이너 밖의 Docker의 호스트 머신상의 볼륨이나 공유 스토리지 볼륨에 마운트하여 사용
  • ==> 컨테이너는 영구 데이터를 저장하는 데 적합하지 않음
  • 설정 가능한 값
# JSON 배열
VOLUME ["/var/log/"]

# 또는
VOLUME /var/log

# 여러 개의 인수로된 문자열
VOLUME /var/log /var/db
728x90
728x90

환경 및 네트워크 설정


ENV: 환경 변수 설정

key value 형식: ENV [key] [value]

  • 단일 환경 변수에 하나의 값 설정
  • ENV 명령이 3줄에 걸쳐있으므로 3개의 Docker 이미지를 겹쳐서 만듦
ENV myName "jinkim"
ENV myOrder Gin Whisky Calvados
ENV myNickName jin

 

key=value 형식: ENV [key]=[value]

  • 한 번에 여러 개의 값 설정
  • 하나의 ENV 명령으로 여러 개의 값을 설정하므로 하나의 Docker 이미지 생성
ENV myName="jinkim" \
    myOrder=Gin \ Whisky \ Calvados \
    myNickName=jin

 


 

WORKDIR: 작업 디렉토리 지정

Dockerfile에서 정의한 명령을 실행하기 위한 작업용 디렉토리 지정을 위해 사용

  • RUN, CMD, ENTRYPOINT, COPY, ADD 명령을 실행하기 위해 작업용 디렉토리를 지정함
  • 지정한 디렉토리가 없다면 새로 생성
  • WORKDIR 명령은 Dockerfile 안에서 여러 번 사용 가능

 

  • 절대 경로/상대 경로 사용 
  • 실행 결과: /first/second/third 출력
WORKDIR /first
WORKDIR second
WORKDIR third
RUN ["pwd"]

 

  • WORKDIR 명령으로 환경 변수 사용
  • 실행 결과: /first/second 출력
ENV DIRPATH /first
ENV DIRNAME second
WORKDIR $DIRPATH/$DIRNAME
RUN ["pwd"]

 


 

USER: 사용자 지정

이미지 실행 또는 Dockerfile의 RUN, CMD, ENTRYPOINT 명령 실행을 위한 사용자 지정 시 사용

  • 첫 번째 whoami 명령은 root 사용자
  • 두 번째 whoami 명령은 jin 사용자
RUN ["adduser", "jin"]
RUN ["whoami"]
USER jin
RUN ["whoami"]

 

  • 실행 결과
[root@localhost Dockerfile]# docker build -t user .
Sending build context to Docker daemon  14.85kB
Step 1/5 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/5 : RUN ["adduser", "jin"]
 ---> Using cache
 ---> ab3430ec1ddd
Step 3/5 : RUN ["whoami"]
 ---> Running in 32bd59d818a1
root
Removing intermediate container 32bd59d818a1
 ---> b88098a6410e
Step 4/5 : USER jin
 ---> Running in 55417d12e8af
Removing intermediate container 55417d12e8af
 ---> 78cdbeeb3385
Step 5/5 : RUN ["whoami"]
 ---> Running in 9a5b3f43a654
jin
Removing intermediate container 9a5b3f43a654
 ---> 04802c29f8a7
Successfully built 04802c29f8a7
Successfully tagged user:latest

 


 

EXPOSE: 포트 설정

컨테이너의 포트 번호를 지정할 때 사용

  • Docker에게 실행 중인 컨테이너가 listen하고 있는 네트워크를 알려줌
  • docker container run 명령의 -p 옵션을 사용할 때 어떤 포트를 호스트에 공개할지 정의
  • 8080 포트 공개
EXPOSE 8080

 


 

ARG: Dockerfile 내 변수 설정

Dockerfile 안에서 사용할 변수를 정의할 때 사용

  • ARG 명령을 사용하면 변수의 값에 따라 생성되는 이미지의 내용을 변경할 수 있음
  • 환경 변수 ENV와 달리 ARG는 Dockerfile 안에서만 사용 가능
ARG YOURNAME="jin"
RUN echo $YOURNAME

 

  • ARG 명령 실행 결과
  • YOURNAME: JIN
[root@localhost Dockerfile]# docker build .
Sending build context to Docker daemon  14.85kB
Step 1/3 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/3 : ARG YOURNAME="JIN"
 ---> Running in 95fabeaddad3
Removing intermediate container 95fabeaddad3
 ---> bfa21b4abbd7
Step 3/3 : RUN echo $YOURNAME
 ---> Running in 90896b892b65
JIN
Removing intermediate container 90896b892b65
 ---> 09ac20e3d14d
Successfully built 09ac20e3d14d

 

  • --build-arg 옵션 사용
  • YOURNAME: KIM
[root@localhost Dockerfile]# docker build . --build-arg YOURNAME=KIM
Sending build context to Docker daemon  14.85kB
Step 1/3 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/3 : ARG YOURNAME="JIN"
 ---> Using cache
 ---> bfa21b4abbd7
Step 3/3 : RUN echo $YOURNAME
 ---> Running in 3fdd25c33b99
KIM
Removing intermediate container 3fdd25c33b99
 ---> 4fd9c9b92486
Successfully built 4fd9c9b92486

 


 

SHELL: 기본 쉘 설정

쉘 형식으로 명령을 실행할 때 기본 쉘 설정 시 사용

  • Linux 기본 쉘: ["/bin/sh", "-c"]
  • Windows 기본 쉘: ["cmd", "/S", "/C"]
# 기본 쉘 지정
SHELL ["/bin/bash", "-c"]

# RUN 명령 실행
RUN echo hello

 

  • 실행 결과
[root@localhost Dockerfile]# docker build .
Sending build context to Docker daemon  14.85kB
Step 1/3 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/3 : SHELL ["/bin/bash", "-c"]
 ---> Running in 99c03fb1a0fe
Removing intermediate container 99c03fb1a0fe
 ---> db4c37552f10
Step 3/3 : RUN echo hello
 ---> Running in 975a1c534dca
hello
Removing intermediate container 975a1c534dca
 ---> fc68001a93ec
Successfully built fc68001a93ec
728x90
728x90

명령 및 데몬 실행


RUN: 명령 실행

- 컨테이너에는 FROM 명령에서 지정한 베이스 이미지에 대해 '애플리케이션/미들웨어 설치 및 설정', '환경 구축 위한 명령 실행' 등과 같은 명령 실행 시 사용

- 이미지를 작성하기 위해 실행하는 명령 기술

Shell 형식

  • 쉘에서 실행
  • Shell 형식의 RUN 명령
# nginx 설치
RUN apt-get install -y nginx

 

Exec 형식

  • 쉘을 경유하지 않고 직접 실행
  • 환경 변수 지정 불가 (ex. $HOME 등)
  • 쉘 이용을 원할 경우 RUN 명령에 쉘 경로 지정
  • Exec 형식의 RUN 명령
# nginx 설치
RUN ["/bin/bash", "-c", "apt-get install -y nginx"]

 

  • RUN 명령의 실행 예
  • 문자열을 인수로 지정할 때는 ' (홑따옴표) 사용
  • RUN 명령은 Dockerfile에 여러 개 기술
# 베이스 이미지 설정
FROM ubuntu:latest

# RUN 명령 실행
RUN echo 안녕하세요 Shell 형식입니다
RUN ["echo", " 안녕하세요 Exec 형식입니다 "]
RUN ["/bin/bash", "-c", "echo ' 안녕하세요 Exec 형식에서 bash를 사용해 보>았습니다' "]

 

 

  • RUN 명령의 실행 로그
  • Dockerfile 은 명령 한 줄마다 이미지를 생성함
[root@localhost Dockerfile]# docker build -t run-test .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM ubuntu:latest
 ---> 27941809078c
Step 2/4 : RUN echo 안녕하세요 Shell 형식입니다
 ---> Running in d44b834efa8a
안녕하세요 Shell 형식입니다
Removing intermediate container d44b834efa8a
 ---> dcf3550fd766
Step 3/4 : RUN ["echo", " 안녕하세요 Exec 형식입니다 "]
 ---> Running in 52f6c3ebf053
 안녕하세요 Exec 형식입니다
Removing intermediate container 52f6c3ebf053
 ---> 7b00dfbd8e60
Step 4/4 : RUN ["/bin/bash", "-c", "echo ' 안녕하세요 Exec 형식에서 bash를 사용해 보았습니다' "]
 ---> Running in da4e2d292bb7
 안녕하세요 Exec 형식에서 bash를 사용해 보았습니다
Removing intermediate container da4e2d292bb7
 ---> dcc5b8101c6b
Successfully built dcc5b8101c6b
Successfully tagged run-test:latest

 

  • 이미지 구성
  • 이미지를 생성할 때 어떤 명령이 실행되는지 확인
[root@localhost Dockerfile]# docker history run-test
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
dcc5b8101c6b   4 minutes ago   /bin/bash -c echo ' 안녕하세요 Exec 형식에서…            0B
7b00dfbd8e60   4 minutes ago   echo  안녕하세요 Exec 형식입니다                          0B
dcf3550fd766   4 minutes ago   /bin/sh -c echo 안녕하세요 Shell 형식입니다               0B

 


 

CMD: 데몬 실행

- 이미지를 바탕으로 생성된 컨테이너 안에서 명령 실행 시 사용

- Dockerfile에는 하나의 CMD 명령만 기술 가능, 여러 개 지정 시 마지막 명령만 유효

Exec 형식

  • 쉘을 호출하지 않음
  • nginx를 포어그라운드에서 실행
CMD ["nginx", "-g", "daemon off;"]

 

Shell 형식

  • nginx를 포어그라운드에서 실행
CMD nginx -g 'daemon off;'

 

ENTRYPOINT 명령의 파라미터로 기술

  • ENTRYPOINT 명령의 인수로 CMD 명령을 사용할 수 있음
# 베이스 이미지 설정
FROM ubuntu:16.04

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

# 포트 지정
EXPOSE 80

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

 

  • Docker 이미지 작성
[root@localhost Dockerfile]# docker build -t cmd-test .

 

  • 컨테이너 실행
[root@localhost Dockerfile]# docker container run -p 80:80 -d cmd-test
5d35e96603b8f7b61a3b9b8b95978e6d7610bbc66854a2598412694c8083e09e

[root@localhost Dockerfile]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS        PORTS                                       NAMES
5d35e96603b8   cmd-test    "nginx -g 'daemon of…"   3 seconds ago   Up 1 second   0.0.0.0:80->80/tcp, :::80->80/tcp           bold_jepsen

 

 


 

ENTRYPOINT: 데몬 실행

- ENTRYPOINT에서 지정한 명령은 Dockerfile에서 빌드한 이미지로부터 Docker 컨테이너를 시작하기 때문에 docker container run 명령 실행 시 실행됨

Exec 형식

  • nginx를 포어그라운드에서 실행
ENTRYPOINT ["nginx", "-g", "daemon off;"]

 

Shell 형식

  • nginx를 포어그라운드에서 실행
ENTRYPOINT nginx -g 'daemon off;'

 

  • ENTRYPOINT 명령과 CMD 명령 조합
  • ENTRYPOINT 명령: 실행하고자 하는 명령 자체 지정
  • CMD명령: 그 명령의 인수 지정
  • ENTRYPOINT 명령으로 TOP 명령 실행, CMD 명령으로 갱신 간격인 -d 옵션을 10초로 지정
  • 이 이미지로부터 작성된 컨테이너는 top 명령이 반드시 실행되는데, 이 때 CMD 명령에서 지정한 옵션을 사용하여 실행 시의 인수를 임의로 docker container run 명령 실행 시로 지정할 수 있음
# 베이스 이미지 설정
FROM ubuntu:16.04

# top 실행
ENTRYPOINT ["top"]
CMD ["-d", "10"]

 

  • 이미지 작성
[root@localhost Dockerfile]# docker build -t ent-cmd .

 

  • 컨테이너 생성 및 실행
# CMD 명령에서 지정한 10초 간격으로 갱신하는 경우
[root@localhost Dockerfile]# docker container run -it ent-cmd

 

  • CMD 명령은 docker container run 명령 실행 시 덮어 쓸 수 있는 구조 때문에 가능함
# 2초 간격으로 갱신
[root@localhost Dockerfile]# docker container run -it ent-cmd -d 2

 


 

ONBUILD: 빌드 완료 후 실행되는 명령

- 다음 빌드에서 실행할 명령을 이미지 안에 설정하기 위한 명령

- Dockerfile로부터 생성한 이미지를 베이스 이미지로 한 다른 Dockerfile을 빌드할 때 실행

- 웹 시스템 구축 시 OS 설치 및 환경 설정, 웹 서버 설치 및 각종 플러그인 설치 등과 같은 인프라 환경 구축과 관련된 부분을 베이스 이미지로 작성

- 인프라 구축 관련 이미지와 애플리케이션 전개 관련 이미지 생성을 나누어 실행

- 이 때, ONBUILD 명령으로 이미지 안에 개발한 프로그램을 전개하는 명령(ADD, COPY 등) 지정

  • 1. 베이스 이미지 작성(Dockerfile.base)
# 베이스 이미지 설정
FROM ubuntu:17.10

# Nignx 설치
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;"]

 

  • 베이스 이미지 빌드
  • Dockerfile을 Dockerfile.base라는 이름으로 지정하여 빌드 (-f 옵션 사용)
  • web-base라는 베이스 이미지가 생성됨
[root@localhost Dockerfile]# docker build -t web-base -f Dockerfile.base .

 

  • 2. 웹 콘텐츠 개발
  • Dockerfile이 있는 디렉토리에서 index.html 파일 생성 후 website.tar 파일로 압축
[root@localhost Dockerfile]# vi index.html
<!doctype html>
<html>
  <head>
    <h1>ONBUILD</h1>
  </head>
  <body>
    <img src="https://3.bp.blogspot.com/-rAve4gA0DNY/WzYXGT3G3aI/AAAAAAAABak/YGC8oM_TMsYDi9ZX8G6iEXgsag728eixgCLcBGAs/s400/Docker%2BONBUILD%2BCommand%2BExplained%2Bwith%2BExamples.jpg">
  </body>
</html>

[root@localhost Dockerfile]# tar -cvf website.tar index.html
index.html

[root@localhost Dockerfile]# ls
Dockerfile  Dockerfile.base  index.html  website.tar

 

  • 3. 웹 서버용 이미지 작성
# Docker 이미지 취득
FROM web-base

 

  • 웹 서버용 이미지 빌드
  • webpage라는 도커 이미지 생성
[root@localhost Dockerfile]# docker build -t webpage .
Sending build context to Docker daemon  14.85kB
Step 1/1 : FROM web-base
# Executing 1 build trigger
 ---> 3a4fd07273fc
Successfully built 3a4fd07273fc
Successfully tagged webpage:latest

 

 

  • 4. 웹 서버용 컨테이너 시작
[root@localhost Dockerfile]# docker container run -d -p 80:80 webpage
8b7f0e59a5d8cbfb08e9eb457c6fb9e8b077dcb4326e774a0f1ed687a4697809

 

  • 웹 브라우저에서 접속하여 확인 (enp0s8)

 

728x90
728x90

Dockerfile 빌드


docker build -t [생성할 이미지명]:[태그명] [Dockerfile의 위치]

Dockerfile로부터 이미지 생성

  • Dockerfile 생성
# test 디렉토리에 Dockerfile 생성
[root@localhost ~]# mkdir test
[root@localhost ~]# cd test
[root@localhost test]# touch Dockerfile
[root@localhost test]# ls
Dockerfile

 

  • Dockerfile 내용
[root@localhost test]# cat Dockerfile
FROM centos:centos7

 

  • docker build 실행
  • test: 이미지명
  • 1.0: 태그명
  • /root/test: Dockerfile이 위치한 경로
[root@localhost ~]# docker build -t test:1.0 /root/test
Sending build context to Docker daemon  2.048kB
Step 1/1 : FROM centos:centos7
centos7: Pulling from library/centos
Digest: sha256:c73f515d06b0fa07bb18d8202035e739a494ce760aa73129f60f4bf2bd22b407
Status: Downloaded newer image for centos:centos7
 ---> eeb6ee3f44bd
Successfully built eeb6ee3f44bd
Successfully tagged test:1.0

[root@localhost ~]# docker image ls
REPOSITORY     TAG       IMAGE ID       CREATED        SIZE
test           1.0       eeb6ee3f44bd   9 months ago   204MB

 

  • 이미지 확인
[root@localhost ~]# docker image ls
REPOSITORY     TAG       IMAGE ID       CREATED        SIZE
test           1.0       eeb6ee3f44bd   9 months ago   204MB

 

베이스 이미지가 로컬에 저장되어 있는 경우 이미지 생성

  • 두 번째 이후는 베이스 이미지를 Docker 레지스터에서 다운로드 하지 않음
[root@localhost ~]# docker build -t test:2.0 /root/test
Sending build context to Docker daemon  2.048kB
Step 1/1 : FROM centos:centos7
 ---> eeb6ee3f44bd
Successfully built eeb6ee3f44bd
Successfully tagged test:2.0

 

  • 이미지 확인
  • 베이스 이미지와 작성한 두 개의 이미지의 IMAGE ID가 동일함 > 이름은 다르지만 모두 동일한 이미지임을 알 수 있음
[root@localhost ~]# docker image ls
REPOSITORY     TAG       IMAGE ID       CREATED        SIZE
centos         centos7   eeb6ee3f44bd   9 months ago   204MB
test           1.0       eeb6ee3f44bd   9 months ago   204MB
test           2.0       eeb6ee3f44bd   9 months ago   204MB

 


 

멀티 스테이지 빌드


Docker 멀티 스테이지 빌드란?

컨테이너 이미지를 만들면서 빌드 등에는 필요하지만 최종 컨테이너 이미지에는 필요 없는 환경을 제거할 수 있도록 단계를 나누어 베이스 이미지를 만드는 방법

  • Dockerfile 빌드

[출처] https://www.metricfire.com/blog/how-to-build-optimal-docker-images/

 

  • 멀티 스테이지 빌드
  • 하나의 Dockerfile을 실행하여 빌드 이미지와 실행 이미지 분리가 가능해짐
  • 배포 이미지의 용량 감소, 빌드 시간 감소
  • 보다 가벼운 크기의 컨테이너 생성

[출처] https://www.metricfire.com/blog/how-to-build-optimal-docker-images/

 

728x90
728x90

Docker Hub 연동


docker login [옵션] [서버]

Docker Hub에 로그인

  • Docker 리포지토리에 이미지 업로드를 위해 Docker Hub 로그인
  • 옵션
옵션 설명
--password, -p 비밀번호
--username, -u 사용자명

 

  • Docker Hub에 로그인
[root@localhost ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: khj708
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

 

 


 

docker image tag <Docker Hub 사용자명>/이미지명[:태그명]

이미지 태그

  • 이미지에 대한 태그 설정
  • [apline:latest]: 사용할 이미지
  • khj708: Docker Hub 사용자명
  • goorm: 이미지명
  • alpine: 태그명
[root@localhost ~]# docker image tag alpine:latest khj708/goorm:alpine

[root@localhost ~]# docker image ls
REPOSITORY     TAG       IMAGE ID       CREATED        SIZE
khj708/goorm   alpine    e66264b98777   3 weeks ago    5.53MB
alpine         latest    e66264b98777   3 weeks ago    5.53MB

 


 

docker image push <Docker Hub 사용자명>/이미지명[:태그명]

이미지 업로드

  • Docker Hub에 이미지 업로드를 위한 명령
  • 업로드할 이미지 이름 형식: <Docker Hub 사용자명>/이미지명:태그명 
  • docker login 명령으로 로그인이 되어야 함
  • 이미지 업로드
[root@localhost ~]# docker image push khj708/goorm:alpine
The push refers to repository [docker.io/khj708/goorm]
24302eb7d908: Mounted from library/alpine
alpine: digest: sha256:4ff3ca91275773af45cb4b0834e12b7eb47d1c18f770a0b151381cd227f4c253 size: 528

# 이름 형식이 맞지 않는 경우 이미지 업로드에 실패함
[root@localhost ~]# docker image push khj708/alpine:latest
The push refers to repository [docker.io/khj708/alpine]
An image does not exist locally with the tag: khj708/alpine

 

 


 

 

Dockerfile을 사용한 구성 관리


Dockerfile이란?

인프라 구성을 기술한 파일

  • Dockerfile은 Docker 상에서 작동시킬 컨테이너의 구성 정보를 기술하기 위한 파일
  • docker build: Dockerfile에 기술된 구성 정보를 바탕으로 Docker 이미지 작성

 

[출처] https://jfrog.com/knowledge-base/a-beginners-guide-to-understanding-and-building-docker-images/

 


 

Dockerfile의 기본 구문

Dockerfile은 텍스트 형식의 파일로 에디터 등을 사용하여 작성

  • 확장자 X
  • 인프라의 구성 정보 기술
  • Dockerfile에서 이미지를 빌드할 때 파일명을 명시적으로 지정해야 함

 

Dockerfile 명령

  • 명령은 대/소문자 상관없지만 관례적으로 대문자로 통일해서 사용
명령 설명
FROM 베이스 이미지 지정
RUN 명령 실행
CMD 컨테이너 실행 명령
LABEL 라벨 설정
EXPOSE 포트 익스포트
ENV 환경 변수
ADD 파일/디렉토리 추가
COPY 파일 복사
ENTRYPOINT 컨테이너 실행 명령
VOLUME 볼륨 마운트
USER 사용자 지정
WORKDIR 작업 디렉토리
ARG Dockerfile 안의 변수
ONBUILD 빌드 완료 후 실행되는 명령
STOPSIGNAL 시스템 콜 시그널 설정
HEALTHCHECK 컨테이너의 헬스 체크
SHELL 기본 쉘 설정

 

 


 

Dockerfile 작성

Dockerfile에는 'Docker 컨테이너를 어떤 Docker 이미지로부터 생성할지'라는 정보를 반드시 기술해야 함

=> 베이스 이미지

 

FROM 명령

  • FROM [이미지명]
  • FROM [이미지명]:[태그명]
  • FROM [이미지명]@[다이제스트]

 

  • CentOS를 베이스 이미지로 한 Dockerfile
  • 태그명을 생략하면 베이스 이미지의 최신 버전이 적용됨
# 베이스 이미지 설정
FROM centos:centos7

 

  • 다이제스트 확인
  • 이미지를 고유하게 특정할 때 사용
  • 다이제스트: Docker Hub에 업로드하면 자동으로 부여되는 식별자, 업로드하지 않은 이미지는 없음
[root@localhost ~]# docker image ls --digests khj708/goorm
REPOSITORY     TAG       DIGEST                                                                    IMAGE ID       CREATED       SIZE
khj708/goorm   alpine    sha256:4ff3ca91275773af45cb4b0834e12b7eb47d1c18f770a0b151381cd227f4c253   e66264b98777   3 weeks ago   5.53MB

# 다이제스트가 없음
[root@localhost ~]# docker image ls --digests khj/os
REPOSITORY   TAG       DIGEST    IMAGE ID       CREATED       SIZE
khj/os       1.1       <none>    a608bf012429   2 hours ago   231MB
khj/os       1.0       <none>    7c82097ba542   3 hours ago   231MB
728x90

+ Recent posts