docker基础学习之容器篇

  1. Docker容器

    容器是Docker的一个核心概念,Docker容器是镜像的运行实例,它在镜像已有的文件层上添加一层可读可写的文件层,使得容器像是一个动态的镜像。

  2. 认识容器
    1. 容器结构

    Docker容器的文件系统,大部分是由Docker镜像来提供的。前面说过,容器是在镜像的文件层之上新建一层可读写层,因此容器内部大部分是镜像的内容。

    如图所示容器内部结构:

    假设一个Dockerfile的镜像如下:

    FROM ubuntu:lastet

    COPY run.sh /run.sh

    CMD ["./run.sh"]

    以上Dockerfile中的每一个命令,在Docker镜像中都是以一个独立镜像层的形式存在的,这也提示我们:在构建镜像时通过减少镜像层是一个不错的控制体积的办法。

    上图中Dockerfile组成的几个文件层实际上就是一个镜像的文件层,镜像每一层对应一个Dockerfile命令。

    然后看一下Docker容器,Docker容器是Docker镜像运行态的体现。Docker容器的文件系统不仅包含Docker镜像,还包括上图的顶上两层,就是Docker为Docker容器新建的内容,但这两层不属于Docker镜像的结构。

    这两层分别为Docker容器的初始化层(init Layer)与可读可写层(Read-Write Layer),初始层中大多是初始化容器环境时与容器相关的环境信息,如容器主机名,主机host信息,以及域名服务文件等。

    而可读写层是Docker 容器内的进程拥有读/写权限的文件层,其他层对进程而言都是只读的(Read-Only)。在AUFS文件系统下,可读写层用到了写时复制(Copy-on-Write)的技术。需要注意的是,数据卷的文件也会挂载到可读写层, 虽然Docker容器在可读写层可以看到数据卷的内容,但那都仅仅是挂载点,真实内容位于宿主机上。

    需要特别指出的是,容器内部像/etc/hosts这种文件实际上是由Docker引擎在启动容器时生成的(里面包含容器主机名--容器ID),并且作为独立的一个层(Layer)存在,虽然用户可写,但下次容器重启时又会恢复为默认状态。

     

    2.容器格式

    容器格式标准是一种不受上层结构绑定的协议,即不限于某种特定操作系统硬件、CPU架构、公有云等,这样做的目的是减少行业内的恶性竞争,提供一个标准允许任何人在遵循该标准的情况下开发应用容器技术,这使得容器技术有了一个更广阔的发展空间 ,OCI下的容器技术不属于任何一家公司或个人。

    随着容器技术发展, Linux基金会于2015年6月成立了。CI(Open Container Initiative)组织,该组织旨在围绕容器格式和运行时制定一个开放的工业化标准。 该组织一经成立便得到了包括Google、微软、亚马逊、华为等一系列云计算大公司的支持。

    而runC就是按照该开放容器格式标准(Open Container Format,OCF)制定的一种具体实现,runC是基于Docker公司提供的Libcontainer项目发展而来的。制定容器格式标准使得容器不受上层结构的绑定,如特定的客户端、编排枝等,同时也不受特定的云服务商或项目的绑定,也就是说,不限于某种特定操作系统、硬件、CPU架构、公有云等。目前Docker就是基于runC构建的。

    标准化容器有两大特点,分别是:操作标准化与工业自动化。

    所谓操作标准化,指的是创建、启动、停止容器使用一套标准,只要实现了接口都可以操作容器,还包括使用标准文件系统工具复制和创建容器快照,使用标准化网络工具进行下载和上传。

    而工业自动化,主要有两方面,一方面是交付流程,标准容器技术的软件分发可以达到工业级交付标准,另一方面是容器自动化,与操作内容无关,与平台无关,实现标准接口就可以实现容器操作自动化。

    要实现这两方面,就需要做到与内容无关、与基础设施无关,也就是指不管针对具体的容器内容是什么,容器标准操作执行后都能产生同样的效果。如容器可以用同样的方式上传、启动,不管是PHP应用还是MySQL数据库服务;而基础设施无关是指任何设备都应该支持容器的各项操作。

    其实,开放容器格式(OCF)标准的实现要求非常宽松,它并不限定具体的实现技术也不限定相应的框架,目前已经有基于OCF的具体实现,相信不久后会有越来越多的项目出现。

     

  3. 容器操作

     

    1. 容器基础操作

    创建容器

    使用docker create可以创建一个容器。例如:

    docker create -it alpine

    使用 docker create创建的容器处于"Created"状态, 这种状态类似 " Stop", 我们可以用docker start来启动它们。

    使用id或者NAMES都可以启动它。

    启动容器

    启动容器有两种情况,一种是原来没有这个容器,我们需要基于一个镜像启动新的容器,另一种是我们宿主机本来有这个容器, 但是这个容器处于非运行状态, 我们可以把这个处于非运行状态的容器启动起来。

    启动一个新的容器我们使用docker run命令,而启动一个已经存在的非运行的容器,我们使用docker start命令。

    如下使用docker run命令新建容器启动,并输出一句话,然后停止。

    docker run ubuntu /bin/echo "hello world! "

    查看容器的状态是"Exited"状态的,就是退出的状态。

    当我们使用docker run命令创建容器时,Docker实际上是在用户感受不到的情况下经过了一系列操作:

    检查本地是否存在这个镜像,如果没有就从镜像仓库下载;如果有就检查启动命令是否有参数冲突(例如-d和-rm不能起用);没有冲突时,利用本地镜像创建一个容器(类似docker create操作);然后挂载可读可写层,启动容器和一系列配置(各种资源隔离操作);再然后在应用参数值时如果遇到参数有误,启动会终止;如果没有问题则执行应用程序,执行完毕后终止容器。这就是一个容器启动的简单过程。

    下面的命令启动一个bash终端,允许用户交互操作:

    上面的-it其实是-i与-t的缩写,很多时候这种没有参数值的参数选项都可以写在一起,例如-itd等。这里面的-t就是让Docker分配一个终端并绑定到容器的标准输出上,而-i则是让容器的标准输出保持打开,这样就形成了一个可交互的终端界面,它是绑定到容器内部的,因此在该终端下执行的动作会在容器内部执行,就像连接虚拟机一样,例如:

    在容器内部使用ps命令查看进程:

    只运行了bash程序。

    用户可以输入exit来退出容器。这个时候容器会处于退出状态,因为上面我们把标准输出绑定到bash中,当bash退出时,容器自然会停止。

    停止的容器可以通过docker start再次启动上面的容器:

    启动后的容器可以使用docker inspect查看容器详细信息,例如查看容器IP地址:

    可以使用docker inspect container_id查看容器的详细信息

    查看其IP,前提是容器IP有配置。

    docker inspect --format '{{.NetworkSettings.IPAddress}}' 3bbca0c529cc

    docker inspect命令允许使用Go Templates来格式化inspect命令的输出信息。在稍后的内容中我们会讲述关于Go Templates的基本知识。

     

     

     

     

    后台运行容器

    大部分时候,我们运行容器都是需要在后台运行较长时间的,上面那种启动容器的方式不适合大部分应用场景。

    后台运行容器需要添加-d参数,例如在后台运行一个Nginx:

    docker run -d nginx:alpine

    容器启动后会返回一个唯一的容器ID,可以通过docker ps看到

    使用docker logs可以查看容器的日志信息,这对于在后台运行的容器是非常重要的,有时候容器意外退出,可以使用docker logs查看原因。

    docker logs <container id>

     

    自动重启容器

    上面讲到容器会意外退出,说明容器可能会发生意外情况,可能是容器内部的程序BUG,从而波及容器,导致退出。所以需要用一个办法让容器重新自动重启,

    重新运行。

    这个参数就是-restart=always,这表示一直重启,参数的默认值为不重启,docker run使用这个参数启动的容器会在容器非正常退出的时候自动重启。

    例如:

    docker run -d --restart=always ubuntu /bin/bash

    这个启动命令必定是运行失败的,因为没有给bash提供一个输出环境,bash启动就退出导致容器跟着不断地重启。使用docker ps可以看到容器的状态一直在restarting。

    需要注意的是:这里的自动重启是面向意外退出的情况,对于手动执行docker stop停止的容器,属于正常退出行为,并不会让容器重启。

     

    停止与杀死容器

    停止容器使用的是docker stop命令,有一个-t参数可以指定发送SIGKILL信号的时间。正常情况下docker stop向容器发送的是SIGTERM信号,这信号会使容器正常操作。

    但是有时候容器会因为各种原因对SIGTERM信号没有响应,这个时候设置的-t参数就起了作用,当一定时间过后容器仍然没有停止就向容器发送SIGKILL信号,让容器强制停止。SIGKILL信号会类似kill命令一样杀死所有正在运行的容器进程。

    格式:

    docker stop <container_id>

    如果是Exited(0)就是退出代码为0是正常的。

    杀死容器的操作是docker kill,这个操作可以快速停止一个容器,类似于我们强制结束一个应用,这样杀死容器有可能导致数据丢失。

    docker kill <container_id>

    可以看到杀死容器的退出码是非0的。是非正常的。

    如果是非人为停止容器的话,可以使用docker logs查看容器日志,以便于定位。

    停止所有容器:

    docker kill$(docker ps -a -q)

    删除所有已经停止的容器:

    docker rm $(docker ps -a -q)

    删除容器

    在执行上面的停止与杀死命令之后,容器不会被删除,而是以停止状态保存在宿主机中,此时容器不会占用磁盘之外的硬件资源。

    如果用户需要释放磁盘资源,删除容器可以执行:

    docker rm <container_id>

    使用docker rm命令只能删除已经停止的容器,想要删除正在运行的容器,可以添加-f参数,该参数会向容器发送 SIGKILL信号,例如:

    docker rm -f <container_id>

    除了-f这个参数,docker rm命令还有-l与-v这两个比较常用的参数。-l参数的作用是删除容器与其他容器的关联,但会保留容器。-v可以在删除容器的时候也把数据卷删除,默认情况下容器与数据卷的生命周期是相互独立的。

    docker run -v /srv:/srv -d ubuntu

    docker rm -v -f <container_id>

     

    查看容器信息

    前面已经多次提到docker inspect命令,该命令用于获取容器/镜像的元数据,例如使用docker inspect -f {{.IPAddress}}来获取容器的IP地址等。

     

    inspect-f参数值其实是个Go模板,把读取到的容器/镜像的元数据按照模板格式返回内容。对于不熟悉Golang的用户来说不容易理解,其实Golang模板是一种模板引擎,让数据以指定的模式输出。Web领域也有很多模板引擎,比如Jinga2(用于PythonFlask )、 Mustache JSP等,看下面的示例:

    docker inspect -f 'Image Id is: {{.Id}}' ubuntu:latest

    上图中{{.Id}}的内容是截取了docker inspect ubuntu:latest的信息:

    现在我们知道了一个简单的模板,通过修改Id这个字符串可以获取其他同级信息。例如上面的 IdRepoDigestsParent等都是同级信息。

    如果我们要获取二级信息,该如何做?例如我们启动了一个容器:并查看它

    现在如果想要查询容器启动时间,可以通过StartedAt获得,但是StartedAt信息属于State下面的内容,所以要这样写:

    又比如要获取容器退出码,确定容器状态,还可以同时显示多项信息:

    除了可以单纯使用模板外,还可以通过加入一些基本语法,例如获取所有退出码为非0的容器名。

    docker inspect -f '{{if ne 0 .State.ExitCode }}{{.Name}} {{.State.ExitCode}}{{ end }}' $(docker ps -a -q)

     

    查看容器IP地址,后面可以是容器名或者ID

    由上面几个演示可以看到:非常方便就能获得容器的数据,但是语法可能有点奇怪。来看看goland模板的基本用法。

    记住以下几点:

     

    1.{{}}语法用于处理模板指令,大括号外的任何字符都将直接输出。

     

    2."."表示"当前上下文",前面提到的同级信息就表示在一个层级上,子级信息通过"."符号可以传达下去。例如".NetworkSettings.IPAddress"就表示NetworkSettings下面的IPAddress信息,NetworkSettingsConfig信息属于同级信息。

    3.允许使用函数可以重定义上下文,with会重定义上下文环境:

    使用$可以获取root的上下文

    1. 使用index可以获取指定下标的数组值:

    空的就是没有。

    没有就会报错。

    1. 除了withindex函数,其他很多函数也很常用。比如逻辑函数andor可以返回布尔结果。注意,函数是不能放在中间的:

    常用的比较函数有:eq等于,ne不等于,lt小于,le小于等于,gt大于,ge大于等于。*json函数可以把信息输出为JSON格式。

     

    1. 最后一点,就是if语句的使用,在上面查退出码非0的容器的例子中就用到了if语句。注意,{{end}}语句必须有,else ifelse则按需使用。

      docker inspect -f 'container is {{if eq .State.ExitCode 0}}good{{else}}no{{end}}' $(docker ps -a -q)

    更多内容见官方文档https://goland.org/pkg/text/template/

     

     

     

     

    1. 进入容器内部

    现在你已经可以让一个容器启动起来了,但是容器对宿主机文件系统是完全隔离的,而很多时候我们需要查看容器的文件系统,使用d参数之后,我们只能通过dockers看到容器的运行状态。那么,怎么进入到个正在运行的容器里面呢?

    attach

    使用docker attach属于Docker的自带命令,该命令依附到正在运行的容器中:如下进入到一个运行的容器中。

    介绍过docker attach的用洼,其中提到不要使用exit命令(或者Ctr+C组合键),那样就是让Docker容器停止了。要退出容器,使用Ctrl + P组合键,然后按Ctrl+Q组合键即可退出容器,容器还会再运行。

     

     

    使用attach命令有时候并不方便。当多个窗口同时attach 到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。

    举个例子:top命令,在多个终端下查看输出。

    docker run -d --name top_demo ubuntu:latest /usr/bin/top -b

    此时打开其他终端,输入docker attach top_demo看到的信息是一样的。相反,从上面看出,如果要实时查看容器日志信息等行为,使用docker attach是最方便的。

     

    exec

    docker exec命令用于进入容器内部进行操作,它与attach原理不一样,docker exec可以像使用SSH登录服务器一样操作容器。

    docker exec的参数如下:

    -d:分离模式

    -i:交互模式

    -t:分配一个tty

    -u:指定用户和用户组,格式为[:]

    --privileged:这个参数会分配一个特权给tty界面,相当于拥有了宿主机的root权限,所以要慎用。

    如启动test容器然后用exec进入

    可以看到使用exec进入容器内部就如同进入另一台机器一样,可以灵活操作,并且使用exit退出时,不会像attach那样导致容器停止,所以非常适合在容器内部操作。此外,每个docker exec都会分配个不同的tty给用户,所以不会像docker attach那样有阻塞。

     

     

    1. 导入导出容器

    就像镜像可以导出导入一样,容器也可以导出导入,docker savedocker load是镜像导出导入的一对命令,而docker exportdocker import则是容器导出导入的一对命令。

    导出容器

    导出容器是指把容器导出到一个归档文件中,不管容器处于运行还是停止的状态都可以导出容器。导出容器会把容器的可读可写的文件层也打包进去,但是不会把Volume的内容囊括进来。例如:

    docker run -v ~/srv:/srv -d --name test abiosoft/caddy:php

    然后进去创建一个test文件,再把容器导出来。

    导入容器

    导入容器并非是把容器导入为容器,导入的容器会变成一个镜像,启动这个镜像才可以恢复容器,这一点有点像docker commit操作。

    在一般情况下,我们直接使用导入tar包:

    docker import test.tar

    这样导入容器所生成的镜像没有名称与标签,需要手动打标签。如果希望在导入时打标签可以使用管道导入:

    cat test.tar |docker import - username/test:latest

    还可以使用网络地址导入,例如:

    docker import https://example.com/container.tar

     

    这样就省去了手动下载传输的麻烦,甚至可以从目录导入:

    sudo tar -c . | docker import - /path/Containerdir

     

    注意:在这个例子中使用sudo,是因为在非root环境下直接导入一个目录有可能不能保留原有文件的权限属性,所以使用这个命令导入需添加权限。此外,在导入过程中使用-change还可以改变Dockerfile中的命令,使用-message可以添加commit信息。

    cat test.tar | docker import --message "import container" - username/test:second

     

    使用-change参数可以在原有的Dockerfile后面追加命令,例如:

    /etc/hosts下的内容输出了。

    原本容器是一个PHP容器,经过-change修改之后执行的是cat/etc/hosts命令。

    上述程序中的docker importdocker load有些类似,但要注意,既然两者都可以导入文件到本地镜像库,那么区别在哪里呢?

    很明显,使用docker export导出的容器像快照一样,它会丢失原来镜像的历史记录与元数据,而docker save保存的镜像保留了全部信息。

     

  4. 数据卷

    到此为止,已经把Docker的两大核心--镜像与容器讲完了,本节是容器部分的扩展,介绍容器的数据卷管理功能。数据卷在Docker容器技术中扮演着非常重要的角色,可以说只要产生数据的Docker应用都需要用到数据卷。

    1. 数据卷是什么

    我们知道Docker启动之后,容器内的文件和宿主机是隔离开来的,如果不使用docker commit操作提交容器为镜像把数据保存下来的话,数据就会因为容器的删除而丢失。而在前面学习构建镜像的过程中,已经明确说明尽量不要使用docker commit提交镜像,因为会导致镜像无法通过Dockerfile复现,不利于迁移、重新构建等情况。

    为了可以保存数据,又不至于破坏镜像的可复现特性,Docker提出了数据卷的概念。Docker的卷概念有两种:数据卷和数据卷容器。

    数据卷简单来讲就是一个目录,它是由Docker daemon挂载到容器中的,因此数据卷并不属于联合文件系统。也就是说,数据卷里面的内容不会因为容器的删除而丢失。一个比较形象的理解就是数据卷就像一个U盘,可以连接电脑,即使电脑硬盘坏掉了,只要不影响U盘,U盘里面的数据并不会随着硬盘损坏而丢失。

    如果挂载了数据卷, 使用docker commit提交时并不会把数据卷里面的内容提交到镜像中。

    虽然一开始数据卷概念的提出只是出于数据持久化的考虑,但实际上数据卷的功能远不止于此,比如:可以让两个容器使用同一个数据卷,也就是数据卷共享。

     

    1. 数据卷挂载

    在使用docker run或者docker create命令时,可以指定,v参数来添加数据卷,这个参数可以使用多次,这样就可以挂载多个数据卷了,同时数据卷还可以使用Linux的软链作为数据卷(受制于容器程序与真实目录的文件系统)。

    这里以一个Alpine镜像为例:

    使用docker inspect volume查看其挂载点。

    现在删掉容器,发现source目录下还在

    虽然避免丢失数据,但是这样也让我们很难管理数据卷。一个比较好的方法是向宿主机映射目录,映射目录很简单:

    现在就不用担心容器删除后数据卷还占用磁盘空间了。可以找到并删除,目前数据卷保存在宿主机的/vol目录下。挂载数据卷到本地不仅仅可以保存数据卷内容,在很多时候还有 "奇效",比如:把程序源代码目录挂载到容器,在容器里面编译,编译成功在宿主机就可以找到编译好的项目,保证了宿主机的清洁与稳定。

    注意,在使用Docker命令操作数据卷时,数据卷的路径必须是绝对路径。 另外删除容器时可以通过指定docker rm -v <container id>参数删除数据卷,但通常建议映射到指定的目录下更好管理。

    3.挂载数据卷容器

    上面挂载本地目录到容器的方法虽然解决了数据持久化的问题,但是在迁移上还是很麻烦的,比如:在多个容器之间共享的数据卷需要迁移时,使用挂载宿主机文件夹的方法迁移起来就会显得很麻烦,因此为了管理数据卷,我们可以启动-个专门用来存放数据的容器:

    上面启动了一个数据卷容器,/bin/true是为了覆盖原有进程并防止容器退出,然后启动其他容器并挂载数据卷容器。

    还可以通过db1挂载到后面启动的容器

    这样一来,删除上面四个容器中的三个,数据卷也不会丢失。即便四个容器都删除了,数据卷也不会消失,因为数据卷还会保存在/volume/目录下。

     

     

     

     

     

    提示1:使用-v参数时还有一个细节可以定制,例如-v /vol:/vol:ro 表示容器对/vol目录只读不可写,而-v /vol :/vol:rw 表示可读可写,这个小改动适用于目录或者文件,在某些场景下使用。

    提示2:如果删除含有数据卷的容器,在删除容器时没有使用-v标志,这些数据卷会成为dangling状态。

    显示所有没有挂载到容器上的数据卷:

    删除这些dangling状态的数据卷(注意:要确保不会误删数据卷);

    docker volume rm <volume name>

     

    为了更加清楚地展示数据卷挂载的规律,下面总结出了下表其中从宿主机文件和容器内文件两个位置是否存在文件为条件,总结出了容器启动后,实际上数据卷的状态。

    总结为一句话就是:凡是启动正常的容器,容器内部的数据卷目录显示的都是宿主机的内容。也就是说宿主机的目录有着最高的优先级,这里主要是想提醒读者, 构建镜像时应保持数据卷路径为空,因为启动后都以宿主机为准,没必要增加镜像体积。

     

     

     

    4.数据卷插件

    卷插件机制是在Docker 1.8的时候引进来的,Docker传统的卷管理只能挂载本机目录到容器中,数据的备份、同步、迁移都是个挑战,因此需要第三方的插件来管理容器中的数据。

    目前Docker社区有不少的卷插件,比较著名的有Flocker、Convoy, GlusterFS、Keywhiz、REX-Ray等,它们各自都有自己的特点。

    卷插件参考官网:https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins

     

    这里以Convoy为例,Convoy是一个单节点卷管理插件,它提供创建、删除、 备份、还原数据卷等功能。由于Convoy是单节点插件,因此对卷的迁移和共享的支持不是很好。下面来看如何安装Convoy插件。

    安装Convoy

    Convoy支持多种存储驱动,包括Device Mapper、VFS、EBS等(可以把NFS挂载到VFS目录下,实现跨主机存储和共享),这里以VFS为例启动Convoy:

     

    启动完后就可以使用Convoy了,在docker run中加入几个参数即可。

    -v参数左边并不是一个宿主机目录,而是一个名称vol_test这表示卷名称。

    如果没有,Convoy会创建一个。docker会把这个数据卷挂载到容器中。如果启动失败请检查convoy的安装。

    convoy可以创建,删除,备份,还原数据卷。

    使用convoy创建一个卷如下:

    删除一个卷,convoy rm命令貌似已经丢弃了

    创建卷快照

    备份一个卷

    还原一个卷

    查看所有卷和查看指定卷信息

     

     

    convoy代码由rancher团队维护。网站为https://github.com/rancher/convoy

     

     

  5. 插件与存储驱动
  6. Docker插件

    官方收录的插件网址为:

    https://docs.docker.com/engine/extend/legacy_plugins/

    插件一共分为三大类:网络插件,数据卷插件,认证插件

    下面以一个简单的sshfs插件为例,介绍Docker的插件系统。

    1. 安装插件

    该插件会请求两个权限,

    需要访问主机网络

    需要CAP_SYS_ADMIN权限(内核功能),允许插件运行mount命令。

    1. 查看插件

    1. 创建插件实例

    上面表示连接远程主机1.2.3.4,并且把/remote目录挂在为数据卷,查看数据卷docker volume ls,注意需要在当前目录把password文件准备,并且要有这个主机。

    4.使用插件

    如果正常,返回将是远程主机上的/remote目录下的内容。

    更多的插件请查看其开发网站的支持。

     

  7. 存储驱动

    Docker提供了可插拔的存储驱动程序架构。它使我们能够灵活地接入Docker存储驱动程序。它完全基于Linux文件系统。

    Docker守护程序只能运行一个存储驱动程序,并且必须在Docker守护进程的开始时就设置驱动程序,该守护程序实例创建的所有容器都使用相同的存储驱动程序。

    可以通过dockerd命令接指定名称来设置存储驱动程序。启动守护程序并设置新的驱动程序的命令如下。

    docker –-storage-driver=devicemapper

    可以通过命令检查Docker服务器驱动程序

    docker info

  8. 容器与操作系统
  9. 为容器而打造:Container Linux(CoreOS)

    CoreOS是一个基于Linux内核的轻量级操作系统,它是为计算机集群的基础设施建设而打造的,专注于自动化,轻松部署、安全、可靠、规模化。与其他通用Linux发行版( Ubuntu、Debian、Redhat)相比,它具有体型小、消耗小 、支持滚动更新等特点。

    除此之外 ,作为一个操作系统,CoreOS提供了在应用容器内部署应用所需要的基础功能环境以及一系列用于服务发现和配置共享的内建工具,内置的分布式系统服务组件给开发者和运维者组建分布式集群、部署分布式服务应用带来了极大便利。

    Co,eOS的官网是https://coreos.com/,目前国内外主流的云平台提供商均提供了CoreOS镜像,通过这些服务,你可以一键建立一个CoreOS实例,这似乎也是CoreOS官方推荐的主流安装方式。CoreOS当然支持其他方式的安装,比如:支持虚拟机安装(Vagrant+Vi1tualbox)、PXE(Preboot execute environmen)安装以及ISO安装到物理硬盘等方式。

    这里我们以使用Vagrant安装CoreOS为例,因为在云服务器环境中一般不支持自定义操作系统,裸机安装可以去官网查看资料。

    通过core-vagrant安装的直接结果是CoreOS被安装到一个VirtualBox虚拟机中,之后我们利用Vagrant命令来进行CoreOS虚拟机的启停。在安装CoreOS之前,我们需要确保以下软件已经安装到你的系统中。

    VirtualBox,官网下载地址:https://www.virtualbox.org/wiki/Downloads.

    Vagrant,地址:http://www.vagrantup.com/downloads.html.

    Git,直接使用包管理工具安装。

     

  10. 定制化容器系统RancherOS

    RancherOS是RancherLabs的一个开源项目,旨在提供一种在生产环境中大规模运行Docker的最简单的方式。它只包含运行Docker必需的软件,其二进制下载包的大小只有20MB左右。

    在RancherOS架构中,一切都是由Docker管理容器的。RancherOS会启动两个 Docker实例。其中一个称为系统Docker,是内核启动的第一个进程,即PIDl。它取代了其他Linux发行版本中的初始化系统,如sysvinit或system,负责初始化系统服务,如udev、DHCP和控制台,并将所有系统服务作为Dockyr容器进行管理(有点像LinuxKit的概念,但是RancherOS支持任意镜像运行)。

    系统Docker会创建一个特殊的系统服务容器,即用户Docker,主要负责创建容器。所有的用户容器都在用户Docker容器中运行,因此删除所有的用户容器并不会影响运行RancherOS 服务的系统容器。

     

posted @ 2021-12-24 21:18  头发重要  阅读(250)  评论(0)    收藏  举报