espossible 2021. 9. 5. 13:29

도커(docker)는 컨테이너를 실행하기 위한 실행 환경(컨테이너 런타임) 및 툴킷이다. 쿠버네티스는 도커 이외의 컨테이너 런타임도 지원하도록 개발되어있다. 

 

쿠버네티스 사용에 앞서 도커 이미지를 빌드하고, 이미지 보관/배포 서버인 도커 레지스트리로 푸시하는 방법을 알아 두어야 한다. 또한, 반드시 알아두면 좋은 지식을 간단히 알아볼 것이다.

 

도커 컨테이너

도커 컨테이너는 도커 이미지를 기반으로 실행되는 프로세스다. 도커 이미지만 있다면 환경의 영향을 받지 않고 다양한 환경에서 컨테이너를 기동시킬 수 있기 때문에 이식성이 높다. 

도커 컨테이너는 가상 머신에 비해 '가볍다', '시작과 중지가 빠르다' 등과 같은 장점이 있다.

그 이유는 가상 머신은 하이퍼바이저를 이용하여 게스트 OS를 동작시키지만, 도커 컨테이너는 호스트 머신의 커널을 이용하면서 네임스페이스 분리와 cgroups를 이용한 제어를 통해 독립적인 OS와 같은 환경을 만들 수 있기 때문이다. 

 

https://www.docker.com/blog/containers-replacing-virtual-machines/

 

도커 컨테이너 설계

도커 컨테이너를 생성할 때 주로 주의해야할 점은 아래와 같다.

- 1 컨테이너당 1 프로세스

여러 프로세스를 기동하도록 만들면 주변 에코시스템과 맞지 않거나 관리가 힘들어진다.

- 변경 불가능한 인프라 이미지로 생성

컨테이너 이미지안에 애플리케이션 실행 바이너리나 관련 리소스를 가능한 한 포함시켜 컨테이너 이미지를 변경불가능한 상태로 만든다.

- 경량의 도커 이미지로 생성

경량 배포판으로는 알파인 리눅스(Alpine Linux)나 Distroless가 있다.

- 실행 계정은 root 이외의 사용자로 한다.

 

도커 파일 작성법

# Alpine 3.11 버전 golang 1.14.1 이미지를 기반 이미지로 사용
From golang:1.14.1-alpine3.11

# 빌드할 머신에 있는 main.go 파일을 컨테이너에 복사
COPY ./main.go ./

# 빌드 시 컨테이너 내부에서 명령어 실행
RUN go build -o ./go-app ./main.go

# 실행 계정을 nobody로 지정
USER nobody

# 컨테이너가 기동할 때 실행할 명령어 정의
ENTRYPOINT ["./go-app"]

도커 파일에서 사용할 수 있는 명령

명령 요약
FROM 기반 이미지를 지정
MAINTAINER 컨테이너 이미지 관리자 정보를 기입(현재는 비추천, 아래 LABEL 명령을 사용함)
LABEL 컨테이너 이미지의 메타데이터를 키:밸류 형식으로 지정(예: LABEL maintainer="XX<xxx@xxx.com>")
USER 명령어 실행 계정 지정
WORKDIR 명령어를 실행할 작업 디렉터리 지정(디렉터리가 없을 경우 생성)
EXPOSE 컨테이너 실행 시 Listen할 포트 지정
COPY 로컬에 있는 파일을 컨테이너로 복사
ADD 로컬에 있는 tar.gz 파일의 압축을 풀고 파일을 컨테이너로 복사
RUN 컨테이너 안에서 명령을 실행
ENTRYPOINT 컨테이너 기동 시에 실행할 명령어
CMD 컨테이너 기동 시에 실행할 명령어 인수

 

ENTRYPOINT와 CMD의 관계

ENTRYPOINT CMD 실행되는 명령어
"/bin/ls" "-a" /bin/ls -a
지정안함 /bin/ls /bin/ls
"/bin/sh", "-c" "ls -a" /bin/sh -c "ls -a"

ex) docker run ubuntu-sleeper 10 -> 10초간 sleep

FROM ubuntu
ENTRYPOINT ["sleep"]


ex) docker run --entrypoint sleep ubuntu-sleeper 10

--entrypoint : it will override entrypoint

FROM ubuntu
ENTRYPOINT ["sleep"]
CMD["5"] #파라미터가 없을 때 default 값을 지정하고자 할 경우, 파라미터 전달시 overrided 됨.

도커 실행시  Environment 전달

docker run -e APP_COLOR=pink simple-webapp-color

 

도커 이미지 빌드 및 확인

docker image build -t sample-image:0.1 (-f DockerFile) .

docker images

 

멀티 스테이지 빌드

기동용 컨테이너에 불필요한 소프트웨어를 설치하지 않는 것은 보안 측면에서도 좋을 뿐만아니라 이미지 사이즈를 줄일 수 있다. 이를 위해 멀티 스테이즈 빌드를 활용하자.

# Stage 1 컨테이너(애플리케이션 컴파일)
FROM golang:1.14.1-alpine3.11 as builder
COPY ./main.go ./
RUN go build -o /go-app ./main.go

# Stage 2 컨테이너(컴파일한 바이너리를 포함한 실행용 컨테이너 생성)
FROM alpine:3.11
# Stage 1에서 컴파일한 결과물 복사
COPY --from=builder /go-app .
ENTRYPOINT ["./go-app"]
# Stage 1 컨테이너(애플리케이션 컴파일)
FROM golang:1.14.1-alpine3.11 as builder
COPY ./main.go ./
RUN CGO_ENABLED=0 go build -o /go-app ./main.go

# Stage 2 컨테이너(컴파일한 바이너리를 포함한 실행용 컨테이너 생성)
FROM scratch
# Stage 1에서 컴파일한 결과물 복사
COPY --from=builder /go-app .
ENTRYPOINT ["./go-app"]

예제는 2단계 구성이지만 3단계 이상의 구성도 가능하다!

 

alpine 이미지 대신 scratch 이미지를 기반으로 사용하면 이미지 사이즈를 더 줄일 수 있는 것을 확인할 수 있다.

(base) jds@jdsui-MacBookPro chapter01 % docker images

REPOSITORY                           TAG                                                     IMAGE ID       CREATED          SIZE

smaple-image                         0.3                                                     a96b26cc1aa5   16 seconds ago   7.41MB

smaple-image                         0.2                                                     72e55cd3def7   46 seconds ago   13.1MB

 

도커 허브에 이미지 푸시

docker login

option 1) docker image build -t DOCKERHUB_USER/sample-image:0.x .

option 2)docker image tag sample-image:0.1 DOCKERHUB_USER/sample-image:0.x

docker image push DOCKERHUB_USER/sample-image:0.x

docker logout

 

컨테이너 기동

docker container run -d -p 1234:8080 sample-image:0.1

(base) jds@jdsui-MacBookPro chapter01 % docker container run -d -p 1234:8080 smaple-image:0.2
7edb8b08e3c4f6385ec814b9157063bbd0fea3da8baed6b61e8c7ee85afee769

(base) jds@jdsui-MacBookPro chapter01 % curl http://localhost:1234
Hello, Kubernetes% 

 


Docker Storage

Docker Storage drivers

도커 엔진은 OS에 따라서 적절한 storage driver를 선택한다.

- AUFS, ZFS, BTRFS, Device Mapper, Overlay, Overlay2

 

 

Docker volume drivers

- local, Azure File Storage, Convoy, AWS EBS, ...

$ docker run -it \
      --name mysql
      --volume-driver rexray/ebs
      --mount src=ebs-vol,target=/var/lib/mysql
      mysql

 

 

도커 파일 시스템

/var/lib/docker# ls
builder   containers  network   plugins   swarm  trust
buildkit  image       overlay2  runtimes  tmp    volumes

 

Docker Layer

- Image Layers

$ docker build -t test/my-app:0.0.1

- Container Layers

$ docker run test/my-app

출처 : https://docs.docker.com/storage/storagedriver/

Docker Volumes & Usage

- volume mount : 볼륨을 생성하지 않은 상태에서 도커 run 명령을 사용해서 볼륨지정을 했다면 자동생성된다.

$ docker volume create data_volume
$ docker run -v data_volume:/var/lib/mysql mysql

- bind mount : any location on the docker host

$ docker run -v ./current-dir:/var/lib/mysql mysql

출처 : https://docs.docker.com/storage/tmpfs/

참고) Container Interface

- CRI(Container Runtime Interface)

- CNI(Container Network Interface)

- CSI(Container Storage Interface)

 

 

다음 포스팅에서 도커 namespace와 cgroup에 대해서 살펴보도록 하자.
https://espossible.tistory.com/19

 


출처

- https://www.docker.com/blog/containers-replacing-virtual-machines/

- [책]쿠버네티스완벽가이드 마사야 아오야마 지음, 박상욱 옮김(길벗)