1. Docker简介
要学习容器固化,那么必须要先了解下Docker容器技术。Docker是基于GO语言实现的云开源项目,通过对应用软件的封装、分发、部署、运行等生命周期的管理,达到应用组件级别的“一次封装,到处运行”。这里的应用软件,既可以是一个Web应用,也可以是一套数据库服务,甚至是一个操作系统或编译器。Docker基于Linux的多项开源技术提供了高效、敏捷和轻量级的容器方案,并且支持在多种主流平台(PaaS)和本地系统上部署。
Docker容器技术有效地将由单个操作系统管理的资源划分到孤立的组中,以便更好地在孤立的组之间平衡有冲突的资源使用需求。每个容器内运行一个应用,不同的容器相互隔离,容器之间也可以建立通信机制。容器的创建和停止都十分快速,容器自身对资源的需求也十分有限,远远低于虚拟机。
1.1 Docker的核心价值
它改变了传统的软件“交付方式”和“运行方式”。传统交付源码或者软件包的方式的最大问题在于,软件运行期间的“依赖环境”无法控制,不能标准化,IT开发和运维人员需要花费大量精力去解决“依赖环境”问题。而Docker将软件及其“依赖环境”打包到一起,以镜像的方式交付,让软件运行在“标准环境”中,非常符合云计算的需求。另外,Docker秒级创建及删除应用和动态调整资源的能力,也非常符合云计算“实例水平扩展,资源动态调整”的需求。
1.2 Docker的应用场景及组件
Web应用的自动化打包和发布;自动化测试和持续集成、发布;在服务型环境中部署和调整数据库或其他的后台应用。Docker组件包括Docker容器、仓库和镜像,容器是Docker的核心组件,负责Docker实例的运行,仓库分公共仓库(Docker hub)和私有仓库,用于Docker镜像的存放和分发,Docker镜像是容器运行时的只读模板。Docker采用Linux技术,所以只能运行在Linux上。
1.3 Docker相关命令
查看H3Cloud OS大云平台使用容器进程的运行状态:
输入命令docker ps ,如下图所示,输出显示的第一列为容器的UUID信息,第二列为容器的镜像名称,第四列为容器进程创建时间,第五列为容器运行状态显示已运行的时长。
进入容器:
输入命令docker exec –it <容器UUID> /bin/bash,其中容器的UUID可以只输入前三位。
查看H3Cloud OS主机名:
输入命令hostname,此时输出的即是主机名。
进入H3Cloud OS控制节点或计算节点容器后,查看openstack相关进程服务的状态,需要先执行加载环境变量,用于openstack内部组件间授权,执行命令:source /root/admin-openrc.sh。
在计算节点容器内查看nova进程状态:
执行命令nova service-list
手动停止和启动nova服务操作
执行命令systemctl start openstack-nova-conductor.service
2. 为什么需要进行固化操作
在容器中,镜像是只读的,不可写,当需要修改时会在镜像上增加一个可写层,写修改发生在可写层里,修改后形成整个新的容器,原镜像还是没有变,即在原镜像之外“包装”不同的可写层的新内容做固化。容器固化是一套方法,用于当容器中文件或内容需要修改发生变化时,将修改的内容固定下来,避免容器重建时修改的内容又还原了。
3. 固化的原理
其核心原理是通过dockfile新建镜像,从而将更改的内容放到新镜像里,然后再通过新镜像启动容器。Docker采用写时复制方式创建根文件系统,可以简单理解为如果有相同内容的文件或者镜像,使用这些资源的不同实例在没有对它们做任何修改的时候是不需要复制的,也就是说不需要创建新的资源来使用,当第一次修改发生时,这个时候再复制出新的资源,修改的内容放置于新的资源中。这样一来部署就会变得极其快捷,并且节省内存和硬盘空间。固化并没有对原始镜像做修改,镜像是不能修改的,只是在镜像的只读层(容器)修改。由于在重启虚机或销毁docker的情况下,会在原始镜像的基础上重新生成一个新的容器,从而我们修改的效果没有生效,因此进行固化操作来达到保存修改的效果。
4. 固化的步骤
容器固化流程图见下:
4.1 备份当前镜像
输入命令docker ps | grep cloudos-openstack来查看关键字为cloudos-openstack的容器,找到相应容器的id,输入命令docker images|grep openstack查看需要操作的镜像。
备份镜像:tag命令来为镜像打上标签,实际上就是备份的过程。
4.2 删除原镜像
使用docker rmi命令来删除原镜像。
此时查看镜像列表,已经没有原镜像了。
4.3 重新制作镜像
重新制作镜像前先登入openstack docker容器中,将pre-install.sh拷贝到/opt/openstack-transfer/中,接下来要修改pre-install.sh文件。
修改pre-install.sh是为了新建dockerfile并新建容器,因此需要从之前容器中退出在设备层操作。拷贝/opt/openstack-transfer/pre-install.sh到/root/eventually目录下,如果该目录不存在需要在/root路径下执行命令mkdir eventually来创建目录。注意不能在不存在相应路径的情况下直接执行命令cp 命令,否则会把pre-install.sh复制到/root路径下并且重命名为eventually。
说明:涉及镜像等与CloudOS有关的配置都需要修改pre-install.sh文件,其他如新建.txt文件这样的配置则无需修改该文件。
拷贝完成后就可以编辑vim /root/eventually路径下的pre-install.sh文件了。按照要求将firewall_type修改为GATEWAY,将lb_type参数修改为SERVICE_CHAIN,将resource_mode修改为NFV。
开始重新制作镜像:已经在/root/eventually/路径下做了以上修改,接着继续在这个路径下通过命令vi dockerfileopenstackbuild.txt创建一个文件。
创建dockerfile文件是为了以docker build来创建镜像,这是创建镜像的方法之一,目前用得最多,CloudOS也用这个。其他的方法还有通过容器创建来使用docker commit命令构建镜像,简单来讲就是先创建好一个容器,然后把它转为镜像。
进入文件进行编辑:首行FROM cloudos-openstack:E1137H10_twins表示以cloudos-openstack:E1137H10_twins镜像为基础启动容器,注意首行必须以FROM开始且行首行末都不能有空格,支持以#开头的注释行。第二行命令USER root表示用户身份为root。第三行命令是对基础镜像的调整变更,这里的意思是将pre-install.sh拷贝替换为/root/scripts/pre-install.sh。编辑结果如下图所示:
创建好后执行docker build –t cloudos-openstack:E1137H10 –f dockerfileopenstackbuild.txt .命令构建镜像,这条命令最后的.表示在当前路径下操作。之后会逐行执行文件里的命令,首先从之前备份过的镜像cloudos-openstack:E1137H10_twins启动,用户名为root,执行的操作为将本路径下的已经修改过配置的pre-install.sh文件拷贝到/root/scripts下。
如果dockerfileopenstackbuild文件内命令输入有误则会报错,举例如下图所示,文件第三行拷贝路径输入有误,那么在执行命令时的第三步会显示失败。
查看结果,显示已创建好新的镜像文件。
4.4 使用新镜像启动容器
先输入命令/opt/bin/kubectl –server=192.168.113.250:8888 get rc查看openstackrc,然后delete将它停止,查看pod状态已经没有openstackrc容器了。
重新创建openstack docker容器前请检查openstack-rc.yaml文件中的image字段是否与上一步build出来的tag一致。如下图所示,查看openstack-rc.yaml文件中的image字段与上一步build出来的tag一致,镜像信息为cloudos-openstack:E1137H10。注意:如果不一致则需要修改,且修改前要先备份。
执行命令/opt/bin/kubectl --server=127.0.0.1:8888 create -f /opt/bin/confFile/openstack-rc.yaml拉起openstack docker,查看运行状态是否都是正常的Running状态。
4.5 进入容器查看修改的内容是否固化
查看文件显示已将firewall_type参数修改为GATEWAY,将lb_type参数修改为SERVICE_CHAIN,将resource_mode参数修改为NFV,固化成功。