[Docker] 2일차 수업 정리

soyeon·2022년 9월 8일
0
post-thumbnail

Why Docker?

: 복잡한 Linux Application을 여러 container로 통합하여 실행할 수 있다.

: 개발, 테스트, 서비스 환경을 하나로 통합하여 효율적 관리가 가능하기 때문이다. 통합한다는 것은 똑같은 환경에서 개발, 테스트 등을 할 수 있다는 의미이다.

: image(&container)를 전세계 사람들과 공유한다. 공유는 GitHub와 유사한 방식(open share)의 Docker Hub를 제공한다.

: 하드웨어 가상화가 없이 격리된 환경에서 실행되는 프로세스

: "프로세스의 표준화된 격리"

프론트 쪽에 접속하는 사용자 수가 갑자기 늘어난다. 서버가 느려지면 사용자는 사용하지 않는다. 프론트를 설계할 때 고려해야 할 사항(사용자 수 등)을 고려해야 한다.

Container

: Process -> ps -ef로 조회가 된다.
Dockerfile을 통해 image을 개발하고, 개발된 image로 container를 실행한다.

Container vs VM

: container는 VM 가상화보다 훨씬 빠르고 가벼운 경량화 기술이다.(micro VM)
container와 vm 모두 이미지를 사용한다. vm은 virtual box로 이미지를 돌리고, container는 docker로 돌린다.
docker run

: vm에는 guest OS(커널)가 존재한다. -> VM은 독립된 커널로 동작한다. 따라서 무겁다.
container는 OS(Ubuntu)를 깔아놓고 container engine을 올리면 그 위에서 OS가 동작한다. container에는 커널이 없다. host OS(Ubuntu)의 커널을 빌려서 사용한다.

LXC(Linux Container)

LXC를 응용해서 만든 것이 docker이다.

  • LXC의 3대 기술
  1. chroot(change root) - 바로 독립된 container 환경을
    시스템에서 PID=1이 존재하지만 systemd가 아닌 container 자체가 PID=1을 소유한다. -> OS
    -> 별도의 prompt가 존재한다. 독립된 영역(격리된 영역 = fw)을 갖는다.
    fuse(filesystem userspace) package - /data 디렉터리를 mount 시키고 daemon으로 실행시킨다.

  2. cgroups(control group) - 생성된 container에 자원 할당을
    : 컨테이너에 자원 할당하는 커널 기술이다. -> 4대 resource(cpu, memory, disk)
    host가 가진 자원을 무제한을 사용할 수 있기 때문에 제한을 해야 한다.

  3. namespace - container에 IP 등을 배치하여 독립된 가상 환경을
    network ns(IP, MAC, IPC, ...) mount, UID, ... 다양한 기술을 포함할 수 있게 해준다.
    IP나 MAC을 제공하는 것을 sandbox라고 부른다.

image

os부터 application, source가 모두 포함된 하나의 패키징
-> OCI를 통해 묶는다.

  • docker run ~ : 이미지명:태그
    1) image의 snapshot을 생성하고, /var/lib/docker에 저장한다. 이미지 원본을 사용하지 않는다. 하나의 image * N(container)
    2) image(정적) vs container(동적)

접근 과정

: docker run -d -m=100m -p 8001:80 --name=myweb nginx:1.23-alpine
명령어로 컨테이너 생성 후, 접근할 때 과정이다.

Docker engine의 3요소

도커, 컨테이터 빌드업! 28 page 참조

서로 통신을 하고 docker engine은 kernel과 통신한다. 통신은 docker.sock으로 통신한다.

  • dockerd (docker daemon)
    : docker CLI(명령어)를 받아들이고 수행한다.

  • containerd
    : container의 lifecycle을 관리한다.

  • runC
    : container를 생성한다.

=> 이 셋 밑에 HostOS(ubuntu)와 kernel이 존재하고, LXC 기술이 사용된다.

Docker installation

전제조건
: kernel version 3.1 이상, 64bit

kevin@hostos1:~$ uname -ar
Linux hostos1 5.15.0-46-generic #49~20.04.1-Ubuntu SMP Thu Aug 4 19:15:44 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
  • 설치
## 업데이트
# lock 걸리는 경우에는 sudo rm -rf [lock 파일]
kevin@hostos1:~$ sudo apt -y update

## docker 설치를 위한 package
kevin@hostos1:~$ sudo apt -y install \
> apt-transport-https \
> ca-certificates \
> curl \
> software-properties-common

## 공식 GPG key 추가
kevin@hostos1:~$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK

## Docker Release (CE deb)가 있는지 확인한다.
kevin@hostos1:~$ sudo apt-key fingerprint
/etc/apt/trusted.gpg
--------------------
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]

## 데비안 계열의 도커 repository PPA 추가
kevin@hostos1:~$ sudo add-apt-repository \
> "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
> $(lsb_release -cs) \
> stable"

## 추가된 것 확인하기
kevin@hostos1:~$ tail /etc/apt/sources.list

## 업데이트하고, 도커 커뮤니티 에디션 설치
kevin@hostos1:~$ sudo apt -y update
kevin@hostos1:~$ apt-cache policy docker-ce
Installed: (none)
  Candidate: 5:20.10.17~3-0~ubuntu-focal
kevin@hostos1:~$ sudo apt-get -y install docker-ce

## 설치 확인
kevin@hostos1:~$ sudo docker version

## 권한 변경
# 계속 sudo를 치면 귀찮기 때문에 
kevin@hostos1:~$ sudo usermod -aG docker kevin
kevin@hostos1:~$ sudo systemctl daemon-reload
kevin@hostos1:~$ sudo systemctl enable docker
kevin@hostos1:~$ sudo systemctl restart docker
kevin@hostos1:~$ sudo reboot

## sudo 없이 docker version 확인하기
kevin@hostos1:~$ docker version
  • 네트워크
kevin@hostos1:~$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:19:03:07:66  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        
kevin@hostos1:~$ route
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
  • 정보 보기
kevin@hostos1:~$ docker info
# registry에 docker.io가 등록되어 있기 때문에 pull을 할 때 바로 받을 수 있다.

bridge 네트워크는 로컬에서만 통신이 가능하다. hostos1과 hostos2 컨테이너끼리는 통신이 불가능하다. overlay를 별도로 이용해야 host 간의 container 통신이 가능해진다.

실습

  • 개발팀으로부터 요청이 들어왔다. ubuntu18.04 버전에 특정 application을 실행하고자 한다. -> image 생성해 주세요.(서버에 세팅해달라는 뜻)
    1) Dockerfile 생성한다.
    2) ubuntu image download(=pull) -> docker run -> ubuntu container 생성 -> container 진입(docker exec ~) -> PID=1(container 자기 자신) host(ps)로 확인 가능하다.
    3) 직접 필요한 패키지들을 설치한다. (모든 image는 기본적으로 online package 설치가 가능하다) => centos(yum), ubuntu(apt) 이걸 이용할 때는 update를 우선 수행해야 한다.
  1. image download

    이미지에서 tag가 붙는데 버전이다.
    ubuntu:18.04

## image download
kevin@hostos1:~$ docker pull ubuntu:18.04
kevin@hostos1:~$ docker pull ubuntu:14.04
kevin@hostos1:~$ docker pull ubuntu:16.04
16.04: Pulling from library/ubuntu
58690f9b18fc: Pull complete
b51569e7c507: Pull complete
da8ef40b9eca: Pull complete
fb15d46c38dc: Pull complete
Digest: sha256:91bd29a464fdabfcf44e29e1f2a5f213c6dfa750b6290e40dd6998ac79da3c41
Status: Downloaded newer image for ubuntu:16.04
docker.io/library/ubuntu:16.04

이미지는 계층 구조
pull을 받을 때 여러개를 받는 것을 볼 수 있다.
여러 개를 다운로드 받고 하나로 합친다.(Merge)
layer 여러개로 이루어져 있다.

이미지는 수정 불가능
image를 수정하면 새로운 image로 저장 가능하다.
새롭게 image를 생성하는 것이다.(commit)

build time -> line(명령줄) -> Step N = layer N
layer는 Dockerfile의 줄 수와 연관이 되어 있다.

  1. download한 image 확인
kevin@hostos1:~$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
ubuntu       18.04     35b3f4f76a24   33 hours ago    63.1MB
ubuntu       16.04     b6f507652425   12 months ago   135MB
ubuntu       14.04     13b66b487594   17 months ago   197MB

: 용량이 작은 것을 알 수 있다.

  1. image를 컨테이너로 만들기
    : run
## echo
kevin@hostos1:~$ docker run -it ubuntu:18.04 echo 'hello docker!'
hello docker!

## container로 들어가기
kevin@hostos1:~$ docker run -it ubuntu:18.04 bash
root@2004c08eea02:/# pwd
/
root@2004c08eea02:/# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 05:00 pts/0    00:00:00 bash
root          12       1  0 05:00 pts/0    00:00:00 ps -ef

## OS 확인하기
root@2004c08eea02:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.6 LTS (Bionic Beaver)"
...

## ip 확인하기
root@2004c08eea02:/# ifconfig
bash: ifconfig: command not found   ## 컨테이너를 최대한 가볍게 유지하기 위해서 없다.
root@2004c08eea02:/# apt -y update
root@2004c08eea02:/# apt -y install net-tools
root@2004c08eea02:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
...

## 나가기
root@2004c08eea02:/# exit
exit

kevin@hostos1:~$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS                       PORTS     NAMES
2004c08eea02   ubuntu:18.04   "bash"                   8 minutes ago   Exited (130) 5 seconds ago             dreamy_turing
1f146748297a   ubuntu:18.04   "echo 'hello docker!'"   9 minutes ago   Exited (0) 9 minutes ago               stoic_wilson

## 컨테이너 다시 시작하기
kevin@hostos1:~$ docker start 2004c08eea02
2004c08eea02

## up 상태로 바뀐다
kevin@hostos1:~$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                      PORTS     NAMES
2004c08eea02   ubuntu:18.04   "bash"                   11 minutes ago   Up 37 seconds                         dreamy_turing
1f146748297a   ubuntu:18.04   "echo 'hello docker!'"   13 minutes ago   Exited (0) 13 minutes ago             stoic_wilson

## 만들었던 컨테이너에 다시 들어가기
kevin@hostos1:~$ docker exec -it 2004c08eea02 bash
root@2004c08eea02:/#

exit으로 나가면 container를 stop 한 것이다.(ctrl + P + Q)
다시 container 안으로 들어갈 때는 exec를 해야 한다.
run을 하면 새로운 container가 만들어진다.

  1. container 아예 삭제하기
## container 멈추기
kevin@hostos1:~$ docker stop 2004c08eea02
2004c08eea02

## container 삭제하기
kevin@hostos1:~$ docker rm 2004c08eea02
2004c08eea02

## 삭제 되었는지 확인하기
kevin@hostos1:~$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                      PORTS     NAMES
1f146748297a   ubuntu:18.04   "echo 'hello docker!'"   16 minutes ago   Exited (0) 16 minutes ago             stoic_wilson
  1. ping
## 터미널 1
kevin@hostos1:~$ docker run -it ubuntu:18.04 bash
root@cd56c674eda5:/# apt -y update
root@cd56c674eda5:/# apt -y install net-tools
root@cd56c674eda5:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
...
root@cd56c674eda5:/# apt -y install iputils-ping
root@cd56c674eda5:/# ping 192.168.56.1

## 터미널 2
kevin@hostos1:~$ docker run -it centos:7 bash
[root@2efbb769b257 /]# yum -y update
[root@2efbb769b257 /]# yum -y install net-tools
[root@2efbb769b257 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
...
## ping 확인
[root@2efbb769b257 /]# ping 192.168.56.1
[root@2efbb769b257 /]# ping 172.17.0.2

## 터미널 3
kevin@hostos1:~$ docker ps -a
CONTAINER ID   IMAGE          COMMAND   CREATED          STATUS          PORTS     NAMES
2efbb769b257   centos:7       "bash"    5 minutes ago    Up 5 minutes              hungry_blackwell
cd56c674eda5   ubuntu:18.04   "bash"    14 minutes ago   Up 14 minutes             sleepy_wiles
  1. 다른 방법으로 ip 확인하기
kevin@hostos1:~$ docker ps -a
CONTAINER ID   IMAGE          COMMAND   CREATED          STATUS          PORTS     NAMES
2efbb769b257   centos:7       "bash"    5 minutes ago    Up 5 minutes              hungry_blackwell
cd56c674eda5   ubuntu:18.04   "bash"    14 minutes ago   Up 14 minutes             sleepy_wiles

## centos ip 확인하기
kevin@hostos1:~$ docker inspect 2efbb769b257 | grep -i ipaddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.3",
                    "IPAddress": "172.17.0.3",

## ubuntu ip 확인하기
kevin@hostos1:~$ docker inspect cd56c674eda5 | grep -i ipaddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",

이미지 명령을 쓸 때는 docker image ~ 로 사용한다.
컨테이너일 때는 생략해서 쓴다.
ex) docker image inspect ~ , docker inspect ~

hostos1에서 ifconfig 했을 때 container 개수에 따라서 vet(virtual ethernet)가 생긴다.

kevin@hostos1:~$ ifconfig
veth8cd372e: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::94cd:86ff:fe1b:c1d3  prefixlen 64  scopeid 0x20<link>
        ether 96:cd:86:1b:c1:d3  txqueuelen 0  (Ethernet)
        RX packets 4202  bytes 240179 (240.1 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5203  bytes 27178929 (27.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vethd66430f: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::2067:66ff:fefd:8ca4  prefixlen 64  scopeid 0x20<link>
        ether 22:67:66:fd:8c:a4  txqueuelen 0  (Ethernet)
        RX packets 11080  bytes 610046 (610.0 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13182  bytes 80436056 (80.4 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  1. mysql
    docker hub에서 확인하면 password 설정이 필수적인 것을 알 수 있다. 설정해주어야 한다.
    password
## image download
kevin@hostos1:~$ docker pull mysql:5.7-debian

## password 설정하고, 안으로 들어가기
kevin@hostos1:~$ docker run -it -e MYSQL_ROOT_PASSWORD=pass123# mysql:5.7-debian bash
root@85ab3f81b2ea:/#

## os 확인하기
root@85ab3f81b2ea:/# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
...

## daemon 실행하고, 들어가기
root@85ab3f81b2ea:/# /etc/init.d/mysql start
root@85ab3f81b2ea:/# mysql -uroot -p

=> 현재는 NAPT가 없기 때문에 외부접근이 되지 않는다. 따라서 실행할 때 -p 옵션을 넣어주면 외부와 통신할 수 있게 된다.

  1. mariadb
    mariadb:10.2의 DB를 컨테이너로 실행하고, item 이라는 데이터베이스에 workbench로 연결하고자 한다.
    ㄴ MARIADB_ROOT_PASSWORD=pass123#, MARIADB_DATABASE=item
    ㄴ workbench와 붙이기 위해서 -p 옵션이 필요하다. (-p 13306:3306)
## mariadb image download하고, container 생성하기
kevin@hostos1:~$ docker run -d -e MARIADB_ROOT_PASSWORD=pass123# -e MARIADB_DATABASE=item --name=itemdb -p 13306:3306 mariadb:10.2

## container 상태 확인하기
kevin@hostos1:~$ docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                                         NAMES
601d80ef1f75   mariadb:10.2       "docker-entrypoint.s…"   29 seconds ago   Up 26 seconds   0.0.0.0:13306->3306/tcp, :::13306->3306/tcp   itemdb

## 포트 확인하기
kevin@hostos1:~$ sudo netstat -nlp | grep 13306
[sudo] password for kevin:
tcp        0      0 0.0.0.0:13306           0.0.0.0:*               LISTEN      6505/docker-proxy

kevin@hostos1:~$ ps -ef | grep 6505
root        6505     956  0 15:05 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 13306 -container-ip 172.17.0.3 -container-port 3306

## 들어가서 mariadb 실행하기
kevin@hostos1:~$ docker exec -it itemdb bash
root@601d80ef1f75:/# mysql -uroot -p
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| item               |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.01 sec)
  • workbench 연결하기
  1. cAdvisor(container advisor)
## cAdvisor download
kevin@hostos1:~$  docker run \
>--volume=/:/rootfs:ro \
>--volume=/var/run:/var/run:rw \
>--volume=/sys:/sys:ro \
>--volume=/var/lib/docker/:/var/lib/docker:ro \
>--publish=9559:8080 \
>--detach=true \
>--name=cadvisor \
>google/cadvisor:latest

## 포트 확인
kevin@hostos1:~$ sudo netstat -nlp | grep 9559
[sudo] password for kevin:
tcp        0      0 0.0.0.0:9559            0.0.0.0:*               LISTEN      6937/docker-proxy

## 실행되었는지 확인
kevin@hostos1:~$ docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                                         NAMES
5b1d36956841   google/cadvisor:latest   "/usr/bin/cadvisor -…"   20 seconds ago   Up 19 seconds   0.0.0.0:9559->8080/tcp, :::9559->8080/tcp     cadvisor

브라우저에서 192.168.56.101:9559 접속해서 확인한다.

## database 생성하기
MariaDB [(none)]> create database empdb;
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| empdb              |
| information_schema |
| item               |
| mysql              |
| performance_schema |
+--------------------+
5 rows in set (0.00 sec)
MariaDB [(none)]> grant all privileges on empdb.*
    -> to emp_admin@localhost identified by 'docker_4U'
    -> with grant option;
MariaDB [(none)]> grant all privileges on empdb.* to emp_admin@'%' \
    -> identified by 'docker_4U';
MariaDB [(none)]> select user,host from mysql.user;
+-----------+-----------+
| user      | host      |
+-----------+-----------+
| emp_admin | %         |
| root      | %         |
| emp_admin | localhost |
| root      | localhost |
+-----------+-----------+
4 rows in set (0.00 sec)
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> exit;
Bye

## over workload 발생 코드 가져오기
root@601d80ef1f75:/# apt-get update
root@601d80ef1f75:/# apt-get install git -y
root@601d80ef1f75:/# git clone https://github.com/brayanlee/emp_db.git
root@601d80ef1f75:/# cd emp_db/
root@601d80ef1f75:/emp_db# ls
Changelog  employees.sql  employees_partitioned.sql  employees_partitioned_5.1.sql  images  load_departments.dump  load_dept_emp.dump  load_dept_manager.dump  load_employees.dump  sakila
root@601d80ef1f75:/emp_db# mysql -u emp_admin -p empdb
MariaDB [empdb]> status;
MariaDB [empdb]> source employees.sql
MariaDB [empdb]> show tables;
  1. Nginx
    : 웹서버, 웹서비스, proxy -> LB
## nginx download
kevin@hostos1:~$ docker pull nginx:1.23.1-alpine

## 용량 확인
kevin@hostos1:~$ docker images | grep nginx
nginx             1.23.1-alpine   804f9cebfdc5   4 weeks ago     23.5MB

## nginx 시작하기
kevin@hostos1:~$ docker run -d --name=myweb1 -p 8001:80 nginx:1.23.1-alpine
b51bfa64b24ed5f0bc13e0c0e1e8f42e621338361d4a530131db4f6b79798476

## port 열렸는지 확인
kevin@hostos1:~$ sudo netstat -nlp | grep 8001
[sudo] password for kevin:
tcp        0      0 0.0.0.0:8001            0.0.0.0:*               LISTEN      8470/docker-proxy
tcp6       0      0 :::8001                 :::*                    LISTEN      8476/docker-proxy
kevin@hostos1:~$ ps -ef | grep 8470
root        8470     956  0 16:04 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8001 -container-ip 172.17.0.5 -container-port 80
kevin       8596    2592  0 16:05 pts/1    00:00:00 grep --color=auto 8470

## http://192.168.56.101:8001/ 접속해서 확인가능하다.
## kevin@hostos1:~$ docker stats myweb1 로도 cAdvisor 처럼 볼 수 있다.

## 개발팀에게 제공받은 소스파일 옮기기 -> 실질적으로는 소스 파일 수정이다.
## 새로운 html 파일 nginx로 복사하기(scp)
kevin@hostos1:~$ mkdir LABs && cd $_
kevin@hostos1:~/LABs$ mkdir nginx-test && cd $_
kevin@hostos1:~/LABs/nginx-test$ vi index.html
# 새로운 html 적기
kevin@hostos1:~/LABs/nginx-test$ docker cp index.html myweb1:/usr/share/nginx/html/index.html

# nginx.html 파일 위치 찾기
kevin@hostos1:~/LABs/nginx-test$ sudo su -
root@hostos1:~# find / -name nginx.html
/var/lib/docker/overlay2/f9a5fa06b202c447072981a0d638bfa1171311b16ea97868c91969148e644027/diff/usr/share/nginx/html/nginx.html
/var/lib/docker/overlay2/f9a5fa06b202c447072981a0d638bfa1171311b16ea97868c91969148e644027/merged/usr/share/nginx/html/nginx.html

이제, 개발팀으로부터 개발 소스를 제공 받았다.
해당 application을 실행할 수 있는 image를 이용하여 소스와 함께 Dockerfile을 만든다. 그러면 소스 파일을 따로 넣는 작업을 하지 않아도 된다.
build time -> image 생성한다. 이 image로 docker run을 하면 소스파일들이 들어가 있는 container가 생기게 된다.

  1. Dockerfile
## Dockerfile 생성
kevin@hostos1:~/LABs/nginx-test$ vi Dockerfile
FROM nginx:1.23.1-alpine
COPY index2.html /usr/share/nginx/html/index.html
COPY docker_logo.png /usr/share/nginx/html/docker_logo.png
EXPOSE 80/tcp
CMD ["nginx", "-g", "daemon off;"]

## build 하기 - Dockerfile이 다섯줄이니까 5 step이 나온다.
kevin@hostos1:~/LABs/nginx-test$ docker build -t myweb:1.0 .
Sending build context to Docker daemon   29.7kB
Step 1/5 : FROM nginx:1.23.1-alpine
 ---> 804f9cebfdc5
Step 2/5 : COPY index2.html /usr/share/nginx/html/index.html
 ---> 299ea43f547c
Step 3/5 : COPY docker_logo.png /usr/share/nginx/html/docker_logo.png
 ---> 0dd40a123f70
Step 4/5 : EXPOSE 80/tcp
 ---> Running in 5b363f143643
Removing intermediate container 5b363f143643
 ---> ee49879fe1aa
Step 5/5 : CMD ["nginx", "-g", "daemon off;"]
 ---> Running in ddfadd3ce498
Removing intermediate container ddfadd3ce498
 ---> 6e7384c06f2a
Successfully built 6e7384c06f2a
Successfully tagged myweb:1.0

## image 생성되었는지 확인하기
kevin@hostos1:~/LABs/nginx-test$ docker images | grep myweb
myweb             1.0             6e7384c06f2a   35 seconds ago   23.6MB

## container 생성하기
kevin@hostos1:~/LABs/nginx-test$ docker run -d -p 8002:80 --name=myweb2 myweb:1.0

## 접속되는지 확인하기
kevin@hostos1:~/LABs/nginx-test$ curl localhost:8002

## index2.html 수정하기
kevin@hostos1:~/LABs/nginx-test$ vi index2.html
kevin@hostos1:~/LABs/nginx-test$ docker cp index2.html myweb2:/usr/share/nginx/html/index.html
  1. 개발팀으로부터 개발 완료된 소스를 제공받는다. 이 소스를 포함하는 nginx 기반의 myweb:2.0 build 하시오. 반드시 image build 후 생성된 image로 container 실행 테스트를 수행해야 한다. -> image validation check
    그 후, public or private registry에 해당 image를 팀에 공유하는 것이다.
kevin@hostos1:~/LABs/nginx-test$ cd
kevin@hostos1:~$ cd LABs/
kevin@hostos1:~/LABs$ mkdir stylish-portfolio && cd $_
# 소스 옮기기
kevin@hostos1:~/LABs/stylish-portfolio$ vi index.html

## Dockerfile 만들기
kevin@hostos1:~/LABs/stylish-portfolio$ vi Dockerfile
FROM nginx:1.23.1-alpine
RUN mkdir -p /usr/share/nginx/html/assets
RUN mkdir -p /usr/share/nginx/html/css
RUN mkdir -p /usr/share/nginx/html/js
COPY assets /usr/share/nginx/html/assets
COPY css /usr/share/nginx/html/css
COPY js /usr/share/nginx/html/js
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80/tcp
CMD ["nginx", "-g", "daemon off;"]

## build 하기
kevin@hostos1:~/LABs/stylish-portfolio$ docker build -t myweb:2.0 .

## container 생성하기
kevin@hostos1:~/LABs/stylish-portfolio$ docker run -d -p 8003:80 --name=myweb3 myweb:2.0

## 접속되는지 확인하기
kevin@hostos1:~/LABs/stylish-portfolio$ curl localhost:8003

container best practice
1. 경량 컨테이너를 위한 image 선택은 tag에 slim, alpine이 있는 것을 권장한다.

bionic - ubuntu 18.04
focal - ubuntu 20.04

0개의 댓글