Open lihongjie0209 opened 4 years ago
The Docker daemon (dockerd
) listens for Docker API requests and manages Docker
objects such as images, containers, networks, and volumes. A daemon can also
communicate with other daemons to manage Docker services.
The Docker client (docker
) is the primary way that many Docker users interact
with Docker. When you use commands such as docker run
, the client sends these
commands to dockerd
, which carries them out. The docker
command uses the
Docker API. The Docker client can communicate with more than one daemon.
A Docker registry stores Docker images. Docker Hub is a public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default. You can even run your own private registry.
When you use the docker pull
or docker run
commands, the required images are
pulled from your configured registry. When you use the docker push
command,
your image is pushed to your configured registry.
An image is a read-only template with instructions for creating a Docker
container. Often, an image is based on another image, with some additional
customization. For example, you may build an image which is based on the ubuntu
image, but installs the Apache web server and your application, as well as the
configuration details needed to make your application run.
You might create your own images or you might only use those created by others and published in a registry. To build your own image, you create a Dockerfile with a simple syntax for defining the steps needed to create the image and run it. Each instruction in a Dockerfile creates a layer in the image. When you change the Dockerfile and rebuild the image, only those layers which have changed are rebuilt. This is part of what makes images so lightweight, small, and fast, when compared to other virtualization technologies.
A container is a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI. You can connect a container to one or more networks, attach storage to it, or even create a new image based on its current state.
By default, a container is relatively well isolated from other containers and its host machine. You can control how isolated a container’s network, storage, or other underlying subsystems are from other containers or from the host machine.
A container is defined by its image as well as any configuration options you provide to it when you create or start it. When a container is removed, any changes to its state that are not stored in persistent storage disappear.
On Linux, Docker manipulates iptables
rules to provide network isolation.
While this is an implementation detail and you should not modify the rules
Docker inserts into your iptables
policies, it does have some implications
on what you need to do if you want to have your own policies in addition to
those managed by Docker.
If you’re running Docker on a host that is exposed to the Internet, you will probably want to have iptables policies in place that prevent unauthorized access to containers or other services running on your host. This page describes how to achieve that, and what caveats you need to be aware of.
Docker installs two custom iptables chains named DOCKER-USER
and DOCKER
,
and it ensures that incoming packets are always checked by these two chains
first.
All of Docker’s iptables
rules are added to the DOCKER
chain. Do not
manipulate this chain manually. If you need to add rules which load before
Docker’s rules, add them to the DOCKER-USER
chain. These rules are applied
before any rules Docker creates automatically.
Rules added to the FORWARD
chain -- either manually, or by another
iptables-based firewall -- are evaluated after these chains. This means that
if you expose a port through Docker, this port gets exposed no matter what
rules your firewall has configured. If you want those rules to apply even
when a port gets exposed through Docker, you must add these rules to the
DOCKER-USER
chain.
By default, all external source IPs are allowed to connect to the Docker host.
To allow only a specific IP or network to access the containers, insert a
negated rule at the top of the DOCKER-USER
filter chain. For example, the
following rule restricts external access from all IP addresses except 192.168.1.1
:
$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP
Please note that you will need to change ext_if
to correspond with your
host’s actual external interface. You could instead allow connections from a
source subnet. The following rule only allows access from the subnet 192.168.1.0/24
:
$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP
Finally, you can specify a range of IP addresses to accept using --src-range
(Remember to also add -m iprange
when using --src-range
or --dst-range
):
$ iptables -I DOCKER-USER -m iprange -i ext_if ! --src-range 192.168.1.1-192.168.1.3 -j DROP
You can combine -s
or --src-range
with -d
or --dst-range
to control both
the source and destination. For instance, if the Docker daemon listens on both
192.168.1.99
and 10.1.2.3
, you can make rules specific to 10.1.2.3
and leave
192.168.1.99
open.
iptables
is complicated and more complicated rules are out of scope for this
topic. See the Netfilter.org HOWTO
for a lot more information.
Docker’s networking subsystem is pluggable, using drivers. Several drivers exist by default, and provide core networking functionality:
bridge
: The default network driver. If you don’t specify a driver, this is
the type of network you are creating. Bridge networks are usually used when
your applications run in standalone containers that need to communicate. See
bridge networks.
host
: For standalone containers, remove network isolation between the
container and the Docker host, and use the host’s networking directly. host
is only available for swarm services on Docker 17.06 and higher. See
use the host network.
overlay
: Overlay networks connect multiple Docker daemons together and
enable swarm services to communicate with each other. You can also use overlay
networks to facilitate communication between a swarm service and a standalone
container, or between two standalone containers on different Docker daemons.
This strategy removes the need to do OS-level routing between these
containers. See overlay networks.
macvlan
: Macvlan networks allow you to assign a MAC address to a container,
making it appear as a physical device on your network. The Docker daemon
routes traffic to containers by their MAC addresses. Using the macvlan
driver is sometimes the best choice when dealing with legacy applications that
expect to be directly connected to the physical network, rather than routed
through the Docker host’s network stack. See
Macvlan networks.
none
: For this container, disable all networking. Usually used in
conjunction with a custom network driver. none
is not available for swarm
services. See
disable container networking.
Volumes: Created and managed by Docker. You can create a
volume explicitly using the docker volume create
command, or Docker can
create a volume during container or service creation.
When you create a volume, it is stored within a directory on the Docker host. When you mount the volume into a container, this directory is what is mounted into the container. This is similar to the way that bind mounts work, except that volumes are managed by Docker and are isolated from the core functionality of the host machine.
A given volume can be mounted into multiple containers simultaneously. When no
running container is using a volume, the volume is still available to Docker
and is not removed automatically. You can remove unused volumes using docker volume prune
.
When you mount a volume, it may be named or anonymous. Anonymous volumes are not given an explicit name when they are first mounted into a container, so Docker gives them a random name that is guaranteed to be unique within a given Docker host. Besides the name, named and anonymous volumes behave in the same ways.
Volumes also support the use of volume drivers, which allow you to store your data on remote hosts or cloud providers, among other possibilities.
Bind mounts: Available since the early days of Docker. Bind mounts have limited functionality compared to volumes. When you use a bind mount, a file or directory on the host machine is mounted into a container. The file or directory is referenced by its full path on the host machine. The file or directory does not need to exist on the Docker host already. It is created on demand if it does not yet exist. Bind mounts are very performant, but they rely on the host machine’s filesystem having a specific directory structure available. If you are developing new Docker applications, consider using named volumes instead. You can’t use Docker CLI commands to directly manage bind mounts.
Bind mounts allow access to sensitive files
One side effect of using bind mounts, for better or for worse, is that you can change the host filesystem via processes running in a container, including creating, modifying, or deleting important system files or directories. This is a powerful ability which can have security implications, including impacting non-Docker processes on the host system.
tmpfs mounts: A tmpfs
mount is not persisted on disk, either
on the Docker host or within a container. It can be used by a container during
the lifetime of the container, to store non-persistent state or sensitive
information. For instance, internally, swarm services use tmpfs
mounts to
mount secrets into a service’s containers.
named pipes: An npipe
mount can be used for communication between the Docker host and a container. Common use case is
to run a third-party tool inside of a container and connect to the Docker Engine API using a named pipe.
docker 引擎
Docker Engine is a client-server application with these major components:
A server which is a type of long-running program called a daemon process (the dockerd command).
A REST API which specifies interfaces that programs can use to talk to the daemon and instruct it what to do.
A command line interface (CLI) client (the docker command).