从Docker在Linux和Windows下的区别简单理解Docker的层次结构
上篇文章我们成功在Windows下安装了Docker,输出了一个简单的Hello World程序。本文中我们将利用Docker已有的云端镜像training/webapp来发布一个简单Python的Web程序,在浏览器中输出hello world。
本文内容的测试环境是Windows7下的Docker,用例基于官方文档用例。
一:从运行一个简单的Python Web程序说起
启动Docker客户端并登陆。在客户端中输入以下内容:
$ sudo docker run -d -P training/webapp python app.py
第一次输入上面命令时,Docker会先从云端镜像库中下载training/webapp镜像(笔者机器已经下载过了,图1略过了此过程),成功运行后如图1所示。

图1.运行截图
下面我们来详细看看这条命令的具体内容,这一部分我们可以在官方文档中找到详细的英文解释,这里笔者将其翻译过来并加了些自己的理解。
前面我们已经说过,Docker虚拟机系统实际也是基于Linux内核,所以这条语句实际上就是Linux的命令,我们可以输入以下内容查看docker命令的详解:
$ sudo docker
输出结果如下:

图2.docker命令的子命令列表
再回到第一条中,我们使用的子命令是run。
在子命令列表中我们看到run子命令解释是:run Run a command in a new container,也就是在一个新的容器中运行一条命令。
我们的run命令后面跟的可选项有-d和-P。
查阅官方文档我们可以知道,-d表示Docker会把当前命令的容器放到后台执行并监控起来。-P则表示让Docker映射任何容器内部需要的端口到虚拟机上。这里需要对Docker一些概念有所了解,我们这里暂且简单地理解为Docker虚拟机下的每个Docker容器都是一台子虚拟机,每个子虚拟机都有一块虚拟网卡,当外部要访问容器时都必须通过Docker虚拟机,而-P就做了相关的端口映射。
命令执行后返回的一长串字符串(也就是fc4028b21d84f5c075821ca2425d74d45dea87cd28c4eb92620ae39ddec22f46)则是Docker的容器ID,这是一个唯一的值,我们可以以它为标识对容器做相应的操作。
当我们需要查看和管理当前后台运行的所有容器时,我们可以输入以下命令。
$ sudo docker ps

图3.容器详细信息
这里我们可以看到容器的详细信息,包括容器ID(精简的ID),镜像,命令,创建时间,状态,端口,以及容器名字。
接下来的training/webapp就是我们运行的容器的源了,Docker中称之为镜像,这个镜像是Docker官方之前就创建好的,里面包含了一个简单Python Flask web应用。
最后,我们在容器中执行了python app.py,python app.py启动了我们的web应用。
二:访问页面——从Linux和Windows的区别到对Docker层次的简单理解
从上面我们查看运行容器的详细信息时(图3)我们看到了,在PORTS这一栏中,有这样的信息:
0.0.0.0:49153->5000/tcp
上文中提到Docker虚拟机对容器做了端口映射,这里我们可以更直观的看到了,Docker虚拟机中的49153端口映射到了容器的5000端口(这里我们运行的是web程序,所以是tcp协议,其他容器有需要可以指定成udp协议)。
在官方文档中,这时我们访问localhost:49153,应该就能出现Hello world了,但是笔者在这个步骤根本访问不到这个页面。

图4.此时访问,浏览器一直处于等待状态
因此这里我们需要重新看看这个虚拟网络的结构,要看整个网络的结构,我们应该先了解Docker的层次结构。在Linux中,Docker的逻辑结构是这样的:
硬件 < Linux系统(Docker Kernel) < Docker容器
而我们在前文中提过,在Windows中要运行Docker,实际上是在虚拟机下运行的,所以在Windows中Docker的逻辑结构应该是:
硬件 < Windows系统 < Docker虚拟机(Docker Kernel) < Docker容器。
因此官方文档中用例应该是基于Linux下的,Linux此时访问localhost:49153是没有问题的,因为Docker Kernel此时把49153端口映射给了容器的5000端口,而Windows则不行,因为我们只是把Docker虚拟机的49153端口映射给了容器,我们在浏览器中输入localhost:49153明显是访问的Windows层级别。
理解到这里问题就已经解决了,我们只需进入VirtualBox中,将Docker虚拟机的网络做个桥接,或者端口映射就行了。
进入VirtualBox主界面,选中Docker虚拟机(boot2docker-vm),单击设置按钮,在设置中选择网络,这里我们发现Docker虚拟机默认选择了“网络地址转换(NAT)”。

图5.Docker虚拟机的网络连接方式默认是NAT
而且端口转发中还默认有两个端口映射。

图6.Docker虚拟机和宿主机默认的端口映射
不难猜测这里可能是Docker客户端和Docker虚拟机进行通信的端口,因此我们不能将Docker虚拟机的网络连接方式改成桥接了,否则Docker客户端无法和Docker虚拟机进行通信。
因此我们这里选择添加一个端口映射,将Windows系统的80端口映射到Docker虚拟机的的49153端口上去。端口映射的名称随便取,协议一定要是TCP(HTTP基于TCP)

图7.添加映射端口
此时我们可以在Windows下的浏览器直接访问localhost了(一般来说浏览器默认访问80端口,80端口可以省略),因为我们直接映射了80端口到Docker虚拟机的49153端口上,而Docker虚拟机的49153端口又映射到了我们刚刚创建的Docker容器的5000端口上,我们的web程序正是运行在该容器的5000端口上。

图8.Hello world!
总结:
本文实际上只运行了一个简单的web程序,用例也是基于官方文档,而且如果读者是在Linux运行的话输入完第一条命令应该直接在浏览器中访问了。因此本文主要是对Docker的run命令做了简单的解释,并且通过Docker在Linux和Windows下的区别来简单理解Docker逻辑层次结构。
希望对初学者有一些帮助,笔者自己也是Docker的初学者,文章错处,万请见谅指正。
从Docker在Linux和Windows下的区别简单理解Docker的层次结构的更多相关文章
- 日期在Linux与Windows下的区别
最近遇到了这个问题,就是相同的代码在Windows与Linux下的日期转换不一致. 原因:时区问题,主要是操作系统与JVM中的时区不同导致的 在网上查了很多处理的方法:最后总结出一条简单粗暴的方法:原 ...
- [笔记]linux下和windows下的 创建线程函数
linux下和windows下的 创建线程函数 #ifdef __GNUC__ //Linux #include <pthread.h> #define CreateThreadEx(ti ...
- 【转】linux和windows下安装python集成开发环境及其python包
本系列分为两篇: 1.[转]windows和linux中搭建python集成开发环境IDE 2.[转]linux和windows下安装python集成开发环境及其python包 3.windows和l ...
- protobuff 配合 libevent 在Linux 和windows 下的使用
protobuff 配合 libevent 在Linux 和windows 下的使用待补全. libprotobuf.lib libproto-lite.lib libprotoc.lib
- tar.xz如何解压:linux和windows下tar.xz解压命令介绍
在linux下怎么解压和压缩tar.xz文件? (本文由www.169it.com搜集整理) 在linux下解压tar.xz文件步骤 1 2 # xz -d ***.tar.xz //先解压xz # ...
- Linux和Windows下查看环境变量方法对比
摘自:Linux和Windows下查看环境变量方法对比 一.查看所有环境变量的名称和值 Linux下:export Windows下:set 二.根据名称查该环境变量的值 Linux下:echo $环 ...
- Golang 在 Mac、Linux、Windows 下如何交叉编译(转)
原文地址:Golang 在 Mac.Linux.Windows 下如何交叉编译 Golang 支持交叉编译,在一个平台上生成另一个平台的可执行程序,最近使用了一下,非常好用,这里备忘一下. Mac 下 ...
- linux和windows下TIME_WAIT过多的解决办法
http://www.51testing.com/html/48/202848-249774.html linux和windows下TIME_WAIT过多的解决办法 http://m.sohu.com ...
- Tomcat日志文件的输出在Linux和Windows下的差异
前言 最近老大发现Tomcat的日志文件catalina.out里存在着大量的和公司项目相关的log信息,因为一般都是会使用日志框架并另外将log信息输出到另外的文件里的,catalina.out文件 ...
随机推荐
- task_struct原码解读
该结构体在linux中的路径为如下,如果是本地也可以根据以下子目录找到task_struct结构体,该结构体源码中在600多行 https://github.com/torvalds/linux/bl ...
- shell i/o交互及重定向
标准输入:/dev/stdin,文件描述号:0,默认设备:键盘 标准输出:/dev/stdout,文件描述号:1,默认设备:显示器 标准错误输出:/dev/stderr,文件描述号:2,默认设备:显示 ...
- BZOJ 1015 并查集&连通块
很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道互相直接或 ...
- Mac下 CMD常用命令
1.常用命令 pwd 当前工作目录 cd(不加参数) 进root cd(folder) 进入文件夹 cd .. 上级目录 cd ~ 返回root cd - 返 ...
- 【u-boot】u-boot对设备树的节点解析(转)
1,设备树的引入2,uboot本身对设备树的支持3,对uboot中设备树节点解析代码的分析 (1)上一篇文章中提到函数 dm_init_and_scan(bool pre_reloc_only) 中有 ...
- mysql中source提高导入数据速率的方法
示例: 第一步: 第二步: 使用 source 导入你所需要导入的文件 第三步: 在导入的数据停止后,输入 commit; 这样数据就算是导入完成了.
- ESP8266—“ICACHE_FLASH_ATTR”宏——解释含义
const uint8 MyArr[1024] ICACHE_RODATA_ATTR = {0}; void MyFun() ICACHE_FLASH_ATTR { } 这种 ICACHE 开头的宏作 ...
- hdu 6068 Classic Quotation
题 QAQ http://acm.hdu.edu.cn/showproblem.php?pid=6068 2017 Multi-University Training Contest - Team 4 ...
- (已解决)FVDI 2018“连接到服务器.....失败”“打不开设备”
FVDI 2018 错误和解决方案来自网站:eobdtool.co.uk FVDI 2018发现以下错误: “连接到服务器.....失败” “设备未打开” 解决方案: 请下载FDVI 2018 V3. ...
- Maven-项目管理(一)_认识Maven
Maven是什么? Maven是Apache下的项目管理工具,它由纯Java语言开发,可以帮助我们更方便的管理和构建Java项目. 为什么要使用Maven? 1. jar包管理: a) 从Maven中 ...