■ 作者:Jarkko Laine
■ 译者:天云软件 刘宁
Docker是当前发展最快的新技术之一,它是一种部署软件和建立可伸缩网络服务架构的解决方案,Docker允许你按照特定的角色与用途将你的应用程序架构进行解耦并使用容器进行承载。通过使用Docker,你也可以在操作系统级别指定应用程序的依赖关系,让我们更接近JAVA最原始的承诺:“一次编写,随处运行”。
Docker的缺点是, 把代码封装到一组容器中可能会导致缺乏可见性:容器变成了黑盒子并使得开发人员对容器内部的工作方式几乎不可见。
为了解决这个问题,New Relic接手了此项任务并使得其服务器端的监控工具(服务器和APM)支持Docker。在2015年6月,所有的New Relic的用户均可通过New Relic实现对Docker的监控。
在宣布对Docker的支持以后,来自New Relic的Andrew Marshall写到:“现在,你可以从应用程序开始深入(这才是你最关心的),然后到个体的Docker容器,再到物理服务器,而不再有盲点”。
通过使用New Relic工具集监控基于Docker的应用程序,可以把应用程序作为一个整体来进行分析,找出出现问题的容器并在容器内部解决问题。
同时,在Docker层面对应用程序进行监控,你将会获得关于配置的一些有价值的信息:你是否在很明智的使用着容器吗?容器之间的资源划分是合理的吗?
在本教程中,我将向你展示如何使用New Relic工具监控一个简单的基于Docker的应用程序。你将会学习到:
为了实现这个目标,我们将建立一个简单的环境来实现WordPress方案:三个WordPress站点每个站点均运行在一个Docker容器中,三个站点共享一个MySQL容器。
安装完毕之后,我们就可以通过监控工具查看监控到的视图与数据。
虽然我希望你通过阅读本教程能够学到关于使用Docker的一些知识,但这并不意味着涉及Docker的知识像文章中关于使用New Relic监控工具监控基于Docker的应用程序的内容一样多。
阅读本教程,你应该至少对Docker比较熟悉,同时如果对Linux 命令行了解的话则更好。
简而言之,Docker是一种工具,它能够将你的应用程序的组件以及它们的依赖打包到一个独立单元并可以快速、安全的部署到不同的环境中——包括用于开发的机器或者生产服务器集群。
这些构建模块被称为容器——概念接近于虚拟机,但并不完全一样。虚拟机运行着自己的操作系统,而容器全部运行于同一个宿主机的操作系统,容器之间有它们自己的依赖性和库。容器之间也可以联系并共享资源。
想学习更多关于Docker的知识,最好的地方就是Docker的在线文档,文档写的很好并且有详细的操作步骤。
下面让我们开始我们的设置吧!
在我们开始实施Docker和New Relic设置之前,这里有一幅图展示了我们在本教程中将要使用的基本架构:
我在介绍中已经提到过,这是个很简单的WordPress服务:在三个容器中(任意数字),我们在每个容器中运行WordPress的安装程序。WordPress的三个容器全部连接到运行MySQL的容器。所有的这些容器全部运行在一台服务器上,本例中的服务器为亚马逊的EC2,当然任何能够运行Docker和NewRelic监控工具的服务器都是可以的。
服务器和运行在服务器上的容器将会被New Relic的APM(Application Performance Monitoring应用程序性能监控)和服务器工具所监控。
我设计的这个示例主要是用于演示目的,但是实际上它仿照了我自己所建立的一个项目:通过添加一个管理工具,适当的DNS配置和一个Nginx反向代理——所有的这些都运行于它们自己的Docker容器中——这个设置可以建立一个功能完善的托管WordPress的服务。然后,这超出了这篇教程的范围,所以让我们回到运行WordPress的容器中来。
当我像本次一样需要一个网络服务器来做实验的时候,我喜欢使用亚马逊的虚拟机:因为它们既便宜又按需付费(不过要记得使用之后将它们关闭!)
然而,使用Docker和New Relic时,亚马逊虚拟机并不是必须的,如果你喜欢其他一些虚拟服务器提供商或者你自己拥有一台可以安装Docker和New Relic监控工具的服务器,这些都是不错的选择。
在这种情况下,你可以跳过这一步,转到步骤二:直接在服务器上安装Docker。
在我之前的教程“Get Started With Monitoring Your Web Application Using New Relic Alerts”中已经一步一步详细记录了在亚马逊云中启动一个虚拟机的指令。按照教程中的指令,在教程的步骤一中,和本次一样,不要安装PHP或者启动apache,因为apache和PHP将会在Docker容器中运行。
如果你已经非常熟悉AWS并且想要快速了解当启动虚拟机时选择哪个选项,下面的清单将指导你完成这个过程:
在一分钟左右之后,你会被通知你的虚拟机已经可以使用。
右击虚拟机的名字并选择“Connect”选项。从弹出窗口复制虚拟机的IP地址并使用SSH连接到虚拟机(在下面的命令行中将所有的“INSERT_IP_HERE”换成你的IP地址)
cp ~/Downloads/docker_test.pem.txt ~/.ssh/docker_test.pem
chmod 400 ~/.ssh/docker_test.pem
ssh -i ~/.ssh/docker_test.pem ec2-user@INSERT_IP_HERE
现在你已经启动了服务器并通过SSH连接到了服务器上, 现在开始安装Docker引擎了。
这个步骤中的指令适用于我们在步骤一中创建的亚马逊Linux服务器。如果你使用的是不同的操作系统,请根据你的环境参照Docker文档中的指令进行安装。
开始安装Docker安装包:
sudo yum update
sudo yum -y install docker
一旦Docker安装完成,把它作为服务启动:
sudo service docker start
现在,Docker服务将一直处于运行状态(除非你把它停止)
为了测试安装,你可以使用docker ps 命令列出正在运行的Docker 容器:
sudo docker ps
此时,列表为空,因为我们还没有启动任何容器:
最后,将默认的用户添加到docker组中以便你可以在使用所有的Docker命令时不需要输入 sudo。虽然仅仅只是4个字母,但是如果你经常输入的话,那将会是完全不同的体验。
sudo usermod -a -G docker ec2-user
为了使修改生效,请关闭当前的ssh连接并使用ssh重新进行连接。
现在,你就可以使用Docker容器了。
如果你搜索WordPress和Docker(或者MySQL和Docker),你会注意到有很多不同的Docker镜像文件可以选择。在你自己的应用程序中,最好的办法就是选择最流行的和对你来说运行起来最好的镜像,否则你应该从头编写一个。
在这篇教程中,我决定使用官方的镜像文件:MySQL镜像由MySQL提供,WordPress的镜像由Docker提供。
首先,使用MySQL镜像mysql/mysql-server:5.5启动一个容器
docker run –name db -e MYSQL_ROOT_PASSWORD=”mypass” -d mysql/mysql-server:5.5
这条命令会下载MySQL的镜像文件并启动MySQL容器,我们将容器的名字命名为db。这个名字很重要,因为我们将使用它连接WordPress容器与数据库。
如果你喜欢,你可以使用docker ps 命令检查容器是否运行。关于容器启动的更多的信息,你可以使用docker logs db命令检查容器的日志文件。你应该可以看到类似以下几行的输出:
MySQL init process done. Ready for start up.
150925 9:03:41 [Note] mysqld (mysqld 5.5.45) starting as process 1 …
接下来,使用WordPress镜像启动一个WordPress容器(使用latest标签,你将会永远得到最新的基于Apache的版本)。
docker run –name wordpress-1 –link db:mysql -e WORDPRESS_DB_NAME=”wordpress_1″ -d -p 80:80 wordpress:latest
在上面的命令行中,你会注意到我们连接容器wordpress-1到MySQL容器(–link db:mysql),将数据库的名字作为环境变量(-e WORDPRESS_DB_NAME=”wordpress_1”) 。这个容器监听标准的HTTP 80端口。
当我们连接db容器的时候根用户的数据库密码会被自动分享。
一旦镜像文件被加载且容器处于运行状态时,请访问虚拟机的URL来检查容器是否正常运行。当在AWS上运行的时候,使用步骤一中的公有IP地址。
只需要一到两分钟即可完成WordPress的安装。你现在已经启动了三个WordPress容器中的第一个容器。在我们进行下一步之前,让我们先为当前的配置建立NewRelic监控。
NewRelic对Docker的支持分为两部分:
让我们先从服务器部分开始吧。
因New Relic是一种在线服务,因此要使用New Relic监控工具的话,你首先需要一个激活的New Relic账户。你可以使用14天的试用版本,也可以使用免费版本。本教程中提供的所有功能都是可用的免费版本。
如果你还没有New Relic账户,首要要从注册一个账户开始。
一旦注册完毕,从页面顶端菜单选择“Servers”来访问服务器监控工具。
如果你已经使用过New Relic服务器,你将会看到被New Relic监控的你的服务器列表。如果你刚刚注册,你将会被直接跳转到“Get started with New Relic Servers”页面。
在这个页面中,根据你需要监控的服务器环境的不同,你将会得到不同的操作指令,选择与你服务器匹配的即可。对于本教程中的亚马逊的Linux服务器,我们选择“Red Hat or CentOS”选项。
向下滚动鼠标,根据你服务器的环境选择相匹配的指令完成安装。
对于亚马逊Linux服务器,我们首先要添加New Relic Yum源。注意这个操作需要使用root权限,所以我们将使用sudo。
sudo rpm -Uvh http://download.newrelic.com/pub/newrelic/el5/i386/newrelic-repo-5-3.noarch.rpm
接下来,在添加了yum源以后,我们使用yum来安装服务器监控的包:
sudo yum install -y newrelic-sysmond
命令行中 -y 参数的作用是在安装过程中所有的提示全部回答yes。如果你想要安装时更小心一些的话,也可以不用 –y 选项,全部手工回答。
完成安装并配置监控代理和设置你的许可证秘钥。你在“Get started with New Relic Servers”页面的某个位置会发现配置许可秘钥的命令行,记得在命令前加上前缀sudo。
sudo nrsysmond-config –set license_key=[KEY HERE]
在启动监控守护进程之前,我们需要为Docker的监控做一些附加的配置。
首先,添加New Relic用户到你服务器的Docker用户组以便允许New Relic收集Docker的数据。
sudo usermod -a -G docker newrelic
然后,重新启动Docker。请尽量避免粗暴的重新启动以便影响到容器中运行的应用。最好先停止所有运行的容器。
docker stop wordpress-1 db
sudo service docker restart
在重新启动之后,我们就可以启动服务器监控守护进程。
sudo /etc/init.d/newrelic-sysmond start
到目前为止,New Relic服务器监控守护进程就安装完毕了。在重新启动Docker容器之后,你将会很快在New Relic的仪表盘看到你服务器的监控信息。
docker start db wordpress-1
让我们看看我们都能在仪表盘看到什么信息吧。
在NewRelic仪表盘页面上,单击“Servers”菜单可以重新加载服务器列表。如果顺利的话,你现在应该可以看到你服务器的列表,如下所示:
单击机器名称可以看到更多的信息。如果还没有数据的话,多等待一会儿或者再重新试一遍。你首先将要看到的是总览页面。
在总览页面当中,一切看起来和没有监控Docker的常规服务器几乎一样。
我们可以看到CPU利用率,服务器负载的平均值,被使用的物理内存总量,磁盘与网络I/O使用率等。因为我们刚刚启动服务器而且也没有用户访问这个站点,所有很多的指标都是处于很低的范围。
如果你查看页面右侧底部的处理器列表,你将会注意到Docker确实已经运行在了这台服务器上。
当我们考虑服务器整体健康状况的时候全局视图是很重要的。但是现在,我们真正感兴趣的是我们在Docker配置部分能够学习到什么。所以,我们更感兴趣的部分是Docker菜单。
单击左边的Docker 菜单。
在Docker页面可以按照镜像文件分组显示出你服务器上Docker容器使用资源的百分比。在本例中,你将可以看到两个镜像文件,wordpress:latest 和mysql/mysql-server:5.5,也就是之前我们的步骤中用于启动容器的镜像文件。我们可以看到WordPress使用了更多的CPU资源,两者使用的内存基本相同。你还可以在页面顶部靠左边使用下拉菜单按照CPU或者内存进行分类。
随着你程序的持续运行,这些页面上的监控信息将会指导你如何更好的配置你的应用程序。举个例子,如果你注意到MySQL使用了很多的内存和CPU资源,这可能意味着你应该考虑把这个应用迁移到一个独立的服务器上。或者发现用更多的容器来运行WordPress比我们真的把它们分为两个容器来运行更合适。
如果你想对某一个镜像文件了解更多信息,单击列表左边镜像的名字,这将会打开一个全新的页面可以详细的展示使用此镜像的容器的信息。
这个页面展示了使用这个镜像的容器的CPU和内存使用率和运行容器的数量。我们可以再添加一对WordPress容器来改变这个页面显示的信息。我们使用之前用过的docker run命令,但是会有一些不同:
具体命令如下:
docker run –name wordpress-2 –link db:mysql -e WORDPRESS_DB_NAME=”wordpress_2″ -d -p 8000:80 wordpress:latest
docker run –name wordpress-3 –link db:mysql -e WORDPRESS_DB_NAME=”wordpress_3″ -d -p 8001:80 wordpress:latest
在亚马逊服务器上,要使两个新的WordPress容器可以被访问,你需要编辑EC2实例的“Security Group”设置,允许来自端口8000和8001的流量进入。使用“Custom TCP Rule”选项并选择流量来源为“Anywhere”。
现在,访问两个新的WordPress站点,并点击它们的一些菜单项。然后回到New Relic “Servers”中查看Docker页面数据的变化。首先,最明显的变化就是所运行容器的数量。现在有三个容器正在运行,而不是之前的一个。
尽管内存使用量显示了增长但是CPU使用率依然很低。
目前为止,我们已经可以从外部看到Docker容器的资源使用率以及他们在服务器中的运行情况。尽管对Docker的监控视图能够提供关于你的服务器和服务器内运行容器的全部有用的信息,但New Relic真正的强大之处在于它以应用为主的方法:通过应用程序级别的监控,你可以获得更多你的服务器上所发生的事件以及如何处理这些事件的详细的信息。
通常情况下,当直接在你的网络服务器上运行PHP代码,你只要安装APM监控代理即可。对于这样的例子,你可以看一看在你的服务器上运行的应用程序。现在,事情变得不同了:我们把应用的架构分成了不同的部分——“微服务”——每一个微服务都在单独的容器中运行,所以服务器自身并不运行Apache或者PHP,也就是为什么如果你在服务器上安装APM代理,你不会看到任何活动,监控需要在容器内部进行。
Docker最伟大一个特点就是允许你将已经存在的镜像作为基础镜像,并在基础镜像之上构建新的镜像,而不需要改变原始镜像或者重写一个新的镜像。
我们将修改在之前教程中使用的WordPress镜像文件以便使New Relic能够从内部进行监控。
你可以从GitHub下载源文件,或者你可以按照本教程中的方法自己建立一个。
为新的镜像文件新建一个目录,例如在ec2-user的家目录中。
mkdir wordpress-newrelic
然后在目录中新建一个文本文件,命名为Dockerfile。这个文件将会包含你的Docker镜像文件内所包含内容的定义。在这个文件中,加入以下代码。
01 FROM wordpress:4.3.1-apache
02
03 # Add custom script for running New Relic daemon
04 ADD run.sh /run.sh
05 RUN chmod +x /run.sh
06
07 # Modify the default entrypoint to call our new run script at its end
08 RUN sed -i “s/exec \”\$@\”/exec \”\/run.sh\”/” /entrypoint.sh
09
10 # Add a simple phpinfo() page for testing
11 ADD test.php /var/www/html/test.php
12
13 # Install New Relic daemon
14 RUN apt-get update && \
15 apt-get -yq install wget && \
16 wget -O – https://download.newrelic.com/548C16BF.gpg | apt-key add – && \
17 echo “deb http://apt.newrelic.com/debian/ newrelic non-free” > /etc/apt/sources.list.d/newrelic.list
18
19 RUN apt-get update && \
20 apt-get -yq install newrelic-php5
21
22 # Setup environment variables for initializing New Relic
23 ENV NR_INSTALL_SILENT 1
24 ENV NR_INSTALL_KEY **ChangeMe**
25 ENV NR_APP_NAME “Default App Name”
现在,让我们通过浏览文件看看它是什么。
第一行:文件开始于指定Docker镜像文件,我们的镜像文件基于此镜像文件构建。
第三至五行:包含初始化New Relic监控的脚本。脚本文件将在容器启动时运行以便我们可以使用脚本为每个容器分别定义应用程序的名字和许可秘钥。
第七至八行:修改默认Entrypoint在其结束时调用我们新的运行脚本。
第十至十一行:在生产环境中这可能不是你想要的东西。然而,对于测试环境是非常方便的,它包含一个简单的PHP文件我们可以使用它来检查New Relic是否正确设置。
确保已经按照下面的内容建立了一个名为test.php的文件。
<?php phpinfo(); ?>
第十三至二十行:这部分内容定义了我们在镜像文件的哪个位置安装New Relic监控的包。
首先,脚本安装wget并使用wget下载New Relic的秘钥并把它添加到APT。
接下来,脚本添加New Relic的安装源到APT。
最后,第十九至二十行,从安装源安装newrelic-php5的包。
第二十二至二十五行:为运行New Relic初始化环境变量。
三个环境变量定义如下:
Dockerfile准备好了,我们需要执行上面提到的启动脚本run.sh。这个脚本将会仅仅完成New Relic的安装并启动服务器。
建立一个文件并添加以下代码:
01 #!/bin/bash
02 set -e
03
04 echo “Enabling APM metrics for ${NR_APP_NAME}”
05 newrelic-install install
06
07 # Update the application name
08 sed -i “s/newrelic.appname = \”PHP Application\”/newrelic.appname = \”${NR_APP_NAME}\”/” /usr/local/etc/php/conf.d/newrelic.ini
09
10 exec “apache2-foreground”
现在,让我们一行一行的浏览这段代码:
第一行:指定脚本使用/bin/bash来执行。
第二行:指定如果发生错误,脚本应该退出执行。
第四至五行:运行New Relic安装脚本。注意我们不需要传递任何参数,因为配置工作被环境变量完成了。NR_INSTALL_SILENT已经在Dockerfile中指定了,NR_INSTALL_KEY应该被传递到 docker run命令中去。
第七至八行:因为安装脚本没有环境变量来指定应用程序的名字,我们将不得不手动编辑配置文件——实际上在这个脚本中是以编程的方式。
在配置文件中,应用程序的名字被指定为:
newrelic.appname = “PHP Application”
在第八行中的sed命令查找字符串并替换它使用在NR_APP_NAME中定义的名字。
第十行:最后,调用apache2-foreground在前台运行apache并使容器处于运行状态。
在前两个步骤你建立并放置文件的目录中,输入如下命令:
docker build -t tutsplus/wordpress-newrelic:4.3.1-apache .
上述命令将建立一个新的镜像文件,名称为tutsplus/wordpress-newrelic,标签为 4.3.1-apache,并把它添加到你本地的Docker镜像仓库中。一旦镜像建立完毕,是时候看看是否一切正常。
首先,停止并删除你已经存在的WordPress容器。
docker stop wordpress-1 wordpress-2 wordpress-3
docker rm wordpress-1 wordpress-2 wordpress-3
然后,运行新的容器,先运行一个容器,一旦你检查这个容器一切正常之后,再运行其他的容器。
docker run –name wordpress-1 –link db:mysql -e NR_INSTALL_KEY=”YOUR KEY HERE” -e NR_APP_NAME=”wordpress-cloud” -e WORDPRESS_DB_NAME=”wordpress_1″ -d -p 80:80 tutsplus/wordpress-newrelic:4.3.1-apache
上面的命令和我们之前看到的启动默认WordPress镜像时的命令基本是一样的。但是有一点儿变化:-e NR_INSTALL_KEY=“YOUR KEY HERE”:在这里指定应该在安装脚本中使用的New Relic的许可秘钥。你可以前往APM的“Get started with New Relic”页面并选择PHP选项找到它。
在这一页中,在安装说明之前,有一个红色按钮写着“Reveal License Key”。单击此按钮并替换“YOUR KEY HERE”。
-e NR_APP_NAME=“wordpress-cloud”:这部分命令用于指定应用程序的名字时设定环境变量用。名字用于在APM内部对数据进行分组。
容器名字的“正确”取值依赖于你的设置和你想如何监控它。如果你所有的容器都作为同一个应用程序的一部分运行的话, 那么为它们取相同的名字并在监控工具的同一个视图中收集它们的数据是合理的。另一方面,如果容器显然是独立没有关联的,那么区分名字是很必要的。在这个例子中,我决定为三个容器使用相同的名字,wordpress-cloud。更详细的关于应用程序命名的内容请查询New Relic的文档。
Tutsplus/wordpress-newrelic:4.3.1-apache : 在命令行的最后,你将会注意到我们现在使用最新建立的镜像文件来替代wordpress:latest。
一旦你在你的服务器上开始运行命令,请访问WordPress测试页确认服务器正在运行并且包含了New Relic。你可能也想要检查 newrelic.appname的值。
你可以再前往主页查看WordPress正常运行。现在你有一个Docker容器正在运行WordPress并且报告它的状态到New Relic APM。
添加剩余的两个容器wordpress-2和wordpress-3。
现在你已经为你的每一个Docker容器都配置了监控,让我们看一看我们在APM中得到的数据。
因为我们为三个WordPress容器添加了相同的名字,所以当你打开APM页面,你会发现只有一个应用程序,wordpress-cloud。当你把你的鼠标指针指向应用程序名字的时候,你将会看到一个弹出框写到“Php application running on 3 hosts (3 instances)”。
单击这个名字可以访问这个应用程序和它的容器的分析数据。
在APM中你首先看到的是总览页面。这个页面展示了这个应用程序的所有容器的性能的一个汇总信息:请求应用程序所花费的平均时间,应用程序的Apdex分数,它的吞吐量和应用程序最慢事务的列表。
在屏幕的底部,你将能够找到一个应用程序结构的摘要信息:什么服务器在上面运行,应用程序使用的容器。
在一个更复杂的,真实的应用程序中,您可能会看到多个服务器以及多个容器。现在,你将会找到三个WordPress容器。因为我们没有安装New Relic到数据库镜像文件中,所以我们在列表中看不到它。
与总览页面类似,默认情况下,在APM的页面将会展示全部应用程序各种指标的性能的摘要。然而,如果你想要深入到具体的某个容器,你可以随时使用屏幕上部的下拉菜单选择你所感兴趣的:
如果你不确定列表中不同服务器代码的含义,你可以使用docker ps命令找到Docker ID与你的容器间的对应关系。
APM不仅仅对追踪你的网络服务器上应用程序的性能有用,它对于发现你应用程序出现的错误以及定位错误也是非常有帮助的。为了测试这个基于Docker的环境,我建立了一个简单的WordPress插件,故意在代码中制造一些错误,并把它们安装在一个容器中。然后,在浏览了一会儿站点之后,我在APM中看到了如下的错误:
看着这张图片,你很快就会看到在应用程序中出错率正在上升。在下面的图片中,你将会发现一个显示最近错误的列表:一个语法错误发生了三次和一个被零除的错误,出现在了代码中的各个位置。这些错误都需要被解决,但是现在,先让我们来看看第一个。
点击错误信息将会把你带到一个包含更多错误信息的页面。
查看这个页面,你将会看到错误发生在一个Docker容器中——402c389c0661,正好是我安装了错误插件且ID为wordpress-3的容器。
现在我们已经发现了发生错误的容器,我们可以使用堆栈跟踪来解决问题并更新受影响容器插件的一个版本,问题就解决了。
你现在已经实现了一个简单的基于Docker的网络服务器的设置并启用了New Relic来对它进行监控。你还了解了如何使用监控工具在基于Docker的应用程序中获得更好的可视性。
无论如何, 我们仅仅只接触了New Relic监控工具的表面功能而已,所以如果你还不是一个New Relic的用户,看看New Relic的Docker监控页面并开始吧!
【原文地址】http://code.tutsplus.com/tutorials/how-to-monitor-docker-based-applications-using-new-relic–cms-24891