Основная технология Docker и принцип реализации

задняя часть Операционная система Linux Docker
Основная технология Docker и принцип реализации

Когда дело доходит до технологии виртуализации, мы должны в первую очередь думать о Docker.После четырех лет быстрого развития Docker стал широко использоваться в производственной среде многих компаний, и это уже не игрушка, которую можно использовать только в этап разработки. Как продукт, широко используемый в производственных средах, Docker имеет очень зрелое сообщество и большое количество пользователей, а содержимое базы кода стало очень большим.

docker-logo

Опять же, из-за развития проекта, разделения функций и различных странных изменений имени.PR, понять общую архитектуру Docker снова становится сложнее.

Хотя в настоящее время Docker состоит из множества компонентов и очень сложен для реализации, в этой статье мы не хотим слишком подробно рассказывать о конкретных деталях реализации Docker, а поговорим об основных технологиях, поддерживающих появление Docker, технологии виртуализации.

docker-core-techs

Прежде всего, появление Docker должно быть связано с тем, что текущая серверная часть действительно нуждается в технологии виртуализации на этапах разработки, эксплуатации и обслуживания, чтобы решить проблему согласованности среды разработки и производственной среды.Через Docker мы можем также включить среду, в которой программа работает в системе контроля версий. , исключить возможность различных результатов работы из-за среды. Однако, хотя вышеуказанные требования способствовали развитию технологии виртуализации, если нет подходящей базовой технической поддержки, мы все равно не сможем получить идеальный продукт. В оставшейся части этой статьи будут представлены несколько основных технологий, используемых Docker.Если мы поймем, как и как они используются, мы сможем понять, как реализован Docker.

Namespaces

Пространства имен (namespaces) — это метод, который Linux предоставляет нам для разделения ресурсов, таких как деревья процессов, сетевые интерфейсы, точки монтирования и межпроцессное взаимодействие. При повседневном использовании Linux или macOS нам не нужно запускать несколько совершенно отдельных серверов, но если мы запустим несколько служб на сервере, эти службы фактически будут влиять друг на друга, и каждая служба может видеть процесс других служб, а также может получать доступ к ним. любой файл на хост-компьютере, который часто не хочет видеть.Мы предпочитаем, чтобы разные службы, работающие на одном и том же компьютере, могли это делать.полностью изолирован, как если бы он работал на нескольких разных машинах.

multiple-servers-on-linux

В этом случае, когда служба на сервере захвачена, злоумышленник может получить доступ ко всем службам и файлам на текущей машине, чего мы не хотим видеть, и Docker фактически использует пространства имен Linux для различных служб. изоляция.

Механизм пространства имен Linux предоставляет следующие семь различных пространств имен, в том числеCLONE_NEWCGROUP,CLONE_NEWIPC,CLONE_NEWNET,CLONE_NEWNS,CLONE_NEWPID,CLONE_NEWUSERиCLONE_NEWUTS, с помощью этих семи опций мы можем указать, какие ресурсы новый процесс должен изолировать от хост-компьютера при создании нового процесса.

процесс

Процесс — очень важное понятие в Linux и текущей операционной системе, которое представляет собой выполняемую программу и единицу задачи в современной запланированной системе. Можем передать каждую *NIX операционную системуpsКоманда выводит процессы, которые в данный момент выполняются в текущей операционной системе.Например, в Ubuntu с помощью этой команды можно получить следующие результаты:

$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Apr08 ?        00:00:09 /sbin/init
root         2     0  0 Apr08 ?        00:00:00 [kthreadd]
root         3     2  0 Apr08 ?        00:00:05 [ksoftirqd/0]
root         5     2  0 Apr08 ?        00:00:00 [kworker/0:0H]
root         7     2  0 Apr08 ?        00:07:10 [rcu_sched]
root        39     2  0 Apr08 ?        00:00:00 [migration/0]
root        40     2  0 Apr08 ?        00:01:54 [watchdog/0]
...

На текущей машине выполняется много процессов.Среди вышеперечисленных процессов есть два очень особенных, один из нихpidиз 1/sbin/initпроцесс, другойpidна 2kthreaddпроцесс, оба из которых используются процессом бога в LinuxidleСозданный, первый отвечает за выполнение части работ по инициализации и системной настройке ядра, а также создает некоторые подобныеgettyПроцесс регистрации, который отвечает за управление расписанием и другими основными процессами.

linux-processes

Если у нас запустите новый контейнер докеров под текущей операционной системой Linux и пропуститеexecв его интерьерbashи распечатаем в нем все процессы, получим следующие результаты:

root@iZ255w13cy6Z:~# docker run -it -d ubuntu
b809a2eb3630e64c581561b08ac46154878ff1c61c6519848b4a29d412215e79
root@iZ255w13cy6Z:~# docker exec -it b809a2eb3630 /bin/bash
root@b809a2eb3630:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 15:42 pts/0    00:00:00 /bin/bash
root         9     0  0 15:42 pts/1    00:00:00 /bin/bash
root        17     9  0 15:43 pts/1    00:00:00 ps -ef

Выполнить внутри нового контейнераpsКоманда выводит очень чистый список процессов, содержащий только текущийps -efВключая три процесса, десятки процессов на хост-компьютере исчезли.

Текущий контейнер Docker успешно изолирует процесс в контейнере от процесса на хост-компьютере.Если мы напечатаем все текущие процессы на хост-компьютере, мы получим следующие три результата, связанные с Docker:

UID        PID  PPID  C STIME TTY          TIME CMD
root     29407     1  0 Nov16 ?        00:08:38 /usr/bin/dockerd --raw-logs
root      1554 29407  0 Nov19 ?        00:03:28 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc
root      5006  1554  0 08:38 ?        00:00:00 docker-containerd-shim b809a2eb3630e64c581561b08ac46154878ff1c61c6519848b4a29d412215e79 /var/run/docker/libcontainerd/b809a2eb3630e64c581561b08ac46154878ff1c61c6519848b4a29d412215e79 docker-runc

На текущем хост-компьютере может быть дерево процессов, состоящее из различных процессов, упомянутых выше:

docker-process-group

Это используетclone(2)Передано при создании нового процессаCLONE_NEWPIDЧто достигается, то есть с помощью пространства имен Linux для достижения изоляции процессов любой процесс внутри контейнера Docker ничего не знает о процессе хост-машины.

containerRouter.postContainersStart
└── daemon.ContainerStart
    └── daemon.createSpec
        └── setNamespaces
            └── setNamespace

Контейнер Docker использует описанную выше технологию для достижения изоляции процесса от хост-компьютера.docker runилиdocker start, спецификация для настройки межпроцессной изоляции создается следующим методом:

func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
	s := oci.DefaultSpec()

	// ...
	if err := setNamespaces(daemon, &s, c); err != nil {
		return nil, fmt.Errorf("linux spec namespaces: %v", err)
	}

	return &s, nil
}

существуетsetNamespacesМетод не только установит пространство имен, связанное с процессом, но также установит пространство имен, связанное с пользователем, сетью, IPC и UTS:

func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error {
	// user
	// network
	// ipc
	// uts

	// pid
	if c.HostConfig.PidMode.IsContainer() {
		ns := specs.LinuxNamespace{Type: "pid"}
		pc, err := daemon.getPidContainer(c)
		if err != nil {
			return err
		}
		ns.Path = fmt.Sprintf("/proc/%d/ns/pid", pc.State.GetPID())
		setNamespace(s, ns)
	} else if c.HostConfig.PidMode.IsHost() {
		oci.RemoveNamespace(s, specs.LinuxNamespaceType("pid"))
	} else {
		ns := specs.LinuxNamespace{Type: "pid"}
		setNamespace(s, ns)
	}

	return nil
}

Все настройки, связанные с пространством именSpecв конечном итоге будетCreateПараметры функции задаются при создании нового контейнера:

daemon.containerd.Create(context.Background(), container.ID, spec, createOptions)

Все настройки, связанные с пространством имен, выполняются в двух вышеперечисленных функциях: Docker с полной изоляцией пространства имен от хост-процесса и сетевым успехом.

Интернет

Если контейнер Docker завершает сетевую изоляцию от хост-процесса через пространство имен Linux, но нет возможности подключиться ко всему Интернету через хост-сеть, будет много ограничений, поэтому, хотя Docker может создать изоляцию через пространство имен network среде, но службы в Docker по-прежнему должны быть подключены к внешнему миру, чтобы функционировать.

каждое использованиеdocker runЗапущенные контейнеры имеют отдельное сетевое пространство имен, и Docker предоставляет нам четыре различных сетевых режима: Host, Container, None и Bridge.

docker-network

В этой части мы представим режим настройки сети Docker по умолчанию: режим моста. В этом режиме, помимо выделения изолированных сетевых пространств имен, Docker также устанавливает IP-адреса для всех контейнеров. Когда сервер Docker находится на хосте, создается новый виртуальный мост docker0, и все сервисы, впоследствии запущенные на хосте, подключаются к этому мосту в одном случае.

docker-network-topology

По умолчанию каждый контейнер будет создан при создании пары виртуальных сетевых адаптеров, две сетевые карты образуют виртуальный канал данных, который будет помещен в созданный контейнер, он будет добавлен в мост с именем docker0. Мы можем использовать следующую команду для просмотра текущих интерфейсов моста:

$ brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.0242a6654980	no		veth3e84d4f
							            veth9953b75

Docker0 назначит новый IP-адрес для каждого контейнера и установит IP-адрес Docker0 в качестве шлюза по умолчанию. Мост Docker0 подключается к сетевой карте на хост-машине в iptables, и все подходящие запросы перенаправляются в Docker0 через iptables и распределяются на соответствующие машины с моста.

$ iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL

Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

Используем на текущей машинеdocker run -d -p 6379:6379 redisКоманда для запуска нового контейнера Redis, после чего мы увидим текущийiptablesКонфигурация NAT будет отображаться вDOCKERВ цепочке из :

DNAT       tcp  --  anywhere             anywhere             tcp dpt:6379 to:192.168.0.4:6379

Приведенное выше правило будет пересылать TCP-пакеты, отправленные из любого источника, на порт 6379 текущей машины на адрес, где находится 192.168.0.4:6379.

Этот адрес на самом деле является IP-адресом, назначенным Docker в качестве службы Redis.Если мы напрямую пропингуем этот IP-адрес на текущей машине, он обнаружит, что к нему можно получить доступ:

$ ping 192.168.0.4
PING 192.168.0.4 (192.168.0.4) 56(84) bytes of data.
64 bytes from 192.168.0.4: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 192.168.0.4: icmp_seq=2 ttl=64 time=0.043 ms
^C
--- 192.168.0.4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.043/0.056/0.069/0.013 ms

Из приведенного выше ряда явлений мы можем сделать вывод о том, как Docker раскрывает внутренние порты контейнера и пересылает пакеты данных; когда есть контейнер Docker, которому необходимо предоставить службу хост-компьютеру, он будет выделен контейнеру. IP-адрес и добавляет новое правило в iptables.

docker-network-forward

когда мы используемredis-cliПри доступе к адресу 127.0.0.1:6379 в командной строке хост-машины ip-адрес направляется на 192.168.0.4 через NAT PREROUTING iptables, а перенаправленные пакеты данных можно настроить через FILTER в iptables, и, наконец, NAT POSTROUTING Стадия маскирует IP-адрес как 127.0.0.1.Хотя извне кажется, что мы запрашиваем 127.0.0.1:6379, на самом деле мы запрашиваем порт, открытый контейнером Docker.

$ redis-cli -h 127.0.0.1 -p 6379 ping
PONG

Docker реализует сетевую изоляцию через пространства имен Linux и перенаправляет пакеты через iptables, позволяя контейнерам Docker изящно предоставлять услуги хост-компьютерам или другим контейнерам.

libnetwork

Вся сетевая часть реализована через Docker's Split libnetwork, что обеспечивает реализацию для подключения к разным контейнерам и может также дать приложение для предоставления последовательных интерфейсов программирования и абстрактных слоев сетиМодель контейнерной сети.

The goal of libnetwork is to deliver a robust Container Network Model that provides a consistent programming interface and the required network abstractions for applications.

Наиболее важная концепция в libnetwork, модель контейнерной сети, состоит из следующих основных компонентов, а именно песочницы, конечной точки и сети:

container-network-model

В модели контейнерной сети каждый контейнер содержит песочницу, в которой хранится конфигурация сетевого стека текущего контейнера, включая интерфейс контейнера, таблицу маршрутизации и настройки DNS.Linux использует сетевое пространство имен для реализации этой песочницы, и каждая песочница содержит может быть одна или несколько конечных точек, которая представляет собой виртуальную сетевую карту в Linux.Песочница добавляется в соответствующую сеть через конечные точки.Сеть здесь может быть мостом Linux или VLAN, о которых мы упоминали выше.

Дополнительные сведения о libnetwork или модели контейнерной сети см.Design · libnetworkДля получения дополнительной информации, конечно, вы можете прочитать исходный код, чтобы понять различные реализации разных ОС в модели контейнерной сети.

точка крепления

Хотя мы разрешили проблемы с процессом и сетевыми проблемами изоляции через Linux, у нас нет возможности получить доступ к другим процессам на хосте и ограничить доступ к сети, но процесс в контейнере докена до сих пор доступен или изменен. Другие каталоги на хост-машина, это Это то, что мы не хотим видеть.

Создание пространства имен изолированной точки монтирования в новом процессе требуетcloneпередается в функциюCLONE_NEWNS, чтобы дочерний процесс мог получить копию точки монтирования родительского процесса, если этот параметр не переданДочерний процесс будет синхронизирован с файловой системой для файловой системы и файловой системы всего хоста..

Если контейнер необходимо запустить, он должен предоставить корневую файловую систему (rootfs), контейнер должен использовать эту файловую систему для создания нового процесса, и все выполнение двоичных файлов должно выполняться в этой корневой файловой системе.

libcontainer-filesystem

Для нормального запуска контейнера необходимо смонтировать указанные выше каталоги в rootfs.Помимо указанных выше каталогов, которые необходимо смонтировать, нам также необходимо установить некоторые символические ссылки, чтобы гарантировать отсутствие проблем с системным вводом-выводом.

libcontainer-symlinks-and-io

Чтобы убедиться, что текущий процесс-контейнер не имеет доступа к другим каталогам на хост-компьютере, нам также нужно использовать здесь libcotainer.pivor_rootилиchrootПроцесс изменения функции может получить доступ к корневому каталогу документа.

// pivor_root
put_old = mkdir(...);
pivot_root(rootfs, put_old);
chdir("/");
unmount(put_old, MS_DETACH);
rmdir(put_old);

// chroot
mount(rootfs, "/", NULL, MS_MOVE, NULL);
chroot(".");
chdir("/");

На этом этапе мы монтируем в контейнер необходимые каталоги, а также запрещаем текущему процессу контейнера доступ к другим каталогам на хост-машине, обеспечивая изоляцию разных файловых систем.

Содержимое этой части принадлежит автору в libcontainer.SPEC.mdВ файле, содержащем описание файловой системы, используемой Docker, найдено, действительно ли Docker используетchrootЧтобы гарантировать, что текущий процесс не сможет получить доступ к каталогу хост-машины, автор фактическинет определенного ответа, один Код проекта Docker слишком велик, и я не знаю, с чего начать Автор пытался найти соответствующие результаты через Google, но ответа не нашел.проблема, также получили противоречивые описания в SPECОтвечать, если у читателей есть четкий ответ, вы можете оставить сообщение под блогом, большое спасибо.

chroot

Здесь мы должны кратко представитьchroot(изменить корень), в системе Linux системный каталог по умолчанию/То есть запускается корневой каталог.chrootИспользование может изменить текущую структуру корневого каталога системы, изменив текущий корневой каталог системы, мы можем ограничить права пользователя, в новом корневом каталоге нельзя получить доступ к структуре файлов корневого каталога старой системы, а также установить структуру каталогов. полностью изолированы от исходной системы.

Часть контента, связанного с chroot, взята изПонимание chrootЧитатели могут прочитать эту статью для получения более подробной информации.

CGroups

Мы изолируем файловую систему, сеть и процесс от хост-машины для вновь созданного процесса через пространство имен Linux, но пространство имен не обеспечивает нам изоляцию физических ресурсов, таких как ЦП или память, если в поле " контейнеры», работающие на одной машине, которые ничего не знают друг о друге и хост-машине, но эти контейнеры в совокупности занимают физические ресурсы хост-машины.

docker-shared-resources

Если судно выполняет определенные задачи с интенсивным использованием ЦП, это повлияет на производительность и эффективность выполнения других задач в контейнере, что приведет к большему взаимодействию и захвату ресурсов контейнерами. Как ограничить использование ресурсов стало больше контейнеров для решения основных проблем после процесса изоляции виртуальных ресурсов, а группы управления (называемые CGroups) — это возможность изолировать физические ресурсы на хост-машине, такие как ЦП, память, диск Ввод/вывод и пропускная способность сети.

Каждая CGroup представляет собой группу процессов, ограниченных одними и теми же стандартами и параметрами, между разными CGgroups существует иерархическая связь, то есть они могут наследовать некоторые стандарты и параметры ограничения использования ресурсов от родительского класса.

cgroups-inheritance

CGroup в Linux может выделять ресурсы группе процессов, то есть ЦП, память, пропускную способность сети и другие ресурсы, упомянутые выше.Благодаря распределению ресурсов CGroup может выполнять следующие функции:

groups-features

В CGroup все задачи это процесс системы, а CGroup это группа процессов разделенных по определенному стандарту.В механизме CGroup все управление ресурсами реализуется CGroup как единым целым.Каждый процесс Вы можете присоединиться к CGroup в любое время и выйти из CGroup в любое время.

Введение в CGroup, примеры применения и описание принципа

Linux использует файловую систему для реализации CGroup.Мы можем напрямую использовать следующую команду, чтобы проверить, какие подсистемы находятся в текущей CGroup:

$ lssubsys -m
cpuset /sys/fs/cgroup/cpuset
cpu /sys/fs/cgroup/cpu
cpuacct /sys/fs/cgroup/cpuacct
memory /sys/fs/cgroup/memory
devices /sys/fs/cgroup/devices
freezer /sys/fs/cgroup/freezer
blkio /sys/fs/cgroup/blkio
perf_event /sys/fs/cgroup/perf_event
hugetlb /sys/fs/cgroup/hugetlb

Большинство дистрибутивов Linux имеют очень похожие подсистемы, а перечисленные выше вещи, такие как набор процессоров, процессор и т. д., называются подсистемами, потому что они могут распределять ресурсы по соответствующим контрольным группам и ограничивать использование ресурсов.

Если мы хотим создать новую контрольную группу, просто создайте новую папку под подсистемой, которую мы хотим выделить или ограничить ресурсы, тогда в этой папке автоматически будет много содержимого, если у вас установлен Docker в Linux, вы найдете папку с именем docker в каталоге всех подсистем:

$ ls cpu
cgroup.clone_children  
...
cpu.stat  
docker  
notify_on_release 
release_agent 
tasks

$ ls cpu/docker/
9c3057f1291b53fd54a3d12023d2644efe6a7db6ddf330436ae73ac92d401cf1 
cgroup.clone_children  
...
cpu.stat  
notify_on_release 
release_agent 
tasks

9c3057xxxПо сути, это Docker-контейнер, который мы запускаем.При запуске контейнера Docker создаст для контейнера CGroup с тем же идентификатором, что и контейнер.На текущем хосте CGroup будет иметь следующую иерархическую взаимосвязь:

linux-cgroups

Под каждой CGroup естьtasksфайл, в котором хранятся pids всех процессов, входящих в текущую контрольную группу, как подсистема, отвечающая за cpu,cpu.cfs_quota_usСодержимое файла может ограничивать использование ЦП.Если содержимое текущего файла равно 50000, использование ЦП всеми процессами в текущей контрольной группе не может превышать 50%.

Если системный администратор хочет контролировать использование ресурсов контейнера Docker, это может бытьdockerНайдите соответствующие дочерние группы управления в этой родительской группе управления и измените содержимое соответствующих файлов.Конечно, мы также можем использовать параметры непосредственно во время работы программы, чтобы позволить процессу Docker изменить содержимое соответствующих файлов.

$ docker run -it -d --cpu-quota=50000 busybox
53861305258ecdd7f5d2a3240af694aec9adb91cd4c7e210b757f71153cdd274
$ cd 53861305258ecdd7f5d2a3240af694aec9adb91cd4c7e210b757f71153cdd274/
$ ls
cgroup.clone_children  cgroup.event_control  cgroup.procs  cpu.cfs_period_us  cpu.cfs_quota_us  cpu.shares  cpu.stat  notify_on_release  tasks
$ cat cpu.cfs_quota_us
50000

Когда мы используем Docker для закрытия запущенного контейнера, папка, соответствующая подгруппе управления Docker, также будет удалена процессом Docker.Когда Docker использует CGroup, он фактически выполняет только некоторые файловые операции для создания папок и изменения содержимого Тем не менее, использование CGroup действительно решает проблему, заключающуюся в том, что мы ограничиваем использование ресурсов подконтейнерами.Системный администратор может разумно распределять ресурсы для нескольких контейнеров без проблемы, когда несколько контейнеров вытесняют ресурсы друг друга.

UnionFS

Пространство имен и контрольная группа Linux решают проблему изоляции различных ресурсов соответственно.Первое решает изоляцию процесса, сети и файловой системы, а второе реализует изоляцию таких ресурсов, как ЦП и память, но в Docker есть еще одна очень важная вещь. Проблема должна быть решена - это зеркалирование.

Что такое образ, как он составлен и организован — вопрос, который озадачил автора некоторое время с тех пор, как он использовал Docker.docker runОчень легко загружать образы Docker с удаленного компьютера и запускать локально.

Образ Docker на самом деле представляет собой сжатый пакет. Мы можем использовать следующую команду для экспорта файлов в образ Docker:

$ docker export $(docker create busybox) | tar -C rootfs -xvf -
$ ls
bin  dev  etc  home proc root sys  tmp  usr  var

Вы можете увидеть содержимое структуры корневого каталога операционной системы Linux в зеркале busybox, и можно сказать, что особой разницы нет.Образ Docker — это просто файл.

накопитель

Docker использует ряд различных драйверов хранилища для управления файловой системой внутри образа и запуска контейнера.Эти драйверы хранилища несколько отличаются от тома (тома) Docker, а подсистема хранилища управляет хранилищем, которое может совместно использоваться несколькими контейнерами.

Чтобы понять драйверы хранилища, используемые Docker, нам сначала нужно понять, как Docker создает и хранит образы и как образы Docker используются каждым контейнером; каждый образ в Docker состоит только из серии Каждая команда в Dockerfile создает новый слой поверх существующего слоя только для чтения:

FROM ubuntu:15.04
COPY . /app
RUN make /app
CMD python /app/app.py

Каждый слой в контейнере вносит очень небольшие изменения в текущий контейнер.Вышеупомянутый Dockerfile создаст образ с четырьмя слоями:

docker-container-laye

Зеркалоdocker runПри создании команды к верхнему слою образа добавляется доступный для записи слой, то есть слой контейнера.Все модификации контейнера среды выполнения фактически являются модификациями слоя чтения-записи контейнера.

Разница между контейнерами и образами в том, что все образы доступны только для чтения, и каждый контейнер фактически равен изображению плюс слой чтения-записи, то есть одному и тому же образу может соответствовать несколько контейнеров.

docker-images-and-container

AUFS

UnionFS на самом деле является службой файловой системы, разработанной для операционной системы Linux для «присоединения» нескольких файловых систем к одной и той же точке монтирования. AUFS или Advanced UnionFS на самом деле является обновленной версией UnionFS, которая обеспечивает более высокую производительность и эффективность.

Как файловая система объединения, AUFS может объединять слои в разных папках в одну папку.Эти папки называются ветвями в AUFS, а весь процесс "объединения" называетсяЮнион Маунт:

docker-aufs

Каждый слой изображения или слой контейнера/var/lib/docker/Подпапка каталога; в Docker все содержимое слоя изображений и контейнеров хранится в/var/lib/docker/aufs/diff/В каталоге:

$ ls /var/lib/docker/aufs/diff/00adcccc1a55a36a610a6ebb3e07cc35577f2f5a3b671be3dbc0e74db9ca691c       93604f232a831b22aeb372d5b11af8c8779feb96590a6dc36a80140e38e764d8
00adcccc1a55a36a610a6ebb3e07cc35577f2f5a3b671be3dbc0e74db9ca691c-init  93604f232a831b22aeb372d5b11af8c8779feb96590a6dc36a80140e38e764d8-init
019a8283e2ff6fca8d0a07884c78b41662979f848190f0658813bb6a9a464a90       93b06191602b7934fafc984fbacae02911b579769d0debd89cf2a032e7f35cfa
...

и/var/lib/docker/aufs/layers/Метаданные зеркального слоя хранятся в файле, и каждый файл сохраняет метаданные зеркального слоя./var/lib/docker/aufs/mnt/Точки монтирования, содержащие изображения или слои контейнера, в конечном итоге будут собраны Docker в федеративной манере.

docker-filesystems

Это изображение выше показывает процесс сборки очень хорошего, каждый слой изображения построен на верхней части другого слоя изображения, в то время как все зеркальные слои являются только для чтения, и только каждый контейнер верхний слой контейнеров, который пользователь может напрямую прочитать и писать, все Контейнеры построены на одном из базовой службы (ядра), включая пространства имен, контрольную группу, rootfs и т. Д., Этот способ сборки контейнера обеспечивает большую гибкость, только чтение, только путем совместного использования зеркального слоя может уменьшить использование дискового пространства.

Другие накопители

AUFS — это лишь один из драйверов хранилища, используемых Docker.Помимо AUFS, Docker также поддерживает различные драйверы хранилища, в том числеaufs,devicemapper,overlay2,zfsиvfsПодождите, в последнем Docker,overlay2замененыaufsстал рекомендуемым драйвером хранилища, но когда нетoverlay2будет по-прежнему использоваться на силовых машинахaufsВ качестве драйвера по умолчанию для Docker.

docker-storage-driver

Различные драйверы хранилища также имеют совершенно разные реализации при хранении образов и файлов-контейнеров.Заинтересованные читатели могут обратиться к официальной документации Docker.Select a storage driverнайти соответствующий контент.

Чтобы узнать, какой драйвер хранилища используется в Docker текущей системы, просто используйте следующую команду для получения соответствующей информации:

$ docker info | grep Storage
Storage Driver: aufs

В Ubuntu автора нетoverlay2драйвер хранилища, поэтому используйтеaufsВ качестве драйвера хранилища по умолчанию для Docker.

Суммировать

Docker has become very mainstream technology has been used in many mature companies in the production environment, but Docker's core technology actually has a lot of years of history, Linux namespace control group and three technical support UnionFS current Docker implementation is the most important reason Docker can происходить.

В ходе исследования авторы смотрели на докер реализацию принципа много информации, которые также связаны с участием многих знаний операционной системы Linux, но поскольку Code Code Code Docker слишком велик, вы хотите, чтобы исходный код из Пункт целиком докер деталей реализации уже очень трудно понять, но если вы читатели действительно заинтересованы в его деталях реализации, отDocker CEИсходный код начинает понимать принципы Docker.

Reference

О картинках и репринтах

知识共享许可协议
В этой работе используетсяМеждународная лицензия Creative Commons Attribution 4.0Лицензия. При перепечатке просьба указывать ссылку на оригинал.При использовании рисунка просьба сохранять все содержание на рисунке.Его можно соответствующим образом увеличить и ссылку на статью,где находится рисунок,прикрепить к ссылке.Картинка нарисована с помощью Скетча.

Комментарии и отзывы

Если эта статьяОсновная технология Docker и принцип реализацииЕсли у вас есть какие-либо вопросы по содержанию, пожалуйста, оставьте сообщение в системе комментариев ниже, спасибо.

Оригинальная ссылка:Основная технология Docker и принцип реализации · Программирование, ориентированное на веру

Follow: Draveness · GitHub