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

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
日志服务 SLS,月写入数据量 50GB 1个月
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 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日志的持久化

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
3月前
|
存储 Kubernetes 容器
Kubernetes 存储选项:持久化卷与存储类
【8月更文第29天】随着容器化的普及,越来越多的应用程序需要持久化数据以保持状态信息。Kubernetes 提供了一套完整的解决方案来管理和配置持久化存储,包括持久卷 (Persistent Volume, PV)、持久卷声明 (Persistent Volume Claim, PVC) 和存储类 (StorageClass)。本文将详细介绍这些概念,并通过实际示例来演示如何在 Kubernetes 中配置存储。
291 1
|
3月前
|
存储 Kubernetes 调度
在K8S中,怎样实现数据持久化?
在K8S中,怎样实现数据持久化?
|
6月前
|
存储 运维 监控
Kubernetes 集群监控与日志管理实践
【5月更文挑战第28天】在微服务架构日益普及的当下,容器编排工具如 Kubernetes 已成为运维工作的核心。有效的集群监控和日志管理是确保系统稳定性和服务可靠性的关键。本文将深入探讨 Kubernetes 集群的监控策略,以及如何利用现有的工具进行日志收集、存储和分析,以实现对集群健康状况的实时掌握和问题快速定位。
|
6月前
|
存储 监控 Kubernetes
Kubernetes 集群监控与日志管理实践
【5月更文挑战第27天】 在微服务架构日益普及的当下,容器化技术与编排工具如Kubernetes已成为现代云原生应用的基石。然而,随着集群规模的不断扩大和复杂性的增加,如何有效监控和管理这些动态变化的服务成为了维护系统稳定性的关键。本文将深入探讨Kubernetes环境下的监控策略和日志管理的最佳实践,旨在为运维人员提供一套系统的解决思路,确保应用性能的最优化和问题的快速定位。
|
3月前
|
存储 Kubernetes Cloud Native
告别数据丢失的噩梦!PersistentVolume全攻略,让你轻松玩转Kubernetes数据持久化秘籍!
【8月更文挑战第25天】随着容器技术的发展,Kubernetes已成为云原生应用的主流部署平台。然而,数据持久化成为一个亟待解决的问题。Kubernetes通过PersistentVolume(PV)提供了解决方案。PV是一种存储资源对象,它抽象出底层存储技术(例如Ceph、GlusterFS或NFS),让用户仅需关注存储容量和访问模式等属性。PV由管理员创建与维护,Pod通过PersistentVolumeClaim(PVC)请求存储资源。本文详细介绍了PV的工作原理、配置方法及示例,帮助读者更好地理解和应用此功能。
129 2
|
3月前
|
存储 Kubernetes 调度
在k8S中,Pod如何实现数据持久化?数据共享?跨节点Pod如何实现数据共享?
在k8S中,Pod如何实现数据持久化?数据共享?跨节点Pod如何实现数据共享?
|
3月前
|
存储 Kubernetes 容灾
在k8S中,K8S持久化可以对接哪些储存,为什么要选择它?
在k8S中,K8S持久化可以对接哪些储存,为什么要选择它?
|
3月前
|
XML Java Maven
logback在springBoot项目中的使用 springboot中使用日志进行持久化保存日志信息
这篇文章详细介绍了如何在Spring Boot项目中使用logback进行日志记录,包括Maven依赖配置、logback配置文件的编写,以及实现的日志持久化和控制台输出效果。
logback在springBoot项目中的使用 springboot中使用日志进行持久化保存日志信息
|
3月前
|
C# Windows 开发者
超越选择焦虑:深入解析WinForms、WPF与UWP——谁才是打造顶级.NET桌面应用的终极利器?从开发效率到视觉享受,全面解读三大框架优劣,助你精准匹配项目需求,构建完美桌面应用生态系统
【8月更文挑战第31天】.NET框架为开发者提供了多种桌面应用开发选项,包括WinForms、WPF和UWP。WinForms简单易用,适合快速开发基本应用;WPF提供强大的UI设计工具和丰富的视觉体验,支持XAML,易于实现复杂布局;UWP专为Windows 10设计,支持多设备,充分利用现代硬件特性。本文通过示例代码详细介绍这三种框架的特点,帮助读者根据项目需求做出明智选择。以下是各框架的简单示例代码,便于理解其基本用法。
163 0
|
3月前
|
存储 Kubernetes 调度
在K8S中,是怎么实现数据持久化的?
在K8S中,是怎么实现数据持久化的?