Docker 이미지와 컨테이너의 차이점은 무엇입니까?
Docker를 사용할 때는 기본 이미지로 시작합니다. 우리는 그것을 부팅하고 변경 사항을 만들고 이러한 변경 사항은 다른 이미지를 형성하는 레이어에 저장됩니다.
그래서 결국에는 PostgreSQL 인스턴스 용 이미지와 웹 애플리케이션 용 이미지를 갖게되었으며 변경 사항은 계속 유지됩니다.
그래서 질문은 : 컨테이너 란 무엇입니까?
이미지의 인스턴스를 컨테이너라고합니다. 설명하는대로 레이어 집합 인 이미지가 있습니다. 이 이미지를 시작하면이 이미지의 실행중인 컨테이너가있는 것입니다. 동일한 이미지의 실행중인 컨테이너를 여러 개 가질 수 있습니다.
으로 모든 이미지를 docker images
볼 수 있지만으로 실행중인 컨테이너를 docker ps
볼 수 있습니다 (으로 모든 컨테이너를 볼 수 있음 docker ps -a
).
따라서 실행중인 이미지 인스턴스는 컨테이너입니다.
Docker 배포 자동화 에 대한 내 기사에서 :
Docker 이미지와 컨테이너
Dockerland에는 이미지 가 있고 컨테이너 가 있습니다 . 둘은 밀접하게 관련되어 있지만 구별됩니다. 나에게는이 이분법을 파악함으로써 Docker가 엄청나게 명확 해졌습니다.
이미지 란?
이미지는 본질적으로 컨테이너의 스냅 샷 인 비활성, 변경 불가능한 파일입니다. 이미지는 build 명령으로 생성되며 run으로 시작하면 컨테이너를 생성 합니다 . 이미지는 같은 도커 레지스트리에 저장됩니다 registry.hub.docker.com . 이미지가 상당히 커질 수 있기 때문에 이미지는 다른 이미지의 레이어로 구성되도록 설계되어 네트워크를 통해 이미지를 전송할 때 최소한의 데이터를 전송할 수 있습니다.
다음을 실행하여 로컬 이미지를 나열 할 수 있습니다 docker images
.
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 13.10 5e019ab7bf6d 2 months ago 180 MB
ubuntu 14.04 99ec81b80c55 2 months ago 266 MB
ubuntu latest 99ec81b80c55 2 months ago 266 MB
ubuntu trusty 99ec81b80c55 2 months ago 266 MB
<none> <none> 4ab0d9120985 3 months ago 486.5 MB
참고할 사항 :
- IMAGE ID는 이미지에 대한 실제 식별자의 처음 12 자입니다. 주어진 이미지의 많은 태그를 만들 수 있지만 해당 ID는 모두 동일합니다 (위와 같이).
- VIRTUAL SIZE는 모든 고유 한 기본 레이어의 크기를 더하기 때문에 가상 입니다. 이는 해당 열에있는 모든 값의 합계가 모든 이미지에서 사용하는 디스크 공간보다 훨씬 큼을 의미합니다.
- REPOSITORY 열의 값
-t
은docker build
명령 의 플래그 또는docker tag
기존 이미지 -ing 에서 가져옵니다 . 이해하기 쉬운 명명법을 사용하여 이미지에 태그를 지정할 수 있지만 docker는 태그를docker push
또는docker pull
. - 태그의 전체 형식은입니다
[REGISTRYHOST/][USERNAME/]NAME[:TAG]
. 를 들어ubuntu
위, REGISTRYHOST는 것으로 추정된다registry.hub.docker.com
. 따라서my-application
레지스트리에 라는 이미지를 저장할 계획이라면docker.example.com
해당 이미지에 태그를 지정해야합니다docker.example.com/my-application
. - TAG 열은 전체 태그 의 [: TAG] 부분 일뿐 입니다. 이것은 불행한 용어입니다.
latest
태그는 단순히 당신이 태그를 지정하지 않은 기본 태그의 마법이 아니다.- 태그가없는 이미지는 IMAGE ID로만 식별 할 수 있습니다. 이들은
<none>
TAG 및 REPOSITORY를 얻습니다 . 잊어 버리기 쉽습니다.
이미지에 대한 자세한 정보는 Docker 문서 및 용어집 에서 확인할 수 있습니다 .
컨테이너 란?
프로그래밍 비유를 사용하기 위해 이미지가 클래스 인 경우 컨테이너는 런타임 객체 인 클래스의 인스턴스입니다. 컨테이너는 Docker를 사용하는 이유입니다. 응용 프로그램을 실행할 환경의 가볍고 이식 가능한 캡슐화입니다.
다음을 사용하여 로컬 실행 컨테이너보기 docker ps
:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2ff1af05450 samalba/docker-registry:latest /bin/sh -c 'exec doc 4 months ago Up 12 weeks 0.0.0.0:5000->5000/tcp docker-registry
여기에서는 Docker 레지스트리의 dockerized 버전을 실행하여 이미지를 저장할 수있는 개인 공간을 확보했습니다. 다시 한 번 주목할 사항 :
- IMAGE ID와 마찬가지로 CONTAINER ID는 컨테이너의 실제 식별자입니다. 형식은 같지만 다른 종류의 개체를 식별합니다.
docker ps
실행중인 컨테이너 만 출력 합니다 . 를 사용하여 모든 컨테이너 ( 실행 중 또는 중지됨 )를 볼 수 있습니다docker ps -a
.- NAMES는
--name
플래그 를 통해 시작된 컨테이너를 식별하는 데 사용할 수 있습니다 .
이미지 및 컨테이너 축적을 방지하는 방법은 무엇입니까?
Docker에 대한 나의 초기 좌절감 중 하나는 태그가없는 이미지와 중지 된 컨테이너 가 겉보기에 지속적으로 쌓이는 것입니다 . 몇 가지 경우에 이러한 축적으로 인해 하드 드라이브가 최대로 사용되어 노트북 속도가 느려지거나 자동화 된 빌드 파이프 라인이 중단되었습니다. "사방의 컨테이너"에 대해 이야기하십시오!
docker rmi
최근 dangling=true
쿼리 와 결합 하여 태그가없는 모든 이미지를 제거 할 수 있습니다.
docker images -q --filter "dangling=true" | xargs docker rmi
Docker는 기존 컨테이너 뒤에있는 이미지를 제거 할 수 없으므로 docker rm
먼저 중지 된 컨테이너를 제거해야 할 수 있습니다 .
docker rm `docker ps --no-trunc -aq`
이는 Docker의 알려진 문제점 이며 향후 릴리스에서 해결 될 수 있습니다. 그러나 이미지와 컨테이너를 명확하게 이해하면 몇 가지 사례를 통해 이러한 상황을 피할 수 있습니다.
- 항상 쓸모없고 중지 된 컨테이너를
docker rm [CONTAINER_ID]
. - 항상 쓸모없고 중지 된 컨테이너 뒤에있는 이미지를
docker rmi [IMAGE_ID]
.
컨테이너를 실행중인 이미지로 생각하는 것이 가장 간단 하지만 정확 하지는 않습니다 .
이미지는 실제로 컨테이너로 변환 할 수있는 템플릿입니다. 이미지를 컨테이너로 전환하기 위해 Docker 엔진은 이미지를 가져 와서 읽기-쓰기 파일 시스템을 맨 위에 추가하고 네트워크 포트, 컨테이너 이름, ID 및 리소스 제한을 포함한 다양한 설정을 초기화합니다. 실행중인 컨테이너에는 현재 실행중인 프로세스가 있지만 컨테이너를 중지 (또는 Docker 용어로 종료) 할 수도 있습니다 . 종료 된 컨테이너는 다시 시작할 수 있고 해당 설정과 모든 파일 시스템 변경 사항을 유지하므로 이미지와 동일 하지 않습니다 .
쉬운 말로.
이미지 -
컨테이너를 만드는 데 사용되는 파일 시스템 및 구성 (읽기 전용) 응용 프로그램입니다. 자세한 내용 .
컨테이너 -
These are running instances of Docker images. Containers run the actual applications. A container includes an application and all of its dependencies. It shares the kernel with other containers and runs as an isolated process in user space on the host OS. More detail.
Other important terms to notice:
Docker daemon -
The background service running on the host that manages the building, running and distributing Docker containers.
Docker client -
The command line tool that allows the user to interact with the Docker daemon.
Docker Store -
Store is, among other things, a registry of Docker images. You can think of the registry as a directory of all available Docker images.
A picture from this blog is worth a thousand words.
(For deeper understanding please read this.)
Summary:
- Pull image from Docker hub or build from a Dockerfile => Gives a Docker image (not editable).
- Run the image (
docker run image_name:tag_name
) => Gives a running Image i.e. container (editable)
Maybe explaining the whole workflow can help.
Everything starts with the Dockerfile. The Dockerfile is the source code of the Image.
Once the Dockerfile is created, you build it to create the image of the container. The image is just the "compiled version" of the "source code" which is the Dockerfile.
Once you have the image of the container, you should redistribute it using the registry. The registry is like a git repository -- you can push and pull images.
Next, you can use the image to run containers. A running container is very similar, in many aspects, to a virtual machine (but without the hypervisor).
Workflow
Here is the end-to-end workflow showing the various commands and their associated inputs and outputs. That should clarify the relationship between an image and a container.
+------------+ docker build +--------------+ docker run -dt +-----------+ docker exec -it +------+
| Dockerfile | --------------> | Image | ---------------> | Container | -----------------> | Bash |
+------------+ +--------------+ +-----------+ +------+
^
| docker pull
|
+--------------+
| Registry |
+--------------+
To list the images you could run, execute:
docker image ls
To list the containers you could execute commands on:
docker ps
I couldn't understand the concept of image and layer in spite of reading all the questions here and then eventually stumbled upon this excellent documentation from Docker (duh!).
The example there is really the key to understand the whole concept. It is a lengthy post, so I am summarising the key points that need to be really grasped to get clarity.
Image: A Docker image is built up from a series of read-only layers
Layer: Each layer represents an instruction in the image’s Dockerfile.
Example
: The below Dockerfile contains four commands, each of which creates a layer.
FROM ubuntu:15.04
COPY . /app
RUN make /app
CMD python /app/app.py
Importantly, each layer is only a set of differences from the layer before it.
- Container. When you create a new container, you add a new writable layer on top of the underlying layers. This layer is often called the “container layer”. All changes made to the running container, such as writing new files, modifying existing files, and deleting files, are written to this thin writable container layer.
Hence, the major difference between a container and an image is the top writable layer. All writes to the container that add new or modify existing data are stored in this writable layer. When the container is deleted, the writable layer is also deleted. The underlying image remains unchanged.
Understanding images cnd Containers from a size-on-disk perspective
To view the approximate size of a running container, you can use the docker ps -s
command. You get size
and virtual size
as two of the outputs:
Size: the amount of data (on disk) that is used for the writable layer of each container
Virtual Size: the amount of data used for the read-only image data used by the container. Multiple containers may share some or all read-only image data. Hence these are not additive. I.e. you can't add all the virtual sizes to calculate how much size on disk is used by the image
Another important concept is the copy-on-write strategy
If a file or directory exists in a lower layer within the image, and another layer (including the writable layer) needs read access to it, it just uses the existing file. The first time another layer needs to modify the file (when building the image or running the container), the file is copied into that layer and modified.
I hope that helps someone else like me.
Dockerfile > (Build) > Image > (Run) > Container.
Dockerfile: contains a set of docker instructions that provisions your operating system the way you like, and installs/configure all your software's.
Image: compiled Dockerfile. Saves you time from rebuilding the Dockerfile every time you need to run a container. And it's a way to hide your provision code.
Container: the virtual operating system itself, you can ssh into it and run any commands you wish, as if it's a real environment. You can run 1000+ containers from the same Image.
Simply said, if an image is a class, then a container is an instance of a class is a runtime object.
A container is just an executable binary that is to be run by the host OS under a set of restrictions that are preset using an application (e.g., docker) that knows how to tell the OS which restrictions to apply.
The typical restrictions are process-isolation related, security related (like using SELinux protection) and system-resource related (memory, disk, cpu, networking).
Until recently only kernels in Unix-based systems supported the ability to run executables under strict restrictions. That's why most container talk today involves mostly Linux or other Unix distributions.
Docker is one of those applications that knows how to tell the OS (Linux mostly) what restrictions to run an executable under. The executable is contained in the Docker image, which is just a tarfile. That executable is usually a stripped-down version of a Linux distribution (Ubuntu, centos, Debian etc) preconfigured to run one or more applications within.
Though most people use a Linux base as the executable, it can be any other binary application as long as the host OS can run it. (see creating a simple base image using scratch). Whether the binary in the docker image is an OS or simply an application, to the OS host it is just another process, a contained process ruled by preset OS boundaries.
Other applications that, like Docker, can tell the host OS which boundaries to apply to a process while it is running include LXC, libvirt, and systemd. Docker used to use these applications to indirectly interact with the Linux OS, but now Docker interacts directly with Linux using its own library called "libcontainer".
So containers are just processes running in a restricted mode, similar to what chroot used to do.
IMO what sets Docker apart from any other container technology is its repository (Docker Hub) and their management tools which makes working with containers extremely easy.
See https://en.m.wikipedia.org/wiki/Docker_(Linux_container_engine)
The core concept of docker is to make it easy to create "machines" which in this case can be considered containers. The container aids in reusability, allowing you to create and drop containers with ease.
Images depict the state of a container at every point in time. So the basic workflow is:
- create an image
- start a container
- make changes to the container
- save the container back as an image
As many answers pointed this out: You build Dockerfile to get an image and you run image to get a container.
However, following steps helped me get a better feel for what Docker image and container are:
1) Build Dockerfile:
docker build -t my_image dir_with_dockerfile
2) Save the image to .tar
file
docker save -o my_file.tar my_image_id
my_file.tar
will store the image. Open it with tar -xvf my_file.tar
, and you will get to see all the layers. If you dive deeper into each layer you can see what changes were added in each layer. (They should be pretty close to commands in the Dockerfile).
3) To take a look inside of a container, you can do:
sudo docker run -it my_image bash
and you can see that is very much like an OS.
Image is an equivalent to a class definition in OOP and layers are different methods and properties of that class.
Container is the actual instantiation of the image just like how an object is an instantiation or an instance of a class.
A Docker image packs up the application and environment required by the application to run, and a container is a running instance of the image.
Images are the packing part of docker, analogous to "source code" or a "program". Containers are the execution part of docker, analogous to a "process".
In the question, only the "program" part is referred to and that's the image. The "running" part of docker is the container. When a container is run and changes are made, it's as if the process makes a change in it's own source code and saves it as the new image.
As in the programming aspect,
Image is a source code.
When source code is compiled and build, it is called as application.
Simillar to that "when instance is created for the image", it is called as "Container"
In short:
Container is a division (virtual) in a kernel which shares a common OS and runs an image (Docker image).
A container is a self-sustainable application that will have packages and all the necessary dependencies together to run the code.
A Docker container is running an instance of an image. You can relate an image with a program and a container with a process :)
An image is to a class as a container to an object.
A container is an instance of an image as an object is an instance of a class.
Dockerfile is like your bash script that produce a tarball (Docker image).
Docker containers is like extracted version of the tarball. You can have as many copies as you like in different folders (the containers)
For a dummy programming analogy, you can think of Docker has a abstract ImageFactory which holds ImageFactories they come from store.
Then once you want to create an app out of that ImageFactory, you will have a new container, and you can modify it as you want. DotNetImageFactory will be immutable, because it acts as a abstract factory class, where it only delivers instances you desire.
IContainer newDotNetApp = ImageFactory.DotNetImageFactory.CreateNew(appOptions);
newDotNetApp.ChangeDescription("I am making changes on this instance");
newDotNetApp.Run();
I think it is better to explain at the beginning.
Suppose you run command: Docker run hello-world. what happens ?
it calls docker cli which is responsible to take docker commands and transform to call docker server commands. as soon as docker server gets command to run image, it checks weather images cache holds an image such name. suppose hello-world do not exists. docker server goes to docker hub ( docker hub is just a free repository of images ) and asks, hey Hub, do you have an image called hello-world ? Hub responses - yes i do. then give it to me, please. and download process starts. as soon as docker image is downloaded, docker server puts it in image cache.
So before we explain what is docker image and docker container, let's start with introduction about operation system on your computer and how it runs software.
when you run for example chrome on your computer, it calls operation system, operation system itself calls kernel and asks, hey i want to run this program. kernel manages to run files from your hard disk.
now imagine that you have two programs chrome and nodejs. chrome requires python version 2 to run and nodejs requires python version 3 to run. if you have installed only python v2 on your computer, only chrome will be runned.
to make both cases work, somehow you need to use operational system feature known as namespacing. namespace is feature which gives you opportunity to isolate processes, hard drive, network, users, hostnames and so on.
So, when we talk about an Image we actually talk about file system snapshot. An image is a physical file which contains directions and metadata to build specific container. Container itself is an instance of an image, it isolates hard drive using namespacing which is available only for this container. So container is a process or set of processes which groups different resources assigned to it.
An image is a "snapshot" of a container. You can make images from a container (new "snapshots"), and you can also start new containers from an image (instantiate the "snapshot").
For example, you can instantiate a new container from a base image, run some commands in the container, and then snapshot that as a new image. Then you can run 100 containers from that new image.
Other things to consider:
- An image is made of layers, layers are snapshot "diffs" (so when you push an image, you only need to send the "diff" to the registry).
- A Dockerfile defines some commands on top of a base image, that creates new layers ("diffs") that result in a new image ("snapshot").
- Image tags are not just tags, they are the image "full name" ("repository:tag"). If the same image has multiple names, it shows multiple times when doing
docker images
.
'development' 카테고리의 다른 글
Python에서 파일을 이동하는 방법 (0) | 2020.09.29 |
---|---|
jQuery UI 대화 상자에서 닫기 버튼을 제거하는 방법은 무엇입니까? (0) | 2020.09.29 |
PHP 임의 문자열 생성기 (0) | 2020.09.29 |
기본 "긴 폴링"을 어떻게 구현합니까? (0) | 2020.09.29 |
Java, 매개 변수의 점 3 개 (0) | 2020.09.29 |