在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日志的持久化

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
1月前
|
存储 JSON 监控
可以通过配置Filebeat来将Higress日志持久化到磁盘
【2月更文挑战第10天】可以通过配置Filebeat来将Higress日志持久化到磁盘
27 4
|
4月前
|
消息中间件 存储 Kafka
阿里 P7 三面凉凉,kafka Borker 日志持久化没答上来
阿里 P7 三面凉凉,kafka Borker 日志持久化没答上来
|
4月前
|
Kubernetes 容器
k8s学习-CKS真题-日志审计 log audit
k8s学习-CKS真题-日志审计 log audit
73 0
|
4月前
|
Kubernetes Shell Linux
linux|shell脚本|有趣的知识---格式化输出日志和脚本调试方法以及kubernetes集群核心服务重启和集群证书备份脚本
linux|shell脚本|有趣的知识---格式化输出日志和脚本调试方法以及kubernetes集群核心服务重启和集群证书备份脚本
59 0
|
4月前
|
Kubernetes 监控 容器
k8s学习-CKA真题-监控Pod日志
k8s学习-CKA真题-监控Pod日志
78 0
|
1月前
|
Prometheus 监控 Kubernetes
Kubernetes 集群监控与日志管理实践
【2月更文挑战第29天】 在微服务架构日益普及的当下,Kubernetes 已成为容器编排的事实标准。然而,随着集群规模的扩大和业务复杂度的提升,有效的监控和日志管理变得至关重要。本文将探讨构建高效 Kubernetes 集群监控系统的策略,以及实施日志聚合和分析的最佳实践。通过引入如 Prometheus 和 Fluentd 等开源工具,我们旨在为运维专家提供一套完整的解决方案,以保障系统的稳定性和可靠性。
|
1月前
|
Prometheus 监控 Kubernetes
Kubernetes 集群的监控与日志管理实践
【2月更文挑战第31天】 在微服务架构日益普及的今天,容器编排工具如Kubernetes已成为部署、管理和扩展容器化应用的关键平台。然而,随着集群规模的扩大和业务复杂性的增加,如何有效监控集群状态、及时响应系统异常,以及管理海量日志信息成为了运维人员面临的重要挑战。本文将深入探讨 Kubernetes 集群监控的最佳实践和日志管理的高效策略,旨在为运维团队提供一套系统的解决思路和操作指南。
26 0
|
4月前
|
存储 Kubernetes Docker
k8s持久化储存:pv,pvc和nfs等相关技术
k8s持久化储存:pv,pvc和nfs等相关技术
|
4月前
|
存储 Kubernetes Cloud Native
云原生|kubernetes|apiserver审计日志的开启
云原生|kubernetes|apiserver审计日志的开启
49 0
|
4月前
|
Kubernetes Cloud Native 网络协议
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统
74 0