이 글은 도커를 어느 정도 알고 있다는 가정하에 작성한 글입니다 :/
혹시나 도커를 잘 모르시는 분은 생활코딩의 도커를 추천합니다.
오랜만에 도커를 사용하다 보니 자잘한 실수도 많이 하고 (특히 경로라던가 경로라던가...)
복습 겸 정리를 하는 것이 좋다고 생각해서 이렇게 정리를 하게 되었다
알잖아요, 도커는 신기술이 아니란 걸...
요새 쭈니어분들이 아주 똑똑하단 것을 나는 안다. 아마 이 글을 보는 당신도 그렇겠지... ㅠㅠ
지나가도 좋다! 나도 알고 있던걸 다시 한번 정리해보는 거니깐... ㅎ.ㅎ
어느 기술이나 다 그렇겠지만 도커는 유독 신기술이 아니다란 꼬리표가 더 잘 붙어다닌다
리눅스에 가상화 관련 기술인 namespace, cgroups, chroot 가 이미 있었다
그리고 저 위에 LinuX Container라는 최초의 컨테이너 기술이 나온다
그리고 이걸 바탕으로 libcontainer라는 기술이 나온다 (지금의 도커의 저수준 기술이고 도커 0.9이다)
그리고 또 이걸 바탕으로 고수준으로 이쁜 인터페이스로 포장하고 나온 것이 도커라고 한다
쪼~금 더 자세히 가보자
리눅스에서는 커널에서 namespace, groups 라는 기술을 제공하는데,
namespace는 독릭적인 자원을 할당하게 해준다 (파일시스템, 프로세스, 네트워크, 사용자 등)
cgroups는 자원에 대한 제어를 할 수 있다 (메모리, CPU, IO, 네트워크)
도커가 사용하는 커널 기능으로 바라보면
(컨테이너 생성) namespace으로 영역을 나누고
(최대 메모리, 네트워크 대역 설정 등) cgroups로 각 영역에 대해 자원을 할당하는 것으로 보인다
호스트 OS와 VM사이의 어딘가에
우테코 때 난 궁금했다. 왜 Ubuntu 환경에서 도커를 띄웠는데, 컨테이너 속 OS는 Oracle Linux(Redhat 계열)일까?
분명 이상하다, 도커는 호스트 OS를 공유해서 사용한다며, 근데 OS가 왜 다르지...?
도커는 호스트 OS를 그대로 사용하는 것이 아닌 일부(커널)를사용한다
그리고 그 위에 별도의 파일시스템, 소프트웨어(라이브러리, 툴)들이 설치되어 돌아간다
이렇게나 보면 무거워 보일 수 있지만 VM보다는 훨씬 가볍다
VM은 하드웨어를 에뮬레이팅(가상으로 구성)하고 실제 OS(커널까지 포함하여)를 띄운다
그렇기 때문에 VM은 무겁고 도커는 가볍다고 하는 것 같다
의외로 무거운 도커, 의외로 가벼운 VM
그러나 최근에 느낀 건... 도커는 생각보다 가볍지 않다.
실제로 쿠버 강사인 일프로님도 도커는 가볍지 않다고 한다.
도커 데몬이 항상 실행되는데, 도커가 기능이 많아지면서 무거워졌다고 ..
그리고 근래의 VM의 생각보다 무겁지 않다
얼마전에 VMware로 실습했는데 너무나도 쾌적한 GUI환경으로 행복하게 실습을 진행한 경험이 있다
Docker File sciprt
아래는 생활코딩 이고잉님의 수업자료에서 발췌한 Dockerfile 스크립트이다
FROM ubuntu:20.04
RUN apt update && apt install -y python3
WORKDIR /var/www/html
COPY [ "index.html", "." ]
CMD [ "python3", "-u", "-m", "http.server" ]
ubuntu라는 base 이미지를 기초로 하여 python 웹서버를 설치 후
index.html을 넣어서 실행하면 작은 웹서버가 실행되는 간단한 스크립트이다
COPY명령어 대신에
RUN echo "Hello, <strong>Docker</strong>" > index.html
위 명령어로도 대체할 수 있다
여기서 RUN, COPY는 이미지를 빌드할때, 사용하는 명령어이고 또, Layer를 생성하는 명령어이다
음.. 아래와 같이 준비해봤다 : )
이미지 생성 이전의 빌드시에 사용되는 명령어는 COPY, RUN, ARG가 있고
컨테이너 실행 시점에 사용되는 명령어는 EXPOSE, CMD, ENTRYPOINT가 있다
COPY는 (빌드할때) 호스트에서 게스트로 파일을 넣는 명령어이다
ADD는 네트워크 I/O 등이 필요한 작업 등에 사용한다고 한다 (사용해본 적이 없다)
RUN은 명령문을 실행한다 (주로 빌드를 위한 사전 작업 등)
ARG는 ` docker build` 명령어 사용시에 인자로 넘겨주기 위해 사용한다 (--build-arg key=val)
ENV는 빌드와 컨테이너 실행시에 모두 사용할 수 있고 환경 변수를 설정할때 사용한다
ENTRYPOINT, CMD는 컨테이너 최초 실행시 동작해야할 명령어를 실행한다
CMD와 같은 경우 Default Parameter처럼 동작하는데 활용될 수 있다
예)
기존 도커파일
CMD ["sh default.sh"]
`docker build .. "sh specific.sh" `라고 입력하면 ` specific.sh ` 실행
`docker build ..` (커맨드 인자 제외) 입력하면 ` default.sh` 실행
Docker File command
아래는 빌드하는 예시 명령어이다
docker build \
-t progress0407/my-docker-app \
-f ./BuildDockerfile .
도커 이미지를
파일을 불러온 후(-f)
이름을 지정해서 (-t)
빌드하는 것이다
특히 여기서 -f 옵션이 중요하다...
명령어 실행부와 스크립트 위치가 일치하면 상관이 없지만,
만일 다를 경우 no such file 에러로 삽질을 많이 할 수 있다
스크립트가 실행될 당시의 현재 위치는 스크립트의 위치가 아니다
명령어 실행할 때의 위치가 현재 위치다
그래서 나의 경우 아래처럼 실행부를 현재 위치를 스크립트 위치로 바꾸었다
CURRENT_FILE_PATH="$(dirname $0)"
cd $CURRENT_FILE_PATH
도커 컨텍스트
그리고 마지막 줄의 점(.) 중요하다!
저 쩜은 도커 컨텍스트를 삼을 위치를 말한다
만일 도커파일이 필요한 파일을 가져올때 (COPY 등)
파일의 위치가 도커 컨텍스트보다 위에 있으면 파일을 가져올 수 없다!
직접 해보면...
이때 실행은 script 상위 디렉터리에서 하고,
도커 컨텍스트는 script에서 잡았다. 이 경로 밑으로 sample-app.jar 파일은 상위 디렉터리에 존재한다
분명 파일이 존재함에 불구하고 not found가 뜬다
그래서 도커 컨텍스트 경로를 app.jar가 포함되도록 잡으면
아래처럼 빌드에 성공하는 것을 볼 수 있다
Docker Compose
Dockerfile과 다르게 멀티 컨테이너로 실행할 수 있다
version: '3.7'
services:
db:
image: mysql:5.7
volumes:
- ./data/db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: 1234
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress_user
MYSQL_PASSWORD: 1234
app:
depends_on:
- db
image: wordpress:latest
volumes:
- ./data/app_data:/var/www/html
ports:
- 8080:80
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress_user
WORDPRESS_DB_PASSWORD: 1234
위와 같이 WAS와 DB랑 연결할 수 있고
위와 같이 설정하면 WAS와 DB는 같은 (도커에서 구성한) 네트워크에 속하게 되어
`network` 속성 추가 없이 내부 포트로 통신 가능하다
위와 같이 볼드 처리한 이유는 저 부분에서 많이 해맸기 때문이다 ㅠ
당시의 난 (외부)13306:3306(내부)으로 포트를 지정하고 13306으로 통신을 시도했으나
연결이 되지 않아서 다른 부분 설정을 열심히 바꾸어가면서 고쳤던 기억이 있다... 후...
참고
갓 생활 코딩 이고잉좌 도커
달서님의 도커
https://www.daleseo.com/dockerfile/
컨테이너 기술 심화 자료..
https://tech.ssut.me/what-even-is-a-container/
https://www.44bits.io/ko/post/how-docker-image-work
https://www.44bits.io/ko/post/change-root-directory-by-using-chroot
리눅스 커널
https://www.redhat.com/ko/topics/linux/what-is-the-linux-kernel
CMD, ENTRYPOINT 차이
https://choco-life.tistory.com/49
'Infra, DevOps > Kubernetes, Docker' 카테고리의 다른 글
[k8s] 쿠버로 백엔드 환경 구축하기 (0) | 2024.02.19 |
---|---|
[k8s] 쿠버로 무중단 배포 3종 모두 해보자 (argo없는 Blue Green) (0) | 2024.01.30 |
따끈따끈 쿠버네티스 기초 개념 요약 (0) | 2024.01.17 |
윈도우에서 쿠버네티스 긴급 사용 후기 (2) | 2024.01.16 |
순전히 GPT의 도움으로 Docker기반 MySQL 셋업하기 (0) | 2023.07.08 |
hi hello... World >< 가장 아름다운 하나의 해답이 존재한다
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!