Docker安装及简易使用教程(适用于Ubuntu及Windows 10系统)

2020年10月11日 99 字 教程整理


Docker是一种开源且流行的操作系统级虚拟化(俗称“容器化”)技术,主要在Linux和Windows上运行。 Docker使用容器可以更轻松地创建,部署和运行应用程序。
在本文中将记录在Ubuntu/Windows 10系统安装Docker CE(Community Edition)及Docker Desktop的过程,以及常见的使用命令。

1. Docker的安装

1.1. 在Ubuntu系统安装Docker

1.1.1. 自动安装

安装命令如下:

curl -fsSL https://get.docker.com | bash -s docker

也可以使用国内 daocloud 一键安装命令:

curl -sSL https://get.daocloud.io/docker | sh

1.1.2. 手动安装

1.1.2.1. 卸载旧版本应用

Docker 的旧版本被称为 docker,docker.io 或 docker-engine 。如果已安装,需卸载它们:

sudo apt-get remove docker docker-engine docker.io containerd runc

1.1.2.2. 设置Docker仓库

先更新apt索引:

sudo apt-get update

安装 apt 依赖包,用于通过HTTPS来获取仓库:

sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

添加 Docker 的官方 GPG 密钥:

curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

通过搜索指纹的后8个字符: 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88,验证您现在是否拥有带有指纹的密钥:

sudo apt-key fingerprint 0EBFCD88

最后可以使用以下指令设置稳定版仓库:

sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/ $(lsb_release -cs) stable"

1.1.2.3. 安装Docker Engine-Community

首先更新apt-package索引:

sudo apt-get update

安装最新版本的 Docker Engine-Communitycontainerd:

sudo apt-get install docker-ce docker-ce-cli containerd.io

接下来即可测试Docker是否安装成功。
输入以下指令,如能打印出以下信息则安装成功:

sudo docker run hello-world
root@VM-16-2-ubuntu:~# sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

root@VM-16-2-ubuntu:~#

1.2. Docker Desktop (以Docker Desktop for Windows为例)

Docker Engine最初是为Linux系统开发的;随着产品版本的更新和扩展,Docker逐渐开始支持在Windows 和 Apples操作系统运行。
Docker为Windows和Mac系统提供了一个桌面本地应用程序管理的安装包(Docker Desktop for Windows / Docker Desktop for Mac),为这两类系统提供了一个简单易用的环境,支持容器化应用及微服务在本地环境的的构建、运输、运行和共享。

需注意的是,Docker Desktop并不是‘Windows或Mac版本的Docker Engine’, 更不是简单的‘Docker GUI’;它是一个针对Windows或Mac 桌面/客户端SKU的解决方案(而不是生产环境)。 Docker Desktop的安装包则同时包含Docker Engine, Docker CLI Client, Docker Compose, Docker Machine, Notary, KubernetesCredential Helper

只要Docker Desktop应用在Windows/Mac 系统上在运行, Docker即可在终端使用。通过Docker Desktop自带的UI界面, 可以对配置参数进行相关设置:

1.2.1. 安装及运行环境需求

1.2.1.1. Windows10 (x64) + Hyper-V

Docker Desktop for Windows 支持64位版本的Windows 10Windows Server 2019;且运行其间需同时开启Hyper-V服务(如果没有开启,当手动切换到Windows Container的时候也会自动开启该服务)。

1.2.1.2. 系统配置

CPU需包含SLAT功能;在BIOS中启用虚拟化; 以及运行内存需4G及以上。

如果系统不符合运行Docker Desktop for Windows的基本环境需求,则可以安装Docker Toolbox为替代;它使用的是Oracle Virtual Box而不是Hyper-V。

1.2.2. 安装步骤

1.2.2.1. 获取安装程序

进入Docker 官网: https://www.docker.com/ , 获取Docker Desktop下载路径: https://www.docker.com/products/docker-desktop

安装程序也可以通过DockerHub获取: https://hub.docker.com/editions/community/docker-ce-desktop-windows/

1.2.2.2. 开始安装

待安装程序下载完成即可启动安装文件(Docker Desktop Installer.exe):

安装程序启动后会先下载相关的package。
待相关package下载完成之后, 一路点击next即可, 直至程序安装完成。

安装完成后桌面即可看到Docker Desktop图标:

双击图标即可开始使用Docker Desktop。

2. Docker使用示例

2.1. Docker安装MySQL数据库

‘ 查询镜像

docker search mysql

     

‘ 从仓库中拉取镜像

docker pull mysql

    

‘ 查看镜像

docker images

    

‘ 创建并运行一个容器:

‘ -p [PORT]:3306 将本机的 [PORT] 端口映射到 mysql 容器的 3306 端口,根据需要自行更改;

‘ -e MYSQL_ROOT_PASSWORD=[MYSQL PASSWORD] 设置远程登录的 root 用户密码;

‘ –name [Container-Name] (可选参数)设置容器别名;

‘ -v [localSQLDConfPath]/mysql.d:/etc/mysql/conf.d 目录挂载; 将本地目录下设置文件夹映射到容器的 /etc/mysql/conf.d

docker run -d -p [PORT]:3306 -e MYSQL_ROOT_PASSWORD=[MYSQL PASSWORD] -v [localSQLDConfPath]/mysql.d:/etc/mysql/conf.d --name [Container-Name] mysql

‘ 例:

docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=database@Container1-11889 -v /home/Docker_Containers/Configs/MySQLDataBaseContainer-1/mysql.d:/etc/mysql/conf.d --name MySQLDataBase-Container-1 mysql  

此时使用docker container lsdocker ps 命令即可看到当前container (mysql: 3307)已运行成功:

安装完成后即可使用Navicat或命令行访问数据库:

2.2. Docker部署Nginx + Tomcat架构

2.2.1. 安装Nginx服务器

‘ 搜索nginx镜像

docker search nginx

‘ 拉取nginx镜像

docker pull nginx:latest

‘ 根据nginx镜像创建nginx容器

docker run --name [Container-Name] -d -p [PORT]:80 nginx

‘ 例:

docker run --name Nginx-Container-2 -d -p 82:80 nginx

2.2.2. 安装JDK环境 及Tomcat 容器

安装Tomcat容器之前须确保系统已安装JDK环境。

JDK的版本信息可以通过java -version命令查看:

接下来即可开始安装Tomcat:

‘ 搜索tomcat镜像

docker search tomcat

‘ 拉取tomcat镜像

docker pull tomcat:latest

‘ 根据镜像启动tomcat容器
docker run –name [Container-Name] -d -v [localWebappsConfPath]/webapps:/usr/local/tomcat/webapps tomcat

‘ 例:
docker run –name Tomcat-Container-3 -d -v /var/lib/webapps:/usr/local/tomcat/webapps tomcat

2.2.2.1. * Docker安装Tomcat无法访问问题的解决

使用docker安装tomcat时可能会遇到无法访问tomcat的问题: 查看container状态完好,但通过curl 命令或浏览器仍无法请求Tomcat主页:

这是因为使用docker pull tomact下载的tomcat镜像中包含有两个webapps文件夹:一个文件夹名为webapps,但是这个文件夹是空的(所以请求http://localhost:8080页面时无法找到对应的root文件夹),另外一个文件夹名为webapps.dist,这个路径里面才是tomcat完整的文件夹和文件。

我们需要做的是将目录webapps.dist内部的全部文件复制到webapps路径下,然后将webapps.dist文件夹删除即可。

cp -r webapps.dist/* ./webapps
rm -rf webapps.dist

此时再请求http://localhost:8080, Tomcat主页即可正常访问:

如手动调整上述路径, 在tomcat容器停止重新启动后,还会再次出现这两个文件夹。

更合适的方法是通过commit操作创建自己的镜像, 后续创建新的Container依据自己的镜像即可:

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

如:

docker commit -a="Shawn" -m="tomcat_modified" 0e5320738cfe tomcat9:9.1

2.2.3. 配置 Nginx+Tomcat upstream

安装完成后,获取tomcat容器IP:

docker inspect [Container-Name]|grep "IPAddress"
docker inspect Tomcat-Container-3|grep "IPAddress"

将获取到的Tomcat-IP配置到nginx的配置文件中即可。

首先进入Nginx容器:

docker exec -ti Nginx-Container-2 /bin/bash

接下来修改nginx的配置文件:

cd etc/nginx/conf.d/

vim default.conf

重启Nginx服务器, 即可访问tomcat:

2.2.3.0.1. * 开启多个Tomcat容器

之前在没有使用Docker的时候,如果想要开启多个tomcat服务器,需要先复制tomcat相关文件目录,再进入tomcat的配置文件中修改有关端口的配置,非常麻烦,费时费力。
现在,使用Docker,只需要在启动容器的时候指定端口映射,就可以开启多个tomcat服务器了。 只需一条命令就可以代替以前的很多麻烦的操作。这也是Docker的强大之处之一。

例:输入下面的3条命令,就可以开启3个tomcat服务器:

docker run --name Tomcat-Container-4 -d -v /var/lib/webapps:/usr/local/tomcat/webapps tomcat
docker run --name Tomcat-Container-5 -d -v /var/lib/webapps:/usr/local/tomcat/webapps tomcat
docker run --name Tomcat-Container-6 -d -v /var/lib/webapps:/usr/local/tomcat/webapps tomcat

2.3. 使用Docker搭建Nginx-Tomcat集群

2.3.1. 创建日志/配置文件及webapps应用文件目录

首先创建tomcat日志/配置文件:

mkdir /data/[tomcat_server_name]/{catalina_logs,app_logs,conf,bin} -pv

如:

mkdir /usr/local/tomcat_server_colony/colony_1001/tomcat_1/{catalina_logs,app_logs,conf,bin} -pv


mkdir /usr/local/tomcat_server_colony/colony_1001/tomcat_2/{catalina_logs,app_logs,conf,bin} -pv

接下来开始创建webapps应用目录:

mkdir /usr/local/tomcat_server_colony/colony_1001/webapps/{tomcat_1,tomcat_2} -pv

创建好webapps目录, 分别向两个路径添加index.jsp文件:

tomcat_1: /usr/local/tomcat_server_colony/colony_1001/webapps/tomcat_1/index.jsp

<%@ page language="java" %>

<html>

  <head><title>Tomcat_1</title></head>

  <body>

<h1><font color="red">Tomcat_1.example.com</h1>

<table align="centre" border="1">

  <tr>

<td>Session ID</td>

<% session.setAttribute("example.com","example.com"); %>

<td><%= session.getId() %></td>

  </tr>

  <tr>

<td>Created on</td>

<td><%= session.getCreationTime() %></td>

 </tr>

</table>

  </body>

</html>

tomcat_2: /usr/local/tomcat_server_colony/colony_1001/webapps/tomcat_2/index.jsp

<%@ page language="java" %>

<html>

  <head><title>tomcat_2</title></head>

  <body>

<h1><font color="green">tomcat_2.example.com</h1>

<table align="centre" border="1">

  <tr>

<td>Session ID</td>

<% session.setAttribute("example.com","example.com"); %>

<td><%= session.getId() %></td>

  </tr>

  <tr>

<td>Created on</td>

<td><%= session.getCreationTime() %></td>

 </tr>

</table>

  </body>

</html>

2.3.2. 创建配置文件

首先,创建一个tomcat-container作为配置模板, 并访问容器:

docker run --name tomcat-sample --rm -it docker.io/tomcat /bin/bash
' -rm 选项可以在容器退出的时候直接删除容器

新开启一个SSH终端(由于上一命令参数设置, 如使用exit命令退出当前container, container将会被删除),复制相应的配置文件至对应tomcat单机的配置目录:

docker cp tomcat-sample:/usr/local/tomcat/conf/server.xml /usr/local/tomcat_server_colony/colony_1001/tomcat_1/conf/

docker cp tomcat-sample:/usr/local/tomcat/bin/catalina.sh /usr/local/tomcat_server_colony/colony_1001/tomcat_1/bin/


docker cp tomcat-sample:/usr/local/tomcat/conf/server.xml /usr/local/tomcat_server_colony/colony_1001/tomcat_2/conf/

docker cp tomcat-sample:/usr/local/tomcat/bin/catalina.sh /usr/local/tomcat_server_colony/colony_1001/tomcat_2/bin/

docker cp 完成后, tomcat-sample容器即可退出(退出即自动删除此container)。

2.3.3. 调整tomcat单机配置文件参数

如:

  • ../bin/catalina.sh文件添加JDK参数;
  • 调整../conf/server.xml文件port/unpackWARs/docBase等参数配置。

例:

vim /usr/local/tomcat_server_colony/colony_1001/tomcat_1/bin/catalina.sh
#!/usr/bin/env bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# -----------------------------------------------------------------------------
# Control Script for the CATALINA Server
#
# For supported commands call "catalina.sh help" or see the usage section at
# the end of this file.
#
# Environment Variable Prerequisites
#
#   Do not set the variables in this script. Instead put them into a script
#   setenv.sh in CATALINA_BASE/bin to keep your customizations separate.
#
#   CATALINA_HOME   May point at your Catalina "build" directory.
#
#   CATALINA_BASE   (Optional) Base directory for resolving dynamic portions
#   of a Catalina installation.  If not present, resolves to
#   the same directory that CATALINA_HOME points to.
#
#   CATALINA_OUT(Optional) Full path to a file where stdout and stderr
#   will be redirected.
#   Default is $CATALINA_BASE/logs/catalina.out
#
#   CATALINA_OUT_CMD (Optional) Command which will be executed and receive
#   as its stdin the stdout and stderr from the Tomcat java
#   process. If CATALINA_OUT_CMD is set, the value of
#   CATALINA_OUT will be used as a named pipe.
#   No default.
#   Example (all one line)
#   CATALINA_OUT_CMD="/usr/bin/rotatelogs -f $CATALINA_BASE/logs/catalina.out.%Y-%m-%d.log 86400"
#
#   CATALINA_OPTS   (Optional) Java runtime options used when the "start",
#   "run" or "debug" command is executed.
#   Include here and not in JAVA_OPTS all options, that should
#   only be used by Tomcat itself, not by the stop process,
#   the version command etc.
#   Examples are heap size, GC logging, JMX ports etc.
#
#   CATALINA_TMPDIR (Optional) Directory path location of temporary directory
#   the JVM should use (java.io.tmpdir).  Defaults to
#   $CATALINA_BASE/temp.
#
#   JAVA_HOME   Must point at your Java Development Kit installation.
#   Required to run the with the "debug" argument.
#
#   JRE_HOMEMust point at your Java Runtime installation.
#   Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME
#   are both set, JRE_HOME is used.
#
#   JAVA_OPTS   (Optional) Java runtime options used when any command
#   is executed.
#   Include here and not in CATALINA_OPTS all options, that
#   should be used by Tomcat and also by the stop process,
#   the version command etc.
#   Most options should go into CATALINA_OPTS.
#
#   JAVA_ENDORSED_DIRS (Optional) Lists of of colon separated directories
#   containing some jars in order to allow replacement of APIs
#   created outside of the JCP (i.e. DOM and SAX from W3C).
#   It can also be used to update the XML parser implementation.
#   This is only supported for Java <= 8.
#   Defaults to $CATALINA_HOME/endorsed.
#
#   JPDA_TRANSPORT  (Optional) JPDA transport used when the "jpda start"
#   command is executed. The default is "dt_socket".
#
#   JPDA_ADDRESS(Optional) Java runtime options used when the "jpda start"
#   command is executed. The default is localhost:8000.
#
#   JPDA_SUSPEND(Optional) Java runtime options used when the "jpda start"
#   command is executed. Specifies whether JVM should suspend
#   execution immediately after startup. Default is "n".
#
#   JPDA_OPTS   (Optional) Java runtime options used when the "jpda start"
#   command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
#   and JPDA_SUSPEND are ignored. Thus, all required jpda
#   options MUST be specified. The default is:
#
#   -agentlib:jdwp=transport=$JPDA_TRANSPORT,
#   address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND
#
#   JSSE_OPTS   (Optional) Java runtime options used to control the TLS
#   implementation when JSSE is used. Default is:
#   "-Djdk.tls.ephemeralDHKeySize=2048"
#
#   CATALINA_PID(Optional) Path of the file which should contains the pid
#   of the catalina startup java process, when start (fork) is
#   used
#
#   CATALINA_LOGGING_CONFIG (Optional) Override Tomcat's logging config file
#   Example (all one line)
#   CATALINA_LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
#
#   LOGGING_CONFIG  Deprecated
#   Use CATALINA_LOGGING_CONFIG
#   This is only used if CATALINA_LOGGING_CONFIG is not set
#   and LOGGING_CONFIG starts with "-D..."
#
#   LOGGING_MANAGER (Optional) Override Tomcat's logging manager
#   Example (all one line)
#   LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
#
#   UMASK   (Optional) Override Tomcat's default UMASK of 0027
#
#   USE_NOHUP   (Optional) If set to the string true the start command will
#   use nohup so that the Tomcat process will ignore any hangup
#   signals. Default is "false" unless running on HP-UX in which
#   case the default is "true"
# -----------------------------------------------------------------------------


JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx512m -Duser.timezone=Asia/Shanghai"


# OS specific support.  $var _must_ be set to either true or false.
cygwin=false
darwin=false
os400=false
hpux=false
case "`uname`" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
HP-UX*) hpux=true;;
esac

# resolve links - $0 may be a softlink
PRG="$0"

while [ -h "$PRG" ]; do
  ls=`ls -ld "$PRG"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
  else
PRG=`dirname "$PRG"`/"$link"
  fi
done

# Get standard environment variables
PRGDIR=`dirname "$PRG"`

# Only set CATALINA_HOME if not already set
[ -z "$CATALINA_HOME" ] && CATALINA_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`

# Copy CATALINA_BASE from CATALINA_HOME if not already set
[ -z "$CATALINA_BASE" ] && CATALINA_BASE="$CATALINA_HOME"

# Ensure that any user defined CLASSPATH variables are not used on startup,
# but allow them to be specified in setenv.sh, in rare case when it is needed.
CLASSPATH=

if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
  . "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
  . "$CATALINA_HOME/bin/setenv.sh"
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin; then
  [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  [ -n "$JRE_HOME" ] && JRE_HOME=`cygpath --unix "$JRE_HOME"`
  [ -n "$CATALINA_HOME" ] && CATALINA_HOME=`cygpath --unix "$CATALINA_HOME"`
  [ -n "$CATALINA_BASE" ] && CATALINA_BASE=`cygpath --unix "$CATALINA_BASE"`
  [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi

# Ensure that neither CATALINA_HOME nor CATALINA_BASE contains a colon
# as this is used as the separator in the classpath and Java provides no
# mechanism for escaping if the same character appears in the path.
case $CATALINA_HOME in
  *:*) echo "Using CATALINA_HOME:   $CATALINA_HOME";
   echo "Unable to start as CATALINA_HOME contains a colon (:) character";
   exit 1;
esac
case $CATALINA_BASE in
  *:*) echo "Using CATALINA_BASE:   $CATALINA_BASE";
   echo "Unable to start as CATALINA_BASE contains a colon (:) character";
   exit 1;
esac

# For OS400
if $os400; then
  # Set job priority to standard for interactive (interactive - 6) by using
  # the interactive priority - 6, the helper threads that respond to requests
  # will be running at the same priority as interactive jobs.
  COMMAND='chgjob job('$JOBNAME') runpty(6)'
  system $COMMAND

  # Enable multi threading
  export QIBM_MULTI_THREADED=Y
fi

# Get standard Java environment variables
if $os400; then
  # -r will Only work on the os400 if the files are:
  # 1. owned by the user
  # 2. owned by the PRIMARY group of the user
  # this will not work if the user belongs in secondary groups
  . "$CATALINA_HOME"/bin/setclasspath.sh
else
  if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then
. "$CATALINA_HOME"/bin/setclasspath.sh
  else
echo "Cannot find $CATALINA_HOME/bin/setclasspath.sh"
echo "This file is needed to run this program"
exit 1
  fi
fi

# Add on extra jar files to CLASSPATH
if [ ! -z "$CLASSPATH" ] ; then
  CLASSPATH="$CLASSPATH":
fi
CLASSPATH="$CLASSPATH""$CATALINA_HOME"/bin/bootstrap.jar

if [ -z "$CATALINA_OUT" ] ; then
  CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
fi

if [ -z "$CATALINA_TMPDIR" ] ; then
  # Define the java.io.tmpdir to use for Catalina
  CATALINA_TMPDIR="$CATALINA_BASE"/temp
fi

# Add tomcat-juli.jar to classpath
# tomcat-juli.jar can be over-ridden per instance
if [ -r "$CATALINA_BASE/bin/tomcat-juli.jar" ] ; then
  CLASSPATH=$CLASSPATH:$CATALINA_BASE/bin/tomcat-juli.jar
else
  CLASSPATH=$CLASSPATH:$CATALINA_HOME/bin/tomcat-juli.jar
fi

# Bugzilla 37848: When no TTY is available, don't output to console
have_tty=0
if [ -t 0 ]; then
have_tty=1
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
  JAVA_HOME=`cygpath --absolute --windows "$JAVA_HOME"`
  JRE_HOME=`cygpath --absolute --windows "$JRE_HOME"`
  CATALINA_HOME=`cygpath --absolute --windows "$CATALINA_HOME"`
  CATALINA_BASE=`cygpath --absolute --windows "$CATALINA_BASE"`
  CATALINA_TMPDIR=`cygpath --absolute --windows "$CATALINA_TMPDIR"`
  CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
  [ -n "$JAVA_ENDORSED_DIRS" ] && JAVA_ENDORSED_DIRS=`cygpath --path --windows "$JAVA_ENDORSED_DIRS"`
fi

if [ -z "$JSSE_OPTS" ] ; then
  JSSE_OPTS="-Djdk.tls.ephemeralDHKeySize=2048"
fi
JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS"

# Register custom URL handlers
# Do this here so custom URL handles (specifically 'war:...') can be used in the security policy
JAVA_OPTS="$JAVA_OPTS -Djava.protocol.handler.pkgs=org.apache.catalina.webresources"

# Check for the deprecated LOGGING_CONFIG
# Only use it if CATALINA_LOGGING_CONFIG is not set and LOGGING_CONFIG starts with "-D..."
if [ -z "$CATALINA_LOGGING_CONFIG" ]; then
  case $LOGGING_CONFIG in
-D*) CATALINA_LOGGING_CONFIG="$LOGGING_CONFIG"
  esac
fi

# Set juli LogManager config file if it is present and an override has not been issued
if [ -z "$CATALINA_LOGGING_CONFIG" ]; then
  if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then
CATALINA_LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
  else
# Bugzilla 45585
CATALINA_LOGGING_CONFIG="-Dnop"
  fi
fi

if [ -z "$LOGGING_MANAGER" ]; then
  LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
fi

# Set UMASK unless it has been overridden
if [ -z "$UMASK" ]; then
UMASK="0027"
fi
umask $UMASK

# Java 9 no longer supports the java.endorsed.dirs
# system property. Only try to use it if
# JAVA_ENDORSED_DIRS was explicitly set
# or CATALINA_HOME/endorsed exists.
ENDORSED_PROP=ignore.endorsed.dirs
if [ -n "$JAVA_ENDORSED_DIRS" ]; then
ENDORSED_PROP=java.endorsed.dirs
fi
if [ -d "$CATALINA_HOME/endorsed" ]; then
ENDORSED_PROP=java.endorsed.dirs
fi

# Make the umask available when using the org.apache.catalina.security.SecurityListener
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask`"

if [ -z "$USE_NOHUP" ]; then
if $hpux; then
USE_NOHUP="true"
else
USE_NOHUP="false"
fi
fi
unset _NOHUP
if [ "$USE_NOHUP" = "true" ]; then
_NOHUP="nohup"
fi

# Add the JAVA 9 specific start-up parameters required by Tomcat
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.base/java.lang=ALL-UNNAMED"
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.base/java.io=ALL-UNNAMED"
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"
export JDK_JAVA_OPTIONS

# ----- Execute The Requested Command -----------------------------------------

# Bugzilla 37848: only output this if we have a TTY
if [ $have_tty -eq 1 ]; then
  echo "Using CATALINA_BASE:   $CATALINA_BASE"
  echo "Using CATALINA_HOME:   $CATALINA_HOME"
  echo "Using CATALINA_TMPDIR: $CATALINA_TMPDIR"
  if [ "$1" = "debug" ] ; then
echo "Using JAVA_HOME:   $JAVA_HOME"
  else
echo "Using JRE_HOME:$JRE_HOME"
  fi
  echo "Using CLASSPATH:   $CLASSPATH"
  echo "Using CATALINA_OPTS:   $CATALINA_OPTS"
  if [ ! -z "$CATALINA_PID" ]; then
echo "Using CATALINA_PID:$CATALINA_PID"
  fi
fi

if [ "$1" = "jpda" ] ; then
  if [ -z "$JPDA_TRANSPORT" ]; then
JPDA_TRANSPORT="dt_socket"
  fi
  if [ -z "$JPDA_ADDRESS" ]; then
JPDA_ADDRESS="localhost:8000"
  fi
  if [ -z "$JPDA_SUSPEND" ]; then
JPDA_SUSPEND="n"
  fi
  if [ -z "$JPDA_OPTS" ]; then
JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"
  fi
  CATALINA_OPTS="$JPDA_OPTS $CATALINA_OPTS"
  shift
fi

# TODO: Bugzilla 63815
# This doesn't currently work (and can't be made to work) if values used in
# CATALINA_OPTS and/or JAVA_OPTS require quoting. See:
# https://bugs.openjdk.java.net/browse/JDK-8234808
if [ "$1" = "debug" ] ; then
  if $os400; then
echo "Debug command not available on OS400"
exit 1
  else
shift
if [ "$1" = "-security" ] ; then
  if [ $have_tty -eq 1 ]; then
echo "Using Security Manager"
  fi
  shift
  exec "$_RUNJDB" "$CATALINA_LOGGING_CONFIG" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-D$ENDORSED_PROP="$JAVA_ENDORSED_DIRS" \
-classpath "$CLASSPATH" \
-sourcepath "$CATALINA_HOME"/../../java \
-Djava.security.manager \
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start
else
  exec "$_RUNJDB" "$CATALINA_LOGGING_CONFIG" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-D$ENDORSED_PROP="$JAVA_ENDORSED_DIRS" \
-classpath "$CLASSPATH" \
-sourcepath "$CATALINA_HOME"/../../java \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start
fi
  fi

elif [ "$1" = "run" ]; then

  shift
  if [ "$1" = "-security" ] ; then
if [ $have_tty -eq 1 ]; then
  echo "Using Security Manager"
fi
shift
eval exec "\"$_RUNJAVA\"" "\"$CATALINA_LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
  -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
  -classpath "\"$CLASSPATH\"" \
  -Djava.security.manager \
  -Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \
  -Dcatalina.base="\"$CATALINA_BASE\"" \
  -Dcatalina.home="\"$CATALINA_HOME\"" \
  -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  org.apache.catalina.startup.Bootstrap "$@" start
  else
eval exec "\"$_RUNJAVA\"" "\"$CATALINA_LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
  -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
  -classpath "\"$CLASSPATH\"" \
  -Dcatalina.base="\"$CATALINA_BASE\"" \
  -Dcatalina.home="\"$CATALINA_HOME\"" \
  -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  org.apache.catalina.startup.Bootstrap "$@" start
  fi

elif [ "$1" = "start" ] ; then

  if [ ! -z "$CATALINA_PID" ]; then
if [ -f "$CATALINA_PID" ]; then
  if [ -s "$CATALINA_PID" ]; then
echo "Existing PID file found during start."
if [ -r "$CATALINA_PID" ]; then
  PID=`cat "$CATALINA_PID"`
  ps -p $PID >/dev/null 2>&1
  if [ $? -eq 0 ] ; then
echo "Tomcat appears to still be running with PID $PID. Start aborted."
echo "If the following process is not a Tomcat process, remove the PID file and try again:"
ps -f -p $PID
exit 1
  else
echo "Removing/clearing stale PID file."
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
  if [ -w "$CATALINA_PID" ]; then
cat /dev/null > "$CATALINA_PID"
  else
echo "Unable to remove or clear stale PID file. Start aborted."
exit 1
  fi
fi
  fi
else
  echo "Unable to read PID file. Start aborted."
  exit 1
fi
  else
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
  if [ ! -w "$CATALINA_PID" ]; then
echo "Unable to remove or write to empty PID file. Start aborted."
exit 1
  fi
fi
  fi
fi
  fi

  shift
  if [ -z "$CATALINA_OUT_CMD" ] ; then
touch "$CATALINA_OUT"
  else
if [ ! -e "$CATALINA_OUT" ]; then
  if ! mkfifo "$CATALINA_OUT"; then
echo "cannot create named pipe $CATALINA_OUT. Start aborted."
exit 1
  fi
elif [ ! -p "$CATALINA_OUT" ]; then
  echo "$CATALINA_OUT exists and is not a named pipe. Start aborted."
  exit 1
fi
$CATALINA_OUT_CMD <"$CATALINA_OUT" &
  fi
  if [ "$1" = "-security" ] ; then
if [ $have_tty -eq 1 ]; then
  echo "Using Security Manager"
fi
shift
eval $_NOHUP "\"$_RUNJAVA\"" "\"$CATALINA_LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
  -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
  -classpath "\"$CLASSPATH\"" \
  -Djava.security.manager \
  -Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \
  -Dcatalina.base="\"$CATALINA_BASE\"" \
  -Dcatalina.home="\"$CATALINA_HOME\"" \
  -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  org.apache.catalina.startup.Bootstrap "$@" start \
  >> "$CATALINA_OUT" 2>&1 "&"

  else
eval $_NOHUP "\"$_RUNJAVA\"" "\"$CATALINA_LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
  -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
  -classpath "\"$CLASSPATH\"" \
  -Dcatalina.base="\"$CATALINA_BASE\"" \
  -Dcatalina.home="\"$CATALINA_HOME\"" \
  -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  org.apache.catalina.startup.Bootstrap "$@" start \
  >> "$CATALINA_OUT" 2>&1 "&"

  fi

  if [ ! -z "$CATALINA_PID" ]; then
echo $! > "$CATALINA_PID"
  fi

  echo "Tomcat started."

elif [ "$1" = "stop" ] ; then

  shift

  SLEEP=5
  if [ ! -z "$1" ]; then
echo $1 | grep "[^0-9]" >/dev/null 2>&1
if [ $? -gt 0 ]; then
  SLEEP=$1
  shift
fi
  fi

  FORCE=0
  if [ "$1" = "-force" ]; then
shift
FORCE=1
  fi

  if [ ! -z "$CATALINA_PID" ]; then
if [ -f "$CATALINA_PID" ]; then
  if [ -s "$CATALINA_PID" ]; then
kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1
if [ $? -gt 0 ]; then
  echo "PID file found but either no matching process was found or the current user does not have permission to stop the process. Stop aborted."
  exit 1
fi
  else
echo "PID file is empty and has been ignored."
  fi
else
  echo "\$CATALINA_PID was set but the specified file does not exist. Is Tomcat running? Stop aborted."
  exit 1
fi
  fi

  eval "\"$_RUNJAVA\"" $LOGGING_MANAGER "$JAVA_OPTS" \
-D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
-classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$@" stop

  # stop failed. Shutdown port disabled? Try a normal kill.
  if [ $? != 0 ]; then
if [ ! -z "$CATALINA_PID" ]; then
  echo "The stop command failed. Attempting to signal the process to stop through OS signal."
  kill -15 `cat "$CATALINA_PID"` >/dev/null 2>&1
fi
  fi

  if [ ! -z "$CATALINA_PID" ]; then
if [ -f "$CATALINA_PID" ]; then
  while [ $SLEEP -ge 0 ]; do
kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1
if [ $? -gt 0 ]; then
  rm -f "$CATALINA_PID" >/dev/null 2>&1
  if [ $? != 0 ]; then
if [ -w "$CATALINA_PID" ]; then
  cat /dev/null > "$CATALINA_PID"
  # If Tomcat has stopped don't try and force a stop with an empty PID file
  FORCE=0
else
  echo "The PID file could not be removed or cleared."
fi
  fi
  echo "Tomcat stopped."
  break
fi
if [ $SLEEP -gt 0 ]; then
  sleep 1
fi
if [ $SLEEP -eq 0 ]; then
  echo "Tomcat did not stop in time."
  if [ $FORCE -eq 0 ]; then
echo "PID file was not removed."
  fi
  echo "To aid diagnostics a thread dump has been written to standard out."
  kill -3 `cat "$CATALINA_PID"`
fi
SLEEP=`expr $SLEEP - 1 `
  done
fi
  fi

  KILL_SLEEP_INTERVAL=5
  if [ $FORCE -eq 1 ]; then
if [ -z "$CATALINA_PID" ]; then
  echo "Kill failed: \$CATALINA_PID not set"
else
  if [ -f "$CATALINA_PID" ]; then
PID=`cat "$CATALINA_PID"`
echo "Killing Tomcat with the PID: $PID"
kill -9 $PID
while [ $KILL_SLEEP_INTERVAL -ge 0 ]; do
kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1
if [ $? -gt 0 ]; then
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
if [ -w "$CATALINA_PID" ]; then
cat /dev/null > "$CATALINA_PID"
else
echo "The PID file could not be removed."
fi
fi
echo "The Tomcat process has been killed."
break
fi
if [ $KILL_SLEEP_INTERVAL -gt 0 ]; then
sleep 1
fi
KILL_SLEEP_INTERVAL=`expr $KILL_SLEEP_INTERVAL - 1 `
done
if [ $KILL_SLEEP_INTERVAL -lt 0 ]; then
echo "Tomcat has not been killed completely yet. The process might be waiting on some system call or might be UNINTERRUPTIBLE."
fi
  fi
fi
  fi

elif [ "$1" = "configtest" ] ; then

eval "\"$_RUNJAVA\"" $LOGGING_MANAGER "$JAVA_OPTS" \
  -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
  -classpath "\"$CLASSPATH\"" \
  -Dcatalina.base="\"$CATALINA_BASE\"" \
  -Dcatalina.home="\"$CATALINA_HOME\"" \
  -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  org.apache.catalina.startup.Bootstrap configtest
result=$?
if [ $result -ne 0 ]; then
echo "Configuration error detected!"
fi
exit $result

elif [ "$1" = "version" ] ; then

"$_RUNJAVA"   \
  -classpath "$CATALINA_HOME/lib/catalina.jar" \
  org.apache.catalina.util.ServerInfo

else

  echo "Usage: catalina.sh ( commands ... )"
  echo "commands:"
  if $os400; then
echo "  debug Start Catalina in a debugger (not available on OS400)"
echo "  debug -security   Debug Catalina with a security manager (not available on OS400)"
  else
echo "  debug Start Catalina in a debugger"
echo "  debug -security   Debug Catalina with a security manager"
  fi
  echo "  jpda startStart Catalina under JPDA debugger"
  echo "  run   Start Catalina in the current window"
  echo "  run -security Start in the current window with security manager"
  echo "  start Start Catalina in a separate window"
  echo "  start -security   Start in a separate window with security manager"
  echo "  stop  Stop Catalina, waiting up to 5 seconds for the process to end"
  echo "  stop nStop Catalina, waiting up to n seconds for the process to end"
  echo "  stop -force   Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running"
  echo "  stop n -force Stop Catalina, wait up to n seconds and then use kill -KILL if still running"
  echo "  configtestRun a basic syntax check on server.xml - check exit code for result"
  echo "  version   What version of tomcat are you running?"
  echo "Note: Waiting for the process to end and use of the -force option require that \$CATALINA_PID is defined"
  exit 1

fi
vim /usr/local/tomcat_server_colony/colony_1001/tomcat_1/conf/server.xml
<Host name="localhost" appBase="webapps"

unpackWARs="true" autoDeploy="true">

<Context path="" docBase="tomcat_1" reloadable="false" />#指定项目包的路径

<!-- SingleSignOn valve, share authentication between web applications

 Documentation at: /docs/config/valve.html -->

<!--

<Valve className="org.apache.catalina.authenticator.SingleSignOn" />

-->

<!-- Access log processes all example.

 Documentation at: /docs/config/valve.html

 Note: The pattern used is equivalent to using pattern="common" -->

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

   prefix="localhost_access_log" suffix=".txt"

   pattern="%h %l %u %t &quot;%r&quot; %s %b" />

  </Host>

.......
vim /usr/local/tomcat_server_colony/colony_1001/tomcat_2/conf/server.xml
<Host name="localhost" appBase="webapps"

unpackWARs="true" autoDeploy="true">

<Context path="" docBase="tomcat_2" reloadable="false" />#指定项目包的路径

<!-- SingleSignOn valve, share authentication between web applications

 Documentation at: /docs/config/valve.html -->

<!--

<Valve className="org.apache.catalina.authenticator.SingleSignOn" />

-->

<!-- Access log processes all example.

 Documentation at: /docs/config/valve.html

 Note: The pattern used is equivalent to using pattern="common" -->

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

   prefix="localhost_access_log" suffix=".txt"

   pattern="%h %l %u %t &quot;%r&quot; %s %b" />

  </Host>

.......

2.3.4. 创建tomcat单机Container

docker run -p 8080:8080 --name tomcat_1 \
    --memory 512M \
    -d \
    -v /usr/local/tomcat_server_colony/colony_1001/tomcat_1/catalina_logs/:/usr/local/tomcat/logs/ \
    -v /usr/local/tomcat_server_colony/colony_1001/tomcat_1/app_logs/:/usr/local/logs \
    -v /usr/local/tomcat_server_colony/colony_1001/webapps/:/usr/local/tomcat/webapps/ \
    -v /usr/local/tomcat_server_colony/colony_1001/tomcat_1/conf/server.xml:/usr/local/tomcat/conf/server.xml \
    -v /usr/local/tomcat_server_colony/colony_1001/tomcat_1/bin/catalina.sh:/usr/local/tomcat/bin/catalina.sh \
    docker.io/tomcat
docker run -p 8081:8080 --name tomcat_2 \
    --memory 512M \
    -d \
    -v /usr/local/tomcat_server_colony/colony_1001/tomcat_2/catalina_logs/:/usr/local/tomcat/logs/ \
    -v /usr/local/tomcat_server_colony/colony_1001/tomcat_2/app_logs/:/usr/local/logs \
    -v /usr/local/tomcat_server_colony/colony_1001/webapps/:/usr/local/tomcat/webapps/ \
    -v /usr/local/tomcat_server_colony/colony_1001/tomcat_2/conf/server.xml:/usr/local/tomcat/conf/server.xml \
    -v /usr/local/tomcat_server_colony/colony_1001/tomcat_2/bin/catalina.sh:/usr/local/tomcat/bin/catalina.sh \
    docker.io/tomcat

2.3.5. 配置tomcat-cluster配置参数

修改tomcat单机../conf/server.xml文件,在host配置段中添加cluster配置段:

例:

vim /usr/local/tomcat_server_colony/colony_1001/tomcat_1/conf/server.xml
<Host name="localhost" appBase="webapps"

unpackWARs="true" autoDeploy="true">

<Context path="" docBase="tomcat_1" reloadable="false" />

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

   prefix="localhost_access_log" suffix=".txt"

   pattern="%h %l %u %t &quot;%r&quot; %s %b" />

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"

 channelSendOptions="8">

  <Manager className="org.apache.catalina.ha.session.DeltaManager"

   expireSessionsOnShutdown="false"

   notifyListenersOnReplication="true"/>

  <Channel className="org.apache.catalina.tribes.group.GroupChannel">

<Membership className="org.apache.catalina.tribes.membership.McastService"

address="228.0.0.4"

port="45565"

frequency="50"

dropTime="3000"/>

<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"

  address="auto"

  port="4001"

  autoBind="100"

  selectorTimeout="5000"

  maxThreads="10"/>

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">

  <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>

</Sender>

<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>

<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>

  </Channel>

  <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"

 filter=""/>

  <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

  <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>

</Cluster>

  </Host>
vim /usr/local/tomcat_server_colony/colony_1001/tomcat_2/conf/server.xml
<Host name="localhost" appBase="webapps"

unpackWARs="true" autoDeploy="true">

<Context path="" docBase="tomcat_2" reloadable="false" />

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

   prefix="localhost_access_log" suffix=".txt"

   pattern="%h %l %u %t &quot;%r&quot; %s %b" />

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"

 channelSendOptions="8">

  <Manager className="org.apache.catalina.ha.session.DeltaManager"

   expireSessionsOnShutdown="false"

   notifyListenersOnReplication="true"/>

  <Channel className="org.apache.catalina.tribes.group.GroupChannel">

<Membership className="org.apache.catalina.tribes.membership.McastService"

address="228.0.0.4"

port="45565"

frequency="50"

dropTime="3000"/>

<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"

  address="auto"

  port="4001"

  autoBind="100"

  selectorTimeout="5000"

  maxThreads="10"/>

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">

  <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>

</Sender>

<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>

<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>

  </Channel>

  <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"

 filter=""/>

  <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

  <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>

</Cluster>

  </Host>

配置文件修改完成后, 重启两个container:

docker restart tomcat_1

docker restart tomcat_2

2.3.6. 配置Nginx upstream

首先使用docker inspect 命令查看相应的容器所使用的IP信息,包括挂载的目录路径,网络IP信息等:

docker inspect --format '{{.NetworkSettings}}' tomcat_1

docker inspect --format '{{.NetworkSettings}}' tomcat_2

接下来即可在本地Nginx服务器配置文件(nginx.conf)中设置相应的upstream:

upstream www.docker.tomcat_colony_test {
        server 172.18.0.5:8080;
        server 172.18.0.6:8080;
        fair; 
}
location /docker_tomcat_clony_test/ {
    proxy_pass http://www.docker.tomcat_colony_test/;
    proxy_set_header Host $host:$server_port;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

重启nginx服务器:

接下来通过浏览器访问http://[服务器IP]/docker_tomcat_clony_test/, 即可验证集群配置已成功:

多次刷新页面,可发现另一个tomcat单机也在响应请求:

2.4. 使用Dockerfile部署war项目 (tomcat)

假设我们当前有一个war项目需要部署到tomcat服务器中。

在使用Docker之前,我们一般都是同maven将项目打包为war包文件,再将war包移动到tomcat容器webapps路径下,重启tomcat服务。

通过Docker可以使这个过程更加简洁:

首先我们在项目路径下,新建一个Docker文件夹:

进入Docker路径,我们将这个项目常用的tomcat特殊配置/lib包放置于这个路径:

接下来在这个Docker路径下,自定义项目.Dockerfile文件:

#基础镜像
FROM tomcat:latest

#维护者信息
MAINTAINER "Shawn-Nie <nie_yushuang@outlook.com>"

#将项目需要单独配置修改的context.xml,setting.xml,tomcat-user.xml配置文件、授权文件及lib包add到当前Dockerfile中,不再直接放到Linux的文件管理系统中
ADD tomcat-users.xml /usr/local/tomcat/conf/
ADD catalina.sh /usr/local/tomcat/bin/

ADD websocket-api.jar /usr/local/tomcat/lib
ADD tomcat-jdbc.jar /usr/local/tomcat/lib
ADD tomcat7-websocket.jar /usr/local/tomcat/lib
ADD context.xml /usr/local/tomcat/conf/
#将jdk-8u131-linux-x64.tar.gz文件复制到Dockerfile同级目录下,并安装至tomcat-container环境
RUN mkdir /usr/local/java
ADD jdk-8u131-linux-x64.tar.gz /usr/local/java

#定义tomcat镜像的环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_131
ENV PATH $JAVA_HOME/bin:$PATH
ENV CLASSPATH .:$JAVA_HOME/lib
ENV TZ=Asia/Shanghai
ENV BUNDLE_VER=0.0.1-SNAPSHOT
ENV SERVICE_NAME=Docker_DTest

#Make java and tomcat install directory
ENV PROJECT_WORKDIR=/usr/local/tomcat/webapps/
#将webapp下原有的全部项目清空
RUN rm -rf ${PROJECT_WORKDIR}*
#将项目target目录下的war包(先移动至Dockerfile文件同一路径下)复制进webapps目录中
COPY ${SERVICE_NAME}-${BUNDLE_VER}.war ${PROJECT_WORKDIR}${SERVICE_NAME}.war

#指定端口
EXPOSE 8080

#为tomcat启动命令授权
RUN chmod u+x /usr/local/tomcat/bin/catalina.sh

#启动tomcat容器
CMD ["catalina.sh","run"]

接下来我们将打包项目为war包文件:

打包完成后,先将打包好的war包文件移动至Dockerfile文件同一目录下:

接下来我们将回到Dockerfile所在位置,基于刚刚创建的Dockerfile 文件创建镜像:

docker build -f Dockerfile -t tomcat_service:1.0 .
# . 表示当前路径

镜像构建完成后, 即可启动服务:

docker run --name Docker_DTest_TomcatContainer tomcat_service:1.0

此时进入容器,即可访问项目页面: http://localhost:8080/Docker_DTest/.

docker exec -ti Docker_DTest_TomcatContainer /bin/bash