Docker 快速驗(yàn)證 tomcat 單機(jī)多實(shí)例方案

概述

主要講的是解決問(wèn)題的思路痒玩。當(dāng)然也附帶了盡可能詳細(xì)的步驟,感興趣的童鞋可以一步一步跟著來(lái)實(shí)踐一把搂妻。因?yàn)檫\(yùn)維職業(yè)的緣故蒙保,基本上是把事故當(dāng)故事來(lái)寫了,希望能夠喜歡欲主。

緣起

至少10年了邓厕,沒(méi)在一線玩過(guò) Tomcat 了,這次客戶現(xiàn)場(chǎng)就來(lái)了一場(chǎng)遭遇戰(zhàn)扁瓢。雖然客戶說(shuō)了他來(lái)搭建详恼,但是項(xiàng)目進(jìn)度不等人,還是自己動(dòng)手吧引几。當(dāng)然了昧互,新服務(wù)器是要走流程申請(qǐng)的,只能在現(xiàn)有服務(wù)器想辦法伟桅。猶記得當(dāng)年解決 Tomcat 部署這些都是小菜敞掘,沒(méi)想到在苛刻的商業(yè)環(huán)境中,處處是坑楣铁,步步有雷渐逃。不過(guò),咱干過(guò)開(kāi)發(fā)也干過(guò)運(yùn)維民褂,這點(diǎn)兒動(dòng)手的事情茄菊,還不至于發(fā)郵件請(qǐng)救兵不是。干赊堪!

服務(wù)器在內(nèi)網(wǎng)面殖,有瘦終端可以訪問(wèn)。MacBook 只能訪問(wèn)外網(wǎng)哭廉,一邊查資料脊僚,一邊比對(duì)著在內(nèi)網(wǎng)做,效果不好遵绰,老是擔(dān)心現(xiàn)有環(huán)境給整趴了:開(kāi)發(fā)測(cè)試那邊就沒(méi)得玩了辽幌。干過(guò)開(kāi)發(fā)的都知道,服務(wù)器從來(lái)都是直接上 root 賬號(hào)椿访。干過(guò)運(yùn)維的人都知道乌企,永遠(yuǎn)別碰 root。╮(╯▽╰)╭哎成玫,職業(yè)病加酵,還是小心謹(jǐn)慎地好拳喻。

只能調(diào)整了方法:先在 MacBook 上搭建單機(jī)多實(shí)例,驗(yàn)證通過(guò)之后猪腕,再去內(nèi)網(wǎng)服務(wù)器動(dòng)手冗澈。本來(lái)計(jì)劃20~30分鐘搞完的事,最終花了小半天時(shí)間驗(yàn)證了方案陋葡,在內(nèi)網(wǎng)實(shí)施的時(shí)候亚亲,又遇到苛刻的環(huán)境限制,逐步排雷腐缤,最終搞定捌归。客戶滿意柴梆,項(xiàng)目進(jìn)度開(kāi)心陨溅。

思路

根據(jù)實(shí)際環(huán)境,判斷問(wèn)題解決方向:?jiǎn)螜C(jī)多實(shí)例绍在;放棄內(nèi)網(wǎng)危險(xiǎn)的嘗試:不能快速有效解決门扇,且賬號(hào)權(quán)限太大;選擇外網(wǎng)驗(yàn)證方案后再進(jìn)內(nèi)網(wǎng)實(shí)施。很多時(shí)候偿渡,選擇大于努力臼寄。

我們先簡(jiǎn)化問(wèn)題

寫個(gè)驗(yàn)證文件打包成 war 包。為啥不使用現(xiàn)有代碼溜宽。一是因?yàn)楝F(xiàn)有 war 包在內(nèi)網(wǎng)吉拳,二是因?yàn)樘珡?fù)雜,除了問(wèn)題不能排除是代碼自身的問(wèn)題還是我們的部署方式有問(wèn)題适揉,或者是內(nèi)外網(wǎng)網(wǎng)絡(luò)環(huán)境的問(wèn)題留攒,亦或是 RPWT。

對(duì)于驗(yàn)證方案嫉嘀,排查問(wèn)題時(shí)炼邀,盡量簡(jiǎn)化,拋卻一切外在的東西剪侮,只驗(yàn)證核心拭宁。方案驗(yàn)證通過(guò),再引入實(shí)際war包驗(yàn)證瓣俯。這和面向?qū)ο缶幊痰闹笇?dǎo)思想是一致的:通過(guò)抽象來(lái)提煉最核心的東西杰标,每次聚焦一個(gè)地方,不要全面出擊彩匕。人腔剂,畢竟精力有限。

至于為什么用 tomcat7推掸,沒(méi)什么桶蝎,客戶這兒只允許這個(gè)版本驻仅。

先放出整理后方案

2017.8.8Update:

已 commit 到 docker hub谅畅,心急的童鞋自行

docker pull aninputforce/tomcat7-ins

最終方案

這個(gè)不是診斷問(wèn)題的思路登渣,是最終解決完問(wèn)題后的,對(duì)整體方案的梳理毡泻,這樣的順序才整潔胜茧,有基礎(chǔ)時(shí)間緊的童鞋直接看這個(gè)就足夠了。有時(shí)間的童鞋可以看看正文仇味,貫穿了分析問(wèn)題解決問(wèn)題的思路呻顽。

# 簡(jiǎn)化問(wèn)題:建模先--宿主機(jī)編輯 -> jdk7打war包 -> tomcat默認(rèn)配置 -> 單機(jī)單實(shí)例 -> 單機(jī)雙實(shí)例
├── # docker搭建jdk7初始環(huán)境:用來(lái)打包驗(yàn)證用的war包
│   ├── docker search jdk7
│   ├── docker pull codenvy/jdk7
│   ├── docker run --name jjj codenvy/jdk7 /bin/bash
│   ├── java -version && mkdir ~/web && ls ~/ && exit  # 鏡像容器環(huán)境工作正常,創(chuàng)建工作目錄丹墨,退出
│   ├── mkdir ~/prms001 ~/prms002 # 宿主機(jī) 
│   ├── # 編輯prms001/index.htm,編輯prms002/index.htm
│   ├── docker cp prms001 jjj:/home/user/web && docker cp prms002 jjj:/home/user/web
│   ├── docker exec -it jjj /bin/bash # 進(jìn)入容器
│   ├── sudo chown -R user:user prms001 prms002 改變屬組
│   ├── cd ~/web/prms001 && jar -cvf prms001.war ./* && ls -la
│   ├── cd ~/web/prms002 && jar -cvf prms002.war ./* && ls -la && exit
│   ├── docker cp jjj:/home/user/web/prms001/prms001.war ~/.
│   ├── docker cp jjj:/home/user/web/prms002/prms002.war ~/.
│   └── docker rm jjj # 退出容器廊遍,jdk7容器使命結(jié)束
├── # docker搭建tomcat7初始環(huán)境:用來(lái)推演單機(jī)多實(shí)例
│   ├── # docker拉取tomcat7鏡像
│   ├── # 啟動(dòng)名為www的tomcat容器
│   │   ├── ./startup.sh # 啟動(dòng)web服務(wù)
│   │   ├── curl localhost:8080 # 訪問(wèn)正常
│   │   ├── ./shutdown.sh # 停止web服務(wù)
│   │   └── # 搭建第一個(gè)實(shí)例
│   │      ├── mkdir tom-ins001
│   │      ├── mv work tom-ins001/ && mv conf/ tom-ins001/ mv logs/ tom-ins001/ 
│   │      ├── mv temp/ tom-ins001/ && mv webapps/ tom-ins001/
│   │      ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins001/
│   │      ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
│   │      ├── curl localhost:8080 # 訪問(wèn)正常
│   │      └── exit && docker commit www mytomcat:latest && docker rm www # 容器www使命結(jié)束
│   └── docker run --name web -it -p 8080:8080 -p 80:80 mytomcat /bin/bash # 啟動(dòng)新容器 
│      ├── # 啟動(dòng)第一個(gè)實(shí)例
│      │   ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins001/
│      │   ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
│      │   └── curl localhost:8080 # 訪問(wèn)正常
│      └── # 搭建并啟動(dòng)第二個(gè)實(shí)例
│         ├── cp -r tom-ins001/ tom-ins002
│         ├── # 編輯tom-ins002/conf/server.xml的3個(gè)端口,規(guī)避和實(shí)例1沖突贩挣,
│         │   ├── Server port="8001"喉前、 Connector port="80" protocol="HTTP/1.1"
│         │   ├── Connector port="8002" protocol="AJP/1.3"
│         │   ├── docker cp www:/usr/local/tomcat/conf/server.xml .
│         │   ├── vi server.xml
│         │   └── docker cp ./server.xml www:/usr/local/tomcat/conf/
│         └── # 啟動(dòng)新容器 啟動(dòng)實(shí)例2
│             ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins002/
│             ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
│             ├── curl localhost:80 # 訪問(wèn)正常
│             ├── exit && docker commit web mytomcat:latest 
│             └── docker rm web # 容器web使命結(jié)束
└── # 展示單機(jī)雙實(shí)例:
  ├── # 配置實(shí)例2根目錄運(yùn)行
  │   ├── docker run --name web -d -it -p 8080:8080 -p 80:80 mytomcat /bin/bash # 啟動(dòng)新容器 
  │   ├── docker exec -it web /bin/bash 
  │   ├── cd /usr/local/tomcat/tom-ins002/webapps && tar cvf rootbak.tar ./ROOT/*
  │   ├── cd ROOT && rm -rf * # 清空ROOT目錄
  │   ├── mkdir /usr/local/tomcat/myapps && exit # 創(chuàng)建實(shí)例2war包存放目錄,退出容器
  ├── # 部署實(shí)例1王财、實(shí)例2的war包卵迂,啟動(dòng)驗(yàn)證
  │   ├── # 編輯ROOT.xml,配置實(shí)例2的war包解到 /usr/local/tomcat/tom-ins002/ROOT 目錄
  │   ├── docker cp ~/ROOT.xml web:/usr/local/tomcat/tom-ins002/conf/Catalina/localhost
  │   ├── docker cp ~/prms002.war web:/usr/local/tomcat/myapps
  │   └── docker cp ~/prms001.war web:/usr/local/tomcat/tom-ins001/webapps
  ├── docker exec -it web /bin/bash
  │   ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins001/
  │   ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
  │   ├── curl localhost:8080 # 訪問(wèn)正常:Hello from Tomcat instance 001
  │   ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins002/
  │   ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
  │   └── curl localhost # 訪問(wèn)正常:Hello from Tomcat instance 002
  └── # 宿主機(jī)驗(yàn)證
     ├── curl localhost:8080 # 訪問(wèn)正常:Hello from Tomcat instance 001
     ├── curl localhost # 訪問(wèn)正常:Hello from Tomcat instance 002
     └── exit && docker commit web mytomcat:latest # 退出绒净,提交容器變動(dòng)到鏡像见咒,驗(yàn)證通過(guò);

以下開(kāi)始講故事:

外網(wǎng)驗(yàn)證方案

換做十年前挂疆,要學(xué)習(xí) Java改览,光搭建個(gè)環(huán)境,就能耗盡新人 90% 的熱情缤言。放棄內(nèi)網(wǎng)嘗試宝当,轉(zhuǎn)由外網(wǎng)先驗(yàn)證方案,我也是經(jīng)過(guò)略微的思想斗爭(zhēng)的墨闲,不過(guò)轉(zhuǎn)念一想今妄,有 Docker 神器,也就淡定了鸳碧。

開(kāi)始之前盾鳞,先列一下客戶的要求

  • 部署新實(shí)例作為 UAT 測(cè)試環(huán)境,但是新服務(wù)器還沒(méi)有
  • 根目錄啊瞻离,別帶上 Project 路徑了
  • 端口用 80 吧腾仅,你們開(kāi)發(fā)測(cè)試還用 8080

需求分析

在內(nèi)網(wǎng)的一番碰墻,也不是沒(méi)有一點(diǎn)兒成果套利,至少理順了方向:

  • 方案的方向是單機(jī)多實(shí)例
  • Server 部署在根目錄
  • 別讓用戶敲端口訪問(wèn)了

開(kāi)始推励,進(jìn)行 tomcat 單機(jī)多實(shí)例方案的推演鹤耍。

至于docker環(huán)境搭建,請(qǐng)參考官方文檔验辞。我的另一篇筆記里附有鏈接:<u style="text-decoration: none; border-bottom: 1px dashed rgb(128, 128, 128);">Docker的第一次親密接觸(https://my.oschina.net/hexie/blog/785315)</u>

上 Docker 搭建第一個(gè)實(shí)例

準(zhǔn)備拉取鏡像

docker pull tomcat:7.0

啟動(dòng)并運(yùn)行 tomcat

容器名www稿黄,端口8080:

ChinaDreams:work-diary kangcunhua$ docker run --name www -it -p 8080:8080 tomcat:7.0 /bin/bash
root@4b8f58d2cd64:/usr/local/tomcat# cd bin
root@4b8f58d2cd64:/usr/local/tomcat/bin# java -version
java version "1.7.0_131"
OpenJDK Runtime Environment (IcedTea 2.6.9) (7u131-2.6.9-2~deb8u1)
OpenJDK 64-Bit Server VM (build 24.131-b00, mixed mode)
root@4b8f58d2cd64:/usr/local/tomcat/bin# ./startup.sh 
root@4b8f58d2cd64:/usr/local/tomcat/bin# ps -ef | grep java
root@4b8f58d2cd64:/usr/local/tomcat/logs# tail -f catalina.out 
root@4b8f58d2cd64:/usr/local/tomcat/logs# curl localhost:8080

查看 java 進(jìn)程有,查看日志正常跌造,訪問(wèn) http://localhost:8080 正常杆怕,證明鏡像和容器是可以正常工作的。

搭建第一個(gè)實(shí)例

root@4b8f58d2cd64:/usr/local/tomcat# mkdir tom-ins001
root@4b8f58d2cd64:/usr/local/tomcat# ls
LICENSE  RELEASE-NOTES  bin   include  logs    native-jni-lib  tom-ins001  work
NOTICE   RUNNING.txt  conf  lib      myapps  temp        webapps
root@4b8f58d2cd64:/usr/local/tomcat# mv work tom-ins001/
root@4b8f58d2cd64:/usr/local/tomcat# mv conf/ tom-ins001/
root@4b8f58d2cd64:/usr/local/tomcat# mv logs/ tom-ins001/
root@4b8f58d2cd64:/usr/local/tomcat# mv temp/ tom-ins001/
root@4b8f58d2cd64:/usr/local/tomcat# mv webapps/ tom-ins001/
root@4b8f58d2cd64:/usr/local/tomcat# ls
LICENSE  NOTICE  RELEASE-NOTES  RUNNING.txt  bin  include  lib  myapps  native-jni-lib  tom-ins001
root@4b8f58d2cd64:/usr/local/tomcat# cd tom-ins001/
root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# ls
conf  logs  temp  webapps  work
root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# echo $CATALINA_HOME
/usr/local/tomcat
root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# export CATALINA_BASE=$CATALINA_HOME/tom-ins001/
root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# ps -ef | grep java
root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# tail -f catalina.out 
root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# curl localhost:8080

啟動(dòng)成功,宿主機(jī)訪問(wèn) http://localhost:8080 正常

提交變動(dòng)到鏡像備份

root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# exit
ChinaDreams:~ kangcunhua$ docker commit www mytomcat:latest

搭建第二個(gè)實(shí)例

啟動(dòng)新容器壳贪,并啟動(dòng)第一個(gè)實(shí)例

基于剛提交生成的鏡像陵珍,新啟一個(gè)容器。啟動(dòng)實(shí)例1违施,驗(yàn)證正常

ChinaDreams:~ kangcunhua$ docker run --name web -it -p 8080:8080 -p 80:80 mytomcat /bin/bash
root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# export CATALINA_BASE=$CATALINA_HOME/tom-ins001
root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# ps -ef | grep java
root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# tail -f catalina.out 
root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# curl localhost:8080

生成第二個(gè)實(shí)例目錄

root@c8cc5f309d18:/usr/local/tomcat# cp -r tom-ins001/ tom-ins002
root@c8cc5f309d18:/usr/local/tomcat# ls
LICENSE  NOTICE  RELEASE-NOTES  RUNNING.txt  bin  include  lib  myapps  native-jni-lib  tom-ins001  tom-ins002
root@c8cc5f309d18:/usr/local/tomcat# cd tom-ins002
root@c8cc5f309d18:/usr/local/tomcat/tom-ins002# ls
conf  logs  temp  webapps  work
root@c8cc5f309d18:/usr/local/tomcat/tom-ins002# cd ..
root@c8cc5f309d18:/usr/local/tomcat# cd tom-ins001/
root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# ls
conf  logs  temp  webapps  work

編輯 server.xml

主要是修改三處端口,避免和實(shí)例1端口沖突互纯。

  • Server port=”8001”
  • Connector port=”80” protocol=”HTTP/1.1”
  • Connector port=”8002” protocol=”AJP/1.3”
<?xml version='1.0' encoding='utf-8'?>
<Server port="8001" shutdown="SHUTDOWN">
<!-- 此處省略了無(wú)修改的內(nèi)容 -->
 <Service name="Catalina">
   <Connector port="80" protocol="HTTP/1.1"
              connectionTimeout="20000"
              redirectPort="8443" />
   <Connector port="8002" protocol="AJP/1.3" redirectPort="8443" />
<!-- 此處省略了無(wú)修改的內(nèi)容 -->
</Service>
</Server>

編輯 ROOT.xml

作用是指定一個(gè)不在 webapps 目錄的 war 包,部署時(shí)自動(dòng)解壓到 webapps\ROOT 目錄磕蒲。

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/prms" docBase="/usr/local/tomcat/myapps/prms002.war"></Context>

cp 到 tomcat 容器 web 中查看

ChinaDreams:~ kangcunhua$ docker cp ~/ROOT.xml www:/usr/local/tomcat/tom-ins002/conf/Catalina/localhost
ChinaDreams:~ kangcunhua$ docker exec -it www /bin/bash
root@4b8f58d2cd64:/usr/local/tomcat# cd conf/Catalina/localhost/
root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# ls
ROOT.xml
root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# more ROOT.xml 
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/prms" docBase="/usr/local/tomcat/myapps/prms002.war"></Context>
root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# pwd
/usr/local/tomcat/conf/Catalina/localhost

文件屬主不對(duì)留潦,改

root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# ls -al
total 12
drwxr-xr-x 2 root root    4096 Jul 31 05:58 .
drwxr-xr-x 3 root root    4096 Jul 31 04:23 ..
-rw-r--r-- 1  502 dialout  111 Jul 31 05:56 ROOT.xml
root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# chown root:root ROOT.xml 
root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# ls -la
total 12
drwxr-xr-x 2 root root 4096 Jul 31 05:58 .
drwxr-xr-x 3 root root 4096 Jul 31 04:23 ..
-rw-r--r-- 1 root root  111 Jul 31 05:56 ROOT.xml

打個(gè) war 部署包

打 war 包報(bào)錯(cuò)

在 tomcat 容器中,發(fā)現(xiàn) jar 命令找不到亿卤。

root@4b8f58d2cd64:/usr/local/tomcat/webapps/examples# jar -cvf prms.war ./*
bash: jar: command not found

構(gòu)建 jdk7 環(huán)境

本地沒(méi)有 java 環(huán)境愤兵。果斷上 docker 構(gòu)建一個(gè)

ChinaDreams:~ kangcunhua$ docker search jdk7
ChinaDreams:~ kangcunhua$ docker pull codenvy/jdk7
ChinaDreams:~ kangcunhua$ docker run --name jjj -it codenvy/jdk7 /bin/bash
user@b040d98042c0:/$ java -version
user@b040d98042c0:/$ jar
user@b040d98042c0:/$ mkdir ~/web && ls ~/ && exit 創(chuàng)建工作目錄,退出

宿主機(jī)編輯代碼 cp 到容器中打 jar 包

ChinaDreams:~ kangcunhua$ mkdir ~/prms001 ~/prms002
ChinaDreams:~ kangcunhua$ vi ~/prms001/index.html
ChinaDreams:~ kangcunhua$ vi ~/prms002/index.html
ChinaDreams:~ kangcunhua$ docker cp prms001 jjj:/home/user/web && docker cp prms002 jjj:/home/user/web
ChinaDreams:~ kangcunhua$ docker exec -it jjj /bin/bash 進(jìn)入容器
user@b040d98042c0:~/web$ sudo chown -R user:user prms001 prms002 改變屬組
user@b040d98042c0:~/web$ cd ~/web/prms001 && jar -cvf prms001.war ./* && ls -la
user@b040d98042c0:~/web$ cd ~/web/prms002 && jar -cvf prms002.war ./* && ls -la && exit
ChinaDreams:~ kangcunhua$ docker cp jjj:/home/user/web/prms001/prms001.war ~/.
ChinaDreams:~ kangcunhua$ docker cp jjj:/home/user/web/prms001/prms002.war ~/.
ChinaDreams:~ kangcunhua$ docker rm jjj 退出容器排吴,jdk7容器使命結(jié)束

vi ~/prms001/index.html

<html>
   <head>
       <meta charset="UTF-8" >
       <title> Tomcat instance 1</title>
   </head>

   <body>
       <h1> Hello from Tomcat instance 1</h1>
   </body>
</html>

vi ~/prms002/index.html

<html>
   <head>
       <meta charset="UTF-8" >
       <title> Tomcat instance 2</title>
   </head>

   <body>
       <h1> Hello from Tomcat instance 2</h1>
   </body>
</html>

啟動(dòng)實(shí)例1秆乳、實(shí)例2

回到 tomcat 容器

root@c8cc5f309d18:/usr/local/tomcat# export CATALINA_BASE=$CATALINA_HOME/tom-ins001
root@c8cc5f309d18:/usr/local/tomcat# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
root@c8cc5f309d18:/usr/local/tomcat# curl localhost:8080 訪問(wèn)正常
root@c8cc5f309d18:/usr/local/tomcat# export CATALINA_BASE=$CATALINA_HOME/tom-ins002/
root@c8cc5f309d18:/usr/local/tomcat# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
root@c8cc5f309d18:/usr/local/tomcat# curl localhost:80 訪問(wèn)正常

激動(dòng)人心的時(shí)刻

提交鏡像和刪除舊容器 web

docker commit web mytomcat:latest && docker rm web

基于最新鏡像,啟動(dòng)新容器命名為 web

ocker run --name web -it -p 8080:8080 -p 80:80 mytomcat /bin/bash

宿主機(jī)訪問(wèn)

<u style="text-decoration: none; border-bottom: 1px dashed rgb(128, 128, 128);">http://localhost/</u> 訪問(wèn)正常:Hello from Tomcat instance 001.

<u style="text-decoration: none; border-bottom: 1px dashed rgb(128, 128, 128);">http://localhost:8080</u> 訪問(wèn)正常:Hello from Tomcat instance 002.

單機(jī)多實(shí)例方案本地通過(guò)

方案補(bǔ)充

啟動(dòng)命令

export CATALINA_BASE=$CATALINA_HOME/tom-ins001 && sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
export CATALINA_BASE=$CATALINA_HOME/tom-ins002 && sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

停止命令

export CATALINA_BASE=$CATALINA_HOME/tom-ins001 && sh $CATALINA_HOME/bin/shutdown.sh -Dcatalina.base
export CATALINA_BASE=$CATALINA_HOME/tom-ins002 && sh $CATALINA_HOME/bin/shutdown.sh -Dcatalina.base

排錯(cuò)命令

ps -ef | grep java
kill -9 xxx tomcat實(shí)例進(jìn)程號(hào)
tail -f $CATALINA_HOME/tom-ins001/logs/catalina.out
tail -f $CATALINA_HOME/tom-ins002/logs/catalina.out
curl localhost:8080/prms001/
curl localhost

目錄結(jié)構(gòu)參考

保留了最關(guān)鍵的要素:

.
├── bin
├── lib
├── myapps
│   └── prms002.war
├── tom-ins001
│   ├── conf
│   │   └── server.xml
│   ├── logs
│   │   └── catalina.out
│   ├── webapps
│   │   ├── prms001
│   │   └── prms001.war
│   └── work
└── tom-ins002
   ├── conf
   │   ├── Catalina
   │   │   └── localhost
   │   │       └── ROOT.xml
   │   └── server.xml
   ├── logs
   ├── temp
   ├── webapps
   │   └── ROOT
   │       ├── META-INF
   │       │   └── MANIFEST.MF
   │       └── index.htm
   └── work

提交到 docker hub

update:2017.8.8

ChinaDreams:work-diary kangcunhua$ docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
mytomcat                   latest              3f6c6cce5355        7 days ago          370MB
ChinaDreams:work-diary kangcunhua$ docker tag 3f6c6cce5355 aninputforce/tomcat7-ins:latest
ChinaDreams:work-diary kangcunhua$ docker push aninputforce/tomcat7-ins
ChinaDreams:work-diary kangcunhua$ docker push aninputforce/tomcat7-ins:1.0
ChinaDreams:work-diary kangcunhua$ docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
mytomcat                   latest              3f6c6cce5355        7 days ago          370MB
aninputforce/tomcat7-ins   1.0                 3f6c6cce5355        7 days ago          370MB
aninputforce/tomcat7-ins   latest              3f6c6cce5355        7 days ago          370MB

進(jìn)內(nèi)網(wǎng)玩:殘酷的商業(yè)環(huán)境

一切都很順利钻哩,直到碰上訪問(wèn)80端口屹堰。。街氢。扯键。

順利

搭建實(shí)例1

備份后,搭建實(shí)例1珊肃,確保原始應(yīng)用能正常荣刑;

搭建實(shí)例2

停止實(shí)例1,保證實(shí)例2默認(rèn)也能運(yùn)行伦乔;

根目錄部署實(shí)例2

編輯server.xml厉亏,ROOT.xml,清空ROOT目錄烈和,新建myapps目錄爱只,拷貝war包進(jìn)去;

curl http://localhost web server上訪問(wèn)正常招刹。

局域網(wǎng)訪問(wèn) 恬试,http://10.29.11.23 不窝趣!能!訪训柴!問(wèn)Q剖妗!畦粮!

坑:Suse 訪問(wèn) 80 端口

實(shí)例2需要使用 80 端口散址。受阻乖阵。

坑+:沒(méi)有任何限制宣赔。我們需要客戶的信息,但是不能全信瞪浸。就像這次請(qǐng)教客戶說(shuō)的“我們對(duì)端口沒(méi)有任何限制”儒将。不要盲目相信客戶說(shuō)的,要相信科學(xué)排查对蒲。

依稀記得架構(gòu)師課程 PC 大神講過(guò)钩蚊,linux 默認(rèn)只有 root 用戶才能訪問(wèn) 80 端口。當(dāng)時(shí)我一直有個(gè)疑問(wèn)蹈矮,那我們 web server 需要用到 80 端口是怎么解決的砰逻?我記得請(qǐng)教過(guò)PC 老師,可惜當(dāng)時(shí)課程緊泛鸟,雖然聽(tīng)的云里霧里的蝠咆,也沒(méi)好意思多追問(wèn),更沒(méi)線下自己實(shí)踐北滥。直到這次在客戶現(xiàn)場(chǎng)栽了跟頭刚操。

開(kāi)發(fā)測(cè)試環(huán)境,我們倒是有 root 賬號(hào)再芋,但是我們 web server 總不能用 root 部署吧菊霜,太不專業(yè)了。在 Reboot 校友群中厚著臉皮請(qǐng)教了各位童鞋济赎,很快 get 了解決方案:將所有80端口的訪問(wèn)鉴逞,轉(zhuǎn)發(fā)到 8081 即可;8081 就是我們可以配置的 tomcat 實(shí)例2的訪問(wèn)端口司训,這個(gè)是普通用戶有權(quán)限的构捡。

修訂 IPtables 策略,轉(zhuǎn)發(fā) 80 端口請(qǐng)求

剛檢查防火墻時(shí)豁遭,看到 80 端口是放開(kāi)的叭喜。部署機(jī)上可以訪問(wèn),局域網(wǎng)打不開(kāi):將所有針對(duì) 80 端口的訪問(wèn)蓖谢,轉(zhuǎn)發(fā)到 8081捂蕴。

[root@tomcat7conf]# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8081

使用8081端口

修改了 tomins-002 的 server.xml,仍是部署機(jī)上可以訪問(wèn)譬涡,局域網(wǎng)打不開(kāi);

檢查防火墻

配置上 8081 端口啥辨,重啟防火墻生效涡匀,部署機(jī)訪問(wèn)正常,局域網(wǎng)打開(kāi)正常

找到 FW_SERVICES_EXT_TCP溉知,加上 8081 端口

[root@tomcat7conf]# vi /etc/sysconfig/SuSEfirewall2 
[root@tomcat7conf]# rcSuSEfirewall2 restart

切換到 tomcat 用戶陨瘩,重啟 tomcat,局域網(wǎng)訪問(wèn)正常级乍。

坑:成熟平臺(tái)也有硬編碼

發(fā)現(xiàn)系統(tǒng)首頁(yè)這個(gè)鏈接舌劳,雖然配置的是”#”,但是一點(diǎn)擊就回到 project 的路徑。經(jīng)查找文件玫荣,發(fā)現(xiàn)是在開(kāi)發(fā)平臺(tái)的兩個(gè)js文件中甚淡,寫了硬編碼。應(yīng)該是平臺(tái)自動(dòng)生成代碼時(shí)用了硬編碼捅厂,改之贯卦。

坑:成熟產(chǎn)品也不是沒(méi)有 Bug

發(fā)現(xiàn)只要是配置了根目錄訪問(wèn),統(tǒng)一認(rèn)證就報(bào)錯(cuò)焙贷。去掉統(tǒng)一認(rèn)證接入就能正常訪問(wèn)撵割。反饋給客戶,協(xié)調(diào)解決辙芍;懸了兩天啡彬,未能有任何反饋,追著逼急了沸手,唯一答案就是:成熟產(chǎn)品外遇,我們不要先去懷疑統(tǒng)一認(rèn)證平臺(tái)。

我這個(gè)暴脾氣契吉,馬上和工程師排查跳仿。單步跟一下,發(fā)現(xiàn)是提交到統(tǒng)一認(rèn)證時(shí)捐晶,我們要傳過(guò)去一個(gè)參數(shù) ssotarget菲语,這個(gè) ssotarget 是通過(guò)認(rèn)證后,瀏覽器要打開(kāi)的首頁(yè)惑灵,context-path 不為空時(shí)山上,url 正常,context-path 為 null英支,即我們部署到根目錄時(shí)佩憾,ssotarget 只能得到個(gè)”/“。檢查統(tǒng)一認(rèn)證接入邏輯,發(fā)現(xiàn)是使用了平臺(tái)提供的 filter妄帘,反編譯楞黄,單步跟蹤,發(fā)現(xiàn) ssotarget 來(lái)自 homepage 的賦值抡驼。捏著鼻子看源碼鬼廓,果然代碼邏輯有問(wèn)題,偽算法如下:

String ccontext_path=request.getContextPath(); // 得到web 服務(wù)上下文
String urlt = requerst.getRequestURL(); // 得到請(qǐng)求的完整網(wǎng)址
String cwebhost = urlt.substring(0, urlt.IndexOf (context-path)); // 得到http://hostname:端口
homepage = webhost + context_path + "/"; // 拼出web server的應(yīng)用首頁(yè)地址

改之

String context_path = request.getContextPath();  
String homepage = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

嘗試致盟,自己改了源碼之后重新打 jar 包碎税,commit svn,jenkins 編譯部署后發(fā)現(xiàn)沒(méi)起作用馏锡。想起來(lái)使用的是 maven雷蹂,所有 jar 包都來(lái)自平臺(tái)的私有倉(cāng)庫(kù),這眷篇。萎河。。

換種思路蕉饼,寫個(gè) java 類繼承一下,結(jié)果一看對(duì)應(yīng)邏輯所在 function玛歌,private 的昧港,往上再看 class,finall 的支子,一萬(wàn)只神獸按捶省!V蹬蟆叹侄!

要啥面向?qū)ο螅?jiǎn)單粗暴昨登,源碼照抄趾代,修訂了后命名為 MySsoFilter.java,在工程配置文件替換上我們寫的 filter丰辣,svn commit撒强,jenkins 立即構(gòu)建部署,世間從此安靜笙什。

參考和感謝

參考清單

感謝

  • 感謝項(xiàng)目組的小伙伴們琐凭,辛苦努力排查缺陷芽隆,撰寫了新的 filter;
  • 感謝 Reboot 的同學(xué)群,關(guān)鍵時(shí)刻胚吁,是請(qǐng)教你們給指出了方向臼闻;
  • 感謝 Reboot 的架構(gòu)師課程和運(yùn)維自動(dòng)化課程,前者使我開(kāi)闊了眼界囤采,后者讓我收獲了docker 神器


51Reboot 最新課程招生信息

docker + k8s

此課程為網(wǎng)絡(luò)直播課程述呐,一共 10 個(gè)課時(shí),每周上一個(gè)全天蕉毯,歷時(shí)兩個(gè)多月乓搬。附加:錄播視頻+筆記+除課堂外的答疑時(shí)間(7次+)2019-1-13 開(kāi)課,原價(jià) 5800 代虾,現(xiàn)在周年活動(dòng) 100 定金抵 500

課程主講師

GY 老師:

10年一線軟件開(kāi)發(fā)經(jīng)驗(yàn)进肯,先后經(jīng)歷了傳統(tǒng)安全公司,以及多家互聯(lián)網(wǎng)公司棉磨;在安全開(kāi)發(fā)方面江掩,曾開(kāi)發(fā)過(guò) Linux 防火墻、web 應(yīng)用防火墻乘瓤、Linux 安全內(nèi)核加固环形,基于大流量的 Web 安全威脅分析等項(xiàng)目;在互聯(lián)網(wǎng)公司工作時(shí)衙傀,曾基于 DPDK 高性能網(wǎng)絡(luò)開(kāi)發(fā)框架開(kāi)發(fā)過(guò)基于全流量的網(wǎng)絡(luò)流量分析平臺(tái)和基于 Sflow 網(wǎng)絡(luò)流量分析平臺(tái)抬吟,基于 Golang 開(kāi)發(fā) SmartDNS 等;開(kāi)發(fā)語(yǔ)言也是從C -> python -> golang 的轉(zhuǎn)變過(guò)程统抬?現(xiàn)從事基于 K8S 和 Docker在私有云平臺(tái)建設(shè)方面的研發(fā)工作火本;具備豐富的Linux系統(tǒng)開(kāi)發(fā)經(jīng)驗(yàn)、網(wǎng)絡(luò)開(kāi)發(fā)經(jīng)驗(yàn)以及項(xiàng)目管理經(jīng)驗(yàn)聪建;目前開(kāi)發(fā)工作90+% 都在用 Golang钙畔,Golang 是一門簡(jiǎn)潔、高效金麸、強(qiáng)大且靈活的編程語(yǔ)言擎析。

關(guān)于課程的具體內(nèi)容想要了解的, 掃碼加小助手咨詢


掃碼咨詢,備注“來(lái)源簡(jiǎn)書”
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钱骂,一起剝皮案震驚了整個(gè)濱河市叔锐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌见秽,老刑警劉巖愉烙,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異解取,居然都是意外死亡步责,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蔓肯,“玉大人遂鹊,你說(shuō)我怎么就攤上這事≌岚” “怎么了秉扑?”我有些...
    開(kāi)封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)调限。 經(jīng)常有香客問(wèn)我舟陆,道長(zhǎng),這世上最難降的妖魔是什么耻矮? 我笑而不...
    開(kāi)封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任秦躯,我火速辦了婚禮,結(jié)果婚禮上裆装,老公的妹妹穿的比我還像新娘踱承。我一直安慰自己,他們只是感情好哨免,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布茎活。 她就那樣靜靜地躺著,像睡著了一般铁瞒。 火紅的嫁衣襯著肌膚如雪妙色。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天慧耍,我揣著相機(jī)與錄音,去河邊找鬼丐谋。 笑死芍碧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的号俐。 我是一名探鬼主播泌豆,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吏饿!你這毒婦竟也來(lái)了踪危?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤猪落,失蹤者是張志新(化名)和其女友劉穎贞远,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體笨忌,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蓝仲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袱结。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亮隙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出垢夹,到底是詐尸還是另有隱情溢吻,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布果元,位于F島的核電站促王,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏噪漾。R本人自食惡果不足惜硼砰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望欣硼。 院中可真熱鬧题翰,春花似錦、人聲如沸诈胜。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)焦匈。三九已至血公,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缓熟,已是汗流浹背累魔。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留够滑,地道東北人垦写。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像彰触,于是被迫代替她去往敵國(guó)和親梯投。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 至少10年了况毅,沒(méi)在一線玩過(guò) Tomcat 了分蓖,這次客戶現(xiàn)場(chǎng)就來(lái)了一場(chǎng)遭遇戰(zhàn)。雖然客戶說(shuō)了他來(lái)搭建尔许,但是項(xiàng)目進(jìn)度不等...
    51reboot閱讀 471評(píng)論 2 1
  • 教程:https://www.yiibai.com/jenkins/ 本節(jié)內(nèi)容: Jenkins介紹 安裝部署Je...
    達(dá)微閱讀 9,015評(píng)論 2 77
  • Docker — 云時(shí)代的程序分發(fā)方式 要說(shuō)最近一年云計(jì)算業(yè)界有什么大事件么鹤?Google Compute Engi...
    ahohoho閱讀 15,548評(píng)論 15 147
  • 美好的事物總是能讓人心曠神怡! 比如說(shuō)最近的養(yǎng)花記母债。 偶爾訂了一次鮮花午磁,每周送一次尝抖,周周有不同的期待。 藍(lán)的迅皇,粉的...
    清風(fēng)伏筆閱讀 192評(píng)論 0 10
  • 一個(gè)人默默地走 低著頭 直到有一天 撞到了另一個(gè)人 從此 她依然默默地走 低著頭 卻再也沒(méi)有撞到其他人 他說(shuō)昧辽,不能...
    魚木魚魚魚閱讀 253評(píng)論 2 2