개발

Docker 시작하기

cozynow 2017. 10. 16. 23:39

about Docker

가상화 기술의 3가지 종류

  • 호스트 가상화
    • H/W 위에 기본이 되는 즉, host os를 설치하고 별도 s/w를 이용하여 그 기반으로 guest os를 설치하는 것을 말함.
    • 장점 : 쉽게 사용이 가능
    • 단점 : host 기반에서 guest os가 구동되기 때문에 그에 따른 오버헤드(guest에 할당된 CPU/MEM/HDD 자원 등)가 있음
    • 예) oracle VM VirturalBox, WMWare Player
  • 하이퍼바이저 가상화
    • '하이퍼바이저'를 설치하고 가상환경으로 하이퍼바이저 통해서 h/w를 제어한다.
    • 장점 : 호스트 서버가 없기때문에 효율적인 리소스 관리가 가능하다.
    • 단점 : 가상 환경별로 OS가 동작하기 때문에 가상 환경 동작에 걸리는 오버헤드가 있을 수 있다.
  • 컨테이너 가상화
    • 호스트 OS내에서 논리적으로 컨테이너를 나눠 어플리케이션 동작을 위한 라이브러리와 어플리케이션만 놓고 구동시킬 수 있다.
    • 장점 : 빠르고 오버헤드가 없다.
    • 예) docker

Docker Toolbox 설치

  1. DockerHub 에서 구하는 방법
  2. 기본 명령어 익히기
  3. 추가)MS에서는 VM설치 후 리눅스에서만 사용가능했으나, windows10에서는 아래와 같은 pro 버전과 Enterprise버전에서 설치가 가능하다.


실습 환경

codeanywhere

*Tip sudo 없이 사용하기

  sudo groupadd docker
  sudo gpasswd -a ubuntu docker
  #reboot(sudo shutdown -r now) or 재 로그인
  sudo service docker restart
 

# Hello World 찍어보기


docker run ubuntu:latest /bin/echo 'Hello World'

#최초 수행하면 이미지 레이어를 다운받고, 수행하며, 그후에는 바로 수행된다.


#버전 확인

docker version

Client: Version: 18.06.1-ce API version: 1.38 Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:21:31 2018 OS/Arch: darwin/amd64 Experimental: false Server: Engine: Version: 18.06.1-ce API version: 1.38 (minimum version 1.12) Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:29:02 2018 OS/Arch: linux/amd64 Experimental: true



# Docker 환경 보기

docker system info

Containers: 10 Running: 2 Paused: 0 Stopped: 8 Images: 12 Server Version: 18.06.1-ce Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog Swarm: inactive Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: 468a545b9edcd5932818eb9de8e72413e616e86e runc version: 69663f0bd4b60df09991c08812a60108003fa340 init version: fec3683 Security Options: seccomp Profile: default Kernel Version: 4.9.93-linuxkit-aufs Operating System: Docker for Mac OSType: linux Architecture: x86_64 CPUs: 3 Total Memory: 5.572GiB Name: linuxkit-025000000001 ID: QWIX:3FA2:CDTG:A2XN:2XBJ:I6NU:VQP5:2RQR:IU2P:NCZL:CDM7:Z4N7 Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): true File Descriptors: 54 Goroutines: 71 System Time: 2018-10-17T06:17:53.464731868Z EventsListeners: 2 HTTP Proxy: gateway.docker.internal:3128 HTTPS Proxy: gateway.docker.internal:3129 Registry: https://index.docker.io/v1/ Labels: Experimental: true Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false


#docker 디스크 현황

docker system df

TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 8 5 1.38GB 396.3MB (28%) Containers 10 2 239.7MB 0B (0%) Local Volumes 3 1 722.4kB 18.94kB (2%) Build Cache 0 0 0B 0B


#docker 를 활용해서 웹서버를 띄워보자

docker run --name webserver -d -p 9963:80 nginx


#apache로 해볼까?

docker run --name apache -d -p 9967:80 httpd


.docker search ubuntu : docker hub에서 컨테이너 이미지 검색 \\

#star 1000 이상의 이미지 검색하기

docker search --filter=stars=1000 nginx

.docker pull ubuntu:latest : ubuntu 이미지를 다운받기(tag인 lastest는 생략되면 default임)\\ .docker images : 이미지 보기\\

#또는 docker image ls와 동일함

.docker run -dit --name wiki_ubuntu -p 8001:80 -v /Users/akamikang/developer/docker/dokuwiki:/root/dokuwiki ubuntu /bin/bash   .모든 docker 삭제(중지 후 삭제)   .docker ps -a : 모든 docker 컨테이너의 상태 표기 .docker run|start|stop|restart container_id

컨테이너 생성 및 실행

  docker run [옵션] <이미지명>[:태그명][]
옵션설명
-a, –a=[STDIN | STOUT | STDERR]표준 입력, 출력, 에러를 연결
–cidfile=“파일명”컨테이너ID를 파일로 출력
-d,–detache=false컨테이너를 생성하여 백그라운드에서 실행
-i, –interactive=false컨테이너 표준 입력 열기
-t, –tty=falsetty(단말 디바이스)를 사용
–name컨테이너명
  • 예제
  docker run -dit --name wiki_ubuntu -p 8001:80 -v /Users/akamikang/developer/docker/dokuwiki:/root/dokuwiki ubuntu /bin/bash
 
## ubuntu 이미지를 wiki_ubuntu라는 이름으로 컨테이너를 실행하고, 8001로 유입되는 데이터를 신규 docker에 80으로 전달한다.\\
##폴더도 공유 했다. /Users/akamikang/developer/docker/dokuwiki => /root/dokuwiki\\

* 예제 : 로그 보기

  docker run -d centos /bin/ping localhost
 
  docker logs -t <containerID>

* 예제 : /bin/bash가 종료되어도 컨테이너를 재구동시킨다.

  docker run -it --restart=always centos /bin/bash

* 예제 : 커맨드 실행 후 컨테이너 삭제하기

docker run -it --name stop --rm  centos /bin/cal

* 예제 : hostname을 변경하고, 호스트명과 IP를 설정할 수 있다.

docker run -it --hostname=akami --add-host=wiki.akami.com:192.168.1.10 centos

* 예제 : CPU와 메모리 설정

docker run --cpu-shares=512 --memory=512m centos

* 예제 : 환경설정, –env-file=일괄환경변수가 담긴파일명, 작업directory는 /tmp/akami

docker run -it -e dev=akami -w=/tmp/akami centos /bin/bash
 
[root@1bb2003b2292 akami]# pwd
/tmp/akami
[root@1bb2003b2292 akami]# set
BASH=/bin/bash
~
dev=akami
~
[root@akami /]$ 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
192.168.1.10	wiki.akami.com
172.17.0.4	akami

Docker PS (컨테이너 상태보기)

* 주요 옵션

옵션설명
-a, –all==fasle모든 상태의 컨테이너 표시
–before=“”입력한 컨테이명 또는 ID 보다 이전에 시작된 컨테이너 조회
-f, –filter '[key]=[value]'목록에 표시할 컨테이너를 필터링
-l, –last=false마지막에 구동된 컨테이너 표기
–no-trunc=false생략된 정보 없이 모두 표시
-q, –quiet=false컨테이너 ID만 조회
-s, –size=false파일 사이즈를 표시
–since=““입력한 컨테이너명 또는 ID보다 이후에 구동된 컨테이너를 표시

* 예제 filter사용법

docker ps -a -f 'name=akami'
docker ps -a -f 'exited=0'
placeholder설명
.IDid
.Imageimage
.Command실행명령어
.CreateAt생성시간
.RunningFor수행시간
.Ports포트
.Status상태
.Size컨테이너 사이즈
.Labels컨테이너 모든 라벨
.Lable컨테이너 라벨

* 예제 placeholder 사용법

docker ps -a --format "{{.ID}}:{{.Status}}"
docker ps -a --format "table {{.ID}}:{{.Status}}"

* 각 컨테이너 상태 보기

docker stats 컨테이너ID

* 컨테이너 이미지 생성

docker commit -a "akami kang" centos1 akami/web:10
docker inspect akami/web:10

* 컨테이너를 파일로 받기

docker commit -a "akami kang" centos1 akami/web:10
docker inspect akami/web:10

Container 실행(start) 및 중지(stop)

* 예제

docker start 컨테이너ID   #2초후에 종료 docker stop -t 2 컨테이너ID   #2초후에 재시작 docker retart -t 2 컨테이너ID #컨테이너 중단/재개

docker pause 컨테이너ID

docker unpause 컨테이너ID

Container 삭제(rm) 및 일시정지(pause)

* 예제

docker rm 컨테이너ID
 
#docker 모두 삭제(Up 된것은 삭제 불가)
top
 
#강제 삭제
docker rm -f $(docker ps -aq)
 
 
 
#2초후에 재시작
docker retart -t 2 컨테이너ID

Container 접속(attach)

* 예제

docker attach 컨테이너ID
 
#프로세스 실행(실행 중인 컨테이너만 됨)
docker exec -it 컨테이너ID /bin/cal
docker exec -it 컨테이너ID /bin/touch a 
docker exec -it 컨테이너ID /bin/ls -al  a
docker exec -it 컨테이너ID /bin/pwd
#쉘빠져나오기(exit이면 컨테이너가 stop 됨)
ctrl+P, Q

Container 프로세스 확인(top)

* 예제

docker top 컨테이너ID

Container 포트 확인(port)

* 예제

docker port 컨테이너ID

Container 이름변경(rename)

* 예제

docker rename old new

Container 파일을 밖으로 빼내기(cp)

* 예제

docker cp <컨테이너명orID>:<컨테이너내파일경로> <호스트 디렉토리>
docker cp akami:/a /tmp/

Container 이미지 생성(commit)

* 예제

docker commit <옵션>:<컨테이너ID or 명> [이미지 명]
docker commit -a "akami_dev" akami centos/akami:1.0
docker inspect centos/akami:1.0

Container를 tar로 저장(export/import)

* history를 포함하지 않는다. * 예제

#docker import <tar 파일의 URL 또는 -> <저장소 이름>/<이미지 이름>:<태그>
docker export < <이미지명> 
docker export akami > akami_lastest.tar
ls -la  | grep lastest.tar
 
docker import http://example.com/hello.tar.gz hello
docker import [백업 파일명] [생성할 이미지명] 
docker import akami_lastest.tar akami4
 
cat akami_lastest.tar | docker import - hello
ubuntu@ip-172-31-2-230:~$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello               latest              3ac97c084bf0        9 seconds ago       192.6 MB
 
docker image history [IMAGE ID]

Container를 tar 이미지로 복구(save/load)

* 예제

#save로 백업된 tar는 레이어를 볼 수 있다.
docker save -o <파일명.tar> akamidb
docker save -o akami.tar akami4
docker load -i <파일명.tar>
docker load -i akami.tar 
docker image history akami4
 
#save/load 와 export/import를 비교해보자.
#java 이미지를 export로 백업해본다.
akamikang@mini ~/developer/docker/hangle $ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
java                latest              a21d993a65a6        4 minutes ago       1.18 GB
 
akamikang@mini ~/developer/docker/hangle $ docker export java > akami.tar
akamikang@mini ~/developer/docker/hangle $ ll
total 1882576
drwxr-xr-x   7 akamikang  staff   238B Jun 13 01:26 ./
drwxr-xr-x  11 akamikang  staff   374B Jun 13 00:51 ../
-rw-r--r--   1 akamikang  staff   919M Jun 13 01:26 akami.tar
 
 
akamikang@mini ~/developer/docker/hangle $ docker save -o akami_save.tar java
akamikang@mini ~/developer/docker/hangle $ ll
total 4202480
drwxr-xr-x   8 akamikang  staff   272B Jun 13 01:27 ./
drwxr-xr-x  11 akamikang  staff   374B Jun 13 00:51 ../
-rw-r--r--   1 akamikang  staff   919M Jun 13 01:26 akami.tar      #==> export된 tar
-rw-------   1 akamikang  staff   1.1G Jun 13 01:27 akami_save.tar #==> save 된 tar
 
akamikang@mini ~/developer/docker/hangle $ docker import akami.tar akami.export
sha256:87d9105940a893458fa751cb0bef844eb8c5543f2c37af6caf5c92e4d39d382b
akamikang@mini ~/developer/docker/hangle $ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
akami.export        latest              87d9105940a8        4 seconds ago       955 MB
 
#export된 이미지는 layer가 없다.
akamikang@mini ~/developer/docker/hangle $ docker image history 87d9105940a8
IMAGE               CREATED             CREATED BY          SIZE                COMMENT
87d9105940a8        20 seconds ago                          955 MB              Imported from -
 
 
akamikang@mini ~/developer/docker/hangle $ docker load -i akami_save.tar
Loaded image: java:latest
akamikang@mini ~/developer/docker/hangle $ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
akami.export        latest              87d9105940a8        About a minute ago   955 MB
java                latest              a21d993a65a6        12 minutes ago       1.18 GB
 
#save된 이미지는 각 단계의 레이어가 존재한다.
akamikang@mini ~/developer/docker/hangle $ docker image history java
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
a21d993a65a6        13 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/b..."   0 B
<missing>           13 minutes ago      /bin/sh -c #(nop)  ENV PATH=/usr/local/sbi...   0 B
<missing>           13 minutes ago      /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/tool...   0 B
<missing>           13 minutes ago      /bin/sh -c cd /                                 0 B
<missing>           13 minutes ago      /bin/sh -c #(nop) WORKDIR /usr/tools            0 B
<missing>           13 minutes ago      /bin/sh -c ln -s jdk1.8.0_131 java              12 B
<missing>           13 minutes ago      /bin/sh -c tar -xvf *.tar                       376 MB
<missing>           13 minutes ago      /bin/sh -c gunzip *                             378 MB
<missing>           13 minutes ago      /bin/sh -c wget --header "Cookie: oracleli...   186 MB
<missing>           13 minutes ago      /bin/sh -c #(nop) WORKDIR /usr/tools            0 B
<missing>           13 minutes ago      /bin/sh -c mkdir tools                          0 B
<missing>           13 minutes ago      /bin/sh -c #(nop) WORKDIR /usr                  0 B
<missing>           13 minutes ago      /bin/sh -c cd /                                 0 B
.....
...
..
  1. 반복해서 하다보니 매번 docker 삭제도 귀찮을때,
dockerInit.sh
#!/bin/bash
# Delete all containers
docker rm $(docker ps -a -q)
# Delete all images
docker rmi $(docker images -q)

자동으로 만들기(Dockerfile)

미니 프로젝트

목표 : 2 tier 구성하여 web application 구성

주요기능 :was, db 각각 node를 구성하여 db 내용을 UI에서 조회하도록 한다.

  • 각 tier끼리 접근할때는 host 이름을 지정하여 접근할 수 있도록 link를 제공한다.
    • mysql 서버를 띄우고 그 서버를 접속할 tomcat을 링크시켜보자.

# STEP 1. DB 역할을 할 컨테이너로 mysql을 사용 할 것이다.

#mysql 이미지를 받는다.
docker pull mysql
#akami.mysql 이름으로 mysql 컨테이너를 띄운다.root 계정의 PW는 123456으로 하겠다.
 
docker run -dit\
           --name akami.mysql \
           -e MYSQL_ROOT_PASSWORD=123456  \
           mysql /bin/bash
 
#IP확인           
docker inspect --format '{{ .NetworkSettings.IPAddress }}' container_ID
 
 
 
 
#docker attach 후
#mysql 서비스 시작
service mysql start
#그럼 테스트용 database와 테이블을 만들자
#msyql 콘솔
mysql  -uroot -p
CREATE DATABASE akamidb;
 
USE  akamidb;
 
 CREATE TABLE IF NOT EXISTS `tbl_test` 
	(
	seq INT(11) NOT NULL AUTO_INCREMENT,
		name VARCHAR(10), 
        regdate TIMESTAMP NOT NULL DEFAULT now(),
         PRIMARY KEY(seq)
 
	);  
 
 
INSERT INTO tbl_test (name) VALUES ('A');
INSERT INTO `tbl_test` (name) VALUES ('B');
INSERT INTO `tbl_test` (name) VALUES ('C');
INSERT INTO `tbl_test` (name) VALUES ('D');
INSERT INTO `tbl_test` (name) VALUES ('E');
INSERT INTO `tbl_test` (name) VALUES ('F');
INSERT INTO `tbl_test` (name) VALUES ('G');
 
commit;
 
 
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'qazwsx';
FLUSH PRIVILEGES;
 


# STEP 2. WAS역할을 할 컨테이너로 tomcat을 할 것이다.

#tomcat 이미지를 받는다.
 
#호스트의 외부80 포트를 컨테이너 8080으로 연결한다.
docker run -dit --name akami.tomcat --link akami.mysql:db -p 9000:8080 tomcat:8.0 /bin/bash
 
#배포할 소스를 빌드해서 war 파일 생성
akamikang@mymac ~/developer/workspace/akami $ mvn -Dmaven.test.skip package
#개발서버로 올림
scp ./target/*.war akamikang@cozy.ddns.net:~
#컨테이너로 넣기
akamikang@mini ~ $ docker cp simple-1.0.0-BUILD-SNAPSHOT.war akami.tomcat:/usr/local/tomcat/webapps
 
#docker attach 후
#tomcat 구동
catalina.sh run &
set | grep DB

docker-compose

* 여러 컨테이너를 한꺼번에 제어하는 불편함을 해소할 수 있는 제품 * 명령어는 아래와 같다.

commnad설명
up컨테이너 생성 및 구동
scale구동할 컨테이너 숫자 지정
ps컨테이너 목록 확인
logs컨테이너 로그 출력
run실행
start구동
stop정지
restart재기동
kill강제종료
rm삭제

up : 한꺼번에 여러개 띄우기

#여러개 백그라운드에서 실행
docker-compose up -d
docker-compose.yml
web:
   image: httpd
 
db:
   image: mysql

scale : 생성할 컨테이너 수 지정

#web과 db 10개씩 증설
docker-compose up web=10 db=10

- 자동으로 만들기 Dockerfile

  1. ubuntu에 dokuwiki가 설치된 것을 사용하려고 했으나 wiki는 되지만 attach가 되지 않아서 걍 다 설치함

docker를 이용한 docuwiki설치