前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker入门:简化Devops

Docker入门:简化Devops

作者头像
WindCoder
发布2018-09-19 18:09:40
1.6K0
发布2018-09-19 18:09:40
举报
文章被收录于专栏:WindCoder

前言

之前只听过其名,没详细看过,趁着这篇文章顺便了解下。老规矩,原文如下:

Getting Started with Docker: Simplifying Devops

文章正文

如果您喜欢鲸鱼,或者您只需要快速,无痛地连续将您的软件交付给生产,那么我邀请您阅读本介绍的Docker教程。一切似乎都表明,软件容器是IT的未来,让我们快速地和Moby DockMolly的容器鲸鱼一起开始吧。

Docker以一个友好的鲸鱼标志为代表,是一个开源的项目,可以方便在软件容器内部署应用程序。其基本功能由Linux内核的资源隔离功能启用,但它在其上提供了一个用户友好的API。第一个版本于2013年发布,从此变得非常受欢迎,被eBay,Spotify,Baidu等许多大厂商广泛使用。在最后一轮融资中,Docker已经投入了9,500万美元

运输货物类比(Transporting Goods Analogy)

Docker背后的理念可以通过以下简单的比喻进行说明。在国际运输业,货物必须以叉车,卡车,火车,起重机和船舶等不同方式运输。这些货物的形状和尺寸不同,存储要求不同:糖,牛奶罐,植物等。从历史上看,每个过境点的装卸依靠手动干预是一个痛苦的过程。

随着多式联运集装箱的采用,这一切都发生了变化。由于它们符合标准尺寸,并以运输为中心制造,所有相关机构都可以设计为以最少的人为干预来处理。密封容器的附加优点是可以保护敏感物品的温度和湿度等内部环境。结果,运输行业可以不再担心货物本身,而是集中精力从A到B。

而这也是Docker所在的地方(感觉可能是说这是Docker与之的相似之处),并为软件行业带来了类似的收益。

与虚拟机有何不同?

快速浏览,虚拟机和Docker容器可能看起来一样。但是,当您查看以下图表时,它们的主要区别将变得明显:

运行在虚拟机中的应用程序除了需要虚拟机管理程序外,还需要操作系统和任何支持库的完整实例。另一方面,容器与主机共享操作系统。管理程序与容器引擎(在上图中表示为Docker)相当,因为它管理容器的生命周期。重要的区别是容器内运行的进程与主机上的本机进程一样,不会引入与管理程序执行相关的任何开销。此外,应用程序可以重用库并在容器之间共享数据。

由于两种技术具有不同的优点,通常找到组合虚拟机和容器的系统。一个完美的例子是Docker安装部分中描述的一个名为Boot2Docker的工具。

Docker架构

在架构图的顶部有注册表。默认情况下,主注册表中托管Docker Hub 的公共和官方镜像(official images)。组织机构们如果愿意也可以托管(host )自己的私有注册表( private registries)。

在右边我们有镜像和容器。当启动一个容器时,镜像可以从注册表显式(docker pull imageName)或隐式下载。一旦镜像被下载,它将在本地缓存。

容器是镜像的实例。它们都是有生命的。基于同一个镜像可以运行多个容器。

在中心,Docker daemon的责任是创建、运行和检测容器。它还负责构建和存储镜像。最后,左侧有一个Docker客户端。它通过HTTP与daemon进程通信。在同一台机器上使用Unix套接字,但通过基于HTTP的API可以进行远程管理。

安装Docker

有关最新的说明,请务必参考官方文档

Docker在Linux原生地(natively)运行,所以根据目标distribution可能会很简单sudo apt-get install docker.io。有关详细信息,请参阅文档。通常在Linux中,您可以通过sudo使用Docker命令,但为了清楚起见,我们将在本文中略过它。

由于Docker daemon使用特定于Linux的内核功能,因此无法在Mac OS或Windows中原生地(natively)运行Docker。为了能在其上运行,应该安装一个名为Boot2Docker的应用程序。该应用程序由VirtualBox虚拟机,Docker本身和Boot2Docker管理实用程序(management utilities)组成。您可以按照MacOSWindows的正式安装说明在这些平台上安装Docker。

使用Docker

让我们以简单的例子开始本节:

代码语言:javascript
复制
docker run phusion/baseimage echo "Hello Moby Dock. Hello Molly."

我们应该看到这个输出:

代码语言:javascript
复制
Hello Moby Dock. Hello Molly.

不过,幕后还发生了更多比你想象的要多的事情:

  • 从 Docker Hub下载 ‘phusion/baseimage’镜像(如果尚未在本地缓存中)
  • 一个基于该镜像的容器被启动。
  • 命令echo在容器内执行
  • 当命令被释放时,容器被停止

首次运行时,您可能会在屏幕上打印文字之前注意到延迟。如果镜像已经在本地缓存,一切都将花费几分之一秒。可以通过运行docker ps -l获取最近一个容器的详细信息:

代码语言:javascript
复制
CONTAINER ID		IMAGE					COMMAND				CREATED			STATUS				PORTS	NAMES
af14bec37930		phusion/baseimage:latest		"echo 'Hello Moby Do		2 minutes ago		Exited (0) 3 seconds ago		stoic_bardeen

采取下一个Dive

正如你所知,在Docker中运行一个简单的命令就像在标准终端上直接运行一样简单。为了说明一个更实际的用例,在本文的剩余部分中,我们将看到我们如何利用Docker部署一个简单的Web服务器应用程序。为了保持简单,我们将编写一个Java程序来处理HTTP GET请求‘/ping’以及响应 ‘pong\n’字符串。

代码语言:javascript
复制
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class PingPong {

    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
        server.createContext("/ping", new MyHandler());
        server.setExecutor(null);
        server.start();
    }

    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange t) throws IOException {
            String response = "pong\n";
            t.sendResponseHeaders(200, response.length());
            OutputStream os = t.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }
}

Dockerfile

在跳入和构建您自己的Docker映像之前,一个很好的做法是首先检测Docker Hub中或您可以访问的任何私人注册表是否存在一个现有的。例如,我们可以使用官方镜像 java:8,而不是自己安装一个java。

要构建一个镜像,首先我们需要决定一个我们要使用的基本镜像。它由FROM指令表示。在这里,它是来自Docker Hub的Java 8的官方图像。我们将通过发出COPY指令将其复制到我们的Java文件中。接下来,我们将使用RUN编译它EXPOSE指令表示图像将在特定端口上提供服务ENTRYPOINT是一个当基于此镜像的容器启动时我们要执行的指令,CMD指示将要传递给它的默认参数

代码语言:javascript
复制
FROM java:8
COPY PingPong.java /
RUN javac PingPong.java
EXPOSE 8080
ENTRYPOINT ["java"]
CMD ["PingPong"]

在将这些指令保存在名为“Dockerfile”的文件中后,我们可以通过执行以下命令来构建相应的Docker镜像:

代码语言:javascript
复制
docker build -t toptal/pingpong .

Docker的官方文档有一节专门介绍关于编写Dockerfile的最佳做法

运行容器

当镜像建成时,我们可以将其作为容器使用。有几种方法可以运行容器,现在让我们从一个简单的开始:

代码语言:javascript
复制
docker run -d -p 8080:8080 toptal/pingpong

其中-p port-on-the-host:port-in-the-container分别表示主机和容器上的端口映射。此外,我们通过指定-d告诉Docker在后台作为daemon 程序进程运行容器。您可以通过尝试访问‘http://localhost:8080/ping’来测试Web服务器应用程序是否正在运行。请注意,在使用Boot2docker的平台上,您需要将“localhost”替换为运行Docker的虚拟机的IP地址。

在Linux上:

代码语言:javascript
复制
curl http://localhost:8080/ping

在需要Boot2Docker的平台上:

代码语言:javascript
复制
curl $(boot2docker ip):8080/ping

如果一切顺利,你应该看到回应:

代码语言:javascript
复制
pong

23333,我们的第一个定制Docker容器是活着和游泳( is alive and swimming,应该是想表达容器正常运行了的意思吧)!我们也可以以交互模式启动容器-i -t。在我们的例子中,我们将覆盖entrypoint命令,所以我们给了一个bash终端。现在我们可以执行我们想要的任何命令,但退出容器将会停止它:

代码语言:javascript
复制
docker run -i -t --entrypoint="bash" toptal/pingpong

还有更多的选项可用于启动容器。让我们再来一些。例如,如果我们要保留容器外的数据,我们可以使用-v与容器共享主机文件系统。默认情况下,访问模式为读写,但可以通过附加:ro到容器内卷路径来更改为只读模式。当我们需要使用任何安全信息(例如容器中的凭证和私钥)时,卷(Volumes)是特别重要的,不应该存储在镜像上。此外,它还可以防止数据重复,例如通过将本地Maven存储库映射到容器来保存您下载Internet两次。

Docker还具有将容器连接在一起的能力。即使没有端口被暴露,链接的容器也可以相互通信。可以用-link其他容器名称来实现。以下是上述参数组合的示例:

代码语言:javascript
复制
docker run -p 9999:8080 
    --link otherContainerA --link otherContainerB 
    -v /Users/$USER/.m2/repository:/home/user/.m2/repository 
    toptal/pingpong

其他容器和镜像操作

毫不奇怪,可以应用于容器和图像的操作列表相当长。为了简洁起见,我们来看看其中的几个:

  • stop - 停止运行容器。
  • start - 启动一个停止的容器。
  • commit -从容器的更改创建新的镜像。
  • rm - - 删除一个或多个容器。
  • rmi - - 删除一个或多个镜像。
  • ps - 列出容器。
  • images - 列出镜像。
  • exec -在运行容器中运行命令。

最后一个命令可能对于调试目的特别有用,因为它可以连接到运行容器的终端:

代码语言:javascript
复制
docker exec -i -t <container-id> bash

Docker为微服务世界撰写(Docker Compose for the Microservice World)

如果您有不仅仅是几个互连的容器,使用docker-compose这样的工具是有意义的。在配置文件中,您将说明如何启动容器以及如何将它们彼此链接起来。无论涉及的容器数量及其依赖关系如何,您都可以使用一个命令来运行所有容器:docker-compose up

Docker在野外(Docker in the Wild)

我们来看看项目生命周期的三个阶段,看看我们的友好鲸鱼如何能够帮上忙。

开发(Development)

Docker可帮助您保持本地开发环境的清洁。不需要安装多个版本的不同服务,如Java,Kafka,Spark,Cassandra等,您可以在必要时启动和停止所需的容器。您可以进一步了解并且并行运行多个软件堆栈,以避免依赖关系版本的混合。

使用Docker,您可以节省时间,精力和金钱。如果您的项目设置非常复杂,“dockerise”它。经历一次创建Docker镜像的痛苦,从此之后,每个人都可以快速启动一个容器。

您还可以在本地(或CI)上运行“集成环境”,并使用在Docker容器中运行的实际服务替换存根。

测试/持续集成(Testing / Continuous Integration)

使用Dockerfile,很容易实现可重复构建。可以将Jenkins或其他CI解决方案配置为创建Docker镜像用于每个构建。您可以将一些或所有镜像存储在专用Docker注册表中,以备将来参考。

使用Docker,您只需测试需要测试的内容,并将环境排除在等式之外。在运行容器上执行测试可以帮助保持其更加可预测。

拥有软件容器的另一个有趣的特征是,使用相同的开发设置可以轻松地分出子机。它对于集群部署的负载测试尤其有用。

生产(Production)

Docker可以是开发人员和操作人员之间的通用接口,消除了摩擦的根源。它还鼓励在管道的每一步使用相同的镜像/二进制文件。此外,能够部署经过全面测试的容器而无需环境差异,有助于确保在构建过程中不会引入错误。

您可以将应用程序无缝迁移到生产环境中。曾经是一个乏味和片状的过程的东西现在可以简单到:

代码语言:javascript
复制
docker stop container-id; docker run new-image

如果部署新版本出现问题,您可以随时快速回滚或更改为其他容器:

代码语言:javascript
复制
docker stop container-id; docker start other-container-id

..保证不要留下任何混乱或让事情处于不一致的状态。

总结

Docker做的一个很好的总结包括在自己的座右铭中:构建(Build),运输( Ship),运行(Run)

  • Build - Docker允许您从微服务中组合应用程序,而不必担心开发和生产环境之间的不一致,并且不会锁定到任何平台或语言中。
  • Ship - Docker可让您设计整个应用程序开发,测试和分发周期,并通过一致的用户界面进行管理。
  • Run - Docker为您提供在各种平台上安全可靠地部署可伸缩服务的能力。

祝大家与鲸鱼玩的愉快!

这部作品的灵感来自于由Adrian Mouat 使用Docker的优秀作品。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 文章正文
    • 运输货物类比(Transporting Goods Analogy)
      • 与虚拟机有何不同?
        • Docker架构
          • 安装Docker
            • 使用Docker
              • 采取下一个Dive
                • Dockerfile
                  • 运行容器
                    • 其他容器和镜像操作
                      • Docker为微服务世界撰写(Docker Compose for the Microservice World)
                        • Docker在野外(Docker in the Wild)
                          • 开发(Development)
                          • 测试/持续集成(Testing / Continuous Integration)
                          • 生产(Production)
                        • 总结
                        相关产品与服务
                        容器镜像服务
                        容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档