深入剖析 Kubernetes
张磊
Kubernetes 社区资深成员与项目维护者
116705 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 57 讲
再谈开源与社区 (1讲)
结束语 (1讲)
深入剖析 Kubernetes
15
15
1.0x
00:00/00:00
登录|注册

08 | 白话容器基础(四):重新认识Docker容器

docker push
docker tag
docker login
docker run
docker build
CMD
ENV
EXPOSE
RUN
ADD
WORKDIR
FROM
Docker Volume的核心原理
绑定挂载
Volume机制
Linux Namespace的工作原理
使用docker commit
上传镜像到Docker Hub
启动容器
制作容器镜像
Dockerfile
Volume(数据卷)
Docker部署Python Web应用
思考题
Docker容器的本质
基于rootfs的文件系统
Linux Cgroups的限制能力
Linux Namespace的隔离能力
庖丁解牛:重新认识Docker容器

该思维导图由 AI 生成,仅供参考

你好,我是张磊。今天我和你分享的主题是:白话容器基础之重新认识 Docker 容器。
在前面的三次分享中,我分别从 Linux Namespace 的隔离能力、Linux Cgroups 的限制能力,以及基于 rootfs 的文件系统三个角度,为你剖析了一个 Linux 容器的核心实现原理。
备注:之所以要强调 Linux 容器,是因为比如 Docker on Mac,以及 Windows Docker(Hyper-V 实现),实际上是基于虚拟化技术实现的,跟我们这个专栏着重介绍的 Linux 容器完全不同。
而在今天的分享中,我会通过一个实际案例,对“白话容器基础”系列的所有内容做一次深入的总结和扩展。希望通过这次的讲解,能够让你更透彻地理解 Docker 容器的本质。
在开始实践之前,你需要准备一台 Linux 机器,并安装 Docker。这个流程我就不再赘述了。
这一次,我要用 Docker 部署一个用 Python 编写的 Web 应用。这个应用的代码部分(app.py)非常简单:
from flask import Flask
import socket
import os
app = Flask(__name__)
@app.route('/')
def hello():
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
在这段代码中,我使用 Flask 框架启动了一个 Web 服务器,而它唯一的功能是:如果当前环境中有“NAME”这个环境变量,就把它打印在“Hello”之后,否则就打印“Hello world”,最后再打印出当前环境的 hostname。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了Docker容器技术的核心原理和操作流程,通过实际案例和命令演示,读者可以深入了解Docker容器的基本概念和操作流程。作者首先展示了如何用Python编写Web应用,并通过Dockerfile制作容器镜像,详细解释了Dockerfile中各个原语的作用。接着演示了如何通过docker run命令启动容器,并通过curl命令访问容器内应用的返回结果。此外,文章还深入解释了Linux Namespace的隔离机制和docker exec的实现原理,以及如何通过setns()系统调用加入到容器进程的Namespace中。另外,文章还介绍了Docker镜像上传到Docker Hub的操作,以及使用docker commit指令的情况。最后,文章还讲解了Docker项目另一个重要的内容:Volume(数据卷),并详细解释了Volume机制的原理和使用方式。整篇文章通俗易懂,适合读者快速了解Docker容器的基本概念和操作流程。通过对Linux Namespace、Cgroups和rootfs的深入解读,读者可以更清晰地理解容器技术的运行原理。文章还提出了一些思考题,引发读者对容器技术更深入的思考和探讨。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入剖析 Kubernetes》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(187)

  • 最新
  • 精选
  • 黄文刚 
    收货很大,感谢张磊!请教一个问题,请问在容器内部如何获取宿主机的IP? 谢谢。

    作者回复: 单靠容器,在隔离开的情况下是拿不到的。但是有了kubernetes之后这些系统信息都可以从环境变量里拿到。这个功能叫downwardapi

    2018-09-10
    4
    78
  • silver
    所以说 docker exec 每次都会创建一个和容器共享namespace的新进程?

    作者回复: 可以这么理解,i.e. spawn a new process in existing namespace

    2018-09-10
    34
  • long904
    图中不太明白为什么'CMD'属于只读层,那如果 dockfile 里面 yum install 并且 commit 的话,这些 CMD 执行的 yum 命令修改的内容还属于只读层?

    作者回复: 任何镜像里的内容,都属于只读层。commit之后的东西当然也属于只读层。

    2018-09-13
    4
    24
  • 陶希阳
    想知道云服务器等技术是不是也是通过namespace + cgroup实习的?

    作者回复: 当然不是,那可是正儿八经的虚拟化技术

    2018-09-10
    5
    22
  • Geek_9ca34e
    ;老师,有个地方还是不太明白,以下是你些的原文: 注意:这里提到的 " 容器进程 ",是 Docker 创建的一个容器初始化进程(dockerinit),而不是应用进程 (ENTRYPOINT + CMD) dockerinit 会负责完成根目录的准备、挂载设备和目录、配置 hostname 等一系列需要在容器内进行的初始化操作。 最后,它通过 execv() 系统调用,让应用进程取代自己,成为容器里的 PID=1的进程。 我有以下疑问: 1、dockerinit 是一个进程,完成初始化之后 ,让应用进程取代自己,那么dockerinit 进程会自动销毁么? 2、这里的dockerinit和应用进程在宿主机中是两个不同的进程id么? 3、执行 docker exec -it container bin/sh 命令后,bin/sh 命令创建的进程只是加入了container的namespace,但是从宿主机的角度它是一个独立的进程,只是共享了namespace信息么? 4、一个容器内部是否只有一个进程?,或者说容器只是一个房间(由namespace和cgroup组成),而其他的进程都是走进了这个房间,让大家以为这个房间就是一个系统,里面包含了这么多进程,其实在宿主机的角度他们都是一个个进程,只是共享了namespace和cgroup 而已,这样理解对么?

    作者回复: 是。替换当然就是为了保证pid不变。注意,容器里的其他进程都是1号进程的子进程,不存在独立的说法。

    2018-09-21
    3
    21
  • 大卫
    张老师,当Dockerfile中使用sh脚本启动,而不是exec启动java应用时,若通过docker stop不能优雅的停掉Java进程。查资料说可用trap接受信号处理,这个有什么其他好的解决办法没?

    作者回复: trap sig term kill很标准的做法

    2019-01-04
    17
  • 蔡鹏飞
    docker run 时指定-v挂载宿主机目录到容器目录,即使容器原有目录内有数据,也会被我宿主机目录数据替代的呀。难道是和我使用的storage-driver有关?我用的是overlay存储。

    作者回复: 这个行为其实是可配置的

    2018-09-12
    5
    13
  • 老师好,又来问您问题了。生产中有没有什么好的工具管理本地的docker registry,比如磁盘满了想清理等等的操作。期待老师的回复,谢谢!

    作者回复: harbor啊

    2018-10-18
    12
  • ShJin、Cheng
    那么老师,请问有没有办法禁止通过exec -it的方式进入容器?

    作者回复: 权限控制的办法很多,但这也啥意义呢?我手写一个20行的C语言代码就可以加入容器的namespace 啊。所以不随便给人root权限比较重要吧。

    2018-09-17
    10
  • jssfy
    请问docker挂载有何限制没,是否随便一个目录都可以挂载?在容器里应该是root用户,岂不是可以对目录无节制地操作,哪怕原本主机目录中有些文件并不允许当前用户访问?是否可以相应限制

    作者回复: 无限制。至于用户权限,是有user namespace可以做一定的限制。

    2018-09-11
    10
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部