Run The Bridge
docker 3일차 본문
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 ./
(실습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 .
기타 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
'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 |