1: 前言

kubernetes的基本运行单元是pod,而pod是无状态的,pod可能会遇到挂掉,重启等情况.而tomcat运行在pod上,日志信息也存储在pod上。一旦pod挂了,存储在pod上的日志也就丢失了。而如果只是简单的将tomcat的日志目录进行数据卷的映射,在一个主机上运行着多个相同的tomcat pod时,日志信息又会非常混乱。

2: 目标

实现tomcat的日志持久化,并且实现一个主机 多个tomcat pod的日志不混淆。

3: 步骤1

制作自己的tomcat镜像。

Dockerfile:

FROM tomcat:8-jre8
MAINTAINER "miao bainian <miaobainian36@163.com>"
ADD logging.properties /usr/local/tomcat/conf/
ADD server.xml /usr/local/tomcat/conf/
ADD catalina.sh /usr/local/tomcat/bin/

logging.properties:

通过pod名和pod命名空间变量,唯一标识输出文件名。

给所有的log前缀加上${my.pod.name}_${my.pod.namespace}

比如:1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina. 改成

1catalina.org.apache.juli.AsyncFileHandler.prefix = ${my.pod.name}_${my.pod.namespace}_catalina.

# 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.handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler.handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler############################################################ # Handler specific properties. # Describes specific configuration info for Handlers. ############################################################1catalina.org.apache.juli.AsyncFileHandler.level = FINE
1catalina.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.AsyncFileHandler.prefix = ${my.pod.name}_${my.pod.namespace}_catalina.2localhost.org.apache.juli.AsyncFileHandler.level = FINE
2localhost.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
2localhost.org.apache.juli.AsyncFileHandler.prefix = ${my.pod.name}_${my.pod.namespace}_localhost.3manager.org.apache.juli.AsyncFileHandler.level = FINE
3manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
3manager.org.apache.juli.AsyncFileHandler.prefix = ${my.pod.name}_${my.pod.namespace}_manager.4host-manager.org.apache.juli.AsyncFileHandler.level = FINE
4host-manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
4host-manager.org.apache.juli.AsyncFileHandler.prefix = ${my.pod.name}_${my.pod.namespace}_host-manager.java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter############################################################ # Facility specific properties. # Provides extra control for each logger. ############################################################org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.AsyncFileHandlerorg.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.AsyncFileHandlerorg.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.AsyncFileHandler# For example, set the org.apache.catalina.util.LifecycleBase logger to log # each component that extends LifecycleBase changing state: #org.apache.catalina.util.LifecycleBase.level = FINE # To see debug messages in TldLocationsCache, uncomment the following line: #org.apache.jasper.compiler.TldLocationsCache.level = FINE # To see debug messages for HTTP/2 handling, uncomment the following line: #org.apache.coyote.http2.level = FINE # To see debug messages for WebSocket handling, uncomment the following line: #org.apache.tomcat.websocket.level = FINE

server.xml :

也是通过pod名和pod命名空间变量,唯一标识输出文件名,这里标识的是localhost-access日志文件。

找到 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"这个节点,改成 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="${my.pod.name}_${my.pod.namespace}_localhost-access-log" suffix=".log"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />

<?xml version='1.0' encoding='utf-8'?>
<!--Licensed to the Apache Software Foundation (ASF) under one or morecontributor license agreements. See the NOTICE file distributed withthis 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 withthe License. You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed 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 andlimitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may notdefine subcomponents such as "Valves" at this level.Documentation at /docs/config/server.html-->
<Server port="8005" shutdown="SHUTDOWN"><Listener className="org.apache.catalina.startup.VersionLoggerListener" /><!-- Security listener. Documentation at /docs/config/listeners.html<Listener className="org.apache.catalina.security.SecurityListener" />--><!--APR library loader. Documentation at /docs/apr.html --><Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /><!-- Prevent memory leaks due to use of particular java/javax APIs--><Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /><Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /><Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /><!-- Global JNDI resourcesDocumentation at /docs/jndi-resources-howto.html--><GlobalNamingResources><!-- Editable user database that can also be used byUserDatabaseRealm to authenticate users--><Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase"description="User database that can be updated and saved"factory="org.apache.catalina.users.MemoryUserDatabaseFactory"pathname="conf/tomcat-users.xml" /></GlobalNamingResources><!-- A "Service" is a collection of one or more "Connectors" that sharea single "Container" Note: A "Service" is not itself a "Container",so you may not define subcomponents such as "Valves" at this level.Documentation at /docs/config/service.html--><Service name="Catalina"><!--The connectors can use a shared executor, you can define one or more named thread pools--><!--<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"maxThreads="150" minSpareThreads="4"/>--><!-- A "Connector" represents an endpoint by which requests are receivedand responses are returned. Documentation at :Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)Java AJP Connector: /docs/config/ajp.htmlAPR (HTTP/AJP) Connector: /docs/apr.htmlDefine a non-SSL/TLS HTTP/1.1 Connector on port 8080--><Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" /><!-- A "Connector" using the shared thread pool--><!--<Connector executor="tomcatThreadPool"port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />--><!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443This connector uses the NIO implementation that requires the JSSEstyle configuration. When using the APR/native implementation, theOpenSSL style configuration is required as described in the APR/nativedocumentation --><!--<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"maxThreads="150" SSLEnabled="true" scheme="https" secure="true"clientAuth="false" sslProtocol="TLS" />--><!-- Define an AJP 1.3 Connector on port 8009 --><Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /><!-- An Engine represents the entry point (within Catalina) that processesevery request. The Engine implementation for Tomcat stand aloneanalyzes the HTTP headers included with the request, and passes themon to the appropriate Host (virtual host).Documentation at /docs/config/engine.html --><!-- You should set jvmRoute to support load-balancing via AJP ie :<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">--><Engine name="Catalina" defaultHost="localhost"><!--For clustering, please take a look at documentation at:/docs/cluster-howto.html (simple how to)/docs/config/cluster.html (reference documentation) --><!--<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>--><!-- Use the LockOutRealm to prevent attempts to guess user passwordsvia a brute-force attack --><Realm className="org.apache.catalina.realm.LockOutRealm"><!-- This Realm uses the UserDatabase configured in the global JNDIresources under the key "UserDatabase". Any editsthat are performed against this UserDatabase are immediatelyavailable for use by the Realm. --><Realm className="org.apache.catalina.realm.UserDatabaseRealm"resourceName="UserDatabase"/></Realm><Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"><!-- SingleSignOn valve, share authentication between web applicationsDocumentation at: /docs/config/valve.html --><!--<Valve className="org.apache.catalina.authenticator.SingleSignOn" />--><!-- Access log processes all example.Documentation at: /docs/config/valve.htmlNote: The pattern used is equivalent to using pattern="common" --><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="${my.pod.name}_${my.pod.namespace}_localhost-access-log" suffix=".log"pattern="%h %l %u %t &quot;%r&quot; %s %b" /></Host></Engine></Service>
</Server>

catalina.sh:

通过容器传入的变量在tomcat中并不能直接使用,需要在tomcat的启动脚本中,在java的启动命令中加上-D选项。找到所有有-Dcatalina.base="\"$CATALINA_BASE\"" 的地方加上

-Dmy.pod.name="$MY_POD_NAME"
-Dmy.pod.namespace="$MY_POD_NAMESPACE"

#!/bin/sh
 # 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 # # 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_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_HOME Must 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. # 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 # # LOGGING_CONFIG (Optional) Override Tomcat's logging config file # Example (all one line) # LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties" # # LOGGING_MANAGER (Optional) Override Tomcat's logging manager # Example (all one line) # LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" # # 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" # ----------------------------------------------------------------------------- # 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" ]; dols=`ls -ld "$PRG"`link=`expr "$ls" : '.*-> \(.*\)$'`if expr "$link" : '/.*' > /dev/null; thenPRG="$link" elsePRG=`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.shelse echo "Cannot find $CATALINA_HOME/bin/setclasspath.sh" echo "This file is needed to run this program" exit 1fi fi # Add on extra jar files to CLASSPATH if [ ! -z "$CLASSPATH" ] ; thenCLASSPATH="$CLASSPATH":
fi
CLASSPATH="$CLASSPATH""$CATALINA_HOME"/bin/bootstrap.jarif [ -z "$CATALINA_OUT" ] ; thenCATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
fi if [ -z "$CATALINA_TMPDIR" ] ; then # Define the java.io.tmpdir to use for CatalinaCATALINA_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" ] ; thenCLASSPATH=$CLASSPATH:$CATALINA_BASE/bin/tomcat-juli.jar
elseCLASSPATH=$CLASSPATH:$CATALINA_HOME/bin/tomcat-juli.jar
fi # Bugzilla 37848: When no TTY is available, don't output to console
have_tty=0
if [ "`tty`" != "not a tty" ]; thenhave_tty=1
fi # For Cygwin, switch paths to Windows format before running java if $cygwin; thenJAVA_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"`JAVA_ENDORSED_DIRS=`cygpath --path --windows "$JAVA_ENDORSED_DIRS"`
fi if [ -z "$JSSE_OPTS" ] ; thenJSSE_OPTS="-Djdk.tls.ephemeralDHKeySize=2048" fi
JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS" # Set juli LogManager config file if it is present and an override has not been issued if [ -z "$LOGGING_CONFIG" ]; then if [ -r "$CATALINA_BASE"/conf/logging.properties ]; thenLOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties" else # Bugzilla 45585LOGGING_CONFIG="-Dnop" fi fi if [ -z "$LOGGING_MANAGER" ]; thenLOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" fi # Uncomment the following line to 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; thenUSE_NOHUP="true" elseUSE_NOHUP="false" fi fi unset _NOHUP
if [ "$USE_NOHUP" = "true" ]; then_NOHUP=nohup
fi # ----- 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" if [ ! -z "$CATALINA_PID" ]; then echo "Using CATALINA_PID: $CATALINA_PID" fi fi if [ "$1" = "jpda" ] ; then if [ -z "$JPDA_TRANSPORT" ]; thenJPDA_TRANSPORT="dt_socket" fi if [ -z "$JPDA_ADDRESS" ]; thenJPDA_ADDRESS="localhost:8000" fi if [ -z "$JPDA_SUSPEND" ]; thenJPDA_SUSPEND="n" fi if [ -z "$JPDA_OPTS" ]; thenJPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND" fiCATALINA_OPTS="$JPDA_OPTS $CATALINA_OPTS" shift fi if [ "$1" = "debug" ] ; then if $os400; then echo "Debug command not available on OS400" exit 1else shift if [ "$1" = "-security" ] ; then if [ $have_tty -eq 1 ]; then echo "Using Security Manager" fi shift exec "$_RUNJDB" "$LOGGING_CONFIG" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \-sourcepath "$CATALINA_HOME"/../../java \-Djava.security.manager \-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \-Dmy.pod.name="$MY_POD_NAME" \-Dmy.pod.namespace="$MY_POD_NAMESPACE" \-Dcatalina.base="$CATALINA_BASE" \-Dcatalina.home="$CATALINA_HOME" \-Djava.io.tmpdir="$CATALINA_TMPDIR" \org.apache.catalina.startup.Bootstrap "$@" startelse exec "$_RUNJDB" "$LOGGING_CONFIG" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \-sourcepath "$CATALINA_HOME"/../../java \-Dmy.pod.name="$MY_POD_NAME" \-Dmy.pod.namespace="$MY_POD_NAMESPACE" \-Dcatalina.base="$CATALINA_BASE" \-Dcatalina.home="$CATALINA_HOME" \-Djava.io.tmpdir="$CATALINA_TMPDIR" \org.apache.catalina.startup.Bootstrap "$@" startfi 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\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \-Djava.security.manager \-Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \-Dmy.pod.name="$MY_POD_NAME" \-Dmy.pod.namespace="$MY_POD_NAMESPACE" \-Dcatalina.base="\"$CATALINA_BASE\"" \-Dcatalina.home="\"$CATALINA_HOME\"" \-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \org.apache.catalina.startup.Bootstrap "$@" startelse eval exec "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \-Dmy.pod.name="$MY_POD_NAME" \-Dmy.pod.namespace="$MY_POD_NAMESPACE" \-Dcatalina.base="\"$CATALINA_BASE\"" \-Dcatalina.home="\"$CATALINA_HOME\"" \-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \org.apache.catalina.startup.Bootstrap "$@" startfi 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" ]; thenPID=`cat "$CATALINA_PID"`ps -p $PID >/dev/null 2>&1if [ $? -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 1else echo "Removing/clearing stale PID file."rm -f "$CATALINA_PID" >/dev/null 2>&1if [ $? != 0 ]; then if [ -w "$CATALINA_PID" ]; thencat /dev/null > "$CATALINA_PID" else echo "Unable to remove or clear stale PID file. Start aborted." exit 1fi fi fi else echo "Unable to read PID file. Start aborted." exit 1fi elserm -f "$CATALINA_PID" >/dev/null 2>&1if [ $? != 0 ]; then if [ ! -w "$CATALINA_PID" ]; then echo "Unable to remove or write to empty PID file. Start aborted." exit 1fi fi fi fi fi shifttouch "$CATALINA_OUT" if [ "$1" = "-security" ] ; then if [ $have_tty -eq 1 ]; then echo "Using Security Manager" fi shift eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \-Djava.security.manager \-Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \-Dmy.pod.name="$MY_POD_NAME" \-Dmy.pod.namespace="$MY_POD_NAMESPACE" \-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\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \-Dmy.pod.name="$MY_POD_NAME" \-Dmy.pod.namespace="$MY_POD_NAMESPACE" \-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 shiftSLEEP=5if [ ! -z "$1" ]; then echo $1 | grep "[^0-9]" >/dev/null 2>&1if [ $? -gt 0 ]; thenSLEEP=$1 shift fi fiFORCE=0if [ "$1" = "-force" ]; then shiftFORCE=1fi if [ ! -z "$CATALINA_PID" ]; then if [ -f "$CATALINA_PID" ]; then if [ -s "$CATALINA_PID" ]; then kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1if [ $? -gt 0 ]; then echo "PID file found but no matching process was found. Stop aborted." exit 1fi 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 1fi fi eval "\"$_RUNJAVA\"" $LOGGING_MANAGER $JAVA_OPTS \-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \-Dmy.pod.name="$MY_POD_NAME" \-Dmy.pod.namespace="$MY_POD_NAMESPACE" \-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>&1fi fi if [ ! -z "$CATALINA_PID" ]; then if [ -f "$CATALINA_PID" ]; then while [ $SLEEP -ge 0 ]; do kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1if [ $? -gt 0 ]; thenrm -f "$CATALINA_PID" >/dev/null 2>&1if [ $? != 0 ]; then if [ -w "$CATALINA_PID" ]; thencat /dev/null > "$CATALINA_PID" # If Tomcat has stopped don't try and force a stop with an empty PID fileFORCE=0else echo "The PID file could not be removed or cleared." fi fi echo "Tomcat stopped." break fi if [ $SLEEP -gt 0 ]; thensleep 1fi 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"`fiSLEEP=`expr $SLEEP - 1 `done fi fiKILL_SLEEP_INTERVAL=5if [ $FORCE -eq 1 ]; then if [ -z "$CATALINA_PID" ]; then echo "Kill failed: \$CATALINA_PID not set" else if [ -f "$CATALINA_PID" ]; thenPID=`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>&1if [ $? -gt 0 ]; thenrm -f "$CATALINA_PID" >/dev/null 2>&1if [ $? != 0 ]; then if [ -w "$CATALINA_PID" ]; thencat /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 ]; thensleep 1fiKILL_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 \-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \-Dmy.pod.name="$MY_POD_NAME" \-Dmy.pod.namespace="$MY_POD_NAMESPACE" \-Dcatalina.base="\"$CATALINA_BASE\"" \-Dcatalina.home="\"$CATALINA_HOME\"" \-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \org.apache.catalina.startup.Bootstrap configtestresult=$?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.ServerInfoelse 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 start Start 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 n Stop 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 " configtest Run 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 1fi

ok, 制作自己的镜像并上传自己的私有仓库:

docker build -t 10.10.50.161:5000/mbn_containers/tomcat8-jre8:v1.0.0 .

docker push 10.10.50.161:5000/mbn_containers/tomcat8-jre8:v1.0.0

4: 步骤2

pod定义文件传入pod名称和pod命名空间

在rc的yaml中传入pod名称和pod命名空间变量,并对tomcat的logs目录进行主机数据卷映射:

tomcat-controller.yaml:

apiVersion: v1
kind: ReplicationController
metadata:name: mbn-tomcatnamespace: mbn
spec:replicas: 2selector:mbn-app: mbn-tomcattemplate:metadata:name: mbn-tomcatlabels:mbn-app: mbn-tomcatspec:containers:- name: tomcatimage: 10.10.50.161:5000/mbn_containers/tomcat8-jre8:v1.0.0volumeMounts:- name: varlogtomcat8mountPath: /usr/local/tomcat/logsreadOnly: falseenv:- name: MY_POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: MY_POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: MY_POD_IPvalueFrom:fieldRef:fieldPath: status.podIPports:- containerPort: 8080volumes:- name: varlogtomcat8hostPath:path: /var/log/tomcat8

ok,结束。运行起来后,在各个k8s的节点主机的/var/log/tomcat8目录下,看到的就是各个pod名称和pod命名空间唯一标识的日志文件了。

本文转自开源中国-在kubernetes上实现tomcat日志的持久化

在kubernetes上实现tomcat日志的持久化相关推荐

  1. 在Kibana上查看tomcat日志

    介绍 最近公司搭了套kibana的日志系统,感受比原来查看日志方便多了.记得以前查看日志是通过ssh到服务器,查看系统日志用vi查看器查看或者下载到本地,用logview查看搜索,可读性很低.自从用了 ...

  2. 通过XShell将linux服务器上的Tomcat下项目部署后,怎样对日志操作来调试

    场景 使用XShell将linux服务器上的Tomcat下的项目部署后, 发现项目跑不起来. 此时你想通过查看Tomcat运行的日志来调试. 实现 可以进入到Tomcat下的logs目录下 输入: l ...

  3. 在Kubernetes上搭建新版fluentd-elasticsearch_1.22日志收集工具

    背景介绍 第一,对于企业来说,日志的重要性不言而喻,就不赘述了. 第二,日志收集分析展示平台的选择,这里给出几点选择ELK的理由.ELK是一套非常成熟的系统,她本身的构架非常适合Kubernetes集 ...

  4. Kubernetes高效收集生产日志

    容器本身特性: 采集目标多:容器本身的特性导致采集目标多,需要采集容器内日志.容器 stdout.对于容器内部的文件日志采集,现在并没有一个很好的工具能够去动态发现采集.针对每种数据源都有对应的采集软 ...

  5. SpringCloud 应用在 Kubernetes 上的最佳实践 — 部署篇(开发部署)

    作者 | 孤弋  阿里云高级技术专家,负责 EDAS 的开发和用户体验优化工作. 导读:在上一篇文章<SpringCloud 应用在 Kubernetes 上的云上实践 - 开发篇>中讲到 ...

  6. SpringCloud应用在Kubernetes上的最佳实践—开发部署

    作者 | 孤弋  阿里云高级技术专家,负责 EDAS 的开发和用户体验优化工作. 导读:在上一篇文章<SpringCloud 应用在 Kubernetes 上的云上实践 - 开发篇>中讲到 ...

  7. helm安装_如何利用 Helm 在 Kubernetes 上快速部署 Jenkins

    Jenkins 做为最著名的 CI/CD 工具,在全世界范围内被广泛使用,而随着以 Kubernetes 为首的云平台的不断发展与壮大,在 Kubernetes 上运行 Jenkins 的需求越来越多 ...

  8. kubernetes上部署rook-ceph存储系统

    文章目录 1. 简单说说为什么用rook 2. rook-ceph部署 2.1 环境 2.2 Rook Operator部署 2.3 Ceph集群创建 2.3.1 标识osd节点 2.3.2 yaml ...

  9. 同程旅行大数据集群在 Kubernetes 上的服务化实践

    本文将向大家介绍同程旅行大数据集群在 Kubernetes 上服务化建设的一些实践和经验. 同程旅行大数据集群从 2017 年开始容器化改造,经历了自研调度 Docker 容器 ,到现在的云舱平台,采 ...

  10. 定时清理tomcat日志文件

    2019独角兽企业重金招聘Python工程师标准>>> 线上的tomcat没有关闭日志的输出,导致catalina.out会一直增长和localhost_access_log每天生成 ...

最新文章

  1. c语言中栈区运用原理形象图,C语言实现使用动态数组来构造栈结构
  2. 普通用户Mysql 5.6.13 主从,主主及nagios的mysql slave监控
  3. 删除重复数据sql语句
  4. 92. 反转链表 II golang
  5. DOM学习之路--Mr.Ember
  6. python2和python3中的map()
  7. python安装包的路径
  8. MATLAB基本介绍(1)
  9. 锂电池 保护板方案 中颖SH367309方案 原理图 PCB 源代码
  10. axure sketch 对比_Sketch 画原型比 Axure 好用吗?为什么
  11. 看视频用这个太爽了!自动实时翻译英语视频
  12. 易语言取php网页数据,易语言爬取网页内容方法
  13. Bert几个数据集的概念Cola、MRPC、XNLI、MNLI等
  14. android handle 用法
  15. 不同意安装条款就没法使用?新法规对APP霸王条款说“不”
  16. PVE7.0 CPU功耗调节
  17. python从某行开始读_如何从文件的某一行开始读取?
  18. docker安装php扩展大全
  19. QuteCom手记:Phapi/exosip事件②INVITE的响应
  20. js本地缓存-localStorage、sessionStorage

热门文章

  1. word20161219
  2. AngularJs(Part 3)--注册服务
  3. spark开发环境配置
  4. 进程间通信(三)共享内存和信号量
  5. [导入]使用ASP.NET AJAX的注意事项
  6. Java--继承(三)
  7. 列表、元组、字典、集合的定义与操作
  8. 前端工程师-JavaScript
  9. sqlserver修改实例名
  10. Object-C学习(一)——类别的创建、实现及调用