✔️ Docker 버전
도커의 설치가 완료되었다면 도커의 버전을 확인해보자
docker version
Client - 도커 명령어를 의미한다.
- Docker CE : Community Edition
- Docker EE : Enterprise Edition
20.10.14 : 2020년도 10월에 나온 버젼을 의미한다.
Server - 도커 엔진 (도커 서비스가 실행하는 서버)
✔️ Docker 아키텍처
Docker 명령어(클라이언트) Docker host(서버)
서버에는 도커 데몬이 작동하고 있으며 도커 명령어가 도커 데몬에게 명령을 내리는 형태이다.
중요한 것은 레지스트리라고 하는 저장소인데, 우리가 ec2를 만들 때 AMI 이미지가 필요한 것 처럼
컨테이너를 만들기 위해서는 컨테이너용 이미지가 필요하다. 이미지 저장소를 레지스트리라고 한다.
레지스트리를 로컬 컴퓨터에 직접 구축할 수도 다른 서비스를 이용할 수도 있다.
대표적인 서비스가 Dockerhub라는 서비스이다.
저장소를 SaaS 형태로 서비스를 해주는 것이 Dockerhub이다. (AWS, Azure, GitHub 등등 다른 서비스도 많다.)
✔️ Dockerhub
수많은 이미지들이 존재하며 약 900만개의 이미지가 존재한다.
도커 명령어를 가지고 이미지를 컨테이너로 만들기 위해서는 레지스트리에 있는 특정 이미지를 지정해야하며 이미지를 도커 서버로 가져와 컨테이너를 생성한다.
vagrant@docker ~ docker run hello-world
해당 명령어는 "hello-world 이미지로 컨테이너를 실행하라" 라는 의미이다.
hello-world 이미지는 텍스트를 출력 시키는 기능을 가진 이미지이다.
도커 엔진이 정상적으로 작동하는지 체크하기 위해 도커에서 만든 기본 이미지이다.
도커 허브에서 hello-world를 검색해보자
OFFICIAL IMAGE는 도커에서 만든 공식 이미지이다.
다운로드 횟수와 별점, 가장 최근에 업데이트 된 설명과 검색 태그가 나온다.
공식 이미지와는 다르게 계정명(rancher)이 붙어있다.
검증된 사용자라는 마크가 붙어있다.
Unable to find image 'hello-world:latest' locally
레지스트리에서 이미지를 가져오지 않고 실행하면 "로컬에서 이미지를 찾을 수 없다." 라고 출력한다.
도커 호스트에 없기 때문에 다운로드를 받아야 한다.
hello-world:latest
:latest를 tag라고 한다.
✔️ 컨테이너 이미지
(registry)/repository/name:tag
이 구성이 완전한 컨테이너 이미지명이다.
모든 이미지는 이 구조로 되어 있다.
모든 이미지에는 반드시 하나 이상의 태그가 있어야 한다. 태그가 없는 이미지는 없다.
우리가 앞서 hello-world 이미지를 지정해 컨테이너를 만들 때 태그를 지정하지 않았다.
태그를 생략할수도 있는데 태그를 생략할 때는 도커 엔진이 알아서 latest 라는 태그를 지정하게 된다.
그렇다면 이미지에는 어떤 Tag들이 있을까 ?
Dockerhub로 이동해 임의의 이미지를 선택해서 Tag 탭으로 이동해보자. Tag 탭에는 다양한 태그가 있다.
모든 이미지에는 latest 태그가 있다. (하지만 무조건 latest 태그가 있어야 하는 것은 아니다.)
linux386 - 32비트 아키텍처, 이미지의 용량 등을 알 수 있다. 다양한 os에 맞는 아키텍처가 있다.
태그 이름을 붙이는 것은 만든 사람의 마음이다.
로컬에서 hello-world 이미지를 지우고 다시 한번 동일 명령을 실행해보자
latest: Pulling from library/hello-world
hello-world 이미지가 로컬에 없기 때문에 다시 레지스트리(Dockerhub)를 통해 받는 작업을 진행한다.
여기서 알 수 있는 것은 도커 공식 이미지의 이름의 계정명은 library라는 것이다. (보통 생략해서 사용한다.)
2db29710123e: Pull complete
Digest: sha256:10d7d58d5ebd2a652f4d93fdd86da8f265f5318c6a73cc5b6a9798ff6d2b2e67
Status: Downloaded newer image for hello-world:latest
이미지를 다운 받으면 이미지의 해시값을 알 수 있다.
Digest는 실제 sha256으로 해시한 값이며 이 값으로 검증하게 된다.
Status : 다운로드가 완료됐음을 나타낸다.
이미지를 다운로드 받은 후 해당 명령을 실행해보자
vagrant@docker ~ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 7 months ago 13.3kB
한번이라도 사용했던 이미지는 저장된다.
즉, 해당 명령을 통해 출력된 내용은 로컬에 다운로드 받아진 이미지의 목록이다.
✔️ Docker run
docker run hello-world
다운받은 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.
(amd64)
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 컨테이너가 출력한 내용을 보자
이미지에 따라서 무엇을 실행할 것인지는 이미지를 만듣 때 정한다.
VM은 유저 데이터나 앤서블 플레이북을 작성해서 어플리케이션을 실행하고 서비스를 시작하지만,
다시 말해 시스템에서 어플리케이션을 선택적으로 실행할 수 있지만,
컨테이너는 어떤 app을 실행할지 이미 정해져 있어 우리가 선택적으로 실행할 app을 바꿀 방법이 없다.
이미지를 실행하면 끝이다.
컨테이너는 사용자가 컴퓨터를 켜서 접속을 해서 app을 실행한다는 개념이 절대적으로 없다.
컨테이너에는 어플리케이션이 포함되어 있고 어플리케이션이 동작하는데 필요한 binary/library가 있다.
hello-world 라는 이미지는 내용을 출력하는 app이다.
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.
(amd64)
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의 출력 내용을 보자
도커 엔진이 정상적으로 작동하며 도커가 어떻게 작동하는 지에 대한 내용을 설명하고 있다.
아래와 같은 절차를 거친다.
- 도커 클라이언트가 도커 데몬에게 접근한다. docker run hello-world라는 명령을 실행한다.
도커 명령어는 클라이언트이며 도커 데몬에게 이 클라이언트가 접근을 한다. - 도커 데몬은 우리가 hello-world 라는 이미지를 지정해서 컨테이너를 만들라고 명령을 내렸기 때문에 로컬에 해당하는 이미지가 있는지 찾아보고 없으면 레지스트리에서 다운로드 받는다.
도커 데몬은 hello-world라는 이미지를 docker hub로부터 pulling한다. - 도커 데몬은 새로운 컨테이너를 만든다. 메세지를 출력하는 실행 파일을 가지고 있는 hello-world 이미지를 가지고 컨테이너를 만든다.
- 도커 데몬은 도커 클라이언트에게 output을 표준 출력한다.
- stdout
- stderror
- output
stdout, stderr를 데몬에서 클라이언트로 전송시키고 클라이언트는 이것을 터미널로 출력시킨다.
이 절차가 완료되면 현재 우리가 보고 있는 이 텍스트를 볼 수 있다.
다시 한번 run을 실행하면 도커 이미지를 다운받는 과정이 없다. 로컬에 이미 존재하기 때문이다.
vagrant@docker ~ docker run 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.
(amd64)
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/
vagrant@docker ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
vagrant@docker ~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
164efd795ae5 hello-world "/hello" 19 seconds ago Exited (0) 19 seconds ago wizardly_benz
58d9d2e32044 hello-world "/hello" 26 minutes ago Exited (0) 26 minutes ago focused_bell
vagrant@docker ~
-a 옵션을 붙이지 않으면 현재 실행중인 컨테이너만 보인다.
docker ps에서 아무것도 보이지 않았다는 것은 현재 실행중인 컨테이너가 아무것도 없다는 뜻이다.
docker ps -a 명령을 실행하면 2개가 보이는데, docker run을 2번 실행했기 때문이다.
docker run을 실행할 때마다 컨테이너가 만들어지게 되며 n번 실행하면 n개 만들어진다.
- CONTAINER ID - 직접 지정하는 것이 아닌 도커 데몬이 컨테이너를 생성할 때 기본적으로 붙이게 된다.
- IMAGE - 컨테이너로 실행할 어플리케이션 (기본적으로 이미지 내에 결정되어 있다.)
- COMMAND - 이미지 내에서 어떤 명령을 실행하여 app을 실행할 것인가
- CREATE - 컨테이너를 생성한 이후로 지난 시간을 나타낸다.
- STATUS - 현재 상태를 나타낸다. return code가 있어 어떻게 종료되었는지 알 수 있다. (0은 정상 종료이다.)
- PORTS - 외부에 노출 시킬 포트
- NAMES - 컨테이너의 이름이며 직접 지정하지 않으면 랜덤한 이름이 부여된다.
STATUS를 통해 알 수 있는 것 중에 하나는 현재 hello-world 이미지로 만든 컨테이너가 실행 중이지 않다는 것이며
중요한 것은 실행하고자 했던 어플리케이션이 종료되면 컨테이너가 같이 종료된다는 것이다.
VM을 켜고 끄는 것은 관리자가 하는 것이고 apache 실행에 있어 apache가 종료된다고 해서 VM이 꺼지지는 않는다.
다시 말하면 서비스가 중단된다고 VM이 종료되지는 않는다는 것이다.
하지만 컨테이너는 한 몸이다. 어플리케이션이 종료되면 컨테이너도 종료된다.
컨테이너의 존재 이유는 어플리케이션이므로 어플리케이션이 없다면 컨테이너가 더 이상 실행되고 있을 이유가 없다.
컨테이너는 프로세스를 isolation한다. 어플리케이션이 종료됐다는 것은 isolation 할 대상이 없다는 것이다.
컨테이너를 더 이상 유지 시킬 이유가 없다는 것이다.
docker rm [컨테이너 ID]
docker rm [컨테이너 ID 두자리 이상] # 매칭되는 것이 지워진다.
# 만약 매칭되는 것이 두개 이상이면 어느것도 지워지지 않는다.
vagrant@docker ~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d2f514948515 hello-world "/hello" 4 minutes ago Exited (0) 4 minutes ago optimistic_montalcini
164efd795ae5 hello-world "/hello" 12 minutes ago Exited (0) 12 minutes ago wizardly_benz
58d9d2e32044 hello-world "/hello" 38 minutes ago Exited (0) 38 minutes ago focused_bell
vagrant@docker ~ docker rm d
d
vagrant@docker ~ docker rm 1
1
vagrant@docker ~ docker rm 5
5
vagrant@docker ~ docker run httpd
Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
1fe172e4850f: Pull complete
e2fa1fe9b1ec: Pull complete
60dd7398e74e: Pull complete
ea2ca81c6d4c: Pull complete
f646c69a26ec: Pull complete
Digest: sha256:e02a2ef36151905c790efb0a8472f690010150f062639bd8c0760e7b1e884c07
Status: Downloaded newer image for httpd:latest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Tue May 03 15:00:22.132200 2022] [mpm_event:notice] [pid 1:tid 140444738739520] AH00489: Apache/2.4.53 (Unix) configured -- resuming normal operations
[Tue May 03 15:00:22.132388 2022] [core:notice] [pid 1:tid 140444738739520] AH00094: Command line: 'httpd -D FOREGROUND'
[Tue May 03 15:00:44.986413 2022] [mpm_event:notice] [pid 1:tid 140444738739520] AH00492: caught SIGWINCH, shutting down gracefully
이번에는 httpd 이미지를 실행시켜 출력 내용을 확인해보자. 5번의 Pull Complete가 발생한다.
이는 해당 이미지에 5-layer 가 있다는 것이다. 이미지에 따라서 layer가 다르다.
5개의 layer를 모두 받아야 실행 가능한 컨테이너가 되는 것이다.
Status 하단에 출력된 내용은 프로세스가 실행되고 발생한 표준 출력, 표준 오류가 화면에 찍히는 것이다.
적절한 설정이 안되어 있어서 어플리케이션이 종료 되어버렸다.
다시 hello-world 컨테이너로 돌아가보자 hello-world는 텍스트를 출력하고 프로그램이 자동으로 종료됐다.
이는 ls 명령어의 LifeCycle과 유사한데,
ls
아주 찰나의 순간이지만 ls 라는 프로세스가 생성이되고 실행된 후 종료가 되었다.
우리가 사용하는 vscode라는 프로그램은 의도적으로 종료하지 않는 경우 계속 실행되는 app이며,
systemctl 명령을 통해 데몬을 시작하는 이유는 계속적으로 실행하기 위함이지만
ls, cd 등의 명령어는 실행이 되고 바로 종료가 된다.
docker ps 명령을 실행해보자 httpd 컨테이너의 실행은 정상적으로 종료되었다.
vagrant@docker ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
vagrant@docker ~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c9229cffbd62 httpd "httpd-foreground" 3 minutes ago Exited (0) 3 minutes ago funny_shannon
httpd를 실행하면 잠시 동안 터미널을 apache 프로세스가 사용하고 있으므로 ls, cd 명령어를 입력해도 실행이 되지 않으며 해당 컨테이너에서 실행하는 app의 출력을 볼 수 있다. 그것이 방금 말한 Status 하단의 내용이다.
✔️ Docker rm
vagrant@docker ~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c9b1ea8c606c httpd "httpd-foreground" About a minute ago Exited (0) 2 seconds ago eager_swirles
c9229cffbd62 httpd "httpd-foreground" 6 minutes ago Exited (0) 6 minutes ago funny_shannon
vagrant@docker ~ docker rm c9b c92
c9b
c92
vagrant@docker ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
vagrant@docker ~
docker rmi c3 (이미지 ID)
docker rm 명령을 사용해 컨테이너를 지울 수 있다. 컨테이너 ID를 나열하여 한번에 지울 수 있다.
docker rmi 명령은 이미지를 지우는 명령어이다.
'DevOps > Docker' 카테고리의 다른 글
[Docker] Docker 이미지 관리 명령어 (0) | 2022.05.07 |
---|---|
[Docker] Docker LifeCycle과 자주 사용하는 옵션 (0) | 2022.05.07 |
[Docker] Docker(도커) 설치 (0) | 2022.05.06 |
[Docker] Monolithic 구조와 MicroService 구조 (0) | 2022.05.06 |
[Docker] Docker(도커)란 ? (0) | 2022.05.06 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!