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 설치
$ 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 이미지에는 도커가 어떻게 작동하는지 알려주고 있다.
- 도커 데몬에게 도커 클라이언트가 접근을 한다.
- 도커 데몬은 hello-world 이미지를 바탕으로 컨테이너를 만들어야 하는데, 로컬 환경에 없으면 도커 허브에서 이미지를 풀링한다.
- 도커 데몬은 이미지를 바탕으로 새로운 컨테이너를 만든다.
- 도커 데몬은 표준 출력(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 라고 부른다. 다른 이미지를 만들 때 사용한다.