怎么使用Docker构建服务
这篇文章给大家分享的是有关怎么使用Docker构建服务的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
6.1 使用Jekyll框架和Apache构建应用
需要构建两个镜像:
一个镜像安装了Jekyll以及其他用于构建Jekyll网站的必要的软件包;
一个镜像通过Apache来让Jekyll网站工作起来。
工作流程如下:
创建Jekyll基础镜像和Apache镜像;
从Jekyll镜像创建一个容器,这个容器存放通过卷挂载的网站源代码;
从Apache镜像创建一个容器,这个容器利用包含编译后的网站的卷为其创建服务;
在网站需要更新时,清理并重复上面的步骤。
这个例子可以看做是创建一个多主机站点最简单的方法。
1、Jekyll基础镜像
建立构建环境:
mkdir jekyllcd jekylltouch Dockerfile
编写Dockerfile:
FROM ubuntu:14.04MAINTAINER James TurnbullRUN apt-get -yqq updateRUN apt-get -yqq install ruby ruby-dev make nodejsRUN gem install --no-rdoc --no-ri jekyll -v 2.5.3VOLUME /dataVOLUME /var/www/htmlWORKDIR /dataENTRYPOINT [ "jekyll", "build", "--destination=/var/www/html" ]
注意书上的代码 gem jekyll 后面没有 -v 2.5.3,会报错。
在Dockerfile中使用VOLUME指令创建了两个卷:
/data/,用于存放网站源代码;
/var/www/html/,用于存放编译后的Jekyll网站码。
最后,将工作目录指定为/data,并通过ENTRYPOINT指令指定自动构建的命令,这个命令将工作目录/data/中所有的Jekyll网站代码构建到/var/www/html/目录中。
2、构建Jekyll基础镜像
docker build -t ivan/jekyll .
3、Apache镜像
建立构建环境:
mkdir apachecd apachetouch Dockerfile
编写Dockerfile:
FROM ubuntu:14.04MAINTAINER James TurnbullRUN apt-get -yqq updateRUN apt-get -yqq install apache2VOLUME [ "/var/www/html" ]WORKDIR /var/www/htmlENV APACHE_RUN_USER www-dataENV APACHE_RUN_GROUP www-dataENV APACHE_LOG_DIR /var/log/apache2ENV APACHE_PID_FILE /var/run/apache2.pidENV APACHE_RUN_DIR /var/run/apache2ENV APACHE_LOCK_DIR /var/lock/apache2RUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIREXPOSE 80ENTRYPOINT [ "/usr/sbin/apache2" ]CMD ["-D", "FOREGROUND"]
使用了VOLUME指令创建了一个卷--/var/www/html/,这个目录是用来存放编译后的jekyll网站的;
最后指定了ENTRYPOINT和CMD指令组合来在容器启动时默认运行apache。
4、构建Apache镜像
docker build -t ivan/apache .
5、启动Jekyll网站
首先将Jekyll的一些源代码下载:
cd ~git clone https://github.com/jamtur01/james_blog.git
然后启动容器:
docker run -v ~/james_blog:/data/ --name james_blog ivan/jekyll
把刚才从github上下载的james_blog目录作为卷挂载到/data(目录里有jekyll网站的源码)。
这里再复习一下卷,卷是在一个或多个容器中特殊指定的目录,卷会绕过联合文件系统,为持久化数据和共享数据提供几个有用的特性:
卷可以在容器间共享和共用;
共享卷时不一定要运行相应的容器;
对卷的修改会直接在卷上反映出来;
更新镜像时不会包含对卷的修改;
卷会一直存在,直到没有容器使用它们。
卷在Docker宿主机的/var/lib/docker/volumes目录中,通过docker inspect命令可以查看某个卷的具体位置:
docker inspect -f "{{.Volumes}}"
如果想在另一个容器里使用/var/www/html/卷里编译好的网站,可以创建一个新的容器连接到这个卷(即Apache容器):
docker run -d -P --volumes-from james_blog ivan/apache
--volumes-from标志把指定容器里所有的卷加入新建的容器里。
如果删除了最后一个使用卷的容器,卷就被删除了。所以删除有卷的容器时要小心。
这样整个服务就启动好了。
6、备份Jekyll卷
上文说道删除容器可能不小心将卷删除了。所以可以利用一下命令备份卷:
docker run --rm --volumes-from james_blog -v $(pwd):/backup ubuntu tar cvf /backup/james_blog_backup.tar /var/www/html
--rm命令表示该容器只使用一次,运行完后就删除。
将当前目录挂载到/backup,这样在容器中将数据打包到/backup后,该包其实就在当前目录下。
tar cvf命令会创建一个名为james_blog_backup.tar的tar文件(该文件包含了/var/www/html目录里的所有内容)。
7、扩展Jekyll示例
运行多个Apache容器,这些容器都使用james_blog容器的卷,在这些Apache容器前面加一个负载均衡器,就拥有了Web集群;
进一步构建一个镜像,这个镜像把用户提供的源数据复制到卷里,再把这个卷挂载到jekyll容器里。这就是一个可迁移的通用方案,而且宿主机本地包含任何源代码;
在上一个扩展基础上为我们的服务构建一个Web前段,这个服务用语从指定的源自动构建和部署网站。
6.2 构建一个Java应用服务(Tomcat)
1、WAR文件获取器
创建构建环境
mkdir fetchercd fetchertouch Dockerfile
编写Dockerfile
FROM ubuntu:14.04MAINTAINER Ivan JiangENV REFRESHED_AT 2016-07-13 RUN apt-get -yqq updateRUN apt-get -yqq install wget VOLUME ["/var/lib/tomcat7/webapps/"]WORKDIR /var/lib/tomcat7/webapps/ ENTRYPOINT ["wget"]CMD ["--help"]
容器执行时,使用wget从指定的URL获取文件,并把它保存在/var/lib/tomcat7/webapps目录。如果运行容器时没有指定URL,ENTRYPOINT和CMD指令组合起来返回wget的帮助。
2、获取WAR文件
docke run -t -i --name sample ivan/fetcher https://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war
3、构建Tomcat7应用服务器
创建构建环境:
mkdir tomcat7cd tomcat7touch Dockerfile
编写Dockerfile:
FROM ubuntu:14.04MAINTAINER Ivan JiangENV REFRESHED_AT 2016-07-13 RUN apt-get -yqq updateRUN apt-get -yqq install tomcat7 default-jdk ENV CATALINA_HOME /usr/share/tomcat7ENV CATALINA_BASE /var/lib/tomcat7ENV CATALINA_PID /var/run/tomcat7.pidENV CATALINA_SH /usr/share/tomcat7/bin/catalina.shENV 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"]
构建镜像:
docker build -t ivan/tomcat7 .
4、运行tomcat7容器
docker run --name sample_app --volumes-from sample -d -P ivan/tomcat7
查看映射到宿主机的端口号:
docker port sample_app 8080
假设端口号是49154,在浏览器访问:IP地址:49154/sample可查看运行的web app。
在例子中作者使用了命令:
docker inspect -f "{{.Volumes}}" sample
查看sample卷的宿主机挂载位置,但是这个命令报错。
OSChina上的TimWang回答我的问题说Docker 1.8将Volumes信息从docker inspect 的输出中删除了,需改用Mounts:
docker inspect -f "{{.Mounts}}" sample
6.3 多容器的应用栈
1、Node.js镜像
创建构建环境:
mkdir nodejscd nodejstouch Dockerfile
编写Dockerfile:
FROM ubuntu:14.04MAINTAINER James TurnbullENV REFRESHED_AT 2014-06-01RUN apt-get -yqq updateRUN apt-get -yqq install nodejs npmRUN ln -s /usr/bin/nodejs /usr/bin/nodeRUN mkdir -p /var/log/nodeappADD nodeapp /opt/nodeapp/WORKDIR /opt/nodeappRUN npm installVOLUME [ "/var/log/nodeapp" ]EXPOSE 3000ENTRYPOINT [ "nodejs", "server.js" ]
用ln -s建立软连接,把二进制文件modejs连接到node,解决Ubuntu上原有的一些无法向后兼容问题(不懂……)。
构建镜像:
docker build -t ivan/nodejs .
2、Redis基础镜像
mkdir redis_basecd redis_basetouch Dockerfile
FROM ubuntu:14.04MAINTAINER James TurnbullENV REFRESHED_AT 2014-06-01RUN apt-get -yqq updateRUN apt-get install -yqq software-properties-common python-software-propertiesRUN add-apt-repository ppa:chris-lea/redis-serverRUN apt-get -yqq updateRUN apt-get -yqq install redis-server redis-toolsVOLUME [ "/var/lib/redis", "/var/log/redis" ]EXPOSE 6379CMD []
docker build -t ivan/redis .
3、Redis主镜像
mkdir redis_primarycd redis_primarytouch Dockerfile
FROM ivan/redisMAINTAINER James TurnbullENV REFRESHED_AT 2014-06-01ENTRYPOINT [ "redis-server", "--logfile /var/log/redis/redis-server.log" ]
docker build -t ivan/redis_primary
4、Redis从镜像
mkdir redis_replicacd redis_replicatouch Dockerfile
FROM ivan/redisMAINTAINER James TurnbullENV REFRESHED_AT 2014-06-01ENTRYPOINT [ "redis-server", "--logfile /var/log/redis/redis-replica.log", "--slaveof redis_primary 6379" ]
docker build -t ivan/redis_replica .
5、创建Redis集群
启动Redis主镜像
docker run -d -h redis-primary --name redis_primary ivan/redis_primary
这里使用-h参数指定容器的主机名,书中给出的是redis_primary,但是执行会报错,应该是新版本的Docker不支持带下划线的主机名,这里改为redis-primary。
启动Redis从服务
docker run -d -h redis-replical --name redis_replical --link redis_primary:redis_primary ivan/redis_replica
这里对-h参数做相同的处理。
6、创建Node容器
docker run -d --name nodeapp -p 3000:3000 --link redis_primary:redis_primary ivan/nodejs
在浏览器中用 宿主机IP:3000测试。
7、捕获应用日志
使用Logstash捕获日志并将日志保存到日志服务器。
mkdir logstashcd logstashtouch Dockerfile
FROM ubuntu:14.04MAINTAINER James TurnbullENV REFRESHED_AT 2014-06-01RUN apt-get -yqq updateRUN apt-get -yqq install wgetRUN 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.listRUN apt-get -yqq updateRUN apt-get -yqq install logstashADD logstash.conf /etc/WORKDIR /opt/logstashENTRYPOINT [ "bin/logstash" ]CMD [ "--config=/etc/logstash.conf" ]
Logstash监控两个文件/var/log/nodeapp/nodeapp.log和/var/log/redis/redis-server.log,将其中的新内容捕获,捕获到的内容输出到标准输出上。现实中一般会将Logstash的内容输出到Elasticsearch集群。
构建之前将作者的logstash.conf下载到构建根目录。
构建镜像
docker build -t ivan/logstash .
启动容器
docker run -d --name logstash --volumes-from redis_primary --volumes-from nodeapp ivan/logstash
查看logstash容器的输出日志
docker logs -f logstash
6.4 不使用SSH管理Docker容器
传统上,使用SSH登入运行环境或者虚拟机管理服务。在Docker里,大部分容器只运行一个进程,所以不能使用这种方法。可是使用卷或者链接完成大部分管理操作。如需要给容器发送信号,可以使用docker kill命令:
docker kill -s
这个操作会发送指定的信号给容器,而不是杀掉容器。
可以使用nsenter小工作登入容器,它一般适用于1.2或更早的版本,1.3版本引入的docker exec替换了它大部分的功能。
工具nsenter可以进入Docker用来构成容器的内核命名空间。它可以进入一个已经存在的命名空间,或者在新的一组命名空间里执行一个进程。
可以通过Docker容器安装nsenter:
docker run -v /usr/local/bin:/target jpetazzo/nsenter
这会把nsenter安装到/usr/local/bin目录下。
为了使用nsenter,首先要知道要进入的容器的进程ID,可以使用docker inspect命令获得进程PID:
PID=$(docker inspect --format {{.State.Pid}})
然后运行下面的命令进入容器:
nsenter --target $PID --mount --uts --ipc --net --pid
也可以将容器内执行的命令添加在nsenter命令行的后面:
nsenter --target $PID --mount --uts --ipc --net --pid ls
感谢各位的阅读!关于"怎么使用Docker构建服务"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!