open:도커-무작정-따라하기

도커 무작정 따라하기

도커 무작정 따라하기: 도커가 처음인 사람도 60분이면 웹 서버를 올릴 수 있습니다!

출처: https://www.slideshare.net/pyrasis/docker-fordummies-44424016

  • 도커는 하드웨어 가상화 계층이 없음
  • 메모리 접근, 파일 시스템, 네트워크 전송 속도가 가상 머신에 비해 월등히 빠름

이미지 버전 관리도 제공하고 중앙 저장소에 이미지를 올리고 받을 수 있음 (push/pull)

GitHub와 비슷한 형태로 도커 이미지를 공유하는 Docker Hub 제공 (GitHub처럼 유료 저장소도 제공)

다양한 API를 제공하여 원하는 만큼 자동화 가능, 개발과 서버 운영에 매우 유용!

그런데 이미지와 컨테이너는 뭐가 다른 거지?

이미지는 서비스 운영에 필요한 서버 프로그램, 소스 코드, 컴파일된 실행 파일을 묶은 형태

저장소에 올리고 받는건 이미지 (push/pull)

컨테이너는 이미지를 실행한 상태!

이미지로 여러 개의 컨테이너를 만들 수 있음

운영체제로 치면 이미지는 실행파일이고 컨테이너는 프로세스

도커는 이미지의 바뀐 부분을 어떻게 관리하나?

유니온 파일 시스템 형식 (aufs, btrfs, devicemapper)

  • 도커는 베이스 이미지에서 바뀐 부분만 이미지로 생성
  • 컨테이너로 실행할 때는 베이스 이미지와 바뀐 부분을 합쳐서 실행
  • Docker Hub 및 개인 저장소에서 이미지를 공유할 때 바뀐 부분만 주고 받음
  • 각 이미지는 의존 관계 형성
  • 지금까지는 물리 서버를 직접 운영 했음
  • 호스팅 또는 IDC 코로케이션 서비스 사용
  • 서버 구입과 설치에 돈이 많이 들고 시간이 오래 걸림
  • 가상화가 발전하면서 클라우드 환경으로 변환
  • 가상 서버를 임대하여 사용한 만큼만 요금 지불
  • 클릭 몇 번 만으로 가상 서버를 생성
  • 이젠 자동으로 서버를 추가하고 삭제하기까지…
  • 서버 대수가 많아지면서 사람이 일일이 세팅하기 힘들어짐
  • 이제 서버 세팅과 배포는 어떻게?
  • Immutable Infrastructure라는 패러다임이 나옴
  • 호스트 OS와 서비스 운영 환경(서버 프로그램, 소스코드, 컴파일된 바이너리)을 분리
  • 한 번 설정한 운영 환경은 변경하지 않는다(Immutable)는 개념

  • 서비스 운영 환경을 이미지로 생성한 뒤 서버에 배포하여 실행
  • 서비스가 업데이트되면 운영 환경 자체를 변경하지 않고, 이미지를 새로 생성하여 배포
  • 클라우드 플랫폼에서 서버를 쓰고 버리는 것과 같이 Immutable Infrastructure도 서비스 운영 환경 임지를 한 번 쓰고 버림
  • 도커는 Immutable Infrastructure를 구현한 프로젝트

편리한 관리

  • 서비스 환경 이미지만 관리하면 됨
  • 중앙 관리를 통한 체계적인 배포와 관리
  • 이미지 생성에 버전 관리 시스템 활용

확장

  • 이미지 하나로 서버를 계속 찍어낼 수 있음
  • 클라우드 플랫포의 자동 확장(Auto Scaling) 기능과 연동하여 손쉽게 서비스 확장

테스트

  • 개발자 PC, 테스트 서버에서 이미지를 실행만 하면 서비스 운영 환경과 동일한 환경이 구성됨
  • 테스트가 간편

가볍다

  • 운영체제와 서비스 환경을 분리하여 가볍고(Lightweight) 어디서든 실행 가능한(Portable) 환경 제공

컨테이너를 싣고 다니는 고래

  • 고래는 서버에서 여러 개의 컨테이너(이미지)를 실행하고 이미지 저장과 배포(운반)를 의미
  • 도커(Docker)는 부두 노동자를 뜻함 컨테이너를 다루는 도커의 기능과 비슷함
  • 도커는 서비스 운영 환경을 묶어서 손쉽게 배포하고 실행하는 경량 컨테이너 기술

공식문서 ⇒ https://docs.docker.com/install/linux/docker-ce/ubuntu/

도커 레파지토리를 추가

# gedit /etc/apt/sources.list
deb https://apt.dockerproject.org/repo ubuntu-xenial main

HTTPS 통신에 사용되는 패키지와 공개키를 설치

# apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
# apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

linux-image extra와 docker-engine 패키지를 설치

sudo apt-get update
# apt-get install linux-image-extra-$(uname -r)
# apt-get install docker-engine
root@server:~# docker version
Client:
 Version:      17.05.0-ce
 API version:  1.29
 Go version:   go1.7.5
 Git commit:   89658be
 Built:        Thu May  4 22:10:54 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.05.0-ce
 API version:  1.29 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   89658be
 Built:        Thu May  4 22:10:54 2017
 OS/Arch:      linux/amd64
 Experimental: false

main.go 파일 작성

package main

import (
	"fmt"
	"log"
	"net/http"
)


func main(){
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){
		log.Println("received request")
		fmt.Fprintf(w, "Hello Docker !!!")
	})

	log.Println("start server")

	server := &http.Server{Addr: ":8000"}
	if err := server.ListenAndServe(); err != nil {
		log.Println(err)
	}
}

설치

# apt install golang-go
# go run main.go
root@server:~/docker# gedit Dockerfile
FROM golang:1.9

RUN mkdir /echo

COPY main.go /echo

CMD [ "go", "run", "/echo/main.go" ]
snippet.shell
docker image --help
docker image build --help
root@server:~/docker# docker image build -t example/echo:latest .
  • -t 는 이미지 이름:태그

이미지 목록 확인

snippet.shell
root@server:~/docker# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
example/echo        latest              e5bf61deed81        2 minutes ago       750MB
golang              1.9                 ef89ef5c42a9        10 months ago       750MB
snippet.shell
root@server:~/docker# docker image ls -a
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              b4ba25ac2cae        3 minutes ago       750MB
example/echo        latest              e5bf61deed81        3 minutes ago       750MB
<none>              <none>              58f3cb19c839        3 minutes ago       750MB
golang              1.9                 ef89ef5c42a9        10 months ago       750MB

내용 변경 후 이미지 다시 만들기

snippet.shell
root@server:~/docker# docker image build -t example/echo:latest .
Sending build context to Docker daemon  3.072kB
Step 1/4 : FROM golang:1.9
 ---> ef89ef5c42a9
Step 2/4 : RUN mkdir /echo
 ---> Using cache
 ---> 58f3cb19c839
Step 3/4 : COPY main.go /echo
 ---> b812938cbabc
Removing intermediate container c91757d70919
Step 4/4 : CMD go run /echo/main.go
 ---> Running in 5e76624a9714
 ---> 133a6f8f5426
Removing intermediate container 5e76624a9714
Successfully built 133a6f8f5426
Successfully tagged example/echo:latest
root@server:~/docker# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
example/echo        latest              133a6f8f5426        46 seconds ago      750MB
<none>              <none>              e5bf61deed81        8 minutes ago       750MB
golang              1.9                 ef89ef5c42a9        10 months ago       750MB
snippet.shell
root@server:~/docker# docker container run -p 9000:8000 -d example/echo:latest 
25bdbb71d2591730d259c7dcb07da0557add80a9ba70e96753c907b462d4b704
snippet.shell
root@server:~/docker# docker container ls
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                    NAMES
25bdbb71d259        example/echo:latest   "go run /echo/main.go"   2 hours ago         Up 2 hours          0.0.0.0:9000->8000/tcp   thirsty_goldstine
  • 이름을 줄 수 있다.
snippet.shell
root@server:~/docker# docker container run -p 9001:8000 -d example/echo:latest
5a140cf82ca1112164487268e2b2d161a84a725aa5d5af5247a2e711725c9032
root@server:~/docker# docker container ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                    NAMES
5a140cf82ca1        example/echo:latest   "go run /echo/main.go"   6 seconds ago       Up 4 seconds        0.0.0.0:9001->8000/tcp   priceless_shockley
25bdbb71d259        example/echo:latest   "go run /echo/main.go"   2 hours ago         Up 2 hours          0.0.0.0:9000->8000/tcp   thirsty_goldstine
snippet.shell
root@server:~/docker# docker container rm 5a
Error response from daemon: You cannot remove a running container 5a140cf82ca1112164487268e2b2d161a84a725aa5d5af5247a2e711725c9032. Stop the container before attempting removal or force remove
root@server:~/docker# docker container rm -f 5a
5a
 
root@server:~/docker# docker container rm -f 25
25
root@server:~/docker# docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

-f 옵션으로 강제 종료

snippet.shell
root@server:~/docker# docker container ps -q
4ad6c2a7994c
d08c882043e6
snippet.shell
docker container rm -f $(docker container ps -q)
snippet.shell
root@server:~/docker# docker container run -it -p 9000:8000 -d example/echo:latest /bin/bash
9ec1ad3c49f00164195eb7872ab0600f58a5cf58079e566a84bb1e83f253f714
 
root@server:~/docker# docker attach 9e
root@9ec1ad3c49f0:/go# 

종료

snippet.shell
root@9ec1ad3c49f0:/echo# exit
exit
root@server:~/docker# docker container ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
root@server:~/docker# docker container ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                       PORTS               NAMES
9ec1ad3c49f0        example/echo:latest   "/bin/bash"         7 minutes ago       Exited (127) 3 minutes ago                       infallible_joliot

다시 실행

snippet.shell
root@server:~/docker# docker container restart 9e
9e
root@server:~/docker# docker container ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS              PORTS                    NAMES
9ec1ad3c49f0        example/echo:latest   "/bin/bash"         9 minutes ago       Up 3 seconds        0.0.0.0:9000->8000/tcp   infallible_joliot

stop

snippet.shell
root@server:~/docker# docker container stop 9e
9e
root@server:~/docker# docker container ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                     PORTS               NAMES
9ec1ad3c49f0        example/echo:latest   "/bin/bash"         11 minutes ago      Exited (0) 2 seconds ago                       infallible_joliot
snippet.shell
root@server:~/docker# docker container run -it -p 9000:8000 --name echo1 -d example/echo:latest
e2c45c8b92f9c2196b9fbc2bcca10b777384e6ab3f332778116a350ce41bb97e
 
root@server:~/docker# docker container run -it -p 9001:8000 --name echo2 -d example/echo:latest
0371d5eb3d1ed93dfb7408266775781dcdac37e5113b3074d9d43262f2200d6f
root@server:~/docker# docker container ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                    NAMES
0371d5eb3d1e        example/echo:latest   "go run /echo/main.go"   8 seconds ago       Up 7 seconds        0.0.0.0:9001->8000/tcp   echo2
e2c45c8b92f9        example/echo:latest   "go run /echo/main.go"   48 seconds ago      Up 47 seconds       0.0.0.0:9000->8000/tcp   echo1

nginx

snippet.shell
root@server:~/docker# docker container run -d -p 9003:80 --name web2 nginx
fd906f33ad9133796809583f31b275685971dcc82d81a437ecda97a46ea4511b
snippet.shell
root@server:~/docker# docker container ps -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS                      PORTS                    NAMES
fd906f33ad91        nginx                 "nginx -g 'daemon ..."   2 minutes ago       Up 2 minutes                0.0.0.0:9003->80/tcp     web2
e6eb11fb9666        nginx                 "nginx -g 'daemon ..."   6 minutes ago       Exited (0) 4 minutes ago                             web1
0371d5eb3d1e        example/echo:latest   "go run /echo/main.go"   7 minutes ago       Up 7 minutes                0.0.0.0:9001->8000/tcp   echo2
e2c45c8b92f9        example/echo:latest   "go run /echo/main.go"   8 minutes ago       Up 8 minutes                0.0.0.0:9000->8000/tcp   echo1
9ec1ad3c49f0        example/echo:latest   "/bin/bash"              42 minutes ago      Exited (0) 30 minutes ago                            infallible_joliot
snippet.shell
root@server:~/docker# docker container ps --filter "ancestor=example/echo"
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                    NAMES
0371d5eb3d1e        example/echo:latest   "go run /echo/main.go"   9 minutes ago       Up 9 minutes        0.0.0.0:9001->8000/tcp   echo2
e2c45c8b92f9        example/echo:latest   "go run /echo/main.go"   10 minutes ago      Up 10 minutes       0.0.0.0:9000->8000/tcp   echo1
snippet.shell
root@server:~/docker# docker container ps -a --filter "ancestor=example/echo"
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS                      PORTS                    NAMES
0371d5eb3d1e        example/echo:latest   "go run /echo/main.go"   10 minutes ago      Up 10 minutes               0.0.0.0:9001->8000/tcp   echo2
e2c45c8b92f9        example/echo:latest   "go run /echo/main.go"   11 minutes ago      Up 11 minutes               0.0.0.0:9000->8000/tcp   echo1
9ec1ad3c49f0        example/echo:latest   "/bin/bash"              44 minutes ago      Exited (0) 32 minutes ago                            infallible_joliot

docker image

  • build : Dockerfile → Image 생성
  • pull : library/nginx:latest
  • push : [myid]/
    • docker login 후에 push

docker container run [image_name]

  • -d : detach
  • -it : interaction
  • -p : port forwarding
  • –name : 이름 지정

docker container stop [container_id]

docker container restart

docker container rm

  • -f : 강제 삭제
snippet.shell
root@server:~/docker# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
example/echo        latest              133a6f8f5426        3 hours ago         750MB
<none>              <none>              e5bf61deed81        3 hours ago         750MB
nginx               latest              53f3fd8007f7        3 weeks ago         109MB
golang              1.9                 ef89ef5c42a9        10 months ago       750MB
snippet.shell
root@server:~/docker# docker image tag example/echo:latest jacegem/echo:latestroot@server:~/docker# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
example/echo        latest              133a6f8f5426        3 hours ago         750MB
jacegem/echo        latest              133a6f8f5426        3 hours ago         750MB
<none>              <none>              e5bf61deed81        3 hours ago         750MB
nginx               latest              53f3fd8007f7        3 weeks ago         109MB
golang              1.9                 ef89ef5c42a9        10 months ago       750MB
snippet.shell
root@server:~/docker# docker image push jacegem/echo:latest
The push refers to a repository [docker.io/jacegem/echo]
1542d130dabd: Pushed 
da8b71e70fad: Pushed 
186d94bd2c62: Mounted from library/golang 
24a9d20e5bee: Mounted from library/golang 
e7dc337030ba: Mounted from library/golang 
920961b94eb3: Mounted from library/golang 
fa0c3f992cbd: Mounted from library/golang 
ce6466f43b11: Mounted from library/golang 
719d45669b35: Mounted from library/golang 
3b10514a95be: Mounted from library/golang 
latest: digest: sha256:d30f59e7e31708f73d8fcf21f301b6bc46ac0ad8669703e2d305e4bd3c9043cf size: 2417
snippet.shell
root@server:~/docker# docker image pull myanjini/echo
Using default tag: latest
latest: Pulling from myanjini/echo
55cbf04beb70: Already exists 
1607093a898c: Already exists 
9a8ea045c926: Already exists 
d4eee24d4dac: Already exists 
9c35c9787a2f: Already exists 
8b376bbb244f: Already exists 
0d4eafcc732a: Already exists 
186b06a99029: Already exists 
c6f2dfa6c4bc: Pull complete 
0ef374528dd6: Pull complete 
Digest: sha256:349156f17a9f55e548bff2dc2301be0e4937506b25464a1e9a401f1f39728fe5
Status: Downloaded newer image for myanjini/echo:latest

http://70.12.50.160:9500

snippet.shell
root@server:/var/www/html# docker container ls -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS                   PORTS                    NAMES
59aff7e41078        example/echo          "go run /echo/main.go"   15 seconds ago      Created                                           angry_bhaskara
fd906f33ad91        nginx                 "nginx -g 'daemon ..."   2 hours ago         Up 2 hours               0.0.0.0:9003->80/tcp     web2
e6eb11fb9666        nginx                 "nginx -g 'daemon ..."   2 hours ago         Exited (0) 2 hours ago                            web1
0371d5eb3d1e        example/echo:latest   "go run /echo/main.go"   2 hours ago         Up 2 hours               0.0.0.0:9001->8000/tcp   echo2
e2c45c8b92f9        example/echo:latest   "go run /echo/main.go"   2 hours ago         Up 2 hours               0.0.0.0:9000->8000/tcp   echo1
9ec1ad3c49f0        example/echo:latest   "/bin/bash"              2 hours ago         Exited (0) 2 hours ago                            infallible_joliot
root@server:/var/www/html# docker container stop e2
e2
root@server:/var/www/html# docker container run -d -p 9000:8000 example/echo
400484c6af559d31ec5235f02dc56f0f2a840d903748bd34f14573dbb0accd76
snippet.shell
root@server:~/docker# docker container exec 40 ls /echo
main.go
root@server:~/docker# docker container rm -f $(docker container ls -a -q)
400484c6af55
59aff7e41078
fd906f33ad91
e6eb11fb9666
0371d5eb3d1e
e2c45c8b92f9
9ec1ad3c49f0
snippet.shell
root@server:~/docker# docker system prune
WARNING! This will remove:
	- all stopped containers
	- all volumes not used by at least one container
	- all networks not used by at least one container
	- all dangling images
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
snippet.shell
root@server:~/docker# docker container run -d -p 9000:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
743f2d6c1f65: Pull complete 
6bfc4ec4420a: Pull complete 
688a776db95f: Pull complete 
Digest: sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
Status: Downloaded newer image for nginx:latest
862795b066d8425bf832e9fce88e0566789b6c196517b945cf2b6b19913a2b2b
root@server:~/docker# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
862795b066d8        nginx               "nginx -g 'daemon ..."   23 seconds ago      Up 21 seconds       0.0.0.0:9000->80/tcp   hardcore_brattain
snippet.shell
root@server:~/docker# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
862795b066d8        nginx               "nginx -g 'daemon ..."   23 seconds ago      Up 21 seconds       0.0.0.0:9000->80/tcp   hardcore_brattain
root@server:~/docker# docker container exec 86 ls /usr/share/nginx/html
50x.html
index.html
snippet.shell
root@server:~/docker# docker container cp 86:/usr/share/nginx/html/index.html .
root@server:~/docker# ls
Dockerfile  index.html  main.go
snippet.shell
root@server:~/docker# docker container cp ./index.html 86:/usr/share/nginx/html/index.html

도커는 리눅스 배포판 종류를 자동으로 인식하여 도커 패키지를 설치해주는 스크립트를 제공

snippet.shell
$ sudo wget -qO- https://get.docker.com | sh
  • get.docker.com 스크립트로 도커를 설치하면 hello-world 이미지도 자동 설치됨
  • hello-world 이미지는 사용하지 않을 것이므로 모두 삭제
snippet.shell
$ sudo docker rm `sudo docker ps -aq`
$ sudo docker rmi hello-world
  • 자동 설치 스크립트를 사용하지 않고 우분투에서 직접 설치하기
  • 버전은 14.04 LTS 64비트 기준
snippet.shell
$ sudo apt-get update
$ sudo apt-get install docker.io
$ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker

/usr/bin/docker.io 실행 파일을 /usr/local/bin/docker 로 링크하여 사용

  • 자동 설치 스크립트를 사용하지 않고 레드햇 엔터프라이즈 리눅스(RHEL) 와 centos에서 패키지로 직접 설치 하기
  • RHEL과 CentOS 6 패키지 저장소에 docker-io가 없으므로 EPEL(Fedora Extra Packages For Enterprise Linux) 저장소를 사용할 수 있도록 설정
snippet.shell
$ sudo yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6.8.noarch.rpm
$ sudo yum install docker-io
  • AWS EC2에 설치되는 Amazon Linux(RHEL 기반)는 EPEL 저장소를 바로 사용할 수 있으므로 epel-release-6.8.noarch.rpm을 설치하지 않아도 됨
  • centos 7 에서는 docker 패키지를 설치

CentOS 7

snippet.shell
$ sudo yum install docker

Docker 서비스 실행하기

snippet.shell
$ sudo service docker start

부팅했을 때 자동으로 실행하기

snippet.shell
$ sudo chkconfig docker on
  • 배포판 버전이 오래되었거나, centOS 같이 버전업이 보수적인 배포판에서는 도커 패키지 버전이 낮은 경우가 있음
  • 배포판 별 패키지가 아닌 빌드 된 바이너리를 직접 사용하는 방법

이미 패키지로 설치했을 때

snippet.shell
$ sudo service docker stop
$ sudo wget http://get.docker.com/builds/Linux?x86_64/docker-latest -O $(type -P docker)
$ sudo service docker start

새로 설치할 때

snippet.shell
$ wget https://get.docker.com/builds/Linux/x86_4/docker-latest
$ chmod +x docker-latest
$ sudo mv docker-latest /usr/local/bin/docker
$ sudo /usr/local/bin/docker -d

URL을 docker-latest로 지정하면 가장 최신 버전을 받고, docker-1.3.0처럼 지정하면 특정 버전을 받음

  • 도커의 명령은 docker <명령> 형식
    • 예) docker run, docker push
  • 항상 root 권한으로 실행
snippet.shell
# docker search <이미지 이름>
$ sudo docker search ubuntu
  • 보통 ubuntu, centos, redis 등 OS 나 프로그램 이름을 가진 이미지가 공식 이미지
  • 나머지는 사용자들이 만들어서 공개한 이미지
  • 도커는 Docker Hub(https://registry.hub.docker.com)를 통해 이미지를 공유하는 생태계가 구축되어 있음

  • open/도커-무작정-따라하기.txt
  • 마지막으로 수정됨: 2020/06/02 09:25
  • 저자 127.0.0.1