Run The Bridge

docker 3일차 본문

Cloud/docker

docker 3일차

anfrhrl5555 2021. 7. 21. 09:33
728x90
반응형

0.  Dockerfile, 이미지를 생성하는 방법

k8s로 가면 docker로 image를 올리지 않는다.

 

1. 컨테이너로 이미지를 생성하는 방법

 - 아무것도 존재하지 않는 이미지(Ubuntu, CentOS, 등)로 컨테이너 생성

 - application을 위한 환경을 설치하고 소스코드 등을 복사해 잘 동작하는 것을 확인

 - 컨테이너를 이미지로 commit

 

※ 단점

 - application package 설치와 source code 복사 등을 일일이 수작업으로 진행

 - 개발 과정을 단순화, 자동화시키기 위해선 이 과정을 자동화할 필요가 있음

 

2. Dockerfile로 이미지를 생성하는 방법

 - 컨테이너에 설치해야 하는 패키지, 소스코드 추가, 실행 명령어 및 쉘 스크립트 등을 하나의 파일로 기록하여 컨테이너에서 자동으로 작업 수행 후 새로운 이미지 생성 

 - 개발 도구와 연동하여 개발 -> 빌드 -> 배포 과정을 자동화 할 수 있음(CI/CD)

 

(실습) - 웹 서버 이미지를 생성하는 예제

# mkdir Dockerfile && cd Dockerfile
# mkdir apache && cd apache
# echo test >> test.html
# vi Dockerfile
FROM ubuntu:14.04
MAINTAINER alicek106
LABEL "purpose"="practice"
RUN apt-get update
RUN apt-get install apache2 -y
ADD test.html /var/www/html
WORKDIR /var/www/html
RUN ["/bin/bash", "-c", "echo hello >> test2.html"]
EXPOSE 80
CMD apachectl -DFOREGROUND

FROM: 생성할 이미지의 베이스가 되는 이미지. 반드시 한 번 이상 입력해야 한다. 이미지가 없으면 자동으로 pull하고 태그가 없으면 latest가 된다.

 

MAINTAINER: 이미지를 생성자의 정보. 도커 1.13.0 버전 이후로 사용하지 않고 LABEL 명령어를 통해 사용한다.

 

LABEL: 이미지에 메타데이터를 추가한다. ':' 형태. 여러 개 지정 가능

 

RUN: 이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행한다. 실행하는 명령어는 사용자 입력을 받을 수 없으므로 apt-get install 명령어와 같이 y/n 입력이 필요할 경우 미리 입력값을 부여해야 한다.

 

ADD: 파일을 이미지에 추가한다. 추가 대상 파일은 Dockerfile이 존재하는 곳에 있는 컨텍스트들이다.

 

WORKDIR: 명령어를 실행할 디렉토리. 컨테이너 내부에서 cd 명령어를 사용한 것과 같다. 여러 번 사용 시 cd를 여러 번 한 것과 같다.

 

EXPOSE: 컨테이너가 노출할 포트 지정. 실제로 포트가 바인딩 되는 것은 아니며 docker run -P 옵션의 대상이 되는 포트.

 

CMD: 컨테이너가 시작될 때 실행할 명령어 설정, Dockerfile 내에서 한 번만 사용할 수 있다.

 

"-c" option: 뒤에 오는 option을 그대로 실행하여라
docker build 명령어
# docker build -t mybuild:0.0 ./

 

확인하기
# docker images

 

host에서 사용하지 않는 임의포트 할당 및 curl로 테스트하기
# docker run -d -P --name myserver mybuild:0.0
# curl localhost:49156
# http:192.168.100.150:49156/test.html
# docker port myserver → image가 사용중인 port 확인
# docker images --filter "label=purpose=practice" → image가 practice인 것을 찾아준다.

 

빌드 컨텍스트 읽기

  • Dockerfile이 존재하는 디렉토리에 있는 파일(각종 파일, 소스, 메타데이터 등)
  • Dockerfile이 존재하는 곳에는 이미지 빌드에 필요한 파일만 있는 것이 좋다 -> 하위 디렉토리까지 포함되므로 불필요한 파일이 존재하면 빌드도 느리고, 메모리 점유가 높아진다
  • 루트(/) 디렉토리와 같은 곳에서 이미지 빌드를 하지 않도록 주의한다
  • .dockerignore 파일에서 명시된 파일들은 빌드 컨텍스트에서 제외된다

 

Dockerfile에서 ADD 명령어를 쓸 때, 디렉토리 경로를 '../'와 같은 상대경로를 써주면 오류가 난다.

무조건 Dockerfile에 ADD 명령어에 명시한 파일들이 모두 같은 경로에 위치 해야한다.

 

빌드 과정 살펴보기

  • 도커 엔진은 기본적으로 현재 디렉토리에 있는 'Dockerfile'이라는 이름의 파일을 선택
  • ADD, RUN 등의 명령어가 실행될 때마다 새로운 컨테이너가 생성되고 이미지로 커밋 (빌드가 완료되면 Dockerfile의 명령어 줄 수만큼의 레이어가 존재)

 

Docker images에 mybuild를 삭제하고 재빌드해보자
# docker rmi -f mybuild:0.0 
# docker rmi -f mynginx:0.0 
# docker images
# docker build -t mybuild_test:0.0 ./

Step 10번 + Using cache을 사용한다.

 

(실습2) Nginx 이미지를 생성하는 예제

# mkdir ngnix
# vi Dockerfile
FROM ubuntu:14.04
MAINTAINER Foo Bar <foo@bar.com>
RUN apt-get update
RUN apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
RUN chown -R www-data:www-data /var/lib/nginx
VOLUME ["/data", "/etc/nginx/site-enabled", "/var/log/nginx"]  # 컨테이너 디렉토리, 마운트 포인트
WORKDIR /etc/nginx
CMD ["nginx"]
EXPOSE 80
EXPOSE 443
ngnix build 하기
# docker build -t myngnix:0.0 ./
# docker run -d -P myngnix:0.0

 

what is VOLUME ?

Container의 디렉토리, mounting point

 

# docker inspect --type container [container_name]

 

(실습3) Ruby 이미지를 생성하는 예제

# vi Gemfile
source 'https://rubygems.org'
gem 'sinatra'
# vi app.rb
require 'sinatra'
require 'socket'

get '/' do
  Socket.gethostname
end
# vi Dockerfile
FROM       ubuntu:14.04
MAINTAINER Foo Bar <foo@bar.com>
RUN        apt-get -y update

# 2. ruby 설치
RUN apt-get -y install ruby
RUN gem install bundler

# 3. 소스 복사
COPY . /usr/src/app

# 4. Gem 패키지 설치 (실행 디렉토리 설정)
WORKDIR /usr/src/app
RUN     bundle install

# 5. Sinatra 서버 실행 (Listen 포트 정의)
EXPOSE 4567
CMD    bundle exec ruby app.rb -o 0.0.0.0

'COPY' == 'ADD' 라고 봐도된다.(복사와 추가)

 

본격적으로 build & run
# docker build -t myruby:0.0 .
# docker run -d -P myruby:0.0

 

멀티 스테이지를 이용한 Dockerfile 빌드하기

  • 일반적으로 소스를 빌드(컴파일)하기 위해서는 의존성 패키지나 라이브러리가 필요하지만 빌드 완료 후에는 필요 없다 → 이미지 사이즈 커진다
  • 빌드(컴파일)가 완료된 상태의 이미지만 배포가능하다면 이미지 사이즈를 크게 줄일 수 있다
# main.go
package main
import "fmt"
func main() {
        fmt.Println("hello world")
}
# Dockerfile
FROM golang
ADD main.go /root
WORKDIR /root
RUN go build -o /root/mainApp /root/main.go
CMD ["./mainApp"]

 

bulid & run
# docker build -t mygo:0.0 ./
# docker run mygo:0.0

그리고 Dockerfile2를 새로 만들어준다.

# Dockerfile2
FROM golang
ADD main.go /root
WORKDIR /root
RUN go build -o /root/mainApp /root/main.go

FROM alpine:latest
WORKDIR /root
COPY --from=0 /root/mainApp .
CMD ["./mainApp"]

- 첫번째 from에서 가져와라(0번쨰 인덱스)

 

새로만든 Dockerfile2로 빌드
# docker build -t go_helloworld:multi-stage -f Dockerfile2 .

multi-stage 용량이 압도적으로 작아졌다.
결과값은 hello world로 똑같다.

 

기타 Dockerfile 명령어(ENV, VOLUME, AGE. USER)

ENV

  • Dockerfile에서 사용될 환경변수 지정
  • 빌드된 이미지로 컨테이너를 생성해도 사용 가능
# mkdir ENV && cd ENV
# vi Dockerfile
# docker build -t myenv:0.0 .
# docker run -it myenv:0.0
# Dockerfile
FROM ubuntu:14.04
ENV TEST /home
WORKDIR $TEST
RUN touch $TEST/mytouchfile

TEST의 환경변수를 /home으로 변경

 

VOLUME

  • 빌드된 이미지로 컨테이너를 생성했을 때 호스트와 공유할 컨테이너 내부의 디렉토리 설정
  • VOLUME ["/home/dir1", "/home/dir2"] 또는 VOLUME /home/dir1 /home/dir2 형식

 

ARG(Argument)

  • docker build 명령어 실행 시 입력받아 사용할 수 있는 변수 값 설정
  • 기본값 지정 가능
  • ENV와 같은 이름을 사용하면 ENV가 덮어 쓴다
# mkdir arg && cd arg
# vi Dockerfile
# Dockerfile
FROM ubuntu:14.04
ARG my_arg
ARG my_arg_2=value2
RUN touch ${my_arg}/mytouch
# docker build --build-arg my_arg=/home -t myarg:0.0 .
# docker run myarg:0.0 ls /home

 

USER

  • 컨테이너 내에서 사용될 사용자 계정이나 UID를 설정하면 그 아래 명령어는 해당 사용자 권한으로 실행
  • RUN 명령어로 사용자 그룹과 계정을 생성한 뒤 사용
  • 루트 권한이 필요하지 않다면 사용자를 생성하는 것을 권장
# mkdir user && cd user
# vi Dockerfile
# Dockerfile
FROM ubuntu:14.04
RUN groupadd -r author && useradd -r -g author alicek106
USER alicek106
# docker build -t myuser:0.0 .
# docker run -it myuser:0.0 → id 입력
# docker run myuser:0.0 id 

728x90
반응형

'Cloud > docker' 카테고리의 다른 글

docker 5일차  (0) 2021.07.23
dockerfile을 이용하여 DB와 python 연동하기  (0) 2021.07.23
docker 4일차  (0) 2021.07.22
docker 2일차  (0) 2021.07.18
docker 1일차  (0) 2021.07.18
Comments