OCI(OPen Container Initiative)
CRI(Container Runtime Interface)
일반 리눅스에서의 namespace httpd:ftp:nfs
도커(컨테이너)에서의 namespace 컨테이너(1111):컨테이너(1112):컨테이너(1113)
k8s에서의 namespace 각 사용자별로 별도의 작업 공간을 제공
쿠버네티스: 컨테이너 '오케스트레이션' 툴. 일반적으로 오케스트레이션은 컨테이너 '클러스터' 환경에서 이루어지게 된다.
애플리케이션은 '배포'한다.
시스템(서버, 네트워크, 볼륨)은 '프로비저닝' 한다.
배포와 프로비전은 일반적으로 여러 컨테이너, 서버, 네트워크, 볼륨 등을 연계하여 구성해야 하는 복잡한 과정이다. 하나의 작업을 수동으로 한 뒤 이를 묶는 작업은 복잡하므로 'IaC(Infrastructure as Code, 코드형 인프라)'를 도입하여 yml과 같은 파일 형태로 작성한 뒤 이를 활용하여 환경을 구성하는 형식으로 변화하고 있다.
docker-compose.yml: 컨테이너 환경
cloudformation: aws 에서 서버 인프라 환경
heat: openstack 에서 서버 인프라 환경
terraform
docker 컨테이너의 일반적인 라이프사이클
출처: https://medium.com/better-programming/docker-for-front-end-developers-c758a44e622f
컨테이너의 모든 통신은 shim을 통해 이루어지게 되고 해당 내용은 shim에서 containerd와 통신을 통해 관리된다. shim은 컨테이너의 입출력, 로그를 d에게 전달한다.
rapa@rapa:~$ pstree -p | grep containerd
|-containerd(835)-+-{containerd}(872)
| |-{containerd}(873)
| |-{containerd}(874)
| |-{containerd}(877)
| |-{containerd}(878)
| |-{containerd}(930)
| |-{containerd}(931)
| `-{containerd}(983)
|-containerd-shim(1465)-+-mysqld(1520)-+-{mysqld}(1657)
| |-{containerd-shim}(1467)
| |-{containerd-shim}(1468)
| |-{containerd-shim}(1469)
| |-{containerd-shim}(1472)
| |-{containerd-shim}(1473)
| |-{containerd-shim}(1474)
| |-{containerd-shim}(1476)
| |-{containerd-shim}(1480)
| |-{containerd-shim}(1481)
| |-{containerd-shim}(1857)
| `-{containerd-shim}(2586)
|-containerd-shim(1896)-+-mysqld(1929)-+-{mysqld}(2087)
| |-{containerd-shim}(1897)
| |-{containerd-shim}(1898)
| |-{containerd-shim}(1899)
| |-{containerd-shim}(1900)
| |-{containerd-shim}(1901)
| |-{containerd-shim}(1902)
| |-{containerd-shim}(1903)
| |-{containerd-shim}(1904)
| |-{containerd-shim}(1905)
| |-{containerd-shim}(1906)
| `-{containerd-shim}(49446)
|-containerd-shim(2702)-+-apache2(2722)-+-apache2(2801)
| |-{containerd-shim}(2703)
| |-{containerd-shim}(2704)
| |-{containerd-shim}(2705)
| |-{containerd-shim}(2706)
| |-{containerd-shim}(2707)
| |-{containerd-shim}(2708)
| |-{containerd-shim}(2709)
| |-{containerd-shim}(2710)
| |-{containerd-shim}(2711)
| |-{containerd-shim}(2742)
| `-{containerd-shim}(3681)
rapa@rapa:~$ pstree -p | grep dockerd
|-dockerd(982)-+-docker-proxy(1406)-+-{docker-proxy}(1415)
| |-{dockerd}(1011)
| |-{dockerd}(1013)
| |-{dockerd}(1014)
| |-{dockerd}(1016)
| |-{dockerd}(1047)
| |-{dockerd}(1079)
| |-{dockerd}(1085)
| |-{dockerd}(1443)
| |-{dockerd}(1445)
| `-{dockerd}(2187)
컨테이너는 이미지로부터 배포된다. 이미지는 iso 파일과 같이 정적인 파일이다. 따라서 추가 작성된 내용은 기본적으로 저장되지 않는다. 이를 해결하기 위해서는 별도의 볼륨을 사용해야 한다.
/root/test:/var/www/html
testvolume:/root
/root는 /dev/sda3과 같이 특정 파티션이 된다.
docker container exec [ctname] [command]
--link dbctn:mysql
rapa@rapa:~$ docker container ls --all -q
ded23beec1eaf
ee334749beb7
1c8382045175
rapa@rapa:~$ docker container rm -f $(docker container ls --all -q)
ed23beec1eaf
ee334749beb7
1c8382045175
rapa@rapa:~$ docker container ls --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
rapa@rapa:~$ docker container run -it \
> --name centos1 \
> --hostname test \
> centos:7 \
> /bin/bash
[root@test /]# hostname
test
[root@test /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 test
# 호스트(우분투)의 커널을 사용 중
[root@test /]# uname -a
Linux test 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
# ctrl + p, q 눌러서 호스트(우분투)로 빠져나오기
[root@test /]# rapa@rapa:~$
# centos1 컨테이너가 종료되지 않고 실행 중임
rapa@rapa:~$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
abbbbef3ef3d centos:7 "/bin/bash" About a minute ago Up About a minute centos1
rapa@rapa:~$ docker volume ls -q
1931215e79c48a93df85bb4312dc400850b5f8236e875d39397cb7d4dbeb7b92
cea6d051284adc616cb33f95fc5bcdeb82a7956266c7ffd40bb3bd8e9467e771
e382fc7aeafdf4e741bdd92673f0c2347ae5a7d028fd1ff0de036bb8eaed3427
f1fe96aab7edffd26795998469821081c242ec858bfc33b51c6a89cc6bf35354
rapa@rapa:~$ docker volume rm $(docker volume ls -q)
1931215e79c48a93df85bb4312dc400850b5f8236e875d39397cb7d4dbeb7b92
cea6d051284adc616cb33f95fc5bcdeb82a7956266c7ffd40bb3bd8e9467e771
e382fc7aeafdf4e741bdd92673f0c2347ae5a7d028fd1ff0de036bb8eaed3427
f1fe96aab7edffd26795998469821081c242ec858bfc33b51c6a89cc6bf35354
rapa@rapa:~$ docker volume create testvol1
testvol1
rapa@rapa:~$ docker container run -it \
> --name centos01 \
> -v testvol1:/root \
> centos:7 /bin/bash
[root@0a7fa257afd2 /]# df -h | grep /root
/dev/sda5 20G 10G 8.1G 56% /root
[root@0a7fa257afd2 /]#
20GB 중에서 10GB 사용 중
20GB는 호스트(우분투)의 전체 저장공간이다. 이 저장 공간은 flexible하다.
만약 볼륨의 크기를 지정하여 사용하고 싶다면 외부 플러그인을 활용해야 한다.
[root@0a7fa257afd2 /]# touch /root/test.txt
[root@0a7fa257afd2 /]# ls /root
anaconda-ks.cfg test.txt
[root@0a7fa257afd2 /]# exit
exit
rapa@rapa:~$ docker container ls --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a7fa257afd2 centos:7 "/bin/bash" 4 minutes ago Exited (0) 16 seconds ago centos01
rapa@rapa:~$ docker volume ls
DRIVER VOLUME NAME
local testvol1
rapa@rapa:~$ docker container rm centos01
centos01
rapa@rapa:~$ docker volume ls
DRIVER VOLUME NAME
local testvol1
rapa@rapa:~$ docker container run -it \
> --name centos02 \
> -v testvol1:/root \
> centos:7 /bin/bash
[root@6d9132fb36fc /]# ls /root
anaconda-ks.cfg test.txt
[root@6d9132fb36fc /]# df -h | grep root
/dev/sda5 20G 10G 8.1G 56% /root
rapa@rapa:~$ docker container inspect centos02
"Labels": {
"org.label-schema.build-date": "20201113",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS",
"org.opencontainers.image.created": "2020-11-13 00:00:00+00:00",
"org.opencontainers.image.licenses": "GPL-2.0-only",
"org.opencontainers.image.title": "CentOS Base Image",
"org.opencontainers.image.vendor": "CentOS"
}
rapa@rapa:~$ docker container run -it \
> --name centos03 \
> --label color=blue \
> centos:7 /bin/bash
[root@c5fd36fc4cb0 /]#
rapa@rapa:~$ docker container inspect centos03
...
"Config": {
...
"Labels": {
"color": "blue",
"org.label-schema.build-date": "20201113",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS",
"org.opencontainers.image.created": "2020-11-13 00:00:00+00:00",
"org.opencontainers.image.licenses": "GPL-2.0-only",
"org.opencontainers.image.title": "CentOS Base Image",
"org.opencontainers.image.vendor": "CentOS"
}
},
...
rapa@rapa:~$ docker container inspect centos03 -f "{{.Config.Labels.color}}"
blue
rapa@rapa:~$ docker container inspect centos03 -f "{{.NetworkSettings.IPAddress}}"
172.17.0.3
rapa@rapa:~$ ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:8aff:fe84:b19b prefixlen 64 scopeid 0x20<link>
ether 02:42:8a:84:b1:9b txqueuelen 0 (Ethernet)
RX packets 1549 bytes 3350197 (3.3 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1453 bytes 1890942 (1.8 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0는 도커가 설치되면 자동으로 생성되는 네트워크 브릿지이며 NAT를 통해 컨테이너를 외부와 연결시켜준다.
rapa@rapa:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
060582ca6c67 bridge bridge local
3ead376f089f host host local
39430d1f4412 none null local
swarm과 같은 클러스터 환경에서는 'overlay' 드라이버가 생성된다. 이는 kvm과 같은 환경에서 터널을 구성했던 작업이 생략된다.
워드프레스 구축하기
rapa@rapa:~$ docker container run -d \
> --name wpdb \
> -v wpdbvol:/var/lib/mysql \
> --restart=always \
> -e MSYQL_ROOT_PASSWORD=test123 \
> -e MYSQL_DATABASE=wordpress \
> mysql:5.7
9873794e595e7191cab4d272ede90eafeaf2441df0a5064b6e46fe712676b24a
rapa@rapa:~$ docker container run -d \
> --restart=always \
> -p 8080:80 \
> --name wp \
> -e WORDPRESS_DB_PASSWORD=test123 \
> -e WORDPRESS_DB_NAME=wordpress \
> -e WORDPRESS_DB_USER=root \
> --link wpdb:mysql \
> -v wpvol:/var/www/html \
> wordpress
43c48c907ef964a08322120e7bf597cb8c407942605384e71b08a800f3253b3c
--link wpdb:mysql
mysql 컨테이너(wpdb)와 링크 설정
윈도우에서 211.183.3.137:8080 접속
-> 워드프레스가 성공적으로 배포되었다.
rapa@rapa:~$ sudo ls /var/lib/docker
buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
rapa@rapa:~$ sudo ls /var/lib/docker/containers
43c48c907ef964a08322120e7bf597cb8c407942605384e71b08a800f3253b3c 9873794e595e7191cab4d272ede90eafeaf2441df0a5064b6e46fe712676b24a
6d9132fb36fcd968036777f6f575153b29648b1790be4b5fad9f1be440b1afe4 c5fd36fc4cb0f5b38f43da7a0fec86ee5d9bfd9a459da3ce34b813f1f607e826
rapa@rapa:~$ sudo ls /var/lib/docker/volumes
backingFsBlockDev metadata.db testvol1 wpdbvol wpvol
rapa@rapa:~$ docker container run -d \
> -v /:/rootfs:ro \
> -v /var/run:/var/run:rw \
> -v /sys:/sys:ro \
> -v /var/lib/docker/:/var/lib/docker:ro \
> -p 9559:8080 \
> --name cadvisor \
> google/cadvisor:latest
Unable to find image 'google/cadvisor:latest' locally
latest: Pulling from google/cadvisor
ff3a5c916c92: Pull complete
44a45bb65cdf: Pull complete
0bbe1a2fe2a6: Pull complete
Digest: sha256:815386ebbe9a3490f38785ab11bda34ec8dacf4634af77b8912832d4f85dca04
Status: Downloaded newer image for google/cadvisor:latest
14399e870de93f7d51820b616ea68a79e842a0cf91fc4369dce263fa156660c6
컨테이너나 서비스를 직접 만드는 도구는 아니다. 컨테이너, 네트워크, 볼륨 등을 관리(오케스트레이션)하는 도구이다. 실제 컨테이너를 만드는 역할은 runtime이 수행하게 된다. 이 runtime으로 docker(containerd), cri-o, podman, rocket 등을 사용할 수 있고, 쿠버네티스는 모든 런타임과 통신이 가능하다. 이로 인해 사실상 컨테이너 오케스트레이션의 표준으로 불린다.
볼륨의 경우 도커에서는 현재 로컬에 있는 볼륨을 사용하고 있다. 클라우드 환경에서는 외부에 있는 별도의 스토리지의 볼륨을 마운트하여 사용해야 영구적으로 볼륨을 사용할 수 있다. 이러한 볼륨을 영구 볼륨(Persistent Volume)이라 부른다.
개발자가 요청하는 볼륨을 IP정보나 마운트 타입에 관계 없이 조건만 부합한다면 자동으로 마운트 될 수 있는 방법을 제공해야 한다. 이를 Kubernetes에서는 PVC(Persistent Volume Claim)라고 한다.
개발자(PVC) ---> 스토리지(PV)
필요할 때마다 그때 그때 볼륨을 제공하는 방법은 storage class라는 방법을 사용하면 편리하다.
rapa@rapa:~$ docker network prune
WARNING! This will remove all custom networks not used by at least one container.
Are you sure you want to continue? [y/N] y
rapa@rapa:~$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
rapa@rapa:~$ docker system prune
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
rapa@rapa:~/0818$ vi Dockerfile
FROM centos:7
rapa@rapa:~/0818$ docker build -t test:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/1 : FROM centos:7
---> eeb6ee3f44bd
Successfully built eeb6ee3f44bd
Successfully tagged test:1.0
-> 두 파일의 id는 같다
rapa@rapa:~/0818$ docker image inspect test:1.0
"RepoTags": [
"centos:7",
"test:1.0"
],
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Entrypoint": null,
[쉘 형식]
FROM centos:7
RUN yum -y update
RUN yum -y install httpd
[exec 형식]
RUN ["echo", "이것은 테스트입니다"]
-> 리스트 형식으로 작성
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"nginx\" \"-g\" \"daemon off;\"]"
],
CMD nginx -g 'daemon off;'
또는
CMD ["nginx", "-g", "Daemon off;"]
ex) httpd
"Cmd": [
"httpd-foreground"
],
ENTRYPOINT nginx -g 'daemon off,'
CMD와 ENTRYPOINT
ex) test:1.0
FROM ubuntu
ENTRYPOINT ["top"]
CMD ["-d", "10"]
-> top: cpu 확인
-> -d 10: 10초마다 갱신
docker container run -it test:1.0 -d 2
CMD와 ENTRYPOINT에서 실행하는 명령어가 docker container run에서 실행하는 옵션과 동일한 경우 ENTRYPOINT 모두 처리한다. 하지만 CMD는 동일 옵션이 있는 경우 docker container run에 있는 옵션만들 처리한다. ENTRYPOINT는 고정적으로 실행할 명령을 작성하고 CMD는 변경될 가능성이 있는 매개변수, 옵션 등에 대하여 지정할 떄 주로 사용한다.
추가적으로 만약 컨테이너로 배포될 때 실행해야할 명령어가 ENTRYPOINT, CMD 두 개로 너무 부족한 경우에는 shell 파일을 만들고 CMD나 ENTRYPOINT를 이용하여 해당 쉘을 실행하도록 설정한다.
호스트 환경의 파일, 디렉토리를 이미지 안에 복사하는 경우 작성한다.
FROM centos:7
RUN yum -y install httpd
COPY index.html /var/www/html
"COPY"를 포함한다. URL에 있는 파일을 붙여넣기 하는 것도 가능하다. 또한 패키지, 압축파일의 경우에는 이를 해제하여 내용물만 붙여넣기 할 수 있다.
단, URL 상의 tar 파일 등은 해제되지 않은 상태에서 붙여넣기 된다.
이미지에 볼륨을 할당하고자 할 때 사용한다.
VOLUME /var/log
또는
VOLUME ["/var/log"]
마치 방화벽에서 몇 번 포트를 열어놓을지 지정하는 것
FROM centos:7
RUN yum -y install httpd
EXPOSE 80
EXPOSE 8080
ONBUILD는 이를 이용하여 베이스 이미지를 만들 때에는 필요하지 않지만 생성된 이미지를 베이스 이미지로 활용할 경우에는 사용되는 명령
컨테이너 내에서 작업할 경로 설정
WORKDIR /var/www
WORKDIR /root
USER는 작업 사용자 지정하기
컨테이너가 아니라 이미지에서 사용하는 변수 지정
웹 개발 팀장이 팀원들 중에 /blog를 만드는 팀에게 아래와 같이 지시했다.
www.test.com/blog
www.test.com/shop
www.test.con/news
"제가 index.html 파일을 만들테니까 blog 팀은 개발된 파일, 디렉토리를 blog.tar로 만들어서 빌드하세요."
rapa@rapa:~/0818$ touch index.html
rapa@rapa:~/0818$ echo "<h2>TEAM MANAGER<h2>" > index.html
rapa@rapa:~/0818$ tree
.
└── index.html
vi Dockerfile
FROM centos:7
RUN yum -y install httpd
EXPOSE 80
ADD index.html /var/www/html/index.html
ONBUILD ADD blog.tar /var/www/html/
CMD httpd -D FOREGROUND
rapa@rapa:~/0818$ tree
.
├── Dockerfile
└── index.html
rapa@rapa:~/0818$ docker build -t webbase:1.0 .
Sending build context to Docker daemon 3.072kB
Step 1/6 : FROM centos:7
---> eeb6ee3f44bd
Step 2/6 : RUN yum -y install httpd
---> Running in 6c92adea75f6
Removing intermediate container 6c92adea75f6
---> 0e364cb2ed15
Step 3/6 : EXPOSE 80
---> Running in 58e07310ee70
Removing intermediate container 58e07310ee70
---> f2123cc62fbc
Step 4/6 : ADD index.html /var/www/html/index.html
---> c1d6967b052b
Step 5/6 : ONBUILD ADD blog.tar /var/www/html/
---> Running in 549e6a754e1e
Removing intermediate container 549e6a754e1e
---> 15b4d7b4dd27
Step 6/6 : CMD httpd -D FOREGROUND
---> Running in 710a94b707bb
Removing intermediate container 710a94b707bb
---> 56a51820953a
Successfully built 56a51820953a
Successfully tagged webbase:1.0
rapa@rapa:~/0818$ mkdir blogdev
rapa@rapa:~/0818$ cd blogdev/
rapa@rapa:~/0818/blogdev$ mkdir blog
rapa@rapa:~/0818/blogdev$ cd blog/
rapa@rapa:~/0818/blogdev/blog$ touch blog.html
rapa@rapa:~/0818/blogdev/blog$ echo "<h2>BLOG TEAM MEMBER<h2>" > blog.html
rapa@rapa:~/0818$ tree
.
├── blogdev
│ └── blog
│ └── blog.html
├── Dockerfile
└── index.html
rapa@rapa:~/0818/blogdev/blog$ cd ..
rapa@rapa:~/0818/blogdev$ ls
blog
rapa@rapa:~/0818/blogdev$ tar cf blog.tar blog/*
rapa@rapa:~/0818/blogdev$ ls
blog blog.tar
rapa@rapa:~/0818$ tree
.
├── blogdev
│ ├── blog
│ │ └── blog.html
│ └── blog.tar
├── Dockerfile
└── index.html
rapa@rapa:~/0818/blogdev$ touch Dockerfile
rapa@rapa:~/0818/blogdev$ vi Dockerfile
FROM webbase:1.0
rapa@rapa:~/0818$ tree
.
├── blogdev
│ ├── blog
│ │ └── blog.html
│ ├── blog.tar
│ └── Dockerfile
├── Dockerfile
└── index.html
rapa@rapa:~/0818/blogdev$ docker build -t webbase:blog .
Sending build context to Docker daemon 14.34kB
Step 1/1 : FROM webbase:1.0
# Executing 1 build trigger
---> c69cbc539f19
Successfully built c69cbc539f19
Successfully tagged webbase:blog
rapa@rapa:~/0818/blogdev$ docker container run -d \
> -p 8888:80 \
> webbase:blog
e137d3dd8db85d35c4414a5c686f0579020f492f38dd9631429923abbe027109
211.183.3.137:8888 접속 -> 팀장 페이지가 보임
211.183.3.137:8888/blog/blog.html -> 블로그 팀원 페이지가 보임
"ONBUILD"가 작성된 파일을 베이스 이미지로 하는 별도의 Dockerfile에서 동작하는 옵션이다.
ubuntu 18.04 이미지를 베이스이미지로 하여 nginx를 설치하고 해당 nginx에서는 개발자가 작성한 index.html 파일이 보이도록 설정한다.
외부에서 접속 시 해당 컨테이너의 웹페이지가 보여야 하며 포트번호는 8881을 이용하여 접속할 수 있어야 한다.
단, 위의 실습 전 각 ubuntu의 ip 주소는 192.168.1.116으로 설정해야 한다.
VMnet0으로 변경하기
rapa@rapa:~$ sudo vi /etc/netplan/01-network-manager-all.yaml
# Let NetworkManager manage all devices on this system
network:
ethernets:
ens32:
addresses: [192.168.1.116/24]
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 168.126.63.1]
dhcp4: no
version: 2
# renderer: NetworkManager
rapa@rapa:~$ sudo netplan apply
rapa@rapa:~$ ifconfig ens32
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.116 netmask 255.255.255.0 broadcast 192.168.1.255
ether 00:0c:29:16:8d:3f txqueuelen 1000 (Ethernet)
RX packets 384329 bytes 468567019 (468.5 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 234807 bytes 207681523 (207.6 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
rapa@rapa:~$ ping www.google.com -c 3
PING www.google.com (172.217.174.100) 56(84) bytes of data.
64 bytes from nrt12s28-in-f4.1e100.net (172.217.174.100): icmp_seq=1 ttl=111 time=32.9 ms
64 bytes from nrt12s28-in-f4.1e100.net (172.217.174.100): icmp_seq=2 ttl=111 time=31.7 ms
64 bytes from nrt12s28-in-f4.1e100.net (172.217.174.100): icmp_seq=3 ttl=111 time=32.4 ms
--- www.google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 31.718/32.312/32.866/0.469 ms
웹서비스를 위한 컨터이너의 기본 홈 디렉토리
base image home dir
centos/ubuntu /var/www/html
httpd /usr/local/apache2/htdocs
nginx /usr/share/nginx/html
rapa@rapa:~/0818$ vi Dockerfile
FROM ubuntu:18.04
RUN apt-get update
RUN apt-get -y install nginx
EXPOSE 8881
ADD index.html /var/www/html/index.html
CMD nginx -g 'daemon off;'
rapa@rapa:~/0818$ docker build -t ubuntunginx:1.0 .
Sending build context to Docker daemon 16.9kB
Step 1/6 : FROM ubuntu:18.04
---> 8d5df41c547b
Step 2/6 : RUN apt-get update
---> Using cache
---> ed639c80424a
Step 3/6 : RUN apt-get -y install nginx
---> Using cache
---> 0270c5c781db
Step 4/6 : EXPOSE 8881
---> Using cache
---> b94b24a98072
Step 5/6 : ADD index.html /var/www/html/index.html
---> Using cache
---> f9cb1a97131c
Step 6/6 : CMD nginx -g 'daemon off;'
---> Running in 3648d6ac7956
Removing intermediate container 3648d6ac7956
---> b26e017b5678
Successfully built b26e017b5678
Successfully tagged ubuntunginx:1.0
rapa@rapa:~/0818$ docker container run -d \
> --name ubuntunginx \
> -p 8881:80 \
> --restart=always \
> ubuntunginx:1.0
192.168.1.116:8881 접속
다음의 조건을 활용하여 배포된 컨테이너는 접속 즉시 설치 페이지에서 설치 후 게시판을 사용할 수 있어야 한다.
참고: https://missio1227.tistory.com/26
이미지 컨테이너
centos:7을 base로 하여 xe:1.0 이미지를 만들어야 함 xe 컨테이너(xe01)
mysql 5.7 db 컨테이너(db01)
xe01 --(link)-- db01
(80) (3306)
|
8888
rapa@rapa:~/0818$ docker container run -d \
> --name db01 \
> --restart=always \
> -e MYSQL_ROOT_PASSWORD=test123 \
> -e MYSQL_DATABASE=xeDB \
> mysql:5.7
df637eb6cbd5098412fac809002f98aa4cd4ff0a78aa9d5d758a188d6801a0e0
rapa@rapa:~/0818$ vi Dockerfile
FROM centos:7
EXPOSE 80
RUN yum -y install wget
RUN yum -y install unzip
RUN wget http://download.xpressengine.com/download/18325662/22756225
RUN unzip 22756225
RUN mv ./xe/* /var/www/html/
RUN chmod 777 /var/www/html/*
RUN mkdir /var/www/html/files
RUN chmod 707 /var/www/html/files
CMD httpd -D FOREGROUND
rapa@rapa:~/0818$ docker build -t xe01:1.0 .
rapa@rapa:~/0818$ docker container run -it -d \
--name xe01 \
--link db01:mysql \
-p 8888:80 \
xe01:1.0
db 호스트네임: dbcontainer의 이름 (wpdb)
docker container attach: 컨테이너로 직접 들어간다(-it 옵션을 주고 생성된 컨테이너)
docker container exec: 컨테이너로 직접 들어가지 않고 외부에서 컨테이너로 명령을 전달하고 결과값을 밖에서 전달받는다.
docker container start: 중지된 컨테이너를 실행
docker container run(docker run) -> 컨테이너 생성 + 실행
1) 이미지를 로컬 저장소에서 찾는다. 없다면 기본적으로 도커 허브로 접속하여 검색한다.
2) pull된 이미지를 이용하여 컨테이너 생성하고 실행시킨다. 실행 시 문제가 있다면 exit 상태가 된다.
-it: it 옵션은 일반적으로 함꼐 실행한다. 생성된 컨테이너와 직접 통신이 된다.
ex) centos:7 /bin/bash 또는 centos:7 /bin/sh를 주로 사용한다.
-d: 컨테이너를 백그라운드에서 실행시킨다.
--name: 관리를 위한 목적으로 사용한다. 컨테이너 생성되면 각 컨테이너 별로 id, name이 할당된다. 하지만 별도로 관리의 편의를 위해 이름을 직접 지정할 수 있다. 다수의 컨테이너를 관리할 때에는 별도의 이름을 입력하는 것이 불필요한 작업이 될 것이다. 이 때에는 작성하지 않는다.
--restart: 처음 생성 시, 호스트 재부팅 시 컨테이너를 어떻게 실행할 것인가? 웹서버나 DB와 같이 상시 동작해야하는 컨테어너의 경우에는 초기 생성 시 --restart==always로 하여 실행에 문제가 있더라도 계속해서 실행을 시도하도록 설정해주는 것이 좋다.
-e(--env): 시스템 환경 변수를 견테이너에 작성한다.
ex) -e MYSQL_DATABASE=testdb
ex) -e PYTHON=/usr/lib/python2
ex) -e PY3=/usr/lib/python3.4
-v(--volume): 볼륨 지정. 절대 경로를 쓴다면 nfs 방식으로, 상대 경로를 쓴다면 볼륨 방식으로 마운트함.
docker container run -d \
--name db1 \
-v /testvolume1:/var/lib/mysql mysql:5.7
-> nfs 마운트
docker container run -d \
--name db1 \
-v testvolume1:/var/lib/mysql:ro mysql:5.7
-> 볼륨 마운트
:ro 옵션: read only
-p: 호스트의 포트와 매핑하기
ex) -p 80:80 httpd01
--link
mysql 배포 (wpdb1)
rapa@rapa:~/0818/board$ docker container run -d \
> --name wpdb1 \
> -e MYSQL_ROOT_PASSWORD=test123 \
> -e MYSQL_DATABASE=wordpress \
> -v wpdb1:/var/lib/mysql \
> mysql:5.7
7b5b7df898e438d56dd62c788dd7a3d76370fa538e30903c1a4011b47fd8e1cd
rapa@rapa:~/0818/board$ docker container run -d \
> --name wp1 \
> -e WORDPRESS_DB_PASSWORD=test123 \
> -e WORDPRESS_DB_USER=root \
> -e WORDPRESS_DB_NAME=wordpress \
> -p 8001:80 \
> --link wpdb1:db1 \
> wordpress
0332b2486fc0d5281f312cdd4775975ad5c63e939c58d54cd106a78c30470f8d
--link wpdb1:db1을 통해 mysql 컨테이너와 연결함
rapa@rapa:~/0818/board$ docker container exec wp1 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 db1 7b5b7df898e4 wpdb1
172.17.0.2 0332b2486fc0
172.17.0.3 db1 7b5b7df898e4 wpdb1 <--- link된 컨테이너의 ID, 이름, alias명을 IP주소와 함께 등록
172.17.0.2 0332b2486fc0 <--- 자신의 ID와 IP 주소를 등록
docker build -t myimg:1.0 -f dockerfile1
일반적으로는 두 개 이상의 이미지를 생성하고자 한다면 별도의 디렉토리를 만들고 각 디렉토리에서 별도의 Dockerfile을 생성하는 형식으로 이미지를 만들게 된다.
FROM: Dockerfile의 제일 상단에는 무조건 FROM을 위치시킨다. base image를 지정하는 것이다.
MAINTAINER: 작성자 정보를 간략히 입력해 둔다. 최근에는 잘 사용하지 않고, 대신 LABEL을 쓴다.
LABEL:
LABEL author=goyangyee
LABEL email=goyangyee@test.com
LABEL version=1.0
LABEL desc="I love cats"
RUN: 컨테이너가 아닌 베이스 이미지 자체에 전달하는 명령어. RUN은 여러 번 사용 가능하다. 가장 많이 사용하는 명령이다.
FROM centos:7
RUN yum -y install vim # 베이스 이미지 centos:7에게 vim을 설치한다.
CMD: 컨테이너가 배포될 때 실행할 명령어. 가령, web서버 컨테이너를 실행시키고 싶다면 RUN으로 베이스 이미지에 웹서버를 설치하고 컨테이너가 실행될 때 웹서버 데몬이 동작해야 하므로 CMD를 이용하여 데몬 실행 명령을 전달한다.
ENTRYPOINT: 컨테이너가 배포될 떄 실행할 명령어.
CMD vs ENTRYPOINT: 한 번만 사용 가능하다.
FROM centos:7
ENTRYPOINT top # 무조건 실행
CMD -d 10 # docker run과 겹치는 옵션이면 무시됨
위의 구성을 통해 컨테이너가 배포된다면 각 컨테이너는 컨테이너의 CPU 정보를 10초 마다 한 번 씩 갱신하여 보여준다.
docker container run -d \
-d 2 # 2초 마다 갱신한다.
CMD는 이미지 내에 있는 정보와 docker container run에서 작성한 정보가 동일한 옵션인 경우 이미지 내에 있는 옵션은 무시된다.
만약 컨테이너로 실핼될 때 컨테이너가 동작시켜야 할 데몬이 많고 해야할 일이 많다면? shell 파일을 만들고 CMD나 ENTRYPOINT를 이용하여 해당 쉘을 실행하도록 설정한다.
ADD a.sh /root/a.sh
CMD bash a.sh
또는
ADD a.sh /root/a.sh
CMD ["/bin/bash", "/root/a.sh"]
COPY: 호스트에 있는 파일 또는 디렉토리를 이미지에 붙여넣기 한다.
ADD: COPY의 모든 기능을 포함하고 추가적으로 URL을 통해 파일을 붙여넣기 하는 것 가능하다.
ADD http://www.test.com/main.jsp /var/www/html/index.jsp
또한
ADD website.tar.gz /var/www/html
디렉토리를 패키지로 묶은(tar) 후 압축(gz)
ENV: 시스템 환경 변수 선언
EXPOSE: 포트 오픈. 마치 방화벽으로 포트를 여는 것과 같은 효과가 있다.
EXPOSE 80 8080
VOLUME: docker container run -v와 동일하다.
VOLUME /var/log # 컨테이너의 /var/log를 호스트에 있는 볼륨과 연결해 준다.
만약 볼륨 이름을 지정한다면?
VOLUME testvol1:/var/log
ctn1이 testvol1과 연결
ctn2도 testvol1과 연결
좋은 방법이 아니기 때문에 쓰지 말 것!
만약 컨테이너의 여러 디렉토리를 볼륨과 연결하고 싶다면?
VOLUME /var/log /var/www/html /var/lib/mysql
WORKDIR: 작업 경로 지정
WORKDIR /var/www
...
WORKDIR /var/www/html
...
해당 디렉토리에서 작업이 수행됨
RUN cd [디렉토리] 명령어를 사용한다면 바로 root 경로로 돌아와버리기 때문에 해당 디렉토리에서 작업이 수행될 수 없다.
RUN cd /var/www
RUN cd /var/www/html
yaml
key: value
value가 한 개인 경우에는 바로 옆에 띄어쓰기 후 작성
value 가 여러개인 경우 아래와 같이 리스트 형태로 작성
key:
- value1
- value2