Docker速学(三) 网络、用户和进程

在前文,我们介绍了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. 首先,将容器1的做一个端口映射,加入映射到都服务器的3306端口
  2. 然后,通过 服务器IP:3306 就可以访问MySQL

问题:Container中的应用为什么有端口号?Container是带最简的操作系统的,有操作系统就一定会通过端口访问程序

用户

一般来说 Docker 不建议以 root 用户运行容器进程,因此 Dockerfile 的编写者都会在代码中创建普通用户,然后以普通用户运行进程。

如果没有创建普通用户,容器就会默认以 root 用户权限运行

容器的 root 与宿主机的 root 是同一个用户,但容器 root 的权限是有限的,如果加上 --privileged=true,那么它就等同于宿主机 root 权限

img

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原创发布,转载请注明出处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容