容器精华问答 | Docker和虚拟机有什么差别?

2019 年 1 月 25 日 CSDN云计算

戳蓝字“CSDN云计算”关注我们哦!


容器技术是这两年热门的话题,因为容器技术给我们带来了很多方便的地方,节约了不少成本,不管是在运维还是开发上。今天,就让我们来看看关于容器更加有深度的问题吧。


1

Q:宿主如果和容器系统不同的话,那不是和虚拟机一样,一层层的调用,那么Docker和虚拟机还有什么差别?


A:要把Windows和Linux分清楚,更要把内核(kernel)和用户空间(userland)分清楚。容器内的进程是直接运行于宿主内核的,这点和宿主进程一致,只是容器的userland不同,容器的 userland由容器镜像提供,也就是说镜像提供了rootfs。假设宿主是Ubuntu,容器是CentOS。CentOS 容器中的进程会直接向Ubuntu宿主内核发送syscall,而不会直接或间接的使用任何 Ubuntu 的 userland 的库。


这点和虚拟机有本质的不同,虚拟机是虚拟环境,在现有系统上虚拟一套物理设备,然后在虚拟环境内运行一个虚拟环境的操作系统内核,在内核之上再跑完整系统,并在里面调用进程。


还以上面的例子去考虑,虚拟机中,CentOS的进程发送syscall内核调用,该请求会被虚拟机内的CentOS的内核接到,然后CentOS内核访问虚拟硬件时,由虚拟机的服务软件截获,并使用宿主系统,也就是Ubuntu的内核及userland的库去执行。


而且,Linux和Windows在这点上非常不同。Linux的进程是直接发syscall的,而Windows则把 syscall隐藏于一层层的DLL服务之后,因此Windows的任何一个进程如果要执行,不仅仅需要 Windows内核,还需要一群服务来支撑,所以如果Windows要实现类似的机制,容器内将不会像Linux这样轻量级,而是非常臃肿。看一下微软移植的Docker就非常清楚了。


所以不要把Docker和虚拟机弄混,Docker容器只是一个进程而已,只不过利用镜像提供的 rootfs提供了调用所需的userland库支持,使得进程可以在受控环境下运行而已,它并没有虚拟出一个机器出来。


2

Q:如果 Docker 升级或者重启的话,那容器是不是都会被停掉然后重启啊?

      A:在 1.12 以前的版本确实如此,但是从 1.12 开始,Docker 引擎加入了 --live-restore 参数,使用该参数可以避免引擎升级、重启导致容器停止服务的情况。

       默认情况该功能不会被启动,如需启动,需要配置 docker 服务配置文件。比如 Ubuntu 16.04 这类 systemd 的系统,可以修改 /etc/systemd/system/multi-user.target.wants/docker.service 文件,在 ExecStart= 后面配置上 --live-restore:


ExecStart=/usr/bin/dockerd \
    --registry-mirror=https://registry.docker-cn.com \
    --live-restore


    上面的格式中使用了行尾 \ 的换行形式,这点和 bash 脚本一样,systemd 支持这种换行形式,如对此不了解可以先去学习 bash 程序设计。


   需要注意的是,--live-restore 和 Swarm Mode 不兼容,所以在集群环境中不要使用。实际上集群环境也不用担心某个服务器重启的问题,因为其上的服务都会被调度到别的节点上,因此服务并不会被中断。


3

      Q:怎么固定容器 IP 地址?每次重启容器都要变化 IP 地址怎么办?


      A:一般情况是不需要指定容器 IP 地址的。这不是虚拟主机,而是容器。其地址是供容器间通讯的,容器间则不用 IP 直接通讯,而使用容器名、服务名、网络别名。


    为了保持向后兼容,docker run 在不指定 --network 时,所在的网络是 default bridge,在这个网络下,需要使用 --link 参数才可以让两个容器找到对方。


       但这是有局限性的,因为这个时候使用的是 /etc/hosts 静态文件来进行的解析,比如一个主机挂了后,重新启动IP可能会改变。虽然说这种改变Docker是可能更新/etc/hosts文件,但是这有诸多问题,可能会因为竞争冒险导致 /etc/hosts 文件损毁,也可能还在运行的容器在取得 /etc/hosts 的解析结果后,不再去监视该文件是否变动。种种原因都可能会导致旧的主机无法通过容器名访问到新的主机。


       如果可能不要使用这种过时的方式,而是用下面说的自定义网络的方式。而对于新的环境(Docker 1.10以上),应该给容器建立自定义网络,同一个自定义网络中,可以使用对方容器的容器名、服务名、网络别名来找到对方。这个时候帮助进行服务发现的是Docker 内置的DNS。所以,无论容器是否重启、更换IP,内置的DNS都能正确指定到对方的位置。


4

Q:如何修改容器的 /etc/hosts 文件?


A:容器内的 /etc/hosts 文件不应该被随意修改,如果必须添加主机名和 IP 地址映射关系,应该在 docker run 时使用 --add-host 参数,或者在 docker-compose.yml 中添加 extra_hosts 项。不过在用之前,应该再考虑一下真的需要修改 /etc/hosts 么?如果只是为了容器间互相访问,应该建立自定义网络,并使用 Docker 内置的 DNS 服务。


5

Q:怎么映射宿主端口?Dockerfile 中的EXPOSE和 docker run -p 有什么区别?

    A:Docker中有两个概念,一个叫做 EXPOSE ,一个叫做 PUBLISH 。

      EXPOSE 是镜像/容器声明要暴露该端口,可以供其他容器使用。这种声明,在没有设定 --icc=false的时候,实际上只是一种标注,并不强制。也就是说,没有声明EXPOSE的端口,其它容器也可以访问。但是当强制--icc=false的时候,那么只有EXPOSE的端口,其它容器才可以访问。


       PUBLISH则是通过映射宿主端口,将容器的端口公开于外界,也就是说宿主之外的机器,可以通过访问宿主IP及对应的该映射端口,访问到容器对应端口,从而使用容器服务。


       EXPOSE的端口可以不PUBLISH,这样只有容器间可以访问,宿主之外无法访问。而PUBLISH 的端口,可以不事先EXPOSE,换句话说PUBLISH等于同时隐式定义了该端口要EXPOSE。


     docker run命令中的-p, -P参数,以及docker-compose.yml中的ports部分,实际上均是指PUBLISH。


       小写-p是端口映射,格式为 [宿主IP:]<宿主端口>:<容器端口>,其中宿主端口和容器端口,既可以是一个数字,也可以是一个范围,比如:1000-2000:1000-2000。对于多宿主的机器,可以指定宿主IP,不指定宿主IP时,守护所有接口。


      大写 -P 则是自动映射,将所有定义 EXPOSE 的端口,随机映射到宿主的某个端口。


小伙伴们冲鸭,后台留言区等着你!

关于容器,今天你学到了什么?还有哪些不懂的?除此还对哪些话题感兴趣?快来留言区打卡啦!留言方式:打开第XX天,答:……

同时欢迎大家搜集更多问题,投稿给我们!风里雨里留言区里等你~


----------------    --------------


1.微信群:

添加小编微信:color_ld,备注“进群+姓名+公司职位”即可,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!


2.征稿:

投稿邮箱:liudan@csdn.net;微信号:color_ld。请备注投稿+姓名+公司职位。



推荐阅读


点击“阅读原文”,打开 CSDN App 阅读更贴心!

喜欢就点击“好看”吧!
登录查看更多
0

相关内容

Docker - An open platform for distributed applications for developers and sysadmins.
【2020新书】实战R语言4,323页pdf
专知会员服务
98+阅读 · 2020年7月1日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
115+阅读 · 2020年5月10日
【实用书】流数据处理,Streaming Data,219页pdf
专知会员服务
76+阅读 · 2020年4月24日
【资源】100+本免费数据科学书
专知会员服务
105+阅读 · 2020年3月17日
【新书】Java企业微服务,Enterprise Java Microservices,272页pdf
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
68+阅读 · 2020年1月17日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
94+阅读 · 2019年12月4日
社区分享|如何让模型在生产环境上推理得更快
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
VS Code Remote发布!真·远程开发
开源中国
6+阅读 · 2019年5月3日
抖音爬虫
专知
3+阅读 · 2019年2月11日
如何用GitLab本地私有化部署代码库?
Python程序员
9+阅读 · 2018年12月29日
Android P正式发布,你需要尽快做适配了
前端之巅
3+阅读 · 2018年8月7日
Tensorflow 好差劲 !
云头条
8+阅读 · 2017年10月9日
Seeing What a GAN Cannot Generate
Arxiv
7+阅读 · 2019年10月24日
Real-time Scalable Dense Surfel Mapping
Arxiv
5+阅读 · 2019年9月10日
Bidirectional Attention for SQL Generation
Arxiv
4+阅读 · 2018年6月21日
Arxiv
3+阅读 · 2018年3月13日
Arxiv
4+阅读 · 2016年12月29日
VIP会员
相关VIP内容
【2020新书】实战R语言4,323页pdf
专知会员服务
98+阅读 · 2020年7月1日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
115+阅读 · 2020年5月10日
【实用书】流数据处理,Streaming Data,219页pdf
专知会员服务
76+阅读 · 2020年4月24日
【资源】100+本免费数据科学书
专知会员服务
105+阅读 · 2020年3月17日
【新书】Java企业微服务,Enterprise Java Microservices,272页pdf
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
68+阅读 · 2020年1月17日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
94+阅读 · 2019年12月4日
相关资讯
社区分享|如何让模型在生产环境上推理得更快
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
VS Code Remote发布!真·远程开发
开源中国
6+阅读 · 2019年5月3日
抖音爬虫
专知
3+阅读 · 2019年2月11日
如何用GitLab本地私有化部署代码库?
Python程序员
9+阅读 · 2018年12月29日
Android P正式发布,你需要尽快做适配了
前端之巅
3+阅读 · 2018年8月7日
Tensorflow 好差劲 !
云头条
8+阅读 · 2017年10月9日
相关论文
Seeing What a GAN Cannot Generate
Arxiv
7+阅读 · 2019年10月24日
Real-time Scalable Dense Surfel Mapping
Arxiv
5+阅读 · 2019年9月10日
Bidirectional Attention for SQL Generation
Arxiv
4+阅读 · 2018年6月21日
Arxiv
3+阅读 · 2018年3月13日
Arxiv
4+阅读 · 2016年12月29日
Top
微信扫码咨询专知VIP会员