docker 编译程序里面image相当于可执行程序吗?

谈到微服务的话题,技术上我们往往会涉及到多服务、多容器的部署与管理。
Docker 有三个主要的作用:Build, Ship和Run。使用docker compose我们可以在Run的层面解决很多实际问题,如:通过创建compose(基于YUML语法)文件,在这个文件上面描述应用的架构,如使用什么镜像、数据卷、网络、绑定服务端口等等,然后再用一条命令就可以管理所有的服务(如启动、停止、重启、日志监控等等)。

Compose是定义和运行多容器Docker应用程序的工具。 使用Compose,您可以使用YAML文件来配置应用程序的docker服务。 然后,使用单个命令,您可以创建并启动配置中的所有docker服务。

Compose适用于所有环境:生产,开发,测试以及CI工作流程。使用Compose基本上是一个三步过程:

  • 使用Dockerfile定义应用程序的环境,以便在任何地方进行复制。
  • build 构建或重建服务
    logs 显示容器的输出内容
    port 打印绑定的开放端口
    pull 拉取服务镜像
    run 运行一个一次性命令
    scale 设置服务的容器数目
    

    可以看到一份标准配置文件应该包含 version、services、networks 三大部分,共有三级标签,每一级都是缩进两个空格。下面来详细说明一下里面的内容:

    这是定义compose的版本号为version 3,可以参考官方文档详细了解具体有哪些版本

    来查看一下是否启动完成:

    大家想想,仅仅使用Compose,就可以构建自己的容器云吗?答案显然是否定的。docker-compose解决的问题局限在“编排”二字,甚至连“部署”范畴都涉足甚少,而在一个能够服务于大众的云平台中,编排与部署也仅仅是其中的一个组成部分而已。来一起分析一下它的局限制会有哪些:

    1、docker-compse是面向单宿主机部署的,这是一种部署能力的欠缺。在更多的场合下,管理员需要面对大量物理服务器(或者虚拟机),这时如果要实现基于docker-compose的容器自动化编排与部署,管理员就得借助成熟的自动化运维工具(ansible、puppet、chef、saltstack)来负责管理多个目标主机,将docker-compose所需的所有资源(配置文件、用户代码)交给目标主机,然后在目标主机上执行docker-compose指令。
    2、同样网络和存储也比较棘手,Docker不能提供跨宿主机的网络,完全面向Docker daemon的docker-compose当然也不支持。这意味着管理员必须部署一套类似于Open vSwich的独立网络工具,而且管理员还需要完成集成工作。当好不容易把容器编排都安排妥当之后,又会发现容器还处在内网环境中,于是负载均衡、服务发现等一堆问题就面临而来了,这些问题很快能消耗掉工程师所有的耐心。

    那么,是否有一种能够提供完善的面向服务器集群的Docker编排和部署方案呢?Docker官方给出的答案是Compose同Machine和Swarm联动,其实还有大家近期经常听到了kubernetes(k8s)

}

镜像(image):一个特殊的文件系统

操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。

镜像不包含任何动态数据,其内容在构建之后也不会被改变。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
容器与镜像的关系类似于面向对象中的实例对象和类。

Union FS(联合文件系统)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union FS 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。(类似于Java中的继承,子类拥有父类的属性)

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。 镜像实际是由多层文件系统联合组成。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

为什么 Docker 镜像要采用这种分层结构呢?

  1. 分层存储使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
  2. 共享资源。比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像。同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

Docker镜像都是只读的,当容器启动时,一个新的可读写层被加载到镜像的顶部,这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”,镜像层是只读的。

容器(container):镜像运行时的实体

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等 。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。前面讲过镜像使用的是分层存储,容器也是如此。

容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据 ,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器可以随意删除、重新 run,数据却不会丢失。

仓库(repository):集中存放镜像文件的地方

镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。所以说,镜像仓库是 Docker 用来集中存放镜像文件的地方,类似于我们之前常用的代码仓库。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。最常使用的 Registry 公开服务是官方的 Docker Hub ,这也是默认的 Registry,并拥有大量的高质量的官方镜像,网址为:。

在国内访问 Docker Hub 可能会比较慢,国内也有一些云服务商提供类似于 Docker Hub 的公开服务。

总结:docker的架构图

}

在Windows上学习Docker和Kubernetes,开始的时候会让你觉得无从下手。最起码安装好这些软件都不是一件容易的事情。实际上,你应该对Docker和Kubernetes相当熟悉了才知道如何选择安装时启用哪些参数选项。

这篇文章就是为在Winodws上刚刚入门容器和Kubernetes的同学而准备的。

你将会学习到如何做出正确的选择来搭建Windows上的容器开发环境。

让我们从Docker说起。

当Docker的开发者们决定在Winodows上实现Docker时,他们选择了Hyper-V作为虚拟化技术。这个优点十分明显:优秀的性能和原生的hypvervisor。

不幸的是并不是所有的Windows版本带Hyper-V支持。

你可能不会拥有Docker for Windows那样的速度,但是毕竟你不需要Hyper-V就能够构建和运行容器了。

你有最新的Win 10 Pro,你可以安装Docker for Windows。 你拥有了优秀的性能和开发者体验,一切都搞定了,是吗?

这跟你的设置相关,影响可大可小。

如果你已经完全使用容器化了,你就不需要担心VM——过时的东西。

但是如果你仍然要使用VM,以及类似Vagrant这样的工具,那你可能就有麻烦了。

你可以随意的启用或者关闭Hyper-V hypervisor,但是你要重启机器。

如果你频繁的要从容器切换到VM,那可能使用minikube更方便。当你从容器切换到VM的时候就不用重启电脑了。 缺点就是你没办法得到更高性能和更好体验。

如果你想要跑一个本地的Kubernetes,那你应该考虑minikube。

它是一个最小完整的Kubernetes环境。

当然如果你不能跑Hyper-V也没关系,你可以用VirtualBox实现同样的功能。

有很多的选择和权衡,下图列出了一些:


你要去到官网找到正确的下载地址,选择正确的版本,下载安装,最后加到你的path里面去。

这当然可行,但是我敢肯定你更愿意把时间花在编码而不是从网站上下载安装软件包上。

是一个Widnows的包管理器。你告诉它想要安装的包,它会为你装好。你把软件安装的活外包给它了。

安装Chocolatey很简单,你可以在它的 。简单来说,就这么几步:

如果minikube启动失败,那么你可以通过以下命令调试:

有时这个目录被锁,需要在Hyper-v 管理器 里面,关掉minikube虚拟机,释放目录。或者需要重启

更多的输出日志可以帮助你快速排错。我遇到过如下的问题:

这时可以看看安装成功了没。在命令提示符输入:


因为你已经在设备上启用了Hyper-V,你就无法再通过virtualbox跑VM了。如果你强行要启用vm的话,会遇到如下错误:

以管理员打开命令提示符:

当机器重启之后,你就可以正常使用VirtualBox了。

如果你又想要用Docker和minkube了,你要重新打开Hyper-V然后重启机器。

以管理员打开命令行,输入:

重启, 这样你就可以将容器部署到Kubernetes中了。

在装完了以后,你可以启动:

这个命令会下载一个VirtualBox要用到的ISO,然后启动VM。启动之后你就可以查看集群状态:

看见一个node列出来。

注意:每次你打开一个新的命令行窗口,你都需要以上命令。一种提醒你自己的简单方式是敲一下 minikube docker-env

如果连接成功,你可以列出当前正在运行的容器:

你会看到很多容器正在运行。大部分属于Kubernetes。


但是在你继续之前,你需要清楚使用minikube作为你远程Docker daemon的一些限制。

Docker被设计为两个部分:

那么为什么要有客户端和服务器?为什么不用一个文件?

但是有时候你本地没有daemon。

可能你需要在一台远端的机器上构建Docker容器。

特别是你正在运行minikube。


当你的容器运行在远程的Docker daemon上的时候,你需要调整端口绑定。

注意:容器本身暴露的是80,你把它映射到了8080。

然后你可以访问 然后看见Nginx的欢迎页面。

如果你在远程的Docker daemon上运行此命令然后访问这个URL时,你会发现什么也没有,URL不可达。

所以你可以访问本机上的容器。


如果你想要看见你运行的容器你需要访问Docker daemon所在的机器。 你可以用以下命令找到IP:

你可以通过 来访问,看到Nignx的欢迎页面。



你已经安装好了Docker,那你如何知道它是否工作正常呢?

一旦Docker下载完所有的包,你可以通过 来访问。

注意:如果你在使用远程的minikube上的Docker daemon时,你应该使用 来访问。

你应该可以看到Wordpress的安装向导了。

Wordress就在一个容器里面对外服务了。

注意:你还不能完成那个Wordpress的安装因为你还有数据库。

是时候测试你的本地的Kubernetes集群了。在这一部分,你将会部署 。


你可以用如下命令部署:

一旦Kubernetes完成了容器的安装,你可以查看运行状态:


你可以将你部署的服务器暴露出来:

你可以通过浏览器打开面板:

这样你就可以从Kubernetes里面访问面板了! 万岁!

Minikube本身自带了一些好东西。


从这里,你可以查看你的集群详细信息和部署应用。

如果你遇到了文章没提到的错误,请通过 或者 告诉我们。

接下来,你可以在你的环境里面部署更多应用了。请看 。

原文链接: (翻译:姚洪)

}

我要回帖

更多关于 docker 编译程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信