在前文,咱们介绍了 Docker 学习的根本办法和原理,以及根底三大件:镜像、容器、仓库。还有 Dockerfile 和数据卷。
回顾:
Docker 小白入门倡议及基本原理介绍
Docker 速学(一)镜像和容器
Docker 速学(二)Dockerfile 和数据卷
明天,小九给大家介绍的内容是用户、网络和过程。在学习中深刻理解 Docker 网络的概念和原理是十分重要的。接下来,让咱们一起学习吧~
网络
因为容器是用于部署利用的,因而它须要频繁的被其余服务所拜访,深刻理解 Docker 网络的概念和原理就显得至关重要。
组网
对于 Docker 零碎来说,默认有一个容器路由性能,简略的说,Docker 会给每个部署好的 Container 生成一个内网 IP 地址。例如,Docker 下运行了容器,Docker 就主动调配了 3 个内网地址:
容器 1 172.18.0.1
容器 2 172.18.0.2
容器 3 172.18.0.23
对于其中任何 Container 来说,都能够通过 IP 地址作为拜访通道
端口
每个 Container,都能够映射到服务器的一个端口上,以便于内部拜访这个 Container。例如:172.18.0.1 上运行了 MySQL,且 MySQL 自身开启了内部拜访。这个时候,如何通过服务器的 IP 地址来拜访这个 MySQL 呢?
- 首先,将容器 1 的做一个端口映射,退出映射到都服务器的 3306 端口
- 而后,通过 服务器 IP:3306 就能够拜访 MySQL
问题:Container 中的利用为什么有端口号?Container 是带最简的操作系统的,有操作系统就肯定会通过端口拜访程序
用户
一般来说 Docker 不倡议以 root 用户运行容器过程,因而 Dockerfile 的编写者都会在代码中创立普通用户,而后以普通用户运行过程。
如果没有创立普通用户,容器就会默认以 root 用户权限运行
容器的 root 与宿主机的 root 是同一个用户,但容器 root 的权限是无限的,如果加上 –privileged=true,那么它就等同于宿主机 root 权限
UID
尽管有用户名的概念,但因为 Linux 内核最终治理的用户对象是以 uid 为标识,所以本节均以 uid 来代替用户名。
容器因为是基于虚构隔离技术的并共享操作系统内核的独立过程,而内核只治理一套 uid 和 gid,所以容器中的 uid 和 gid 实际上与宿主机内核是一套体系。
了解容器中用户权限、uid、gid 等实质,重点在于了解《Linux User Namespace》
当容器过程尝试写文件时,内核会查看此容器的 uid 和 gid,以确定其是否具备足够的特权来批改文件。
提权
咱们在 Dockerfile 会发现,当须要对用户提权的时候,采纳的不是 su,而是上面两个命令的组合
- gosu
- exec
过程
有人说,容器的实质就是过程。不论这句话是否相对,但可见过程对于容器的重要性显而易见。
查问过程
通过运行 docker top containerid
查问过程。
为了便于了解,咱们先运行一个 Docker 利用:docker-wordpress(opens new window)
然当前别离查问各个容器的过程。
[root@test ~]# docker top wordpress-mysql
UID PID PPID C STIME TTY TIME CMD
polkitd 22107 22080 0 Aug01 ? 00:01:52 mysqld
[root@test ~]# docker top wordpress
UID PID PPID C STIME TTY TIME CMD
33 807 22090 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
33 1675 22090 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
33 2935 22090 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
33 21955 22090 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
root 22090 22054 0 Aug01 ? 00:00:06 apache2 -DFOREGROUND
33 26327 22090 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
33 28793 22090 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
33 30253 22090 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
33 31445 22090 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
33 31955 22090 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
33 32734 22090 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
可见有的容器只运行了一个过程,而有的容器运行了多个过程(Apache 作为 HTTP 服务器,其天生是多过程设计)。
也能够进入其中一个容器,再运行 ps -ef
命令查看过程:
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Aug01 ? 00:00:06 apache2 -DFOREGROUND
www-data 153 1 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
www-data 181 1 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
www-data 193 1 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
www-data 209 1 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
www-data 214 1 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
www-data 215 1 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
www-data 218 1 0 Aug01 ? 00:00:01 apache2 -DFOREGROUND
www-data 219 1 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
www-data 224 1 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
www-data 225 1 0 Aug01 ? 00:00:00 apache2 -DFOREGROUND
root 253 0 0 06:17 pts/0 00:00:00 bash
root 261 253 0 06:18 pts/0 00:00:00 ps -ef
可见,两者的成果是一样的。
新开一个 Shell 窗口,再运行 pstree -a
命令,回看到如下的过程树
├─containerd-shim -namespace moby -id 8a7712fe435afaa79c08e7281de7e1a658cd00261fecc7ba02da1847d47d1715 -address /run/containerd/containerd.sock
│ ├─apache2 -DFOREGROUND
│ │ ├─apache2 -DFOREGROUND
│ │ ├─apache2 -DFOREGROUND
│ │ ├─apache2 -DFOREGROUND
│ │ ├─apache2 -DFOREGROUND
│ │ ├─apache2 -DFOREGROUND
│ │ ├─apache2 -DFOREGROUND
│ │ ├─apache2 -DFOREGROUND
│ │ ├─apache2 -DFOREGROUND
│ │ ├─apache2 -DFOREGROUND
│ │ └─apache2 -DFOREGROUND
│ ├─bash
│ └─12*[{containerd-shim}]
├─containerd-shim -namespace moby -id d287c79eaced1fcdde94b2b6d45781937cb17a0ddf4848d26907dee40602e80f -address /run/containerd/containerd.sock
│ ├─mysqld
│ │ └─30*[{mysqld}]
│ └─13*[{containerd-shim}]
你会发现,这个查问后果也根本类同。
创立过程
通过下面的阐明,咱们曾经有了十分具体的过程印象,那么当初咱们再深刻一些:容器的过程是如何创立的呢?
咱们先回顾 Dockerfile 中的 CMD 和 ENTRYPOINT,其余它就是容器的运行时,镜像提供了容器运行所需的软件包和软件环境,但如果不通过 CMD 和 ENTRYPOINT 来启动各种利用,容器就不会产生过程。
非服务过程
容器个别的用于承载服务,但在开发中,容器镜像也能够用作短暂的过程:在咱们计算机上运行的、容器化的可执行命令。这些容器执行繁多的工作,生命周期短暂,而且通常能够在应用后被删除。咱们称之为可执行镜像,这样的镜像创立的容器的过程能够称之为 非服务过程。
主过程
在 Docker 中有一个很非凡的过程(PID=1 的过程),这也是 Docker 的主过程,通过 Dockerfile 中的 ENTRYPOINT 和 / 或 CMD 指令指定。当主过程退出的时候,容器所领有的 PIG 命名空间就会被销毁,容器的生命周期也会完结 Docker 最佳实际倡议的是一个 container 一个 service,并不强制要你一个 container 一个线程。有的服务,会催生更多的子过程,比方 Apache 和 uwsgi,这是齐全能够的。
PID1 过程须要对本人创立的子过程负责,当主过程没有设计好,不能优雅地让子过程退出,就会照成很多问题,比方数据库 container,如果解决数据的过程没有优雅地退出,可能会照成数据失落。如果很可怜,你的主过程就是这种治理不了子过程的那种,Docker 提供了一个小工具,帮忙你来实现这部分内容。你只须要在 run 创立 container 的时候提供一个 —init flag 就行,Docker 就会手动为你解决好这些问题。
Docker 的主过程因为是一个很非凡的存在,它的生命周期就是 docker container 的生命周期,它得对产生的子过程负责,在写 Dockerfile 的时候,务必明确 PID1 过程是什么。
下篇内容:
Docker 速学(四)编排、集群和常见命令总结
本文由 Websoft9 原创公布,转载请注明出处。