[Docker] Docker 기본

728x90

Container 핵심 기술

  • Cgroup: Controll Group(격리된 공간에 얼마 만큼의 리소스를 사용할 것인지, 리소스 양 제어)
  • Namespace: Isolation(격리를 담당)
    • IPC NS: 프로세스 간에 통신하는 내장 큐
    • PID NS: 프로세스, 프로세스를 격리
    • Network NS: 네트워크, 네트워크를 격리
    • UID NS: 유저, 유저를 격리
    • Mount NS: 마운트 포인트, 마운트를 격리
    • UTS NS: 호스트 네임, 호스트를 격리
  • Layered Filesystem

Docker = Docker Engine

Docker CE: Community Edition

Vagrant 환경 구성

~/vagrant/container/Vagrantfile

Vagrant.configure("2") do |config|
	# Define VM
	config.vm.define "docker" do |centos|
		centos.vm.box = "ubuntu/focal64"
		centos.vm.hostname = "docker"
		centos.vm.network "private_network", ip: "192.168.100.100"
		centos.vm.provider "virtualbox" do |vb|
			vb.name = "docker"
			vb.cpus = 2
			vb.memory = 4096
		end
	end
end

~/.ssh/config

Host docker
    HostName 192.168.100.100
    User vagrant
    IdentityFile C:\Users\choi\vagrant\container\.vagrant\machines\docker\virtualbox\private_key

docker 설치

https://docs.docker.com/engine/install/ubuntu/

$ sudo apt update

$ sudo apt install ca-certificates curl gnupg lsb-release

$ curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] <https://download.docker.com/linux/ubuntu> \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

$ sudo apt update

$ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
  • docker-ce: Docker Engine
  • docker-ce-cli: docker command
  • containerd.io: Container Runtime Interface
  • docker-compose-plugin: Docker Compose
sudo usermod -aG docker vagrant

터미널 환경 구성

zsh 설치

$ sudo apt install zsh

$ sh -c "$(curl -fsSL <https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh>)"

~/.zshrc

...
ZSH_THEME="agnoster"
...

zsh-autosuggestions, zsh-syntax-highlighting, zsh-completions 설치

$ git clone <https://github.com/zsh-users/zsh-autosuggestions> ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

$ git clone <https://github.com/zsh-users/zsh-completions> ${ZSH_CUSTOM:-${ZSH:-~/.oh-my-zsh}/custom}/plugins/zsh-completions

$ git clone <https://github.com/zsh-users/zsh-syntax-highlighting.g>
it ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

~/.zshrc 파일에 플러그인에 아래 처럼 플러그인들을 추가해준다.

 73 plugins=(
 74         git
 75         zsh-autosuggestions
 76         zsh-syntax-highlighting
 77         zsh-completions
 78         docker
 79 )

zsh 재시작

source ~/.zshrc

컨테이너 이미지

docker run hello-world 로컬 환경에 hello-world 이미지가 없기 때문에 도커 허브에서 해당 이미지 이름을 다운로드한 후에 실행한다.

choi@localhost ~ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
7050e35b49f5: Pull complete 
Digest: sha256:10d7d58d5ebd2a652f4d93fdd86da8f265f5318c6a73cc5b6a9798ff6d2b2e67
Status: Downloaded newer image for hello-world:latest

(registry)/repository/name:tag ← 전체 이미지 이름이다.

 

모든 이미지는 위와 같이 구성되어 있다.

 

태그가 없는 이미지는 없다.

 

만약 태그를 생략하는 경우에는 무조건 latest 라는 태그를 디폴트로 갖게 된다.

 

도커 허브에서 태그들을 확인할 수 있다.

 

공식 이미지일 경우 library/~~ 에서 이미지를 풀 받는다.

 

한 번이라도 사용했던 이미지들은 로컬에 다운되고 docker images 명령어로 확인할 수 있다.

 

이미지에 어떤 앱을 실행할 것인지 이미 정의되어 있다. 그냥 이미지를 가져와서 실행하는 것이다.

 

컨테이너는 접속을 해서 어플리케이션 설정을 변경한다거나 그런 것을 할 수 없고 컨테이너를 실행하는 것 밖에 못한다.

 

즉, hello-world 이미지는 아래와 같은 텍스트를 출력하는 컨테이너인 것이다.

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 <https://hub.docker.com/>

For more examples and ideas, visit:
 <https://docs.docker.com/get-started/>

hello-world 이미지에는 도커가 어떻게 작동하는지 알려주고 있다.

  1. 도커 데몬에게 도커 클라이언트가 접근을 한다.
  2. 도커 데몬은 hello-world 이미지를 바탕으로 컨테이너를 만들어야 하는데, 로컬 환경에 없으면 도커 허브에서 이미지를 풀링한다.
  3. 도커 데몬은 이미지를 바탕으로 새로운 컨테이너를 만든다.
  4. 도커 데몬은 표준 출력(stdout, stderr)을 도커 클라이언트에게 전송(streamed)한다. 그리고 도커 클라이언트는 출력값을 내 터미널에 나타낸다.

docker ps 는 현재 실행 중인 도커 컨테이너가 나타난다. docker ps -a 모든 도커 컨테이너가 나타난다.

choi@localhost ~ docker ps -a          
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
849f32a6c6e0   hello-world   "/hello"   36 seconds ago   Exited (0) 34 seconds ago             nice_easley
f981bb9caef5   hello-world   "/hello"   25 minutes ago   Exited (0) 25 minutes ago             gifted_austin
aec7e9f77137   hello-world   "/hello"   25 minutes ago   Exited (0) 25 minutes ago             focused_davinci

COMMAND 는 이미지에서 이미 지정된 명령어이다.

 

이미지에서 지정된 COMMAND 가 전부 실행되고 나면 자동으로 컨테이너가 종료된다.

 

어플리케이션이 종료되면 컨테이너도 종료된다. 컨테이너는 프로세스를 아이솔레이션하기 위해서이다. 그래서 애플리케이션이 종료되면 컨테이너도 종료된다.

 

NAMES 는 컨테이너의 이름으로 직접 지정하지 않으면 랜덤하게 지정된다.

 

docker 컨테이너를 삭제하고 싶을 때는 컨테이너 아이디 한 자리 이상 매칭시켜 주거나, 또는 컨테이너의 이름을 넣어주면 삭제해준다.

 

docker rm <컨테이너_이름> , docker rm <컨테이너_아이디>

 

도커 이미지를 삭제하고 싶을 때는 이미지 아이디를 한 자리 이상 매칭시켜주면 된다.

 

docker rmi 이미지_아이디

choi@localhost ~ docker ps -a
CONTAINER ID   IMAGE     COMMAND              CREATED              STATUS                      PORTS     NAMES
33887fddc4de   httpd     "httpd-foreground"   About a minute ago   Exited (0) 25 seconds ago             eloquent_chaum
a648ce2b56b0   httpd     "httpd-foreground"   4 minutes ago        Exited (0) 2 minutes ago              awesome_ramanujan

choi@localhost ~ docker rm 33 a6 
33
a6
choi@localhost ~ docker ps -a   
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

choi@localhost ~ docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
httpd         latest    a0e3ee522732   12 days ago   136MB
hello-world   latest    46331d942d63   6 weeks ago   9.14kB

choi@localhost ~ docker rmi a0
Untagged: httpd:latest
Untagged: httpd@sha256:e02a2ef36151905c790efb0a8472f690010150f062639bd8c0760e7b1e884c07
Deleted: sha256:a0e3ee522732fc2798b6dd643ea79e58b8cfa2a6dc9568a9c3d6706e3c6c422c
Deleted: sha256:09307274e3aed8a83fae30fcfe0ab7a10e500bdb405863614bfc90a7be7062d6
Deleted: sha256:a7684439bc65885e04b159843ca90b01433ccf7d5325e8aec06eb6a681f08cd2
Deleted: sha256:51a47bbfb2eece80ad969da7dfb1cffb3151b0c053b75d5b320520a8e3d5f5cc
Deleted: sha256:1b5c8214d57a3bff8b1215a3ea4f0d49e60e462550cb50c75af18d362335deed
Deleted: sha256:f941f90e71a87df1d35c7a66a72fd3dda2c2884e1ad190da978321d548db23e2

apache, db 같이 서비스를 해야 하는 녀석들의 경우 지속적으로 띄어 나야 한다. 애플리케이션이 종료되면 안된다.

Life Cycle

create → start → (pause) → (unpause) → (kill) → stop → rm

run(create+start) →

  • application 이 종료되면 컨테이너도 종료(stop)

docker run -d <이미지_이름> : -d 옵션을 붙이면 백그라운드에서 애플리케이션이 실행된다.

docker kill <컨테이너_이름> : 컨테이너를 강제 종료 한다.

docker start <컨테이너_이름> : 종료된 컨테이너를 실행시킨다.

docker create <컨테이너_이름> : 컨테이너를 시작만 시켜놓는다.

create, start 는 보통 사용하지 않고 run 을 사용한다.

컨테이너를 이해하는데 아래 세가지 옵션이 제일 중요하다.

  • -i: 도커 클라이언트가 도커 데몬에게 표준 입력(stdin)을 전송할 수 있게 된다. STDIN 유지
  • -t: 컨테이너 내부에 연결되는 터미널을 부여한다. Terminal 할당
  • -d: Detach, 백그라운드에서 실행

COMMAND 에서 기본적으로 bash 를 실행하는 컨테이너들은 -it 옵션을 사용해서 접속할 수 있다.

-it 옵션은 Shell 을 실행하는 이미지에서 사용한다.

-d 옵션은 application 이 계속적으로 실행되어야 할 때 사용한다.(httpd, database...)

choi@localhost ~ docker ps -a
CONTAINER ID   IMAGE         COMMAND              CREATED          STATUS                       PORTS     NAMES
09481475fe06   centos:7      "/bin/bash"          2 minutes ago    Exited (0) 1 second ago                musing_sanderson

choi@localhost ~ docker run -it centos:7
[root@9662327270d0 /]#

리눅스 배포판 이름으로 된 이미지

  • ubuntu
  • centos
  • rocky
  • debian
  • alpine
  • busybox
  • amzonlinux
  • oraclelinux

→ Base Image 라고 부른다. 다른 이미지를 만들 때 사용한다.

728x90