Когда дело доходит до технологии виртуализации, мы должны в первую очередь думать о Docker.После четырех лет быстрого развития Docker стал широко использоваться в производственной среде многих компаний, и это уже не игрушка, которую можно использовать только в этап разработки. Как продукт, широко используемый в производственных средах, Docker имеет очень зрелое сообщество и большое количество пользователей, а содержимое базы кода стало очень большим.
Опять же, из-за развития проекта, разделения функций и различных странных изменений имени.PR, понять общую архитектуру Docker снова становится сложнее.
Хотя в настоящее время Docker состоит из множества компонентов и очень сложен для реализации, в этой статье мы не хотим слишком подробно рассказывать о конкретных деталях реализации Docker, а поговорим об основных технологиях, поддерживающих появление Docker, технологии виртуализации.
Прежде всего, появление Docker должно быть связано с тем, что текущая серверная часть действительно нуждается в технологии виртуализации на этапах разработки, эксплуатации и обслуживания, чтобы решить проблему согласованности среды разработки и производственной среды.Через Docker мы можем также включить среду, в которой программа работает в системе контроля версий. , исключить возможность различных результатов работы из-за среды. Однако, хотя вышеуказанные требования способствовали развитию технологии виртуализации, если нет подходящей базовой технической поддержки, мы все равно не сможем получить идеальный продукт. В оставшейся части этой статьи будут представлены несколько основных технологий, используемых Docker.Если мы поймем, как и как они используются, мы сможем понять, как реализован Docker.
Namespaces
Пространства имен (namespaces) — это метод, который Linux предоставляет нам для разделения ресурсов, таких как деревья процессов, сетевые интерфейсы, точки монтирования и межпроцессное взаимодействие. При повседневном использовании Linux или macOS нам не нужно запускать несколько совершенно отдельных серверов, но если мы запустим несколько служб на сервере, эти службы фактически будут влиять друг на друга, и каждая служба может видеть процесс других служб, а также может получать доступ к ним. любой файл на хост-компьютере, который часто не хочет видеть.Мы предпочитаем, чтобы разные службы, работающие на одном и том же компьютере, могли это делать.полностью изолирован, как если бы он работал на нескольких разных машинах.
В этом случае, когда служба на сервере захвачена, злоумышленник может получить доступ ко всем службам и файлам на текущей машине, чего мы не хотим видеть, и 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 и пропустите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
На текущем хост-компьютере может быть дерево процессов, состоящее из различных процессов, упомянутых выше:
Это использует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 по умолчанию: режим моста. В этом режиме, помимо выделения изолированных сетевых пространств имен, Docker также устанавливает IP-адреса для всех контейнеров. Когда сервер Docker находится на хосте, создается новый виртуальный мост docker0, и все сервисы, впоследствии запущенные на хосте, подключаются к этому мосту в одном случае.
По умолчанию каждый контейнер будет создан при создании пары виртуальных сетевых адаптеров, две сетевые карты образуют виртуальный канал данных, который будет помещен в созданный контейнер, он будет добавлен в мост с именем 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.
когда мы используем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, модель контейнерной сети, состоит из следующих основных компонентов, а именно песочницы, конечной точки и сети:
В модели контейнерной сети каждый контейнер содержит песочницу, в которой хранится конфигурация сетевого стека текущего контейнера, включая интерфейс контейнера, таблицу маршрутизации и настройки DNS.Linux использует сетевое пространство имен для реализации этой песочницы, и каждая песочница содержит может быть одна или несколько конечных точек, которая представляет собой виртуальную сетевую карту в Linux.Песочница добавляется в соответствующую сеть через конечные точки.Сеть здесь может быть мостом Linux или VLAN, о которых мы упоминали выше.
Дополнительные сведения о libnetwork или модели контейнерной сети см.Design · libnetworkДля получения дополнительной информации, конечно, вы можете прочитать исходный код, чтобы понять различные реализации разных ОС в модели контейнерной сети.
точка крепления
Хотя мы разрешили проблемы с процессом и сетевыми проблемами изоляции через Linux, у нас нет возможности получить доступ к другим процессам на хосте и ограничить доступ к сети, но процесс в контейнере докена до сих пор доступен или изменен. Другие каталоги на хост-машина, это Это то, что мы не хотим видеть.
Создание пространства имен изолированной точки монтирования в новом процессе требуетclone
передается в функциюCLONE_NEWNS
, чтобы дочерний процесс мог получить копию точки монтирования родительского процесса, если этот параметр не переданДочерний процесс будет синхронизирован с файловой системой для файловой системы и файловой системы всего хоста..
Если контейнер необходимо запустить, он должен предоставить корневую файловую систему (rootfs), контейнер должен использовать эту файловую систему для создания нового процесса, и все выполнение двоичных файлов должно выполняться в этой корневой файловой системе.
Для нормального запуска контейнера необходимо смонтировать указанные выше каталоги в rootfs.Помимо указанных выше каталогов, которые необходимо смонтировать, нам также необходимо установить некоторые символические ссылки, чтобы гарантировать отсутствие проблем с системным вводом-выводом.
Чтобы убедиться, что текущий процесс-контейнер не имеет доступа к другим каталогам на хост-компьютере, нам также нужно использовать здесь 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, но пространство имен не обеспечивает нам изоляцию физических ресурсов, таких как ЦП или память, если в поле " контейнеры», работающие на одной машине, которые ничего не знают друг о друге и хост-машине, но эти контейнеры в совокупности занимают физические ресурсы хост-машины.
Если судно выполняет определенные задачи с интенсивным использованием ЦП, это повлияет на производительность и эффективность выполнения других задач в контейнере, что приведет к большему взаимодействию и захвату ресурсов контейнерами. Как ограничить использование ресурсов стало больше контейнеров для решения основных проблем после процесса изоляции виртуальных ресурсов, а группы управления (называемые CGroups) — это возможность изолировать физические ресурсы на хост-машине, такие как ЦП, память, диск Ввод/вывод и пропускная способность сети.
Каждая CGroup представляет собой группу процессов, ограниченных одними и теми же стандартами и параметрами, между разными CGgroups существует иерархическая связь, то есть они могут наследовать некоторые стандарты и параметры ограничения использования ресурсов от родительского класса.
CGroup в Linux может выделять ресурсы группе процессов, то есть ЦП, память, пропускную способность сети и другие ресурсы, упомянутые выше.Благодаря распределению ресурсов 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 будет иметь следующую иерархическую взаимосвязь:
Под каждой 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 run
При создании команды к верхнему слою образа добавляется доступный для записи слой, то есть слой контейнера.Все модификации контейнера среды выполнения фактически являются модификациями слоя чтения-записи контейнера.
Разница между контейнерами и образами в том, что все образы доступны только для чтения, и каждый контейнер фактически равен изображению плюс слой чтения-записи, то есть одному и тому же образу может соответствовать несколько контейнеров.
AUFS
UnionFS на самом деле является службой файловой системы, разработанной для операционной системы Linux для «присоединения» нескольких файловых систем к одной и той же точке монтирования. AUFS или Advanced UnionFS на самом деле является обновленной версией UnionFS, которая обеспечивает более высокую производительность и эффективность.
Как файловая система объединения, AUFS может объединять слои в разных папках в одну папку.Эти папки называются ветвями в 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 в федеративной манере.
Это изображение выше показывает процесс сборки очень хорошего, каждый слой изображения построен на верхней части другого слоя изображения, в то время как все зеркальные слои являются только для чтения, и только каждый контейнер верхний слой контейнеров, который пользователь может напрямую прочитать и писать, все Контейнеры построены на одном из базовой службы (ядра), включая пространства имен, контрольную группу, rootfs и т. Д., Этот способ сборки контейнера обеспечивает большую гибкость, только чтение, только путем совместного использования зеркального слоя может уменьшить использование дискового пространства.
Другие накопители
AUFS — это лишь один из драйверов хранилища, используемых Docker.Помимо AUFS, Docker также поддерживает различные драйверы хранилища, в том числеaufs
,devicemapper
,overlay2
,zfs
иvfs
Подождите, в последнем Docker,overlay2
замененыaufs
стал рекомендуемым драйвером хранилища, но когда нетoverlay2
будет по-прежнему использоваться на силовых машинахaufs
В качестве драйвера по умолчанию для Docker.
Различные драйверы хранилища также имеют совершенно разные реализации при хранении образов и файлов-контейнеров.Заинтересованные читатели могут обратиться к официальной документации 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
- Chapter 4. Docker Fundamentals · Using Docker by Adrian Mount
- TECHNIQUES BEHIND DOCKER
- Docker overview
- Unifying filesystems with union mounts
- Базовая технология DOCKER: AUFS
- RESOURCE MANAGEMENT GUIDE
- Kernel Korner - Unionfs: Bringing Filesystems Together
- Union file systems: Implementations, part I
- IMPROVING DOCKER WITH UNIKERNELS: INTRODUCING HYPERKIT, VPNKIT AND DATAKIT
- Separation Anxiety: A Tutorial for Isolating Your System with Linux Namespaces
- Понимание chroot
- Linux Init Process / PC Boot Procedure
- Подробное объяснение сети Docker, интерпретация и практика исходного кода конвейера
- Understand container communication
- Docker Bridge Network Driver Architecture
- Linux Firewall Tutorial: IPTables Tables, Chains, Rules Fundamentals
- Traversing of tables and chains
- Анализ потока выполнения сетевой части Docker (интерпретация исходного кода Libnetwork)
- Libnetwork Design
- Анатомия файловой системы Docker: Aufs и Devicemapper
- Linux - understanding the mount namespace & clone CLONE_NEWNS flag
- Знания ядра, лежащие в основе Docker — изоляция ресурсов пространства имен
- Infrastructure for container projects
- Spec · libcontainer
- Docker Basic Technologies: пространство имен Linux (ON)
- Базовая технология DOCKER: LINUX CGROUP
- «Сделайте сам пишите докер» три три: Linux Unionfs
- Introduction to Docker
- Understand images, containers, and storage drivers
- Use the AUFS storage driver
О картинках и репринтах
В этой работе используетсяМеждународная лицензия Creative Commons Attribution 4.0Лицензия. При перепечатке просьба указывать ссылку на оригинал.При использовании рисунка просьба сохранять все содержание на рисунке.Его можно соответствующим образом увеличить и ссылку на статью,где находится рисунок,прикрепить к ссылке.Картинка нарисована с помощью Скетча.
Комментарии и отзывы
Если эта статьяОсновная технология Docker и принцип реализацииЕсли у вас есть какие-либо вопросы по содержанию, пожалуйста, оставьте сообщение в системе комментариев ниже, спасибо.Оригинальная ссылка:Основная технология Docker и принцип реализации · Программирование, ориентированное на веру
Follow: Draveness · GitHub