warfaamewar robots进不去去怎么办

第6章 使用构建服务
6.1 构建第一个应用
要构建的第一个应用是使用Jekyll框架的自定义网站,会构建以下两个镜像:
。一个镜像安装了Jekyll及其它用于构建Jekyll网站的必要的软件包
。一个镜像通过Apache来让Jekyll网站工作起来。
在启动容器时,通过创建一个新的Jekyll网站来实现自服务,工作流程如下:
。创建Jekyll基础镜像和Apache镜像(只需要构建一次)
。从Jekyll镜像创建一个容器,这个容器存放通过卷挂载的网站源代码。
。从Apache镜像创建一个容器,这个容器利用包含编译后的网站的卷,并为其服务。
。在网站需要更新时,清理并重复上面的步骤
6.1.1 Jekyll基础镜像
--&mkdir -p jekyll/jekyll
--&cd jekyll
--&vim file
FROM ubuntu:14.04
MAINTAINER James Turnbull &&
ENV REFRESHED_AT
RUN apt-get -y update
RUN apt-get -y install ruby ruby-dev make nodejs
RUN gem install --no-rdoc --no-ri jekyll
RUN mkdir /data /var/www/html
VOLUME /data/
VOLUME /var/www/html
WORKDIR /data
ENTRYPOINT [ "jekyll", "build", "--destination=/var/www/html" ]
这个file使用了第三章的模板作为基础,镜像基于ubuntu 14.04,并且安装了Ruby
和用于支持Jekyll的包,然后使用VOLUME指令创建了以下两个卷。
。/data/ ,用来存放网站的源代码。
。/var/www/html,用来存放编译后的Jekyll网站码。
设置工作目录为/data,并通过ENTRYPOINT指令指定自动构建的命令。这个命令会将工作目录
/data/中的所有的Jekyll网站代码构建到/var/www/html目录。
6.1.2 构建Jekyll基础镜像
--&docker build -t jamtur01/jekyll .
Sending build context to
daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
---& 3f126a502d09
Step 1 : MAINTAINER James Turnbull &&
---& Running in 92ee0cb8c5b8
---& 10b317f5826d
Removing intermediate container 92ee0cb8c5b8
Step 2 : RUN apt-get -y update
---& Running in ed05
...........................................................
---& 3f99ce4730de
Step 12 : RUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIR
---& Using cache
---& 059d48b82c99
Step 13 : EXPOSE 80
---& Using cache
---& bec93e4be569
Step 14 : ENTRYPOINT /usr/sbin/apache2
---& Using cache
Step 15 : CMD -D FOREGROUND
---& Using cache
Successfully built a8
这样就构建了名为jamtur01/jekyll、ID为a8的新镜像。这就是将要使用的新的Jekyll镜像。
。查看镜像:
--&docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
jamtur01/jekyll latest a8 12 minutes ago 265.5 MB
6.1.3 Apache镜像
构建Apache镜像,一个用来架构新网站的Apache服务器,先创建一个新目录和一个空的Dockerfile。
--&cd jekyll/
--&mkdir apache
--&cd apache
--&vim Dockerfile
FROM ubuntu:14.04
MAINTAINER James Turnbull &&
RUN apt-get -y update
RUN apt-get -y install apache2
VOLUME [ "/var/www/html" ]
WORKDIR /var/www/html
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
RUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIR
ENTRYPOINT [ "/usr/sbin/apache2" ]
CMD ["-D", "FOREGROUND"]
这个镜像是基于Ubuntu 14.04的,并安装了Apache,然后使用VOLUME指令创建了一个卷,即
/var/www/html,用来存放编译后的Jekyll网站,然后将/var/www/html设为工作目录。
然后使用了ENV指令设置了一些必要的环境变量,创建了必要的目录,并且使用EXPOSE公开了
80端口,最后指定了ENTRYPOINT和CMD指令组合来在容器启动时默认运行Apache。
6.1.4 构建Jekylll Apache镜像
--&docker build -t jamtur01/apache .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
---& 3f126a502d09
Step 1 : MAINTAINER James Turnbull &&
---& Using cache
---& 10b317f5826d
Step 2 : RUN apt-get update
---& Using cache
---& 8bca2ed2a6d7
Step 3 : RUN apt-get -y install apache2
---& Running in be
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
Removing intermediate container dac4
Step 13 : EXPOSE 80
---& Running in 67d4bf9153c3
---& bec93e4be569
Removing intermediate container 67d4bf9153c3
Step 14 : ENTRYPOINT /usr/sbin/apache2
---& Running in 6c48e1b8aea8
Removing intermediate container 6c48e1b8aea8
Step 15 : CMD -D FOREGROUND
---& Running in cedefba8bcd8
Removing intermediate container cedefba8bcd8
Successfully built a8
这样,就构建了名为jamtur01/apache,ID为a8的新镜像,这就是要使用的Apache镜像。
。查看新镜像
--&docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
jamtur01/apache latest a8 42 seconds ago 265.5 MB
6.1.5 启动jekylll网站
现在已经有了两个镜像:
。Jekyll:安装了Ruby及其它必备软件包的Jekyll镜像。
。Apache:通过Apache Web服务器来让Jekyll网站工作起来的镜像。
使用docker run命令创建一个新的Jekyll容器开始我们的网站,启动容器,并构建网站。
然后需要一些博客的源代码,先把示例Jekyll博客复制到$HOME中(/home/james)。
--&cd $HOME
--&git clone https://github.com/jamtur01/james_blog.git
正克隆到 'james_blog'...
remote: Counting objects: 83, done.
remote: Total 83 (delta 0), reused 0 (delta 0), pack-reused 83
Unpacking objects: 100% (83/83), done.
检查连接... 完成。
在整个目录下可以看到一个启用了Twitter Bootstrap的最基础的Jekyll博客。如果想使用这个博客,
可以修改_config.xml文件和主题,以符合你的要求。
--&ls james_blog/
404.html atom.xml _config.yml _includes pages.html Rakefile sitemap.txt
archive.html categories.html _drafts index.md _plugins README.md tags.html
assets changelog.md History.markdown _layouts _posts rss.xml
--&cd james_blog/
--&docker run -v /root/james_blog:/data/ --name james_blog jamtur01/jekyll
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2.
Set the 'ServerName' directive globally to suppress this message
解决方法:
将 apache 的配置文件httpd.conf中的 ServerName 改成可用域名或如下配置:ServerName localhost:80
===================================================================================================
现在启动了一个叫做james_blog的新容器,把本地的james_blog目录作为/data卷挂载到容器里。容器
已经拿到网站的源代码,并将其构建到已编译的网站,存放到/var/www/html/目录。
卷是在一个或多个容器中特殊指定的目录,卷会绕过联合文件系统,为持久化数据和共享数据提供几个
有用的特性。
。卷可以在容器间共享和重用
。共享卷时不一定要运行相应的容器
。对卷的修改会直接在卷上反应出来。
。更新镜像时不会包含对卷的修改。
。卷会一直存在,直到没有容器使用它们。
利用卷,可以在不用提交镜像修改的情况下,向镜像内加入数据(如源代码、数据或者其他内容),并且
可以在容器间共享这些数据。
卷在Docker宿主机的/var/lib/docker/volumes目录中。可以通过docker inspect命令查看某个卷的挂载位置。
--&docker inspect -f "{{ .Volumes }}"
所以,如果想在另一个容器里使用/var/www/html 卷里编译好的网站,可以创建一个新的连接到这个卷的容器。
--&docker run -d -P --volumes-from james_blog jamtur01/apache
参数:--volume-from,把指定容器里的所有卷都加入新创建的容器里。这意味着,Apache容器可以访问之前创建
的james_blog容器里/var/www/html卷存放的编译后的Jekyll网站。即便james_blog容器没有运行,Apache容器也可以
访问这个卷。如果用docker rm命令删除了james_blog容器,那么这个卷和卷里的内容也就不存在了。
。查看端口映射
--&docker port 09a570cc2267 80
。Docker宿主机上浏览该网站:
6.1.6 更新Jekyll网站
如果要更新网站的数据,假设要修改Jekyll网站,将通过编辑james_blog/_config.yml 文件来修改博客的名字。
--&vim james_blog/_config.yml
将title域改为James' Dynamic Docker-driven Blog。
。更新博客
--&docker start james_blog #再次启动Docker容器即可。
。查看容器日志:
--&docker logs james_blog
可以看到,Jekyll编译过程第二次被执行,并且网站已经被更新。这次更新已经写入了对应的卷。
。浏览Jekyll网站:
由于共享的卷会自动更新,这一切都不需要更新或者重启Apache容器,这个流程非常简单,可以将其扩展到更复杂的
部署环境。
6.1.7 备份Jekyll卷
。创建新容器,用来备份/var/www/html卷
--&docker run --rm --volumes james_blog -v $(pwd):/backup ubuntu tar cvf /backup/james_blog_backup.tar /var/www/html
参数--rm:表示使用一次就删除容器。
此处运行一个已有的Ubuntu容器,并把james_blog的卷挂载到该容器里。这会在该容器里创建/var/www/html目录。然后使用-v标志把
当前目录(通过$pwd命令获得),挂载到容器的/backup目录,最后容器运行这一备份命令。
提示:这个例子对卷中存储的数据库或者其它类似的数据也适用,只要简单地把卷挂载到新容器,完成备份,然后废弃这个用于备份的
容器就可以了。
6.1.8 扩展Jekyll示例网站
下面几种扩展Jekyll网站的方法
。运行多个Apache容器,这些容器都使用来自james_blob容器的卷。在这些Apache容器前面加一个负载均衡器,就拥有了一个Web集群。
。进一步构建一个镜像,这个镜像把用户提供的源数据复制到卷里,再把这个卷挂载到从jamtur01/jekyll镜像创建的容器。这就是一个
可迁移的通用方案,而且不需要宿主机本地包含任何源代码。
。在上一个扩展基础上可以很容易为服务构建一个Web前端,这个服务用于从指定的源自动构建和部署网站。这样就有一个完全属于自己
的GitHub Pages了。
http://aws.amazon.com/s3
http://www.amanda.org
6.2 使用Docker构建一个Java应用服务
工作目标:获取Tomcat服务器上的WAR文件
。一个镜像从ULR拉取指定的WAR文件并将其保存到卷里。
。一个含有Tomcat服务器的镜像运行这些下载的WAR文件。
6.2.1 WAR文件的获取器
构建一个镜像,这个镜像会下载WAR文件并将其挂载在卷里:
--&mkdir fetcher
--&cd fetcher
--&vim Dockerfile
FROM ubuntu:14.04
MAINTAINER James Turnbull &&
ENV REFRESHED_AT
RUN apt-get update
RUN apt-get -y install wget
RUN mkdir -p /var/lib/tomcat7/webapps
VOLUME [ "/var/lib/tomcat7/webapps/" ]
WORKDIR /var/lib/tomcat7/webapps/
ENTRYPOINT [ "wget" ]
CMD [ "-?" ]
此Dockerfile使用wget从指定的URL获取文件并把文件保存在/var/lib/tomcat7/webapps/目录。
这个目录也是卷,并且是所有容器的工作目录,然后把这个卷共享给Tomcat服务器容器运行里面的内容。
最后,如果没有指定URL,ENTRYPOINT和CMD指令会让容器运行,在容器不带URL运行的时候,这两条指令
通过返回wget帮助来做到这一点。
。构建这个镜像
--&docker build -t jamtur01/fetcher .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
---& 3f126a502d09
Step 1 : MAINTAINER James Turnbull &&
---& Using cache
---& 10b317f5826d
Step 2 : ENV REFRESHED_AT
---& Running in d57d943c8c70
Removing intermediate container d57d943c8c70
Step 3 : RUN apt-get update
---& Running in ca9a01a11714
.....................................................
Removing intermediate container 4e1c1bf66ff4
Step 8 : ENTRYPOINT wget
---& Running in 22a1e5aa0ae6
---& 51338e1bfb9e
Removing intermediate container 22a1e5aa0ae6
Step 9 : CMD -?
---& Running in f
---& 452a3a720b32
Removing intermediate container f
Successfully built 452a3a720b32
6.2.2 获取WAR文件
获取一个示例文件来启动新镜像。从Tomcat官网下载Apache Tomcat示例应用:
--&docker run -t -i --name sample jamtur01/fetcher https://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war
可以看到,容器通过下载了sample.war文件。从输出结果看不出最终的保存路径,但是因为设置了容器的工作目录,sample.war文件最终
会保存到/var/lib/tomcat7/webapps/ 目录下。
。查找卷的存储位置
--&docker inspect -f "{{ .Volumes }}" sample
map[/var/lib/tomcat7/webapps:/var/lib/docker/volumes/58c33fea086a39fbeeca6fe0faebc9be18/_data]
。查看这个目录
--&ls -l /var/lib/docker/volumes/
drwxr-xr-x 3 root root 4096 9月 10 10:24 0d8e6e87be6e19f9078cea9697f24c9d324c17e11fd
6.2.3 Tomcat7应用服务器
--&mkdir tomcat7
--&cd tomcat7
--&vim Dockerfile
FROM ubuntu:14.04
MAINTAINER James Turnbull &&
ENV REFRESHED_AT
RUN apt-get update
RUN apt-get -y install tomcat7 default-jdk
ENV CATALINA_HOME /usr/share/tomcat7
ENV CATALINA_BASE /var/lib/tomcat7
ENV CATALINA_PID /var/run/tomcat7.pid
ENV CATALINA_SH /usr/share/tomcat7/bin/catalina.sh
ENV CATALINA_TMPDIR /tmp/tomcat7-tomcat7-tmp
RUN mkdir -p $CATALINA_TMPDIR
VOLUME [ "/var/lib/tomcat7/webapps/" ]
EXPOSE 8080
ENTRYPOINT [ "/usr/share/tomcat7/bin/catalina.sh","run" ]
这个镜像需要安装Java JDK和Tomcat服务器,首先制定一些启动Tomcat需要的环境,然后创建一个临时目录,
还创建了/var/lib/tomcat7/webapps/卷,公开了tomcat 8080端口,最后使用ENTRYPOINT指令来启动Tomcat。
。构建Toomcat 7镜像
--&docker build -t jamtur01/tomcat7 .
Sending build context to Docker daemon 2.56 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
---& 3f126a502d09
Step 1 : MAINTAINER James Turnbull &&
---& Using cache
---& 10b317f5826d
Step 2 : ENV REFRESHED_AT
---& Running in f
---& a5cad6395685
Removing intermediate container f
Step 3 : RUN apt-get update
---& Running in 7e6ce2ab52d9
6.2.4 运行WAR文件
创建一个新的Tomcat实例,运行示例应用。
--&docker run --name sample_app --volumes-from sample -d -P jamtur01/tomcat7
表示创建一个名为sample_app的容器,这个容器会复用sample容器里的卷。意味着存储在/var/lib/tomcat7/webapps/
卷里的WAR文件会从sample容器挂载到sample_app容器,最终被Tomcat加载并执行。
。查看被公开的端口
--&docker port sample_app 8080
。浏览这个应用
--&http://ip:49154/sample/
6.2.5 基于Tomcat应用服务器的构建服务
现在有了自服务Web的基础模块,看看怎么基于这些基础模块做扩展。
已经构建好了一个简单的基于Sinatra的Web应用,这个应用可以通过网页自动展示Tomcat应用。这个应用叫TProv。
下载地址:http://dockerbook.com/code/6/tomcat/tprov/
https://github.com/jamtur01/dockerbook-code/tree/master/code/6/tomcat/tprov
提示:可以把TProv安装在Docker容器里。
--&apt-get -y install ruby make ruby-dev
。通过Ruby gem安装tprov
--&gem install --no-rdoc --no-ri tprov
。启动应用
从输出可知,端口是:
。浏览TProv网站
--&http://ip:
可以指定Tomcat应用的名字和指向Tomcat WAR文件的URL。
从https://gwt-example.googlecode.com/files/Calendar.war下载示例日历应用,并将其称作Calendar。
--&Enter name of the Tomcat application : Calendar
--&Enter the URL of a WAR file you wish to run: https://gwt-example.googlecode.com/files/Calendar.war
单击Submit下载WAR文件,将其放入卷里,运行Tomcat服务器,加载卷例的WAR文件。
可以通过List instances(展示实例)连接来查看实例的运行状态。
。容器的ID;
。容器的内部IP地址;
。服务器映射到接口和端口
利用这些信息,可以通过浏览映射端口来查看应用的运行状态。还可以使用Delete(是否删除)单选框来删除正在
运行的实例。
可以通过查看TProv应用的源代码,看看程序是如何实现这些功能的。这个应用很简单,只是通过shell执行docker
程序,再捕获输出,来运行或者删除容器。
https://github.com/jamtur01/dockerbook-code/blob/master/code/6/tomcat/tprovlib/tprov/app.rb
6.3 多容器的应用栈
构建一系列镜像来支持部署多容器的应用:
。一个Node容器,用来服务于Node应用,这个容器会连接到。
。一个Redis主容器,用于保存和集群化应用状态,这个容器会连接到。
。两个Redis备份容器,用于集群化应用状态。
。一个日志容器,用于捕获应用日志。
Node应用会运行在一个容器里,后面会挂载以主从模式配置在多个容器里的Redis集群。
6.3.1 Node.js镜像
--&mkdir nodejs
--&cd nodejs
--&mkdir -p nodeapp
--&cd nodeapp
--&wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/6/node/nodejs/nodeapp/package.json
--&wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/6/node/nodejs/nodeapp/server.js
--&vim Dockerfile
FROM ubuntu:14.04
MAINTAINER James Turnbull &&
ENV refreshed_at
RUN apt-get update
RUN apt-get -y install nodejs npm
RUN ln -s /usr/bin/nodejs /usr/bin/node
RUN mkdir -p /var/log/nodeapp
ADD nodeapp /opt/nodeapp/
WORKDIR /opt/nodeapp
RUN npm install
VOLUME [ "/var/log/nodeapp" ]
EXPOSE 3000
ENTRYPOINT [ "nodejs", "server.js" ]
Node.js镜像安装了Node,然后把二进制文件nodejs连接到node,解决了Ubuntu上原有的一些无法
向后兼容的问题。
然后将nodeapp的源代码通过ADD指令添加到/opt/nodeapp目录。这个Node.js是一个简单的Express
服务器,包括一个存放应用依赖信息的package.json文件和包含实际应用代码的server.js文件,查看该
应用的子集。
server.js文件引入了所有的依赖,并启动了Express应用。Express应用把会话(session)信息保存到
Redis例,并创建了一个以JSON格式返回状态信息的节点。这个应用默认使用redis_primary作为主机名去
连接Redis,如有必要,可以通过环境变量覆盖这个默认的主机名。
这个应用会把日志记录到/var/log/nodeapp/nodeapp.log文件里,并监听3000端口。
源码位置:http://dockerbook.com/code/6/node/
https://github.com/jamtur01/dockerbook-code/tree/master/6/node
接着将工作目录设置为/opt/nodeapp,并且安装了Node应用的必要软件包,创建了用于存放Node应用日志的
卷/var/log/nodeapp。
最后公开了3000端口,并使用ENTRYPOINT指定了运行Node应用的命令nodejs、server.js。
。构建镜像:
--&mkdir nodeapp
--&mv package.json server.js nodeapp/
--&docker build -t jamtur01/nodejs .
Sending build context to Docker daemon 5.12 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
---& 3f126a502d09
Step 1 : MAINTAINER James Turnbull &&
---& Using cache
---& 10b317f5826d
Step 2 : ENV REFRESHED_AT
---& Running in 09
Removing intermediate container 09
Step 3 : RUN apt-get -y update
---& Running in ce199f84c613
........................................................
├── fresh@0.2.0
├── buffer-crc32@0.2.1
├── cookie@0.1.0
├── mkdirp@0.3.5
├── debug@2.2.0 (ms@0.7.1)
├── send@0.1.4 (mime@1.2.11)
├── commander@1.2.0 (keypress@0.1.0)
└── connect@2.8.8 (uid2@0.0.2, pause@0.0.1, qs@0.6.5, bytes@0.2.0, formidable@1.0.14)
---& 7d7fbe7eb9f6
Removing intermediate container fa9b8f1d81e4
Step 11 : VOLUME /var/log/nodeapp
---& Running in b0c204e52ef3
---& 072d101fc7a3
Removing intermediate container b0c204e52ef3
Step 12 : EXPOSE 3000
---& Running in 35e5beb8e397
Removing intermediate container 35e5beb8e397
Step 13 : ENTRYPOINT nodejs server.js
---& Running in f62e2a176be0
Removing intermediate container f62e2a176be0
Successfully built ae
6.3.2 Redis基础镜像
构建第一个Redis镜像:安装Redis基础镜像,然后使用这个镜像构建主从Redis镜像。
--&mkdir redis_base
--&cd redis_base
--&vim Dockerfile
FROM ubuntu:14.04
MAINTAINER James Turnbull &&
ENV REFRESHED_AT
RUN apt-get update
RUN apt-get install -y software-properties-common python-software-properties
RUN add-apt-repository ppa:chris-lea/redis-server
RUN apt-get -y update
RUN apt-get -y install redis-server redis-tools
VOLUME [ "/var/lib/redis", "/var/log/redis" ]
EXPOSE 6379
这个Redis基础镜像安装了最新版本的Redis(从PPA库安装,而不是使用Ubuntu自带的),
指定了两个卷(/var/lib/redis和/var/log/redis),公开了Redis的默认端口6379,因为不会
执行这个镜像,所以没有包含ENTRYPOINT或CMD指令,然后将只是基于这个镜像构建别的镜像。
。构建镜像:
--&docker build -t jamtur01/redis .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
---& 3f126a502d09
Step 1 : MAINTAINER James Turnbull &&
---& Using cache
---& 10b317f5826d
Step 2 : ENV REFRESHED_AT
---& Using cache
Step 3 : RUN apt-get update
---& Running in f290189afd97
........................................................
---& 6a1b963c8b23
Removing intermediate container 4fd036d34eab
Step 8 : VOLUME /var/lib/redis /var/log/redis
---& Running in bc2cf7a83732
Removing intermediate container bc2cf7a83732
Step 9 : EXPOSE 6379
---& Running in 28aa6097a48b
Removing intermediate container 28aa6097a48b
Step 10 : CMD
---& Running in 6e
---& 5d07afc9555e
Removing intermediate container 6e
Successfully built 5d07afc9555e
6.3.3 Redis主镜像
继续构建第一个Redis镜像,即Redis主服务器:
--&mkdir redis_primary
--&cd redis_primary
--&vim Dockerfile
FROM jamtur01/redis
MAINTAINER James Turnbull &&
ENV REFRESHED_AT
RUN touch /var/log/redis/redis-server.log
ENTRYPOINT [ "redis-server", "--logfile /var/log/redis/redis-server.log" ]
说明:Redis镜像基于之前的jamtur01/redis镜像,并通过ENTRYPOINT指令指定了Redis服务启动命令,
Redis服务的日志文件保存到/var/log/redis/redis-server.log。
。构建主镜像
--&docker build -t jamtur01/redis_primary .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM jamtur01/redis
---& a0a58e52218b
Step 1 : MAINTAINER James Turnbull &&
---& Using cache
Step 2 : ENV REFRESHED_AT
---& Using cache
---& c580e7e933dc
Step 3 : RUN touch /var/log/redis/redis-server.log
---& Running in f7b5
Removing intermediate container f7b5
Step 4 : ENTRYPOINT redis-server --logfile /var/log/redis/redis-server.log
---& Running in c30cf1f2ca9f
Removing intermediate container c30cf1f2ca9f
Successfully built 2a
6.3.4 Redis从镜像
为了配合Redis主镜像,会创建Redis从镜像,保证为Node.js应用提供Redis服务的冗余度。
--&mkdir redis_replica
--&cd redis_replica
--&vim Dockerfile
FROM jamtur01/redis
MAINTAINER James Turnbull &&
ENV REFRESHED_AT
RUN touch /var/log/redis/redis-repa.log
ENTRYPOINT [ "redis-server","--logfile /var/log/redis/redis-repa.log","--slaveof redis_primary 6379" ]
Redis从镜像也是基于Jamtur01/redis构建的,并且通过ENTRYPOINT指令指定了运行Redis服务器的命令,设置了
日志文件和slaveof选项。这就把Redis配置为从模式,从这个镜像构建的任何容器都会将redis_primary主机的Redis
作为主服务,连接其6379端口,成为其对应的从服务器。
。构建Redis从镜像:
--&docker build -t jamtur01/redis_replica .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM jamtur01/redis
---& a0a58e52218b
Step 1 : MAINTAINER James Turnbull &&
---& Using cache
Step 2 : ENV REFRESHED_AT
---& Using cache
---& c580e7e933dc
Step 3 : RUN touch /var/log/redis/redis-repa.log
---& Running in
---& b7c1db6682dd
Removing intermediate container
Step 4 : ENTRYPOINT redis-server --logfile /var/log/redis/redis-replica.log --slaveof redis_primary 6379
---& Running in b1e1e5847fac
Removing intermediate container b1e1e5847fac
Successfully built f56
6.3.5 创建Redis后端集群
开始构建Redis集群环境,从构建Redis主容器开始:
--&docker run -d -h redis_primary --name redis_primary jamtur01/redis_primary
c293a244ea1ff0408b33cafa25dbd873d10b179a4f05d0b7cc4b6
这里使用docker run命令从jamtur01/redis_primary 镜像创建了一个容器。
-h: 用来设置容器的主机名。这会覆盖默认的行为(默认以容器ID作为主机名),并允许指定自己的主机名。使用这个
标志可以确保容器使用redis_primary作为主机名,并被本地的DNS服务正确解析。
--name:确保容器的名字也是redis_primary。使用这个名字来连接容器。
。查看日志了解Redis主容器的运行状况
--&docker logs redis_primary
没有输出,是因为Redis将日志记录到一个文件而不是记录到标准输出。可以使用之前创建的/var/log/redis卷查看。
。查看日志
--&docker run -it --rm --volumes-from redis_primary jamtur01/redis_primary cat /var/log/redis/redis-server.log
这里以交互方式运行了另一个容器,这个命令指定了--rm标志,它会在进程运行完后自动删除容器。
--volumes-from:告诉它从redis_primary容器挂载了所有的卷。
ubuntu:指定的基础镜像,告诉执行cat /var/log/redis/redis-server.log来展示日志文件。
这种方法利用了卷的优点,可以直接从redis_primary容器挂载/var/log/redis目录并读取里面的日志文件。
。创建redis从服务
--&docker run -d -h redis_replical --name redis_replical --link redis_primary:redis_primary jamtur01/redis_replica
e90c86dde89a76fbc912d264440fae9a82c093cd9df413d879f463
这里从jamtur01/redis_replica镜像运行了另一个容器。命令里指定了主机名(通过-h标志)和容器名(通过--name标志)都是
redis_replical。使用了--link标志将redis_primary容器以别名redis_primary连接到了Redis从容器。
。查看容器日志
--&docker run -ti --rm --volumes-from redis_replical jamtur01/redis_replica cat /var/log/redis/redis-replica.log
这里通过交互的方式运行了一个新容器来查询日志。
--rm:它在命令执行完毕后自动删除容器。
--volumes-from:挂载了redis_replical 容器的所有卷
ubuntu:为指定的镜像
cat /var/log/redis..: 指定日志文件的内容。
最终成功运行了redis_primary容器和redis_replical容器,并让其互为备份。
。加入另一个从服务器redis_replica2来确保万无一失。
--&docker run -d -h redis_replica2 --name redis_replica2 --link redis_primary:redis_primary jamtur01/redis_replica
9fa16e8ba208cfa2c4be71d05ea6bfc7
。查看新容器的日志:
--&docker run -ti --rm --volumes-from redis_replica2 jamtur01/redis_replica cat /var/log/redis/redis-replica.log
6.3.6 创建Node容器
现在已经让Redis集群运行了,可以启动Node.js应用启动一个容器:
--&docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fa16e8ba208 jamtur01/redis_replica "redis-server '--log About a minute ago Up About a minute 6379/tcp redis_replica2
e90c86dde89a jamtur01/redis_replica "redis-server '--log 5 minutes ago Up 5 minutes 6379/tcp redis_replical
c293a244ea1f jamtur01/redis_primary "redis-server '--log 35 minutes ago Up 35 minutes 6379/tcp redis_primary
--&docker run -d --name nodeapp -p
--link redis_primary:redis_primary jamtur01/nodejs
1a00ab7dcd4eeaaade65310
从jamtur01/nodejs 镜像启动创建了一个新容器,命名为nodeapp,并将容器内的3000端口映射到宿主机的3000端口,
然后将redis_primary容器以别名redis_primary连接到新的nodeapp容器。
。查看容器日志
--&docker logs nodeapp
Listening on port 3000
。Web访问容器3000端口
--&http://192.168.1.72:3000/,显示如下:
"status": "ok"
这个输出表明应用正在工作。浏览器的会话状态会先被记录到Redis主容器redis_primary,然后同步到两个Redis从
服务容器redis_replical和redis_replica2。
6.37 捕获应用日志
现在应用已经可以运行了,需要把这个应用放到生成环境中。在生产环境里需要确保可以捕获日志将日志保存到日志
服务器。使用Logstash来完成这件事。
参考:https://www.elastic.co/products/logstash
--&wget https://download.elastic.co/logstash/logstash/packages/debian/logstash_1.4.5-1-a2bacae_all.deb
--&wget https://download.elastic.co/logstash/logstash/logstash-1.5.4.tar.gz
。创建Logstash镜像
--&mkdir logstash
--&cd logstash
--&vim Dockerfile
FROM ubuntu:14.04
MAINTAINER James Turnbull &&
ENV REFRESHED_AT
RUN apt-get update
RUN apt-get -y install wget
RUN wget -O - http://packages.elasticsearch.org/GPG-KEY-elasticsearch | apt-key add -
RUN echo 'deb http://packages.elasticsearch.org/logstash/1.4/debian stable main' & /etc/apt/sources.list.d/logstash.list
RUN apt-get update
RUN apt-get -y install logstash
ADD logstash.conf /etc/
RN mkdir /opt/logstash
WORKDIR /opt/logstash
ENTRYPOINT [ "bin/logstash" ]
CMD [ "--config=/etc/logstash.conf" ]
创建了镜像并安装了Logstash,然后将logstash.conf文件使用ADD指令添加到/etc/目录。
接着指定了工作目录为/opt/logstash,通过CMD指定了启动参数--config=/etc/logstash.conf,
这个启动命令会启动Logstash并载入/etc/logstash.conf配置文件。
。查看logstash.conf
--&cat logstash.conf
type =& "syslog"
path =& ["/var/log/nodeapp/nodeapp.log", "/var/log/redis/redis-server.log"]
codec =& rubydebug
此配置文件监控两个文件,即/var/log/nodeapp/nodeapp.log和/var/log/redis/redis-server.log。
Logstash会一直监视这两个文件,将其中新的内容发送给Logstash。配置文件中的第二部分是output部分,
接受所有Logstash输入的内容并将其输出到标准输出上。现实中,一般会将Logstash配置为输出到Elasticsearch
集群或者其它目的地,不过这里只使用标准输出做演示,忽略现实的细节。
。构造镜像
--&docker build -t jamtur01/logstash .
Sending build context to Docker daemon 3.584 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
---& 3f126a502d09
Step 1 : MAINTAINER James Turnbull &&
---& Using cache
---& 10b317f5826d
Step 2 : ENV REFRESHED_AT
---& Running in 88e21669df1d
---& a6f7faa5761f
Removing intermediate container 88e21669df1d
Step 3 : RUN apt-get update
---& Running in de46156bec80
。从镜像启动一个容器
--&docker run -d --name logstash --volumes-from redis_primary --volumes-from nodeapp jamtur01/logstash
这个容器使用--volume-from标志两次,挂载了redis_primary和nodeapp里的卷,这样就可以访问Redis和Node的日志
文件了。任何加到这些日志文件里的内容都会反应在logstash容器里的卷里,并传给Logstash做后续处理。
。查看输出日志
--&docker logs -f logstash
。浏览器访问容器Web
--&http://192.168.1.72:3000/ ,然后刷新页面,产生一个新的日志事件
--&docker logs -f logstash
现在Node和Redis容器都将日志输出到了Logstash。在生产环境中,这些事件会发到Logstash服务器并存储在Elasticsearch
里。如果要加入新的Redis从服务器容器或者其他组件,也可以很容易地将日志输出到日志容器里。
注意:如果需要,可以通过卷对Redis做备份。
6.3.8 Node程序栈的小结
6.4 不使用SSH管理Docker容器
可以使用卷或者链接完成大部分同样的管理操作,如果服务通过某个网络接口做管理,就可以在启动容器时公开这个接口,
如果服务通过Unix套接字(socket)来管理,就可以通过卷公开这个套接字。如果需要给容器发送信号,可以使用dcoker kill这样
发送信号。
docker kill -s
这个操作会发送指定的信号(如HUP信号)给容器,而不是杀掉容器。需要再次登入容器时,可以使用一个叫nsenter的小工作。
注意:nsenter一般适用于Docker 1.2或者更早的版本。docker exec命令是在Docker 1.3中引入的,替换了它的大部分功能。
工具nsenter可以进入Docker用来构建容器的内核命名空间。这个工具可以进入一个已经存在的命名空间,或者在新的一组命名
空间里执行一个进程。简单来说,使用nsenter可以进入一个已经存在的容器的shell,即便这个容器没有运行SSH或者任何类似目的
守护进程。可以通过Docker容器安装nsenter。
--&docker run -v /usr/local/bin:/target jpetazzo/nsenter
这会把nsenter安装到/usr/local/bin目录下,然后立刻就可以使用这个命令。
为了使用nsenter,首先要拿到要进入容器的进程ID(PID)。可以使用docker inspect命令获得PID。
PID=$(docker inspect --format {{.State.Pid}} )
然后就可以进入容器:
--&nsenter --target $PID --mount --uts --ipc --net --pid
这会在容器启动一个shell,而不需要SSH或者其他类似的守护进程或者进程。
还可以将想在容器内执行的命令添加到nsenter命令行的后面:
--&nsenter --target $PID --mount -uts -ipc --net --pid ls
这会在目标容器内执行ls命令。
如无特殊说明,文章均为本站原创,转载请注明出处,谢谢配合!
本文标题:
本文永久链接地址:
让学习成为习惯,坚持-共享-开源-自由!
成功者决不放弃,放弃者绝不成功!
日志总数:123
评论总数:19136 条
标签数量:69 个
友链总数:0 个
运行天数:1710 天
最后更新:
当前没有在线用户
订阅本站,获取最新资讯

我要回帖

更多关于 war3进不去弹出来 的文章

 

随机推荐