Docker技术入门与实战 第11章 Web服务与应用

本章会展示两种创建镜像的过程,其中一些操作比较简单的镜像使用Dockerfile来创建,而像Weblogic这样复杂的应用,则使用commit方式来创建,读者可根据自己的需求进行选择。

通过本章的介绍,用户操作可以根据自己需求轻松定制Web服务或应用镜像。

11.2 Apache

   Apache  是一个高稳定性的、商业级别的开源Web服务器。目前Apache已经是巨世界使用排名第一的Web服务器软件。由于其良好的跨平台和安全性。Apache被广泛应用在多种平台和操作系统上。作为Apache软件基金会支持的项目,这的开发者社区完善而高效。自1995年发布至今,一直以高标准进行维护与开发。Apache名 称源自美国西南部一个印第安人部落:阿帕奇族,它支持类UNIX和Window系统。

编写Dockerfile文件,内容如下:

FROM httpd:2.4
COPY ./public-html /usr/local/apache2/htdocs/

创建项目目录public-html,并在此目录下创建index.html文件:


        
                
                        

Hello,Docker!

构建自定义镜像:

[root@localhost ~]# docker build -t apache2-image .

构建完成后,使用docker run指令运行镜像:

[root@localhost ~]# docker run -it --rm --name apahce-container -p 80:80 apache2-image

通过本地的80端口即可访问静态页面,如图11-1所示。

Docker技术入门与实战 第11章 Web服务与应用_第1张图片

                    图11-1 Apache 运行界面

也可以不创建自定义镜像,直接通过映射目录方式运行Apache容器:

[root@localhost ~]# docker run -it --rm --name my-apache -p 8080:80 -v "$PWD"/public-html:/usr/local/apache2/htdocs httpd:2.4

2.使用自定义镜像

首先,创建一个apache_ubuntu工作目录,在其中创建Dockerfile文件、run.sh文件和sample目录:

[root@localhost ~]# mkdir apache_ubuntu && cd apache_ubuntu
[root@localhost apache_ubuntu]# touch Dockerfile run.sh

下面是Dockerfile的内容和各个部分的说明:

#设置继承用户创建的sshd镜像
FROM sshd:dockerfile
#创建者基本信息
MAINTAINER [email protected]
#设置环境变量,所有操作都是非交互的
ENV DEBIAN_FRONTEND noninteractive
#安装
RUN apt-get -yq install apache2 && \
 rm -rf /var/lib/apt/lists/*
#注意这里要更改系统的时区设置,因为在web应用中经常会用到时区这个系统变量,默认的ubuntu会让你的应用程序发生不可思议的后果
RUN echo "Asia/Shanghai" > /etc/timezone && \
        dpkg-reconfigure -f noninteractive tzdata
#添加用户脚本,并设置权限,这会覆盖之前在这个位置的脚本
ADD run.sh /run.sh
RUN chmod 755 /*.sh
#添加一个示例的web站点,删掉默认安装在apahce文件下面文件,并将应用添加到示例中,用软链接到/var/www/html目录下面
RUN mkdir -p /var/lock/apache2 && mkdir -p /app && rm -rf /var/www/html && ln -s /app /var/www/html
COPY sample/ /app
#设置apache相关的一些变量,在容器启动的时候可以使用-e参数替代
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
ENV APACHE_SERVERADMIN  admin@localhost
ENV APACHE_SERVERNAME localhost
ENV APACHE_SERVERALIAS docker.localhost
ENV APACHE_DOCUMENTROOT /var/www
EXPOSE 80
WORKDIR /app
CMD ["run.sh"]

 此sample站点的内容为输出Hello Docker!。然后在sample目录下创建inde.html,内容如下:




        
                

Hello,Docker!

run.sh脚本内容也很简单,只是启动apache服务

#!/bin/bash
exec apache2 -D FOREGROUND

此时,apache_ubuntu目录下面的文件结构为:

[root@localhost apache_ubuntu]# tree .
.
├── Dockerfile
├── index.html
├── run.sh
└── sample

1 directory, 3 files

下面,创建apache_ubuntu镜像:

#docker build -t apahce:ubuntu .

下面开始使用docker run指令测试镜像。可以使用-P参数映射需要开放的端口(22和80端口):

[root@localhost apache_ubuntu]# docker run -d -P apache:ubuntu
80f0b3f9d01bda0b96c019bee6a48b627a45979b3d26b8b840e1eaf38d72dd43
[root@localhost apache_ubuntu]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                          NAMES
80f0b3f9d01b        apache:ubuntu       "/run.sh"           7 seconds ago       Up 4 seconds        0.0.0.0:32771->22/tcp, 0.0.0.0:32770->80/tcp   stupefied_bose

在本地上使用curl抓取网页来验证刚才创建的sample站点

[root@localhost apache_ubuntu]# curl 127.0.0.1:32770


        
                

Hello,Docker!

读者也可以在其他设备上通过访问宿主主机ip:32770来访问sample站点。

不知道有没有细心的读者发现,在apache镜像的Dockerfile中只用EXPOSE定义了对外开放的80端口,而在docker ps -a命令的返回中,却看到新启动的内容映射了两个端口:22和80。

但是实际上,当尝试使用SSH登录到容器时,会发现无法登录。这是因为在run.sh脚本中并未启动SSH服务。这说明在使用Dockerfile创建镜像时,会继承父镜像的开放端口,但却不会继承启动命令。因此,需要在run.sh脚本中添加启动sshd的服务

命令

#!/bin/bash
/usr/bin/sshd & exec apache2 -D FOREGROUND

再次创建镜像:

[root@localhost apache_ubuntu]# docker build -t apache:ubuntu . 

这次创建的镜像,将默认会同时启动SSH和Apache服务。

   下面,来看看如何映射本地目录。可以通过映射本地目录的方式,来指定容器内Apache服务响应的内容,例如映射本地主机上当前目录下的www目录到容器的/var/www目录:


[root@localhost ~]# docker run -i -d -P -e APACHE_SERVERNAME=test -v `pwd`/www:/var/www/html apache:ubuntu

在当前目录内创建 www目录,并放上定义的页面index.html,内容如下:



        
                

HI,DOcker

This is the first day I meet the new world

Huw are you?


在本地主机上可访问测试容器提供的Web服务,查看获取内容为新配置的index.html页面信息。


11.2 Nginx

1.使用官方镜像

    用户可以使用docker run指令直接运行官方Nginx镜像 :

[root@localhost ~]# docker run -d -p 80:80 --name webserver nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
f2aa67a397c4: Pull complete 
3c091c23e29d: Pull complete 
4a99993b8636: Pull complete 
Digest: sha256:0fb320e2a1b1620b4905facb3447e3d84ad36da0b2c8aa8fe3a5a81d1187b884
Status: Downloaded newer image for nginx:latest
54214f78667d8f9a197de3244cb698329ef673ebd050ce0bced39f917602869f
然后使用docker ps指令查看当前运行的docker ps 指令查看当前运行的内容:
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                          NAMES
54214f78667d        nginx               "nginx -g 'daemon of…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp                             webserver

目前,Nginx容器已经在0.0.0.80启动,并映射了80端口,此时可以打开浏览器访问此地址,就可以看到Nginx输出的页面,如图11-2所示:

Docker技术入门与实战 第11章 Web服务与应用_第2张图片

                                        图11-2 访问Nginx服务

2.自定义Web界面

同样的,创建index.html文件,并将index.html文件挂载至容器中,即可看到显示自定义的页面。

[root@localhost ~]# docker run -i -d -P -v `pwd`/www:/usr/share/nginx/html nginx

另外,也可以使用Dockerfile来构建新镜像。Dockerfile内容如下:

FROM nginx
COPY ./index.html /usr/share/nignx/html
[root@localhost nginx_dockerfile]# docker search tomcat | wc -l
26

开始构建镜像my-nginx:

[root@localhost nginx_dockerfile]# docker build -t my-nginx .

    构建成功后执行docker run指令:

[root@localhost nginx_dockerfile]# docker run --name nginx-container -d my-nginx

11.3  Tomcat

Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照Sun Mircosystems提供的技术规范,实现了对Servlet和Java Server Page(JSP)的支持。同时,它提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等。由于Tomcat本身也内含了一个HTTP服务器,也可以当作一个单独的Web服务器来使用。下面介绍如何定制Tomcat镜像。

首先,尝试的Docker Hubh 搜索已有的Tomcat相关镜像的个数:

[root@localhost nginx_dockerfile]# docker search tomcat | wc -l
26

下面能Tomcat 8.0 为例介绍定制Tomcat镜像的步骤。

1.准备工作

 创建tomcat_ubuntu文件夹,从www.oracle.com网站上下载sun_jdk 1.8压缩包,下载tomcat压缩包

[root@localhost tomcat_ubuntu]# ll
总用量 195788
-rw-r--r--. 1 root root   9552281 4月  28 04:47 apache-tomcat-8.5.31.tar.gz
-rw-r--r--. 1 root root       727 5月  19 12:24 Dockerfile
-rw-r--r--. 1 root root 190921804 3月  30 03:45 jdk-8u172-linux-x64.tar.gz

创建Dockerfile

FROM ubuntu:14.04
MAINTAINER tjjingpan  
# now add java and tomcat support in the container 
ADD apache-tomcat-8.5.31.tar.gz /usr/local/ 
ADD jdk-8u172-linux-x64.tar.gz /usr/local/ 
# configuration of java and tomcat ENV 
ENV JAVA_HOME /usr/local/jdk1.8.0_172 
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.31 
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.31 
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin 
# container listener port 
EXPOSE 8080
# startup web application services by self 
CMD /usr/local/apache-tomcat-8.5.31/bin/catalina.sh run
创建docker镜像
docker build -t tjjingpan/tomcat-web .
docker run -P  tjjingpan/tomcat-web:latest
[root@localhost tomcat_ubuntu]# docker ps -a
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                                          NAMES
11a176f47455        tjjingpan/tomcat-web:latest   "/bin/sh -c '/usr/lo…"   12 minutes ago      Up 12 minutes       0.0.0.0:32805->8080/tcp                        epic_haibt


Docker技术入门与实战 第11章 Web服务与应用_第3张图片

_____________________________________________________________________________________________________

原书生成方法

[root@localhost tomcat_ubuntu_1]# ls
apache-tomcat-8.5.31  create_tomcat_admin_user.sh  Dockerfile  jdk1.8.0_172  run.sh

Dockerfile文件

FROM registry.cn-hangzhou.aliyuncs.com/tjjingpan/ubuntu:14.04
MAINTAINER tjjingpan  
#设置环境变量,所有操作都是非交互的
ENV DEBIAN_FRONTEND noninteractive
#注意这里要更改系统的时区设置
RUN echo "Asia/Shanghai" > /etc/timezone && \
        dpkg-reconfigure -f noninteractive tzdata
#安装跟tomcat用户认证相关的软件
RUN apt-get install -yq --no-install-recommends wget pwgen ca-certificates && \
        apt-get clean && \
        rm -rf /var/lib/apt/lists/*
# now add java and tomcat support in the container 
#设置tomcat环境变量,若读者有其他的环境变量需要设置,也可以在这里添加。
ENV CATALINA_HOME /tomcat
ENV JAVA_HOME   /jdk
#复制tomcat和jdk文件到镜像中
ADD apache-tomcat-8.5.31 /tomcat
ADD jdk1.8.0_172 /jdk
ADD create_tomcat_admin_user.sh /create_tomcat_admin_user.sh
ADD run.sh /run.sh
RUN chmod +x /*.sh
RUN chmod +x /tomcat/bin/*.sh
EXPOSE 8080
CMD ["/run.sh"]

create_tomcat_admin_user.sh文件

[root@localhost tomcat_ubuntu_1]# cat create_tomcat_admin_user.sh 
#! /bin/bash
if [ -f /.tomcat_admin_created ]; then
    echo "Tomcat 'admin' user already created"
    exit 0
fi
#generate password
PASS=${TOMCAT_PASS:-$(pwgen -s 12 1)}
_word=$( [ ${TOMCAT_PASS} ] && echo "preset" || echo "random" )
echo "=> Creating and admin user with a ${_word} password in Tomcat"
sed -i -r 's/<\/tomcat-users>//' ${CATALINA_HOME}/conf/tomcat-users.xml
echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo "" >> ${CATALINA_HOME}/conf/
    tomcat-users.xml
echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo "=> Done! "
touch /.tomcat_admin_created
echo "========================================================================"
echo "You can now configure to this Tomcat server using:"
echo ""
echo "     admin:${PASS}"
echo ""
echo "========================================================================"

run.sh文件

[root@localhost tomcat_ubuntu_1]# cat run.sh 
#!/bin/bash
if [ ! -f /.tomcat_admin_created ]; then
    /create_tomcat_admin_user.sh
fi
/usr/sbin/sshd -D &
exec ${CATALINA_HOME}/bin/catalina.sh run


11.4 Jetty

Jetty是一个优秀的开源Servlet容器,以其高效,小巧,可嵌入式等优点深得人心,这为基于Java的Web内容(如JSP和Servlet)提供运行环境。Jetty基于Java语言编写,它的API以一组JAR包的形式发布,开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行的Java应用提供Web服务。

相对于老牌的Tomcat,Jetty架构更合理,性能更优。尤其在启动速度上,主Tomcat望尘莫及。Jetty目前在国内外互联网企业中应用广泛。

DockerHub官方提供了Jetty镜像,直接运行docker run指令即可:

[root@localhost tomcat_ubuntu_1]# docker run -d -P jetty
[root@localhost tomcat_ubuntu_1]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
a37e12a44150        jetty               "/docker-entrypoint.…"   7 seconds ago       Up 4 seconds        0.0.0.0:32846->8080/tcp   wonderful_meitner

Docker技术入门与实战 第11章 Web服务与应用_第4张图片

由于当前没有内容,会提示错误信息。


11.5 LAMP

可以使用自定义Dockerfile或者Compose方式运行LAMP,同时社区提供十分成熟的linode/lamp和tutum/lamp镜像。下面介绍后两种方法。

1.使用linode/lamp镜像

首先,执行docker run 指令,直接运行镜像,并进入容器内bash shell:

[root@localhost tomcat_ubuntu_1]# docker run -it -p 80:80 linode/lamp /bin/bash
root@b14b7825762b:/# 

在容器内部shell启动apache以及mysql服务:

root@b14b7825762b:/# service apache2 start
 * Starting web server apache2                                                                                                                                                                                   * 
root@b14b7825762b:/# service mysql start
 * Starting MySQL database server mysqld                                                                                                                                                                 [ OK ] 
 * Checking for tables which need an upgrade, are corrupt or were 
not closed cleanly.

此时镜像中apache、mysql服务已经启动,可使用docker ps 指令查看运行中的容器:

[root@localhost tomcat_ubuntu_1]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
b14b7825762b        linode/lamp         "/bin/bash"              5 minutes ago       Up 5 minutes        0.0.0.0:80->80/tcp        awesome_neumann
[root@localhost tomcat_ubuntu_1]# 



此时通过浏览器访问本地80端口即可看到默认页面.


2.使用tutum/lamp镜像

首先,执行docker run指令,直接运行镜像;

Docker技术入门与实战 第11章 Web服务与应用_第5张图片


11.6 CMS

Wordpress和Ghost

1.使用官方镜像

下载官方镜像

[root@localhost ~]# docker pull wordpress

然后,就可以创建并运行一个wrodpress容器

[root@localhost ~]# docker run --name some-wordpress  -d -p 80:80 wordpress

Docker技术入门与实战 第11章 Web服务与应用_第6张图片

ghost

[root@localhost ~]# docker run --name ghost-container -P -d ghost

Docker技术入门与实战 第11章 Web服务与应用_第7张图片

11.7 持续开发与管理

信息行业日新月异,如何响应不断变化需求,快速适应和保证软件的质量?持续集成(Continuous integration,CI)正是针对这类问题的一种开发实践,它倡导开发团队定期进行集成验证。集成通过自动化的构建来完成,包括自动编译、发布和测试,从而尽快地发现错误。CI所描述的软件开发是从原始需求识别到最终产品部署整个过程中,需求以小批量形式在团队的各个角色间顺畅流动,能够以较短地周期完成需求的小粒度频繁交付。整个过程中,需求分析、产品的用户体验和交互设计、开发、测试、运维等角色需要密切协作。

持续集成特点包括:从检出代码、编译构建、运行测试、结果记录、统计等都是自动完成的,减少人工干预。需要有持续集成系统的支持,包括代码托管机制支持,以及集成服务器等。

持续交付(Continuous delivery, CD)则是经典的敏捷软件开发方法的自然延伸,它强调产品在修改后到部署上线的流程要敏捷化、自动化。甚至一些较小的改变也要尽早的部署上线。这跟传统软件在较大版本更新后才上线的思想不同。

11.7.1 Jenkins

11.7.2 Gitlab

11.8

笔者认为:包括Web服务在内的中间件领域十分适合引入容器技术,原因如下:

    中间件服务器是除数据库服务外的主要计算节点,很容易成为性能瓶颈,所以通常需要大批量部署,而Docker对于批量部署有着许多先天的优势。

    中间件服务器结构清晰,在剥离了配置文件、日志、代码目录之后,容器几乎可以处于零增长状态,这使得容器的迁移和批量部署更加方便;

中间件服务器很容易实现集群,

在实践过程中,读者需要注意数据的持久化,对于程序代码、程序的资源目录、日志、数据库文件等需要 实时更新的数据一定要通过-v参数映射到宿主主机的目录中来,避免发生数据丢失和带来性能下降。

你可能感兴趣的:(Docker技术入门与实战)