Murano之:集成docker
来源:互联网 发布:青岛方特梦幻王国知乎 编辑:程序博客网 时间:2024/04/30 11:05
murano是如何集成docker?提供了怎样的接口以辅助用户快捷的编写package呢?这个得利于murano自身的架构,murano的package提供了自定义lib的功能,即根据自己的需要,根据murano package的定义规则,自己拓展一个即可。关于murano package的解析请移步murano实践之package分析
DockerInterfacesLibrary
DockerInterfacesLibrary 中提供了对于一个已正确安装docker环境的虚拟机操作docker的接口,首先看下package中的manifest.yaml
见:murano-apps/manifest.yaml
Format: 1.0Type: LibraryFullName: io.murano.apps.docker.InterfacesName: Docker Interface LibraryDescription: | The library provides all necessary interface for Docker and Kubernetes applicationsAuthor: 'Mirantis, Inc'Tags: [Docker, Kubernetes]Classes: io.murano.apps.docker.DockerApplication: DockerApplication.yaml io.murano.apps.docker.DockerContainer: DockerContainer.yaml io.murano.apps.docker.DockerContainerHost: DockerContainerHost.yaml io.murano.apps.docker.DockerHelpers: DockerHelpers.yaml io.murano.apps.docker.DockerHostVolume: DockerHostVolume.yaml io.murano.apps.docker.DockerTempVolume: DockerTempVolume.yaml io.murano.apps.docker.DockerVolume: DockerVolume.yaml io.murano.apps.docker.ApplicationPort: ApplicationPort.yaml
重点在Classes中,目前这里面主要封装了
- DockerApplication
- DockerContainer
- DockerContainerHost
- DockerHelpers
- DockerHostVolume
- DockerTempVolume
- DockerVolume
- ApplicationPort
这8个docker相关的接口,我们这里以DockerApplication为例做一个分析,在Classes文件包中找到DockerApplication.yaml
提供了deploy
、destroy
、getConnectionTo
等方法。以deploy
为例,显示了虚拟机使用docker安装application的步骤
deploy: Body: - $.host.deploy() - $container: $.getContainer() - $repr: $._getContainerRepresentation($container) - If: $.getAttr(container, null) != $repr Then: - $.onInstallationStart() - Try: - $.applicationEndpoints: $.host.hostContainer($container) - $.setAttr(container, $repr) Catch: - As: e Do: - $formatString: 'Error: {0}' - $._environment.reporter.report_error($, $formatString.format($e.message)) - Rethrow: Else: - $.onInstallationFinish()
首先$.host.deploy()
,这个host
为DockerStandaloneHost
详见DockerStandaloneHost,具有方法deploy
,此处调用的也是deploy方法DockerStandaloneHost
的deploy
方法如下:
deploy: Body: - If: not $.getAttr(deployed, false) Then: - $._environment.reporter.report($this, 'Create VM for Docker Server') - $.instance.deploy() - $resources: new(sys:Resources) - $template: $resources.yaml('StartDocker.template') - $.instance.agent.call($template, $resources) - If: $.dockerRegistry != null and $.dockerRegistry != '' Then: - $._environment.reporter.report($this, 'Configuring Docker registry') - $template: $resources.yaml('SetupDockerRegistry.template').bind(dict( dockerRegistry => $.dockerRegistry )) - $.instance.agent.call($template, $resources) - $._environment.reporter.report($this, 'Docker Server is up and running') - $.setAttr(deployed, true)
从
- $.instance.deploy()- $resources: new(sys:Resources)- $template: $resources.yaml('StartDocker.template')- $.instance.agent.call($template, $resources)
这四步看出,需要拿到StartDocker.template
交给LinuxMuranoInstance
,StartDocker.template
中的内容如下:
startDocker.template
FormatVersion: 2.0.0Version: 1.0.0Name: Start docker serviceBody: | startDocker()Scripts: startDocker: Type: Application Version: 1.0.0 EntryPoint: startDocker.sh Options: captureStdout: false captureStderr: false verifyExitcode: false
这个template的EntryPoint是startDocker.sh
,内容:
#!/bin/bash# Licensed under the Apache License, Version 2.0 (the "License"); you may# not use this file except in compliance with the License. You may obtain# a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the# License for the specific language governing permissions and limitations# under the License.service docker start
一句话,启动docker服务,所以$.host.deploy()
其实就是用了启动虚拟机上的docker服务;根据上面的方法,
- $container: $.getContainer()- $repr: $._getContainerRepresentation($container)
这两步获取container的基础信息
再看- $.host.hostContainer(container)
对应的方法如下:
hostContainer: Arguments: - container: Contract: $.class(DockerContainer).notNull() Body: - $.deploy() - $.deleteContainer($container.name) - $portBindings: {} - $newEndpoints: [] - $._pullImage(image => $container.image) - For: applicationPort In: $container.ports Do: - If: $applicationPort.scope != host Then: - $hostPort: $._acquirePort($applicationPort, $container.name) - $containerPort: $._getPortSpec($applicationPort) - $portBindings[$hostPort]: $containerPort - If: $applicationPort.scope = public Then: - $rule: - ToPort: $hostPort FromPort: $hostPort IpProtocol: toLower($applicationPort.protocol) External: true - $._environment.securityGroupManager.addGroupIngress($rule) - $record: port: $hostPort address: $.instance.ipAddresses[0] scope: cloud containerPort: $applicationPort.port portScope: $applicationPort.scope protocol: $applicationPort.protocol applicationName: $container.name - $newEndpoints: $newEndpoints + list($record) - If: $applicationPort.scope = public and $.instance.floatingIpAddress != null Then: - $record.address: $.instance.floatingIpAddress - $record.scope: public - $newEndpoints: $newEndpoints + list($record) - $volumeMap: {} - For: path In: $container.volumes Do: - $volume: $container.volumes.get($path) - If: $volume.getType() = HostDir Then: - $hostDir: $volume.getParameters() - $volumeMap[$hostDir]: $path - $._environment.reporter.report($this, 'Adding Docker Application') - $resources: new(sys:Resources) - $template: $resources.yaml('RunContainer.template').bind(dict( appName => $container.name, image => $container.image, env => $container.env, portMap => $portBindings, volumeMap => $volumeMap, commands => $container.commands )) - $._removeApplicationEndpoints($container.name) - $privateIp: $.instance.agent.call($template, $resources) - $record: port: $applicationPort.port address: $privateIp scope: host containerPort: $applicationPort.port portScope: $applicationPort.scope protocol: $applicationPort.protocol applicationName: $container.name - $newEndpoints: $newEndpoints + list($record) - $._environment.stack.push() - If: not $container.name in $.containers Then: - $.containers: $.containers + list($container.name) - $.applicationEndpoints: $.applicationEndpoints + $newEndpoints - Return: $.getEndpoints($container.name)
前面几步,判断该container是否存在,如果存在,删除- $._pullImage(image => $container.image)
这一步获取$container.image。中间到- $volumeMap: {}
之前的这一段就是为了组装portBindings和newEndpoints,接着组装volumeMap,完事儿之后呢获取RunContainer.template
。- $privateIp: $.instance.agent.call($template, $resources)
到这一步了自然就是告诉虚拟机,你该调用RunContainer.template
工作啦,RunContainer.template
中其实归根到底就是一段拼装好的执行docker run
命令的脚本。
从上面的分析可以看出来,DockerInterfacesLibrary
事实上是依赖DockerStandaloneHost
与 LinuxMuranoInstance
的这两个对象事实需要创建虚拟机的镜像中包含了murano-agent服务和docker服务的,DockerStandaloneHost
中封装了StandaloneHost对docker的一些操作,如docker run
、service docker start
等,LinuxMuranoInstance
中封装的是获取组装好的模版执行等功能。
以tomcat为例分析
DockerTomcat
Namespaces: =: io.murano.apps.docker std: io.muranoName: DockerTomcatExtends: DockerApplicationProperties: name: Contract: $.string().notNull() publish: Contract: $.bool().notNull() Default: true password: Contract: $.string().notNull()Methods: initialize: Body: - $._environment: $.find(std:Environment).require() - $._scope: switch($.publish, $ => public, not $ => internal) getContainer: Body: Return: name: $.name image: 'tutum/tomcat' env: TOMCAT_PASS: $.password ports: - port: 8080 scope: $._scope onInstallationStart: Body: - $._environment.reporter.report($this, 'Installing Tomcat') onInstallationFinish: Body: - If: $.publish Then: - $endpoints: $.applicationEndpoints.where($.scope = $this._scope). select(format('http://{0}:{1}', $.address, $.port)) - $._environment.reporter.report($this, 'Tomcat {0} is available at {1}'.format($.name, join(', ', $endpoints))) Else: - $._environment.reporter.report($this, 'Tomcat {0} has deployed but is not accessible from outside'.format($.name))
Extends: DockerApplication
直接表明,继承了DockerApplication,也就是上面分析的DockerApplication实例,此处只需要实现getContainer
和 onInstallationFinish
方法即可,deploy
会自动从DockerApplication继承,deploy
方法完成tomcat的具体安装
- Murano之:集成docker
- Murano之:集成docker
- Murano实践之package分析
- Murano实践之package分析
- [Docker-集成] Docker、Jenkins
- [Docker-集成] Docker、Maven、Java
- 深入浅出Docker(四):Docker的集成测试部署之道(infoq)
- 深入浅出Docker(四):Docker的集成测试部署之道
- 深入浅出Docker(四):Docker的集成测试部署之道
- 深入浅出Docker(四):Docker的集成测试部署之道----收藏
- 深入浅出Docker(四):Docker的集成测试部署之道
- 持续集成之jenkins实践教程:基础篇(5): 集成docker
- TFS Services集成Docker
- TFS Services 集成Docker
- Docker中集成bazel
- Docker可持续集成研究
- 手动安装OpenStack-Murano和Murano-dashboard
- Murano.conf的配置
- [Django入门知识浅介]Django框架里的MVC思想
- 正则表达式分组、断言
- mac下修改mysql的默认字符集为utf8
- python中单,双引号和三个双引号的区别
- DB2的简单的体系结构
- Murano之:集成docker
- rabbitmq 服务器管理工具 -rabbitmqadmin
- JSP有三大指令
- Rabbitmq Durability and related matters
- 一对一外键关联关系的理解与实践
- ubuntu设置minicom
- 千里之行,始于足下(二)-------创建基类
- C语言宏与单井号(#)和双井号(##)
- 浅谈英雄联盟之比尔吉沃特事件-一个游戏的生存方式