写点什么

利用 Docker 在 Opsworks 上实现零停机时间部署方案

  • 2015-05-26
  • 本文字数:3511 字

    阅读完需:约 12 分钟

想当初还处于风华正茂的年纪时,我总想当个酷炫的小朋友。之所以想找份跟计算机打交道的工作,是因为这样我就能接触到最新的窗口管理器并使用最前沿的软件版本。然而现实总是残酷的,相信大家都经历过那段“一周七天、每天多次重新编译内核”的黑暗时光。

幸运的是我最终坚持了下来(除了有一次遇上 120GB Raid0 设置丢失,那一回我确实受到了沉重的打击),而且步入成熟期后、我跟每个老头子一样都开始对变化充满恐惧。

出于这个理由,我逡巡了一段时间才真正下决心上手 Docker。每个走在时代最前沿的年轻人都在讨论容器技术,但我已经不再身处那种急于彰显自己的岁数,如今的我只是个平均、内敛而且年纪还不算太大的家伙。

单单通过标题,大家可能已经猜到了故事的结局,不过 Docker 确实让我有了眼前一亮的感觉。它的出现以一种便捷的方式解决了大量常见于开发及部署流程中的难题。

在经过一段时间的学习后,我对自己的应用程序进行重构以保证其顺畅运行在 Docker 容器当中。而在随后的几周内,我把注意力集中在了 Docker 的部署方面。我们的应用程序运行在 AWS 云环境之下,而在众多 Amazon 服务中、我们选择了 Opsworks——理由很简单,易于设置、易于维护、易于扩展。

遗憾的是,Opsworks 并不支持 Docker,而 Amazon 自家的容器运行方案 ECS 目前尚未正式推出生产版本。我需要把自己的复杂应用迁移到 Docker 当中,而且希望现时现下马上开始进行。要实现这一目标,惟一的办法就是将 Docker 支持能力引入 Opsworks。

在谷歌了一圈之后,我发现一篇教程以及几套 GitHub repo,但没有一样能真正满足我的需要。

我的应用程序需要多套容器环境才能实现运作,而我希望找到一种能够实现以下编排需求的方案:

  • 负载均衡器 x1(也可以是 ELB)
  • 前端 Web 服务器 x1(例如 nginx)
  • 用于在不同应用程序服务器之间中转的 haproxy x1,旨在实现零停机部署
  • 应用程序容器 x2,运行其自己的应用程序服务器
  • 用于缓存的 Redis x1(也可以是 Elasticache)
  • 作为数据库的 PostgreSQL x1(也可以是 Amazon RDS)
  • 1 个或更多 cron 任务
  • 1 个或更多 sidekiq 实例用于实现异步处理

除此之外,我希望一切都能以负载水平为基础实现横向规模扩展。这乍看起来似乎是个极为艰巨的任务,但随着我开始编写自己的第一套解决方案,一切开始变得明朗起来。我的灵感源自 fig,我喜欢 fig 那种允许用户在不同容器之间指定彼此关系的设计,我也希望能将这种优势引入到 Opsworks 当中。

大家可以点击此处查看我的工作成果。届时本文截稿时,其中的 README.md 文件仍然一片空白,不过我承诺会在未来为大家提供说明文档……就目前而言,请各位先将本文作为仅有的参考资料:)

在对自己的 Docker 化应用进行部署时,我们首先要做的就是登录 AWS、访问 Opsworks 并点击创建一套堆栈。请如下填写相关表彰:

  • 名称:随便想一个

  • 地区:爱写哪写哪

  • 默认根设备类型:EBS 后台

  • 默认 SSH 密钥:如果大家希望访问自己的实例,请选定一套密钥

  • [其它部分都可保留为默认,当然如果大家很清楚这些项目的意义、也可以根据实际情况填写]

  • 高级

    • 使用自定义 Chef cookbook:是
    • 库 URL: https://github.com/intinig/opsworks-docker.git
    • 管理 Berkshelf:是在拥有了自己的堆栈之后,接下来要做的就是添加一个层。点击“添加一个层”并填写以下表单:
  • 层类型:自定义

  • 名称: Docker

  • 简称: docker

在层创建完成之后,对其配置进行编辑并点击 EBS 分卷标签。我们需要为每个添加到该堆栈中的实例分配 120GB 分卷存储空间。大家可能会问为什么。很遗憾,在 Amazon Linux/EC2 中,Docker 只能使用 devicemapper 实现容器管理,而 devicemapper 所创建的文件会在正常使用过程中增长到高达 100GB。额外的 20GB 则用于存放我们的镜像。大家可以将存储空间调小一些,甚至干脆不分配 EBS 分卷,但请注意我们早晚会面临这样的问题。

  • 载入点: /var/lib/docker
  • 总体大小: 120GB
  • 分卷类型: 通用 (SSD)

在此之后,我们对层进行编辑以添加自己的自定义配置方案:

  • 设置 docker::install, docker::registries, logrotate::default, docker::logrotate
  • 部署 docker::data_volumes, docker::deploy

我们的这套自定义配置方案能做什么?

  • docker::install 非常简便易行,它单纯负责将 Docker 安装在我们的 Opsworks 实例当中。
  • docker::registries 用于登录私有 Docker 账户。其应该能够与多种注册类型顺畅协作,不过我个人只在 quay.io 上进行了测试。
  • logrotate::default 与 docker::logrotate 管理着记录文件的相关设置,旨在避免 Docker 日志文件无限度膨胀。这项设置假定大家切实向远程系统日志处发送了日志内容,我们使用 papertrail 实现这一点。

现在让我们添加一款应用程序。在左侧的 Opsworks 菜单中点击 Apps 而后选择“add a new one”。

  • 名称: 顶呱呱应用
  • 类型: 其它
  • 数据源类型:这里我选择了 RDS,但大家也可以使用 Opsworks,或者干脆不使用数据库而直接通过 Docker 容器或者其它源将数据交付至应用程序。
  • 库类型:其它

现在我们只需要向应用程序当中添加一项环境变量:

  • APP_TYPE: docker

其它一切都将通过(庞大的)Stack JSON 完成配置。检查我们的堆栈设置并对内容进行编辑。大家还需要为自己的容器编译一套堆栈 json。以下为相关示例代码:

复制代码
{
"logrotate": {
"forwarder": "logspout0"
},
"deploy": {
"amazing application": {
"data_volumes": [
{
"socks": {
"volumes": ["/var/run", "/var/lib/haproxy/socks"]
},
"static": {
"volumes": ["/var/static"]
}
}
],
"containers": [
{
"app": {
"deploy": "auto",
"image": "quay.io/mikamai/awesome-app",
"database": true,
"containers": 2,
"volumes_from": ["socks", "static"],
"entrypoint": "/app/bin/entrypoint.sh",
"command": "bundle exec unicorn -c config/unicorn.rb -l /var/lib/haproxy/socks/%{app_name}.sock",
"migration": "bundle exec rake db:migrate",
"startup_time": 60,
"env": {
"RANDOM_VAR": "foo"
},
"notifications": {
"rollbar" : {
"access_token": "",
"env_var": "RACK_ENV",
"rev_var": "GIT_REVISION"
}
}
}
},
{
"cron": {
"deploy": "cron",
"image": "quay.io/mikamai/awesome-app",
"database": true,
"containers": 1,
"env_from": "app",
"command": "bundle exec rake cron:run",
"cron": {"minute": 59}
}
},
{
"sidekiq": {
"deploy": "auto",
"image": "quay.io/mikamai/awesome-app",
"database": true,
"containers": 1,
"env_from": "app",
"command": "bundle exec sidekiq"
}
},
{
"haproxy": {
"deploy": "manual",
"hostname": "opsworks",
"image": "quay.io/mikamai/configured-haproxy",
"volumes_from": ["socks"],
"env": {
"REMOTE_SYSLOG": "logs.papertrailapp.com:1234"
}
}
},
{
"nginx": {
"deploy": "manual",
"image": "quay.io/mikamai/configured-nginx",
"ports": [
"80:80",
"443:443"
],
"volumes_from": [
"socks",
"static"
]
}
},
{
"logspout": {
"deploy": "manual",
"hostname": "%{opsworks}",
"image": "progrium/logspout",
"volumes": [
"/var/run/docker.sock:/tmp/docker.sock"
],
"command": "syslog://logs.papertrailapp.com:1234"
}
}
]
}
},
"docker": {
"registries": {
"quay.io": {
"password": "",
"username": ""
}
}
}
}

哇哦!这些内容可够大家消化一阵子了,对吧?在下一篇文章中,我们将一同走入 Stack JSON 的世界并了解其中各组成部分的实际意义。

感谢大家前来捧场,让咱们下次再见!

原文链接: http://dev.mikamai.com/post/110066104864/zero-downtime-deployments-with-docker-on-opsworks

2015-05-26 07:216104

评论

发布
暂无评论
发现更多内容

@PolarDB,你的动手体验搭子,来啦

阿里云瑶池数据库

数据库 阿里云 云原生

助力企业出海,Ogcloud提供一站式网络解决方案

Ogcloud

网络 网络加速 组网

软件测试开发/全日制/测试管理丨App移动测试体系

测试人

软件测试

聚道云软件连接器助力某餐饮管理有限公司实现人力资源信息自动化

聚道云软件连接器

案例分享

聚道云软件连接器助力某贸易公司实现付款流程自动化

聚道云软件连接器

案例分享

如何在iOS手机上查看应用日志

Geek_66e2f3

10年工作经验老程序员推荐的7个开发类工具

EquatorCoco

程序员 开发工具

提升测试自动化:ForEach 循环在API测试中的高级策略

Apifox

测试 自动化测试 foreach Apifox 测试工具

软件测试开发/全日制/测试管理丨Web 兼容性测试

测试人

软件测试 测试开发

MATLAB R2021b for mac(可视化数学分析软件) v9.11.0.1873467永久激活版

mac

苹果mac Windows软件 MATLAB R2021b 商业数学软件

简便实用:在 ASP.NET Core 中实现 PDF 的加载与显示

快乐非自愿限量之名

如何降低API接口的使用成本和提高效率?

技术冰糖葫芦

身为程序员,你很有必要了解一下提效工具“JNPF”

互联网工科生

程序员 软件开发 低代码 JNPF

Zoho 2023:种长期主义的因,越经济下行的谷

ToB行业头条

高防服务器、高防IP和高防CDN之间有什么区别?

Finovy Cloud

网络安全 网络攻击防御 高防主机 高防IP 高防IP服务

JDK安装与配置教程来啦

小魏写代码

加密钱包监控:守护企业资产与信誉的利器

Footprint Analytics

区块链 加密钱包

揭秘加密货币周期:如何通过顶级代币指标洞察市场变化

Footprint Analytics

区块链 加密货币

体育赛事直播系统源码,自主研发一手源码的重要性

软件开发-梦幻运营部

大语言模型训练数据常见的4种处理方法

不在线第一只蜗牛

淘宝/天猫商品详情实时数据API技术实现

Noah

实现数据一体化的有效措施

RestCloud

ETL 数据一体化

【教程】代码混淆详解

雪奈椰子

联合阿里云,首批诚邀 30 家!Alibaba Cloud Linux 伙伴招募计划发布

OpenAnolis小助手

Linux 阿里云 开源 操作系统 龙蜥社区

精彩回顾 | 《国产数据库共话未来趋势》技术沙龙上海站成功举办!

阿里云数据库开源

数据库 阿里云 数据管理 国产数据库 polarDB

低代码通过图形化编程,快速构建应用程序

高端章鱼哥

低代码 可视化开发 JNPF 软件开卡

软件测试开发/全日制/测试管理丨App测试项目流程

测试人

软件测试

面向设计师的11个必备AI工具

互联网工科生

人工智能 AI

利用Docker在Opsworks上实现零停机时间部署方案_亚马逊云科技_Giovanni Intini_InfoQ精选文章