Shell Script 문법 정리
Title: Bash Shell Script 문법 정리 Author: DongDongE Tags: Programming Release: 2021.02.08 [Shell
인프라 구성을 관리 및 효율적으로 운영하기 위해 "Dockerfile"를 이용할 수 있으며,
Dockerfile를 작성하여 사용자가 원하는 설계 방향이나 설정된 내용으로 도커 이미지를 제작할 수 있습니다.
즉, 이미지를 작성할 수 있는 설정 파일입니다. 기존에 도커 컨테이너에 웹서버 구동을 위해 베이스 이미지 다운로드후 컨테이너에 접속하여 사용자가 수동으로 작업했던 반면, 자동으로 모든 걸 처리하여 이미지로 작성됩니다.
띠용!!
Dockerfile를 빌드할 때는 "Dockerfile"을 포함하고 있는 디렉터리의 서브디렉터리 까지 모두 Docker 데몬으로 보내 처리하기에 많이 느려집니다.
Dockerfile 기반으로 빌드시 하위 디렉터리에서 진행하며, 불필요한 파일을 포함하지 않도록 해주세요.
그러면 본격적으로 Dockerfile를 작성해보도록 하겠습니다.
Dockerfile은 텍스트 형식이며, 파일명 또한 "Dockerfile" 입니다. 확장자는 따로 존재하지 않습니다.
아래 내용은 Dockerfile에 작성되는 명령 옵션 입니다.
dongdonge@dongdonge$ vim Dockerfile
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y vim apache2
COPY index.html /var/www/html/
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
우선 임시로 "Dockerfile"를 생성하여 예시 1와 같이 작성 하였습니다.
"FROM ubuntu:16.04" : 공식 이미지를 기반으로 이미지를 제작하며, 태그명이 생략되면 Base Image의 최신버전(Latest)로 기반됩니다.
"RUN apt-get update && apt-get install -y vim apache2" : 컨테이너가 생성될 때 명령을 수행하며, vim와 Apache 웹서버를 설치한다.
"COPY index.html /var/www/html/" : 컨테이너 내부에 파일을 복사한다. 현재 index.html 파일을 /var/www/html/ 경로에 복사한다.
"CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]" : 컨테이너가 매번 실행될 때 마다 명령이 실행된다.
Dockerfile을 이미지로 제작하기 위해 Docker Build 작업을 하여야 합니다.
docker build <옵션> <Dockerfile 경로>
아래 옵션을 통해 확인해보도록 하겠습니다.
dongdonge@dongdonge$ docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--cgroup-parent string Optional parent cgroup for the container
--compress Compress the build context using gzip
--cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
-m, --memory bytes Memory limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--network string Set the networking mode for the RUN instructions during build
(default "default")
--no-cache Do not use cache when building the image
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--security-opt strings Security options
--shm-size bytes Size of /dev/shm
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
--ulimit ulimit Ulimit options (default [])
해당 옵션 중 "-t <생성할 이미지명>:<태그명> <Dockerfile 위치>" 옵션을 사용하여 이미지를 제작해보도록 하겠습니다.
dongdonge@dongdonge$ docker build -t dongdonge_web:0.2 /root/docker_test/
Sending build context to Docker daemon 3.072kB
Step 1/4 : FROM ubuntu:18.04
18.04: Pulling from library/ubuntu
35c102085707: Pull complete
251f5509d51d: Pull complete
8e829fe70a46: Pull complete
6001e1789921: Pull complete
Digest: sha256:d1d454df0f579c6be4d8161d227462d69e163a8ff9d20a847533989cf0c94d90
Status: Downloaded newer image for ubuntu:18.04
---> a2a15febcdf3
Step 2/4 : RUN apt-get update && apt-get install -y vim nginx
---> Running in d969a5be3c53
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB] ....
.....
Removing intermediate container d969a5be3c53
---> 6ff7d429b509
Step 3/4 : COPY index.html /usr/share/nginx/html/
---> f845adeff3f9
Step 4/4 : CMD ["nginx", "-g", "daemon off;"]
---> Running in b3821cf26c2f
Removing intermediate container b3821cf26c2f
---> 291fcc71f9b1
Successfully built 291fcc71f9b1
Successfully tagged dongdonge_web:0.2
"build" 옵션을 통해 Base Image를 다운로드 받고, 이를 기반으로 이미지가 제작되고 있는걸 볼 수 있습니다.
dongdonge@dongdonge$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dongdonge_web 0.2 291fcc71f9b1 4 minutes ago 206MB
ubuntu 18.04 a2a15febcdf3 2 weeks ago 64.2MB
FROM 명령에서 설정한 베이스 이미지에 대해 실행하며, 패키지 설치 및 명령 실행에 사용될 수 있습니다.
RUN <명령어>
RUN 명령어는 두 가지 형식으로 쓸 수 있습니다.
RUN apt-get install apache2 vim -y
RUN ["/bin/bash", "-c", "apt-get install apache2 vim -y"]
이미지를 바탕으로 생성된 컨테이너 실행 시 매번 명령을 실행합니다. (Docker run / Docker start)
참고로 하나의 CMD만 작성할 수 있으며, 중복일 경우 맨 마지막 하나만 유효 됩니다.
CMD <명령어>
CMD apachectl -D FOREGROUND
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
Dockerfile에서 빌드한 이미지를 컨테이너로 생성(Docker run)할때 단 한번만 실행합니다.
ENTRYPOINT <명령어>
ENTRYPOINT도 RUN 명령어 처럼 두 가지 형식으로 쓸 수 있습니다.
ENTRYPOINT apachectl -D FOREGROUND
ENTRYPOINT ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
다른 이미지의 Base Image로 쓰이는 경우 빌드시 해당 명령이 실행된다.
ONBUILD <명령어>
FROM ubuntu:16.04
RUN apt-get update && apt-get install apcahe2 -y
EXPOSE 80
ONBUILD ADD website.tar /var/www/html/
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
Dockerfile을 통하여 환경변수를 컨테이너 안에 지정할 수 있습니다.
또한 Dockerfile 대신 "docker run" 명령의 "--env" 옵션을 통하여 사용할 수도 있습니다.
ENV <Key> <Value>
또는
ENV <Key> = <Value>
ENV 명령어는 아래와 같이 두 가지 방법을 이용할 수 있습니다.
ENV ServerName "DongDongE"
ENV ServerPw toor
ENV ServerName="DongDongE" \
ServerPw=toor
"Key = Value" 형식은 한 줄에 여러 값을 설정할 수 있습니다.
Dockerfile 내부에서 사용되는 WORKDIR 명령은 작업용 디렉터리를 설정하기 위해 사용됩니다.
주로 "RUN", "CMD", "ENTRYPOINT", "COPY", "ADD" 등 명령에 같이 사용됩니다.
WORKDIR <경로>
WORKDIR /abcd
WORKDIR efgh
WORKDIR ijk
해당 경로가 디렉터리가 존재하지 않는다면 새로 생성되며, Dockerfile내에서 "WORKDIR" 명령을 여러 번 사용할 수 있습니다.
root@2d24bcaa30a3:/abcd/efgh/ijk# pwd
/abcd/efgh/ijk
Dockerfile 내에서 명령을 실행하기 위해 사용자(권한)를 지정할 수 있습니다.
USER <사용자명 또는 UID>
RUN ["useradd", "-m", "DongDongE"]
USER DongDongE
RUN ["touch", "/home/DongDongE/test123"]
우선 USER 명령으로 권한을 설정하기 전, "RUN" 명령을 통해 사용자 계정을 생성한 뒤 "USER" 명령으로 사용자를 지정하였습니다.
DongDongE@c3bf452076b1:~$ ls -la /home/DongDongE/
total 20
drwxr-xr-x 1 DongDongE DongDongE 4096 Sep 3 06:28 .
drwxr-xr-x 1 root root 4096 Sep 3 06:28 ..
-rw-r--r-- 1 DongDongE DongDongE 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 DongDongE DongDongE 3771 Apr 4 2018 .bashrc
-rw-r--r-- 1 DongDongE DongDongE 807 Apr 4 2018 .profile
-rw-r--r-- 1 DongDongE DongDongE 0 Sep 3 06:28 test123
컨테이너 내부에서 Dockerfilr의 "USER" 명령을 통하여 "DongDongE" 사용자 권한으로 파일이 생성된 걸 볼 수 있습니다.
Docker Image의 작성자 정보, 타이틀, 버전, 코맨드 등. 정보를 작성할때 사용됩니다.
LABEL <Key>=<Value>
LABEL maintainer "DongDongE <DongDongE@d0ngd0nge.xyz>"
LABEL title="Test Docker"
LABEL version="0.1"
LABEL description="Docker Test Label"
아래와 같이 Docker 빌드된 도커 이미지의 정보를 확인해보면 지정한 정보가 설정된걸 볼 수 있습니다.
root@dongdonge:/var/www/raonctf/training/test/label# docker inspect --format="{{ .Config.Labels }}" label
map[description:Docker Test Label maintainer:DongDongE <DongDongE@d0ngd0nge.xyz> title:Test Docker version:0.1]
현재 빌드된 컨테이너명을 "label"로 설정되어 있습니다. 아래 명령을 통해 확인 하시면 됩니다.
'docker inspect --format="{{ .Config.Labels }}" <컨테이너명>'
Docker Container의 공개 포트를 호스트와 연결 (지정)할 때 사용됩니다.
EXPOSE <포트 번호>
EXPOSE 80
EXPOSE 443
또는
EXPOSE 80 443
Dockerfile의 EXPOSE 명령은 실행 중인 컨테이너와 호스트와 연결만 하고, 외부에 노출되지는 않습니다.
컨테이너 포트를 외부에 노출하여, 외부에서 접속할 수 있게 하려면 "docker run" 명령의 "-p" 옵션을 사용해야 합니다.
Dockerfile 내부에서 명령을 실행할 때 Shell을 지정할 수 있으며, Default로 리눅스 경우 "/bin/sh"로 설정됩니다.
또한 "RUN", "CMD", "ENTRYPOINT" 명령을 사용할 때만 유효합니다.
SHELL ["SHELL 경로", "파라미터"]
SHELL ["/bin/bash", "-c"]
RUN echo "TEST"
위와 같이 "/bin/bash" Shell로 변경되어, "RUN" 명령을 실행합니다.
호스트 상에 존재하는 파일/디렉터리를 Docker Image에 추가할 때 사용합니다.
ADD <호스트의 파일 경로> <Docker Image의 파일 경로>
또는
ADD ["<호스트의 파일 경로>", "<Docker Image의 파일 경로>"]
예를 들어 웹서버 이미지를 만들기 위해 호스트의 "index.php" 파일을 도커 이미지의 "/var/www/html/"안에 추가하려면 아래와 같이 작성합니다.
ADD index.php /var/www/html/
또한, ADD 명령어는 파일/디렉터리를 호스트뿐만 아니라 URL처럼 원격에서 파일을 다운로드 받을 수 있습니다.
호스트 상에 존재하는 파일/디렉터리를 Docker Image에 복사할 때 사용합니다.
COPY <호스트의 파일 경로> <Docker Image의 파일 경로>
또는
COPY ["<호스트의 파일 경로>", "<Docker Image의 파일 경로>"]
COPY index.php /var/www/html/
"COPY" 명령어는 "ADD" 명령어와 비슷하지만, COPY 명령은 ADD처럼 URL이나 원격 파일의 다운로드를 하지 못하고, 순수히 파일 복사기능만 가지고 있습니다.
"VOLUME" 명령은 도커 컨테이너의 파일/디렉토리를 컨테이너에 저장하지 않고 호스트의 "/var/lib/docker/volumes/" 경로에 저장됩니다.
VOLUME <컨테이너 내부의 마운트 경로>
VOLUME /var/log
또한 "VOLUME" 명령을 사용함으로써 여러 개의 인수로 마운트할 수 있습니다.
영구적인 데이터를 컨테이너에 저장하지 않고 컨테이너 외부 스토리지인 호스트에 저장하기에 적합합니다.
root@dongdonge:# ls -la /var/lib/docker/volumes/283cbe5136bf789cc2954ce67a225d99f19bc7046e4ce34a36664c05c3de5435/_data/
total 184
drwxr-xr-x 4 root root 4096 Sep 3 08:44 .
drwxr-xr-x 3 root root 4096 Sep 3 08:44 ..
-rw-r--r-- 1 root root 5088 Dec 29 2018 alternatives.log
drwxrwxrwx 2 www-data www-data 4096 Sep 3 08:44 apache2
drwxr-xr-x 2 root root 4096 Sep 3 08:44 apt
-rw-rw---- 1 root utmp 0 Dec 26 2018 btmp
-rw-r--r-- 1 root root 126921 Dec 29 2018 dpkg.log
-rw-r--r-- 1 root root 3232 Dec 26 2018 faillog
-rw-rw-r-- 1 root utmp 29492 Dec 26 2018 lastlog
-rw-rw-r-- 1 root utmp 0 Dec 26 2018 wtmp