阅读更多

0顶
0踩

研发管理
【编者按】Vidar Hokstad在Docker使用方面非常有经验,尤其在没有数据丢失前提下,使用Docker创建可重复build上经验丰富,在本博客中,他总结了开发Docker容器的8种模式。

以下为译文:

Docker现在成了我最喜欢的工具,在本文中,我将概述一些在我使用Docker过程中反复出现的模式。我不期待它们能给你带来多少惊喜,但我希望这些能对你有用,我非常愿意与你交流在使用Docker过程中碰到的模式。

我所有Docker实验的基础是保持volume状态不变,以便Docker容器在没有数据丢失的前提下任意重构。

下面所有的Dockerfiles例子都集中在:创建容器在其本身可以随时更换的地方,而无需考虑其它。

1. The Shared Base Container(s)

Docker鼓励“继承”,这应用也很自然——这是高效使用Docker的一个基本方式,不仅由于它有助于减少建立新容器的时间,Docker优点多多,它会cache中间步骤,但也容易在不明确的情况下,失去分享机会。

很显然,在将我的各种容器迁移到Docker上时,首先要面对的是多个步骤。

对于多数想要随处部署的项目来说所,要创建多个容器,尤其是在这个项目需要长进程,或者需要特定包的情况,所以我要运行的容器也变得越来越多。

重要的是为了让mybase环境完全自由支配,我正考虑试图在Docker上运行“所有一切”(包括我依赖几个桌面app)。

所以我很快开始提取我的基本设置到base容器。这是我当的“devbase”Dockerfile:
FROM debian:wheezy
    RUN apt-get update
    RUN apt-get -y install ruby ruby-dev build-essential git
    RUN apt-get install -y libopenssl-ruby libxslt-dev libxml2-dev
    
    # For debugging
    RUN apt-get install -y gdb strace
    
    # Set up my user
    RUN useradd vidarh -u 1000 -s /bin/bash --no-create-home
    
    RUN gem install -n /usr/bin bundler
    RUN gem install -n /usr/bin rake
    
    WORKDIR /home/vidarh/
    ENV HOME /home/vidarh
    
    VOLUME ["/home"]
    USER vidarh
    EXPOSE 8080

这里没有什么需要特别说明的地方——它安装一些需要随时可用的特定工具。这些可能会对大多数人来说是不同的。值得注意的是如果/当你重建一个容器的时候,你需要指定一个特定的标签来避免意外。

使用默认端口8080,因为这是我发布web app的端口,这也是我用这些容器的目的。

它为我添加了一个用户,并且不会创建一个/ home目录。我从宿主机绑定挂载了一个共享文件夹/ home,这就引出了下一个模式。

2. The Shared Volume Dev Container

我所有的dev容器与宿主机分享至少一个volume: / home,这是为了便于开发。对于许多app,在开发模式中,使用基于file-system-change的code-reloader运行,这样一来容器内封装了OS / distro-level的依赖,并在初始环境中帮助验证app-as-bundled工作,而不需要让我每次在代码改变时重启/重建VM。

至于其他,我只需要重启(而不是重建)容器来应对代码的更改。

对于test/staging和production容器,大多数情况下不通过volume共享代码,转而使用“ADD”来增添代码到Docker容器中。

这是我的“homepage”的dev容器的Dockerfile,例如,包含我的个人wiki,存在于“devbase”容器中的 /home下,以下展示了如何使用共享的base容器和/home卷:
FROM vidarh/devbase
    WORKDIR /home/vidarh/src/repos/homepage
    ENTRYPOINT bin/homepage web

以下是dev-version的博客:
FROM vidarh/devbase
    
    WORKDIR /
    USER root
    
    # For Graphivz integration
    RUN apt-get update
    RUN apt-get -y install graphviz xsltproc imagemagick
    
    USER vidarh
    WORKDIR /home/vidarh/src/repos/hokstad-com
    ENTRYPOINT bundle exec rackup -p 8080

因为他们从一个共享的库中取代码,并且基于一个共享的base容器,这些容器通常当我添加/修改/删除依赖项时会极其迅速重建。

即便如此也有一些地方是我非常愿意改善,尽管上面的base是轻量级的,他们大多数在这些容器仍未使用。由于Docker使用copy-on-write覆盖,这不会导致一个巨大的开销,但它仍然意味着我没有做到最小的资源消耗,或者说最小化attack或error的几率。

3. The Dev Tools Container

这可能对我们这些喜欢依靠ssh写代码的人很有吸引力,但是对IDE人群则小一点。对我来说,关于以上设置更大的 一个好处,是它让我在开发应用程序中,能够将编辑和测试执行代码的工作分离开来。

过去dev-systems对我来说一件烦人的事,是dev和production依赖项以及开发工具依赖项容易混淆,很容易产生非法的依赖项。

虽然有很多方法解决这个,比如通过定期的测试部署,但我更偏爱下面的解决方案,因为可以在第一时间防止问题的发生:

我有一个单独的容器包含Emacs的installation以及其他各种我喜欢的工具,我仍然试图保持sparse,但关键是我的screen session可以运行在这个容器中,再加上我笔记本电脑上的“autossh”,这个连接几乎一直保持,在那里我可以编辑代码,并且和我的其他dev容器实时共享。如下:
FROM vidarh/devbase
RUN apt-get update
RUN apt-get -y install openssh-server emacs23-nox htop screen

# For debugging
RUN apt-get -y install sudo wget curl telnet tcpdump

# For 32-bit experiments
RUN apt-get -y install gcc-multilib 

# Man pages and "most" viewer:
RUN apt-get install -y man most

RUN mkdir /var/run/sshd
ENTRYPOINT /usr/sbin/sshd -D

VOLUME ["/home"]
EXPOSE 22
EXPOSE 8080

结合共享“/ home“,已经足够让ssh的接入了,并且被证明能满足我的需要。

4. The Test In A Different Environment containers

我喜欢Docker的一个原因,是它可以让我在不同的环境中测试我的代码。例如,当我升级Ruby编译器到1.9时,我可以生成一个Dockerfile,派生一个1.8的环境。
FROM vidarh/devbase
RUN apt-get update
RUN apt-get -y install ruby1.8 git ruby1.8-dev

当然你可以用rbenv等达到类似的效果。但我总是觉得这些工具很讨厌,因为我喜欢尽可能多地用distro-packages部署,不仅仅是因为如果这项工作的顺利进行,能使其他人更容易地使用我的代码。


当拥有一个Docker容器,我需要一个不同的环境时,我仅需要“docker run”一下,几分钟便能很好的解决这个问题。

当然,我也可以使用虚拟机来达到目的,但使用Docker更省时间。

5. The Build Container

这些天我写的代码大部分都是解释性语言,但还是有一些代价高昂的“build”步骤,我并不愿意每次都去执行它们。

一个例子是为Ruby应用程序运行“bundler”。Bundler 为Rubygems更新被缓存的依赖,并且需要时间来运行一个更大的app。

经常需要在应用程序运行时不必要的依赖项。例如安装依赖本地扩展gems的通常还需要很多包——通常没有记录——通过添加所有build-essential和它的依赖项就轻松启动。同时,你可以预先让bundler做所有的工作,我真的不想在主机环境中运行它,因为这可能与我部署的容器不兼容。

一个解决方案是创建一个build容器。如果依赖项不同的话,你可以创建分别的Dockerfile,或者你可以重用主app Dockerfile以及重写命令运行你所需的build commands。Dockerfile如下:
FROM myapp
RUN apt-get update
RUN apt-get install -y build-essential [assorted dev packages for libraries]
VOLUME ["/build"]
WORKDIR /build
CMD ["bundler", "install","--path","vendor","--standalone"]

然后每当有依赖更新时,都可以运行上面的代码,同时将build/source目录挂载在容器的"/build"路径下。

6. The Installation Container

这不是我擅长的,但是真的值得提及。优秀的nsenter和docker-enter工具在安装时有一个选项,对于现在流行的curl | bash模式是一个很大的进步,它通过提供一个Docker容器实现“Build Container”模式。

这是Dockerfile的最后部分,下载并构建一个nsenter的合适版本:
ADD installer /installer
CMD /installer

“installer”如下:
#!/bin/sh
if mountpoint -q /target; then
       echo "Installing nsenter to /target"
       cp /nsenter /target
       echo "Installing docker-enter to /target"
       cp /docker-enter /target
else
       echo "/target is not a mountpoint."
       echo "You can either:"
       echo "- re-run this container with -v /usr/local/bin:/target"
       echo "- extract the nsenter binary (located at /nsenter)"
fi

虽然可能还有恶意攻击者试图利用容器潜在的特权升级问题,但是attack surface至少显著变小。

这种模式能吸引大多数人,是因为这种模式能避免开发人员在安装脚本时偶尔犯的非常危险的错误。

7. The Default-Service-In-A-Box Containers

当我认真对待一个app,并且相对快速的准备一个合适的容器来处理数据库等,对于这些项目,我觉得难能可贵的是已经有一系列的“基本的”基础设施容器,只做适当的调整就可以满足我的需求。

当然你也可以通过“docker run”得到“主要的”部分,在Docker索引里有诸多替代品,但我喜欢首先检查它们,找出如何处理数据,然后我将修改版本添加到自己的“library”。

例如Beanstalkd:
FROM debian:wheezy
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -q update
RUN apt-get -y install build-essential
ADD <a href="http://github.com/kr/beanstalkd/archive/v1.9.tar.gz">http://github.com/kr/beanstalkd/archive/v1.9.tar.gz</a> /tmp/
RUN cd /tmp && tar zxvf v1.9.tar.gz
RUN cd /tmp/beanstalkd-1.9/ && make
RUN cp /tmp/beanstalkd-1.9/beanstalkd /usr/local/bin/
EXPOSE 11300
CMD ["/usr/local/bin/beanstalkd","-n"]

8. The Infrastructure / Glue Containers

许多这些模式专注于开发环境(这意味着有production 环境有待讨论),但有一个大类别缺失:

容器其目的是将你的环境组合起来成为一个整体,这是目前为止对我来说有待进一步研究的领域,但我将提到一个特殊的例子:

为了轻松地访问我的容器,我有一个小的haproxy容器。我有一个通配符DNS条目指向我的主服务器,和一个iptable入口开放访问我的haproxy容器。Dockerfile没什么特别的:
FROM debian:wheezy
ADD wheezy-backports.list /etc/apt/sources.list.d/
RUN apt-get update
RUN apt-get -y install haproxy
ADD haproxy.cfg /etc/haproxy/haproxy.cfg
CMD ["haproxy", "-db", "-f", "/etc/haproxy/haproxy.cfg"]
EXPOSE 80
EXPOSE 443

这里有趣的是haproxy.cfg
backend test
    acl authok http_auth(adminusers)
    http-request auth realm Hokstad if !authok
    server s1 192.168.0.44:8084

如果我想要特别一点,我会部署类似 AirBnB's Synapse ,但这已经超出了我的需求。

在工作时扩大容器的规模,目的是让部署应用程序简单便捷,就像我正在过渡到一个完整的面向Docker的私有云系统。
来自: CSDN
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • Docker 常见使用

    Docker 常见使用

  • 互联网开发模式的经验之谈

    在这篇文章中:互联网开发的核心问题本质:服务,而不是产品管理:手段.vs.工具资产:代码.vs.流程敏捷开发的意义和实践需求变更的原因架构设计实体化:单元测试统一软件设计思路的重要性代码交流:面向对象代码架构...

  • 必看!互联网开发模式的经验之谈

    当时作为一个小程序员,非常向往业界经典的软件开发模式。因为看上去,如果企业实行了CMM,我们程序员就不用再天天为了老板一个拍脑袋的主意而加班开发了,各种各样的奇葩需求和无理变更,也会烟消云散。但是,在接...

  • Java微服务开发指南-使用Docker和Kubernetes构建可伸缩的微服务

    一个Pod有自己的IP地址,所有运行在这个Pod中的容器共享这个IP(这个不同于普通的Docker容器,普通的Docker容器每个实例都有一个IP),当一个卷挂载到Pod,这个卷也能够被Pod中的容器共同访问。 关于Pod需要注意的...

  • 5年经验之谈:月薪3000到30000,测试工程师的变“行”记

    Linux Docker容器 Docker容器技术讲解,image镜像管理,仓库,容器创建,启动,操作,镜像打包,赶上行业流行技术 三、Shell脚本 掌握Shell脚本:包括Shell基础与运用、Shell逻辑控制、Shell逻辑函数 程序员小濠 ...

  • 5年经验之谈:月薪3k到30k,测试工程师的变“行”记

    Linux Docker容器 Docker容器技术讲解,image镜像管理,仓库,容器创建,启动,操作,镜像打包,赶上行业流行技术 三、Shell脚本 掌握Shell脚本:包括Shell基础与运用、Shell逻辑控制、Shell逻辑函数 百晓生说测试 ...

  • Docker 安全问题与防护 (学习笔记)

    Docker安全方案2.1 Docker安全基线2.2 Docker安全规则2.3 Docker镜像安全扫描与审计2.4 Docker入侵检测2.5 Docker容器安全隔离与资源控制2.5.1 namespace2.5.2 cgroup2.6 Docker容器系统调用和文件访问的权限控制...

  • .NET开发者启程Docker之路

    windows和docker

  • 由Docker大规模运行中总结的六大实践经验

    除非你在过去几年里一直生活在石器时代,否则你肯定知道容器和Docker。如果你是互联网极客的话,可能你已经准备在生产环境中使用Docker了。 一年前我也在尝试跟上技术更新的步伐,但以忙于交付原生态的系统结束。我...

  • 数据库管理工具:dbeaver-ce-23.1.5-macos-aarch64.dmg

    1.DBeaver是一款通用数据库工具,专为开发人员和数据库管理员设计。 2.DBeaver支持多种数据库系统,包括但不限于MySQL、PostgreSQL、Oracle、DB2、MSSQL、Sybase、Mimer、HSQLDB、Derby、SQLite等,几乎涵盖了市场上所有的主流数据库。 3.支持的操作系统:包括Windows(2000/XP/2003/Vista/7/10/11)、Linux、Mac OS、Solaris、AIX、HPUX等。 4.主要特性: 数据库管理:支持数据库元数据浏览、元数据编辑(包括表、列、键、索引等)、SQL语句和脚本的执行、数据导入导出等。 用户界面:提供图形界面来查看数据库结构、执行SQL查询和脚本、浏览和导出数据,以及处理BLOB/CLOB数据等。用户界面设计简洁明了,易于使用。 高级功能:除了基本的数据库管理功能外,DBeaver还提供了一些高级功能,如数据库版本控制(可与Git、SVN等版本控制系统集成)、数据分析和可视化工具(如图表、统计信息和数据报告)、SQL代码自动补全等。

  • 一份关于信号与系统的大纲教程!!!!!!!!!!!!!

    一份关于信号与系统的大纲教程!!!!!!!!!!!!!

  • 【课件】7.5.1散列表的基本概念.pdf

    【课件】7.5.1散列表的基本概念

  • 【课件】8.7.4置换-选择排序.pdf

    【课件】8.7.4置换-选择排序

  • Delphi 12 控件之unidac-10.2.1-d29pro.exe

    unidac_10.2.1_d29pro.exe

  • 基于STM32的微控制器的C++语言研究项目

    此代码是基于 C、C++ 语言的 stm32 为微控制器编写的。 代码包含单独的部分:main、ini、USART code_for_display。 ADC_ini(模数转换器)是关于初始化ADC的。每当您触发模拟输入以开始转换时,它都会对模拟输入进行采样。它执行一个称为量化的过程,以决定电压电平及其在输出寄存器中推送的二进制代码。 USART(通用异步接收器-发射器)是一种外围通信硬件设备,它允许计算机通过 wifi 或蓝牙与串行连接的设备进行同步和异步通信。 code_for_display部分是包含 7 段显示的代码。 main 初始化ADC_ini,USART,code_for_display并开始接收信息的循环,显示它,将其发送到另一个设备,重复

  • 数据库表结构同步工具.zip

    大学生数据结构学习笔记和资料大全!

  • 数据库管理工具:dbeaver-ce-23.2.1-x86-64-setup.exe

    1.DBeaver是一款通用数据库工具,专为开发人员和数据库管理员设计。 2.DBeaver支持多种数据库系统,包括但不限于MySQL、PostgreSQL、Oracle、DB2、MSSQL、Sybase、Mimer、HSQLDB、Derby、SQLite等,几乎涵盖了市场上所有的主流数据库。 3.支持的操作系统:包括Windows(2000/XP/2003/Vista/7/10/11)、Linux、Mac OS、Solaris、AIX、HPUX等。 4.主要特性: 数据库管理:支持数据库元数据浏览、元数据编辑(包括表、列、键、索引等)、SQL语句和脚本的执行、数据导入导出等。 用户界面:提供图形界面来查看数据库结构、执行SQL查询和脚本、浏览和导出数据,以及处理BLOB/CLOB数据等。用户界面设计简洁明了,易于使用。 高级功能:除了基本的数据库管理功能外,DBeaver还提供了一些高级功能,如数据库版本控制(可与Git、SVN等版本控制系统集成)、数据分析和可视化工具(如图表、统计信息和数据报告)、SQL代码自动补全等。

  • Android-Retrofit-Images在这个示例 Android 项目中

    Android-Retrofit-Images在这个示例 Android 项目中

  • 数据库管理工具:dbeaver-ce-23.0.2-macos-aarch64.dmg

    1.DBeaver是一款通用数据库工具,专为开发人员和数据库管理员设计。 2.DBeaver支持多种数据库系统,包括但不限于MySQL、PostgreSQL、Oracle、DB2、MSSQL、Sybase、Mimer、HSQLDB、Derby、SQLite等,几乎涵盖了市场上所有的主流数据库。 3.支持的操作系统:包括Windows(2000/XP/2003/Vista/7/10/11)、Linux、Mac OS、Solaris、AIX、HPUX等。 4.主要特性: 数据库管理:支持数据库元数据浏览、元数据编辑(包括表、列、键、索引等)、SQL语句和脚本的执行、数据导入导出等。 用户界面:提供图形界面来查看数据库结构、执行SQL查询和脚本、浏览和导出数据,以及处理BLOB/CLOB数据等。用户界面设计简洁明了,易于使用。 高级功能:除了基本的数据库管理功能外,DBeaver还提供了一些高级功能,如数据库版本控制(可与Git、SVN等版本控制系统集成)、数据分析和可视化工具(如图表、统计信息和数据报告)、SQL代码自动补全等。

Global site tag (gtag.js) - Google Analytics