如何结合docker-compose和docker pipeworkk

在这一系列文章的中,我们分享了只用Docker时我们开发的初步的工作流,如何创建一个基础的构建和部署流水线。容器的部署方式不再是在登陆server的时候从内存中输入Docker命令。我们已经通过Jenkins server实现了镜像的自动化构建。我们使用脚本将Docker命令进行封装,将其存储到GitHub中并且设置版本。目前我们正采取措施,通过逐步改善现有过程来实现持续部署。然而,仍有一些痛点需要我们去解决。在这篇文章中,我们将看看如何使用Docker Compose 和 Ansible来改善此设计。
在部署镜像时,工程师需要登录到服务器,并从shell运行我们的Docker wrapper脚本。这不是很好的解决方法,因为它也需要开发者进行等待。没有任何一方会从在这种方式中获益(作为一个工程师,当你去做某件你很了解并且很容易自动化的事情时,你有多少次被打断了?)由于每一次部署都是通过操作者电脑中的SSH会话来执行的,因此部署过程是不可见的。
如果你对我们的部署脚本还有印象,你会发现它看起来像下面的代码段:
实际上,我们做的是将Docker run命令语句进行抽象,由此工程师将不需要知道每个图像成功运行时所需要的确切的参数。虽然这改善了必须全部记住并且手动输入所有Docker参数的现状,但同时也会带来新的问题:
每个容器的逻辑都存储在同一文件中,这使得对应用程序部署逻辑的更改更难追踪;
当开发者需要测试或者修改参数时,需要被迫理清脚本中的逻辑,而不是能够在某一特定的程序中轻松地阅读和修改参数。
在我们的工作流中,Docker Compose是一个更适合使用的工具,它同样可以将部署参数进行编码,并且在YAML文件中指定,此文件就是docker-compose.yml。Docker Compose不仅帮助我们解决了上面提到的难点,而且也可以使我们从社区未来的工作中获益。下面让我们理清部署脚本,并且为我们的JAVA程序示例创建一个Compose文件。首先,我们需要基于原来的部署逻辑创建一个docker-compose.yml文件:
现在,部署容器只需要在与docker-compose.yml文件相同目录下输入以下命令:
docker-compose up
它将根据compose文件中设置的参数启动一个容器。在compose文件中一个重要的变量是${VERSION} 。Docker Compose可以从当前的shell环境中插入compose文件里所列出的参数。我们可以通过简单地运行以下语句来设置参数:
VERSION=1.0.0 docker-compose up
它将从我们的私有镜像仓库挑出标记1.0.0的镜像,以此启动java-service-1程序。如果没有设置VERSION变量,Docker Compose将产生一条警告信息,并且用空字符串代替变量值,由此,具有最新版本标签的镜像将会被挑出。因此,正确地设置变量是相当重要的。
作为开发过程的一部分,我们希望开发人员能够在本地建立服务并且测试他们的服务。然而,由于docker-compose.yml指向私有镜像仓库的镜像,运行docker-compose将从最近构建的镜像中开启服务而不是从本地资源中开启。理想情况下,开发者可以通过运行以下代码使用典型的docker-compose工作流:
Docker Compose能在不修改docker-compose.yml文件的情况下,让我们做到这一点。我们可以使用多个文件来覆盖我们在本地测试中想要改变的任何参数。在docker-compose.override.yml中,我们指定一个key而不是一个镜像,并且移除了对VERSION变量的需求。由于这是一个覆盖文件,我们不需要复制任何额外的设置,如端口设置:
使用Docker Compose而非部署脚本之后,我们可以:
在源代码中存储每个compose文件,这与Dockerfile类似;
不再需要复杂的部署脚本;
允许开发人员在本地轻松地测试并修改应用程序。
现在我们有了java-service-1程序的compose文件,我们可以将它从我们的部署脚本中删除,因此文件组织与下面的结构类似:
此时,我们仍然没有解决镜像构建和部署之间的问题。在docker-compose.yml文件中包含了所有的部署逻辑,但是它如何在环境中运行直至结束的呢?正好现在我们在运行与UNIX和TPC socket相关的Docker守护进程,是时候讨论一些与安全有关的问题了。
我们的情况是,工程师登录到服务器上,手动运行每个服务器所需容器的部署脚本。默认情况下,当在局部运行Docker命令时,它将使用UNIX socket /var/run/docker.sock连接Docker守护进程;或者让守护进程监听TCP socket,这允许用户远程连接到每个Docker守护进程,使得工程师能够像登录到主机一样运行命令。这为连接方式提供了更大的灵活性,但是没有考虑到一些开销和安全问题:
通过网络连接增加了安全隐患;
增加了对于基于主机或者基于网络的ACLs需求;
保护守护进程需要分布式CA和客户端认证。
另一种可能的方法是不使用基于UNIX socket的方式运行Docker守护进程,而使用SSH来运行命令。已经建立的ACLs将保护SSH端口,并且它只允许通过SSH授权的特定的用户才能使用Docker守护进程。虽然这不是最简洁的方法,但是它有助于保持较低的运行开销,并且使安全隐患降到最低。这点是非常重要的,尤其是对于细粒度的稀疏的任务队列而言。
为了有利于通过SSH运行Docker命令,我们可以使用Ansible——一个流行的编排和配置管理工具。它是无代理的,并且允许通过SSH连接运行“剧本”(服务器任务集合)。一个运行docker-compose命令的简单的剧本如下所示:
如果你对Ansible没有过多了解,你也许可以通过上面的剧本大致了解到我们想做什么。它们按顺序一步步执行,具体如下所示:
Ansible将通过SSH连接到目标服务器(允许通过使用DESTINATION变量来指定主机)
在每个服务器中,Ansible会通过执行shell命令登录到公司私有的镜像仓库
Ansible将位于Jenkins(运行ansible剧本的服务器)中的docker-compose.yml文件复制到每个目标服务器中的/tmp/docker-compose.yml下
在每个目标服务器中运行docker-compose命令
通过删除远程的/tmp/docker-compose.yml文件进行清理
一个shell脚本可以被运用在同一个事件中。然而在Ansible中,我们将很容易的使任务并行化并且得到经过良好测试的模块,通过使Ansible与新的部署剧本相结合,我们可以远程启动容器,相较于工程师登录到主机、人工运行命令,这是一个重要的进步。为了在部署过程和状态中提供更大的可视性,我们将建立Jenkins任务来运行Ansible代码。通过使用Jenkins,在未来我们可以轻松地将构建和部署任务集成起来,从而得到额外的好处。
Jenkins任务需要两个参数:目标主机(传递给剧本中的DESTINATION变量)和部署镜像的版本(在docker-compose.yml文件中插入VERSION变量)。大多数任务的构建部分是一个shell构建器,它将试图找到程序中的docker-compose.yml文件,然后通过传递变量(用-e)到剧本中,运行ansible-playbook命令:
虽然看起来我们似乎只对工作流做了微小的变化,但是我们正一步一步地向构建一个持续部署模型迈进:
部署是可以被审查的。我们使用日志来记录输出什么、何时输出、以及哪些主机是目标主机等信息,这一切都归功于Jenkins。
程序部署逻辑已经从一个单一的脚本分散到存储在程序源代码中的单独的docker-compose.yml文件中,这意味着我们可以轻松地通过git更改程序部署逻辑。在程序源文件或者部署文件发生变化时,我们也可以容易地进行构建和部署。
虽然这些改进解决了某些问题,但是它们所带来的新的问题也成为了焦点:
哪个容器的哪个版本会被部署到何地?
容器在被部署后会处于哪种状态?
我们如何确定哪个主机成为程序的目标主机?
在这一系列接下来的文章中,我们将探讨怎样运行Rancher以及使用它的原因,尤其是它如何解决上述的问题。与此同时,我们也讨论它在业务和开发团队中所起到的意想不到的桥梁作用。
原文来源:
9月27日,北京海航万豪酒店,容器技术大会Container Day 2017即将举行。
CloudStack之父、海航科技技术总监、华为PaaS部门部长、恒丰银行科技部总经理、阿里云PaaS工程总监、民生保险CIO······均已加入豪华讲师套餐!
11家已容器落地企业,15位真·云计算大咖,13场纯·技术演讲,结合实战场景,聚焦落地经验。免费参会+超高规格,请戳
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:57967次
积分:1662
积分:1662
排名:千里之外
原创:103篇
(6)(3)(10)(8)(4)(13)(6)(13)(9)(10)(21)(6)(3)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'中国领先的IT技术网站
51CTO旗下网站
Docker Compose:链接外部容器的几种方式
容器之间的链接是一种很常见的操作:它提供了访问其中的某个容器的网络服务而不需要将所需的端口暴露给Docker Host主机的功能。Docker Compose中对该特性的支持同样是很方便的。然而,如果需要链接的容器没有定义在同一个 docker-compose.yml 中的时候,这个时候就稍微麻烦复杂了点。
作者:佚名来源:| 16:27
在Docker中,容器之间的链接是一种很常见的操作:它提供了访问其中的某个容器的网络服务而不需要将所需的端口暴露给Docker
Host主机的功能。Docker Compose中对该特性的支持同样是很方便的。然而,如果需要链接的容器没有定义在同一个 docker-compose.yml
中的时候,这个时候就稍微麻烦复杂了点。
在不使用Docker Compose的时候,将两个容器链接起来使用 &link 参数,相对来说比较简单,以 nginx 镜像为例子:
docker&run&&docker&run&&
这样, test2 与 test1 便建立了链接,就可以在 test2 中使用访问 test1 中的服务了。
如果使用Docker Compose,那么这个事情就更简单了,还是以上面的 nginx 镜像为例子,编辑 docker-compose.yml
version:&&3&&services:&&test2:&&image:&nginx&&depends_on:&&-&test1&&links:&&-&test1&&test1:&&image:&nginx&
最终效果与使用普通的Docker命令 docker run xxxx 建立的链接并无区别。这只是一种最为理想的情况。
如果容器没有定义在同一个 docker-compose.yml 文件中,应该如何链接它们呢?
又如果定义在 docker-compose.yml 文件中的容器需要与 docker run xxx 启动的容器链接,需要如何处理?
针对这两种典型的情况,下面给出我个人测试可行的办法:
方式一:让需要链接的容器同属一个外部网络
我们还是使用nginx镜像来模拟这样的一个情景:假设我们需要将两个使用Docker Compose管理的nignx容器( test1 和 test2
)链接起来,使得 test2 能够访问 test1 中提供的服务,这里我们以能ping通为准。
首先,我们定义容器 test1 的 docker-compose.yml 文件内容为:
version:&&3&&services:&&test2:&&image:&nginx&&container_name:&test1&&networks:&&-&default&&-&app_net&networks:&&app_net:&&external:&true&
容器 test2 内容与 test1 基本一样,只是多了一个 external_links ,需要特别说明的是:
最近发布的Docker版本已经不需要使用external_links来链接容器,容器的DNS服务可以正确的作出判断
,因此如果你你需要兼容较老版本的Docker的话,那么容器 test2 的 docker-compose.yml文件内容为:
version:&&3&&services:&&test2:&&image:&nginx&&networks:&&-&default&&-&app_net&&external_links:&&-&test1&&container_name:&test2&networks:&&app_net:&&external:&true&
否则的话, test2 的 docker-compose.yml 和 test1 的定义完全一致,不需要额外多指定一个 external_links
。相关的问题请参见stackoverflow上的相关问题: docker-compose + external container
正如你看到的那样,这里两个容器的定义里都使用了同一个外部网络 app_net ,因此,我们需要在启动这两个容器之前通过以下命令再创建外部网络:
docker&network&create&app_net&
之后,通过 docker-compose up -d 命令启动这两个容器,然后执行 docker exec -it test2 ping test1
,你将会看到如下的输出:
docker&exec&-it&test2&ping&test1&PING&test1&(172.18.0.2):&56&data&bytes&64&bytes&from&172.18.0.2:&icmp_seq=0&ttl=64&time=0.091&ms&64&bytes&from&172.18.0.2:&icmp_seq=1&ttl=64&time=0.146&ms&64&bytes&from&172.18.0.2:&icmp_seq=2&ttl=64&time=0.150&ms&64&bytes&from&172.18.0.2:&icmp_seq=3&ttl=64&time=0.145&ms&64&bytes&from&172.18.0.2:&icmp_seq=4&ttl=64&time=0.126&ms&64&bytes&from&172.18.0.2:&icmp_seq=5&ttl=64&time=0.147&ms&
证明这两个容器是成功链接了,反过来在 test1 中ping test2 也是能够正常ping通的。
如果我们通过 docker run --rm --name test3 -d nginx 这种方式来先启动了一个容器( test3
)并且没有指定它所属的外部网络,而需要将其与 test1 或者 test2 链接的话,这个时候手动链接外部网络即可:
docker&network&connect&app_net&test3&
这样,三个容器都可以相互访问了。
方式二:更改需要链接的容器的网络模式
通过更改你想要相互链接的容器的网络模式为 bridge ,并指定需要链接的外部容器( external_links
)即可。与同属外部网络的容器可以相互访问的链接方式一不同,这种方式的访问是单向的。
还是以nginx容器镜像为例子,如果容器实例 nginx1 需要访问容器实例 nginx2 ,那么 nginx2 的 doker-compose.yml
version:&&3&&services:&&nginx2:&&image:&nginx&&container_name:&nginx2&&network_mode:&bridge&
与其对应的, nginx1 的 docker-compose.yml 定义为:
version:&&3&&services:&&nginx1:&&image:&nginx&&external_links:&&-&nginx2&&container_name:&nginx1&&network_mode:&bridge&
需要特别说明的是,这里的 external_links 是不能省略的,而且 nginx1 的启动必须要在 nginx2 之后,否则可能会报找不到容器
nginx2 的错误。
接着我们使用ping来测试下连通性:
$&docker&exec&-it&nginx1&ping&nginx2&&#&nginx1&to&nginx2&PING&nginx2&(172.17.0.4):&56&data&bytes&64&bytes&from&172.17.0.4:&icmp_seq=0&ttl=64&time=0.141&ms&64&bytes&from&172.17.0.4:&icmp_seq=1&ttl=64&time=0.139&ms&64&bytes&from&172.17.0.4:&icmp_seq=2&ttl=64&time=0.145&ms&&$&docker&exec&-it&nginx2&ping&nginx1&#nginx2&to&nginx1&ping:&unknown&host&
以上也能充分证明这种方式是属于单向联通的。
在实际应用中根据自己的需要灵活的选择这两种链接方式,如果想偷懒的话,大可选择第二种。不过我更推荐第一种,不难看出无论是联通性还是灵活性,较为更改网络模式的第二种都更为友好。【编辑推荐】【责任编辑: TEL:(010)】
大家都在看猜你喜欢
关注关注聚焦聚焦热点
24H热文一周话题本月最赞
讲师:5798人学习过
讲师:662人学习过
讲师:2388人学习过
精选博文论坛热帖下载排行
本书是根据全国计算机技术与软件专业技术资格(水平)考试的“计算机网络管理员考试大纲”所要求的考试范围而编写的辅导用书。全书共分10章...
订阅51CTO邮刊(为容器分配独立IP方法一)使用pipework为docker容器添加IP
pipework -- docker网络增强工具
是的一个网络增强功能插件.
Docker创建的时候, 默认是接入docker0(linux bridge)的. 所以只能单主机工作, 不能多台主机联动工作.
这时候, pipework应运而生.
我们先来介绍一下pipework的简单用法, 之后再深入探讨关于pipework与ovs的结合. 最后基于一个案例分析来结束.
pipework入门
# brctl addbr br0&
# ip link set dev br0 up&
# ip addr add 192.168.2.1/24 dev br0&
# MYSQL=$(docker run -d -p
-e MYSQL_PASS=admin tutum/mysql)&
# pipework br0 $MYSQL 192.168.2.100/24
创建一个br0(linux
bridge).建议自己写个网桥网卡文件(eth0无IP,br0有IP)
配置IP地址给br0.
启动一个mysql docker.
使用pipework为docker添加IP地址.
经过这几个步骤后, 创建的docker就有一个设置指定的IP地址了. pipework的具体工作原理就不在这里详细分析,
有兴趣的同学可以自己去读源代码.
pipework进阶
上面入门介绍中, 我们使用pipework工具, 通过linux bridge的模式指定IP地址给docker容器. 其实,
除了linux bridge, pipework还支持现在流行的虚拟交换机(Open vSwitch).
下面简单的示范一下如何将docker与Open vSwitch(下称ovs)连通.
# ovs-vsctl add-br ovsbr0&
# ip link set dev ovsbr0 up&
# ip addr add 192.168.3.1/24 dev ovsbr0&
# MYSQL=$(docker run -d -p
-e MYSQL_PASS=admin tutum/mysql)&
# pipework ovsbr0 $MYSQL 192.168.3.100/24
对于pipework来说, 底层使用什么虚拟网络设备是透明的. pipework会智能地判断使用的是linux
bridge还是ovs. 所以除了创建桥的方式不同, 其他并没有改变.
pipework案例分析
下面就具体分析一个pipework的应用场景.
docker容器与VLAN
docker容器启动时, 默认是接入到docker0网桥上的. 这样就容易给大家造成一个假象,
docker容器只能运行在单机的情况下. *但是显示并非如此.* 我们可以通过pipework扩展docker的网络功能.
我们假设现在有2台服务器A和B, 交换机S. 现在我们同时在A,B上创建虚拟网桥ovsbr0. 并且在服务器A上,
将网桥启用和配置IP地址. 那么我们现在如果在A,B上,分别启动一个docker.
同时通过pipework将docker接入到ovsbr0上, 并且配置与A服务器上ovs相同网段的IP地址.
那么*两个docker互相之间就能够通信*了. 很神奇有木有!!!
但是万恶的需求是不断进化的(呵呵). 不会都让你们的docker运行在一个网络环境下, 有的应用是需要互相隔离的.
那么就有可能需要VLAN的划分. 这里多说点, 其实在现今的情况下, 除了划分VLAN还有其他的方式达到二层网络隔离的效果,
如VXLAN, NVGRE等技术. 但是我们现在还是只谈论VLAN隔离吧.
我们先在服务器A上做一下操作:
# D1V10=$(docker run -i -t learn/ping /bin/bash)&
# pipework ovsbr0 -i d1v10 $D1V10 10.1.1.10/24&
# D2V10=$(docker run -i -t learn/ping /bin/bash)&
# pipework ovsbr0 -i d2v10 $D2V10 10.1.1.11/24&
# D3V20=$(docker run -i -t learn/ping /bin/bash)&
# pipework ovsbr0 -i d3v20 $D3V20 10.1.1.20/24
这里定义了3个Docker容器, 并且将其添加到ovsbr0这个桥上. 下面开始将不同的网卡设置vlan id. 我们将 D1V10
和 D2V10 设置vlan id为10. 将D3V20 设置vlan id为20.
我们可以通过ovs-vsctl
list-ports 找出桥设备下面的所有端口. 但是刚刚我们一口气连续创建了3个docker,
会看见3个对应的虚拟网卡.
然后我们需要做的是, 找出与Docker容器想对应的虚拟网卡. 刚刚在pipework执行时, 添加了参数-i,
意思是创建的虚拟网卡结尾对应的字符串.
# pipework ovsbr0 -i d1v10 $D1V10 10.1.1.10/24
这命令执行后, ovsbr0设备会添加一个port, port的名字应该是plxxxxd1v10.
当中的xxxx是docker容器的pid.
这时我们就可以通过ovs-vsctl
set port tag=的方式设置vlan id了.
下面是范例:
# ovs-vsctl list-ports ovsbr0
# ovs-vsctl set port pl tag=10&
# ovs-vsctl set port pl tag=10&
# ovs-vsctl set port pl tag=20
这样就完成了设置VLAN的步骤了. 下面我们通过简单的ping命令来验证一下vlan隔离的效果.
# docker attach $D1V10
root@f94dc85c44b1:/# ping 10.1.1.11
# reachable
root@f94dc85c44b1:/# ping 10.1.1.20
# unreachable
多服务器的vlan划分
可能有同学以为, docker只能在单机上工作(docker与docker之间通信只能在本机进行).
但是使用pipework增强插件后, 我们可以通过Linux Bridge或Open vSwitch来进行数据交换.
这样就可以不仅仅局限于Docker默认的隔离桥(原谅我的破翻译, 我真不知道怎么形容这货 --& docker0)
pipework是个强大的docker网络管理工具. 具体的实现也比较简单. 可以配合ovs来实现强大的功能.
剩下就是发挥想象力的时间了...
转载:http://blog.e3rp4y.me/blog//docker-with-openvswitch.html
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。随笔 - 23, 文章 - 2, 评论 - 72, 引用 - 0
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a Compose file to configure your application’s services. Then, using a single command, you create and start all the services from your configuration.
Dockerfile 可以让用户管理一个单独的应用容器;而 Compose 则允许用户在一个模板(YAML 格式)中定义一组相关联的应用容器(被称为一个 project,即项目),例如一个 Web 服务容器再加上后端的数据库服务容器等,就拿官网的 Python 例子来说,功能很简单,利用 redis 的 incr 的功能对页面的访问量进行统计。
docker-compose 的安装可以参考官网,如果安装了 Docker for Mac 或者 Docker for windows 则直接就存在了。
创建项目目录:
$ mkdir composetest
$ cd composetest
创建 Python 的程序 app.py ,功能就是利用 redis 的 incr 方法进行访问计数。
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return 'Hello World! I have been seen %s times.' % redis.get('hits')
if __name__ == &__main__&:
app.run(host=&0.0.0.0&, debug=True)
由于 Python 依赖的 flask、redis 组件都需要另外安装,比如使用 pip来安装,单独设置一文件 requirements.txt,内容如下:
创建 service 依赖的第一个 image,app.py 程序的运行环境,利用 Dockerfile 来制作,内容如下:
FROM python:2.7 #基于 python:2.7 镜像
ADD . /code
#将本地目录中的内容添加到 container 的 /code 目录下
WORKDIR /code
#设置程序工作目录为 /code
RUN pip install -r requirements.txt
#运行安装命令
CMD python app.py
Dockerfile 创建好就可以制作镜像了,运行docker build -t compose/python_app . ,成功后通过docker images查看即能看到:
docker images
REPOSITORY
compose/python_app
1a92fed00abd
59 minutes ago
接下来制作 docker-compose 需要的配置文件 docker-compose.yml, version 要选择 2 ,1的版本很古老了,配置中可以看到创建了 2 个 service,web 和 redis ,各自有依赖的镜像,其中web 开放 container 的5000端口,并与 host 的5000端口应对,方便通过 localhost:5000 来访问, volumes 即将本地目录中的文件加载到容器的 /code 中,depends_on 表名 services web 是依赖另一个 service redis的,完整的配置如下:
version: '2'
image: compose/python_app
depends_on:
image: redis
前提都搞定了,就差最后一步启动了,命令 docker-compose
up ,成功后如下:
Attaching to composetestbypython_redis_1
| 1:C 04 Nov 10:35:17.448 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
_.-``__ ''-._
''-._
Redis 3.2.5 () 64 bit
.-`` .-```.
_.,_ ''-._
Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'|
Port: 6379
`-.__.-'
_.-'_.-'|
_.-'_.-'
http://redis.io
`-._`-.__.-'_.-'
`-.__.-'
_.-'_.-'|
_.-'_.-'
`-._`-.__.-'_.-'
`-.__.-'
`-.__.-'
| 1:M 04 Nov 10:35:17.450 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
| 1:M 04 Nov 10:35:17.450 # Server started, Redis version 3.2.5
| 1:M 04 Nov 10:35:17.451 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
| 1:M 04 Nov 10:35:17.451 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never & /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
| 1:M 04 Nov 10:35:17.451 * The server is now ready to accept connections on port 6379
此时通过compose 的 ps 命令也能看到 docker-compose ps :
docker-compose ps
---------------------------------------------------------------------------------------------
composetestbypython_redis_1
docker-entrypoint.sh redis ...
composetestbypython_web_1
/bin/sh -c python app.py
0.0.0.0:/tcp
ok ,在浏览器中访问 http://localhost:5000 就能看到最终的样子啦。
{% qnimg docker/-22-40-11.jpg title: alt: 'class:' %}
docker-compose 还有很多实用的命令,比如 logs、build、start、stop 等,可以通过 docker-compose --help来查看:
Define and run multi-container applications with Docker.
docker-compose [-f &arg&...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help
-f, --file FILE
Specify an alternate compose file (default: docker-compose.yml)
-p, --project-name NAME
Specify an alternate project name (default: directory name)
Show more output
-v, --version
Print version and exit
-H, --host HOST
Daemon socket to connect to
Use TLS; implied by --tlsverify
--tlscacert CA_PATH
Trust certs signed only by this CA
--tlscert CLIENT_CERT_PATH
Path to TLS certificate file
--tlskey TLS_KEY_PATH
Path to TLS key file
--tlsverify
Use TLS and verify the remote
--skip-hostname-check
Don't check the daemon's hostname against the name specified
in the client certificate (for example if your docker host
is an IP address)
Build or rebuild services
Generate a Docker bundle from the Compose file
Validate and view the compose file
Create services
Stop and remove containers, networks, images, and volumes
Receive real time events from containers
Execute a command in a running container
Get help on a command
Kill containers
View output from containers
Pause services
Print the public port for a port binding
List containers
Pulls service images
Push service images
Restart services
Remove stopped containers
Run a one-off command
Set number of containers for a service
Start services
Stop services
Unpause services
Create and start containers
Show the Docker-Compose version information
更多 docker-compose 例子参考官网 doc 文档 :
Docker-compose with Django :
Get started with Rails :
Get started with WordPress :

我要回帖

更多关于 docker compose 的文章

 

随机推荐