在kubernetes上实现tomcat日志的持久化

简介: 1: 前言 kubernetes的基本运行单元是pod,而pod是无状态的,pod可能会遇到挂掉,重启等情况.而tomcat运行在pod上,日志信息也存储在pod上。一旦pod挂了,存储在pod上的日志也就丢失了。

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.AsyncFileHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.AsyncFileHandler

org.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 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.
-->
<!-- Note: A "Server" is not itself a "Container", so you may not
 define 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 resources
 Documentation at /docs/jndi-resources-howto.html
 -->
 <GlobalNamingResources>
 <!-- Editable user database that can also be used by
 UserDatabaseRealm 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 share
 a 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 received
 and responses are returned. Documentation at :
 Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
 Java AJP Connector: /docs/config/ajp.html
 APR (HTTP/AJP) Connector: /docs/apr.html
 Define 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 8443
 This connector uses the NIO implementation that requires the JSSE
 style configuration. When using the APR/native implementation, the
 OpenSSL style configuration is required as described in the APR/native
 documentation -->
 <!--
 <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 processes
 every request. The Engine implementation for Tomcat stand alone
 analyzes the HTTP headers included with the request, and passes them
 on 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 passwords
 via a brute-force attack -->
 <Realm className="org.apache.catalina.realm.LockOutRealm">
 <!-- This Realm uses the UserDatabase configured in the global JNDI
 resources under the key "UserDatabase". Any edits
 that are performed against this UserDatabase are immediately
 available 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 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="${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" ]; 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 [ "`tty`" != "not a tty" ]; 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"`
 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" # 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 ]; then
 LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties" else # Bugzilla 45585
 LOGGING_CONFIG="-Dnop" fi fi if [ -z "$LOGGING_MANAGER" ]; then
 LOGGING_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; then
 USE_NOHUP="true" else
 USE_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" ]; 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 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" "$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 "$@" start
 else 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 "$@" 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\"" "\"$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
 else 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 "$@" 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
 touch "$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 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 no matching process was found. 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 \
 -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>&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 \
 -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 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 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 1

fi

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-tomcat
 namespace: mbn
spec:
 replicas: 2
 selector:
 mbn-app: mbn-tomcat
 template:
 metadata:
 name: mbn-tomcat
 labels:
 mbn-app: mbn-tomcat
 spec:
 containers:
 - name: tomcat
 image: 10.10.50.161:5000/mbn_containers/tomcat8-jre8:v1.0.0
 volumeMounts:
 - name: varlogtomcat8
 mountPath: /usr/local/tomcat/logs
 readOnly: false
 env:
 - name: MY_POD_NAME
 valueFrom:
 fieldRef:
 fieldPath: metadata.name
 - name: MY_POD_NAMESPACE
 valueFrom:
 fieldRef:
 fieldPath: metadata.namespace
 - name: MY_POD_IP
 valueFrom:
 fieldRef:
 fieldPath: status.podIP
 ports:
 - containerPort: 8080
 volumes:
 - name: varlogtomcat8
 hostPath:
 path: /var/log/tomcat8

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

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

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
2134 5
|
Kubernetes Ubuntu Windows
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
575 3
|
Java 应用服务中间件 Linux
Tomcat运行日志字符错乱/项目启动时控制台日志乱码问题
总结: 通过以上几种方法,概括如下:指定编码格式、设置JVM的文件编码、修改控制台输出编码、修正JSP页面编码和设置过滤器。遵循这些步骤,你可以依次排查和解决Tomcat运行日志字符错乱及项目启动时控制台日志乱码问题。希望这些建议能对你的问题提供有效的解决方案。
2506 16
|
监控 Java 应用服务中间件
Tomcat log日志解析
理解和解析Tomcat日志文件对于诊断和解决Web应用中的问题至关重要。通过分析 `catalina.out`、`localhost.log`、`localhost_access_log.*.txt`、`manager.log`和 `host-manager.log`等日志文件,可以快速定位和解决问题,确保Tomcat服务器的稳定运行。掌握这些日志解析技巧,可以显著提高运维和开发效率。
2080 13
|
Kubernetes API Docker
跟着iLogtail学习容器运行时与K8s下日志采集方案
iLogtail 作为开源可观测数据采集器,对 Kubernetes 环境下日志采集有着非常好的支持,本文跟随 iLogtail 的脚步,了解容器运行时与 K8s 下日志数据采集原理。
1638 8
|
消息中间件 Kubernetes API
在K8S中,如何收集k8s集群日志?
在K8S中,如何收集k8s集群日志?
|
运维 Kubernetes 监控
Loki+Promtail+Grafana监控K8s日志
综上,Loki+Promtail+Grafana 监控组合对于在 K8s 环境中优化日志管理至关重要,它不仅提供了强大且易于扩展的日志收集与汇总工具,还有可视化这些日志的能力。通过有效地使用这套工具,可以显著地提高对应用的运维监控能力和故障诊断效率。
2657 0
|
消息中间件 Kubernetes Kafka
微服务从代码到k8s部署应有尽有系列(十一、日志收集)
微服务从代码到k8s部署应有尽有系列(十一、日志收集)
|
Kubernetes Shell 网络安全
【Azure K8S】记录AKS VMSS实例日志收集方式
【Azure K8S】记录AKS VMSS实例日志收集方式
371 0
|
存储 Prometheus Kubernetes
在K8S中,如何收集K8S日志?有哪些方案?
在K8S中,如何收集K8S日志?有哪些方案?

推荐镜像

更多