I have a spring boot application with the below docker file.
FROM docker.com/base/jdk1.8:latest
MAINTAINER Application Engineering [ https://docker.com/ ]
RUN mkdir -p /opt/docker/svc
COPY application/weather-service.war /opt/docker/svc/
CMD java -jar /opt/docker/svc/weather-service.war --spring.config.location=file:/conf/application.properties -Dlogging.config=/conf/logback.xml
I can use kubernetes configMap or secrets for application.properties and use the volume mount option as below.
"spec": {
        "volumes": [
          {
            "name": "svc-prop",
            "configMap": {
              "name": "svc-app-config",
              "items": [
                {
                  "key": "application.properties",
                  "path": "application.properties"
                }
              ]
            }
          }
         ],
        "containers": [
          "volumeMounts": [
              {
                "name": "svc-prop",
                "mountPath": "/conf"
              }
         ]
How can i achieve the samething for logback.xml. Do i need to use secrets as a file in this case?
I dont want to bundle logback.xml file with the image as we might be changing the log level at runtime.
Is there any other better approach for keeping logback.xml for spring boot app in Kubernetes?
These logs are usually located in the /var/log/containers directory on your host. If a container restarts, kubelet keeps logs on the node. To prevent logs from filling up all the available space on the node, Kubernetes has a log rotation policy set in place.
Kubernetes Pod Log Location If you log in to any Kubernetes worker node and go to /var/log/containers the directory, you will find a log file for each container running on that node. The log file naming scheme follows /var/log/pods/<namespace>_<pod_name>_<pod_id>/<container_name>/ .
The manifest will be sent to the server that will proceed it and store it in etcd - similarly to all Kubernetes objects.
Usually you do not want to provide the whole logback.xml file but rather it's logger list which requires updating at runtime most frequently. 
In order to achieve this you can use Logback's file inclusion feature:
logback.xml file as usual except logger list. Use include element instead:    <configuration scan="true" scanPeriod="10 seconds" debug="true">
        <appender ...></appender>
        <root level="INFO">...</root>
        <!-- Import loggers configuration from external file -->
        <include file="config/mount/loggers-include.xml"/>
    </configuration>
Note those scan* attributes. They are essential for log config reloading at runtime.
Define all the loggers in Kubernetes ConfigMap with loggers-include.xml data section:
apiVersion: v1
kind: ConfigMap
metadata:
  name: microservice-loggers    # the name to refer to from deployment (see below)
  namespace: upc
data:
  loggers-include.xml: |+
    <included>
      <logger name="org.springframework.cloud.netflix.zuul" level="INFO"/>
      <logger name="com.netflix.zuul" level="INFO"/>                              
      <logger name="com.netflix.hystrix" level="INFO"/>                          
      <logger name="com.netflix.ribbon" level="DEBUG"/>
      <logger name="com.netflix.loadbalancer" level="INFO"/>                     
    </included>
Note that all the included content must be enclosed in included tag in order to be correctly parsed by Logback.
Mount your ConfigMap's data into container as config/mount/loggers-include.xml file:
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  template:
    ...
    spec:
      # declare the volume created from ConfigMap
      volumes:
        - name: config-volume             # used with this name below
          configMap:
            name: microservice-loggers    # declared in previous step
      containers:
      - name: microservice
        ...
        ports:
          ...
        # mount the volume declared above to container's file system
        volumeMounts:
          - mountPath: /microservice/config/mount
            name: config-volume       # declared above
Note that mount directory must not be created neither by container itself nor its image. Moreover, if such a directory exists, all its content will be removed during mounting.
Apply the ConfigMap and run the declared deployment. To check if loggers file is correctly mounted execute the following command:
$ kubectl exec restorun-7d757b7c6-wcslx -- ls -l /microservice/config/mount
total 0
lrwxrwxrwx    1 root     root            26 Aug 14 05:52 loggers-include.xml -> ..data/loggers-include.xml
Also if you've set  debug=true attribute in Logback's configuration element (see step 1) then you should see the following record in STDOUT during application startup:
05:52:17,031 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@6e06451e - Adding [file:/microservice/config/mount/loggers-include.xml] to configuration watch list.
Now you can edit your ConfigMap (e.g. set com.netflix.hystrix to level WARN), save its file and tell Kubernetes to apply the changes to the application:
$ kubectl apply -f microservice-log-configmap.yaml
configmap "microservice-loggers" configured
Again, Logback should reflect the changes by logging with the following message to standard output:
    05:59:16,974 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.netflix.hystrix] to WARN
You can also check the effective logging level by directly asking it from the Spring Boot Actuator (if you have an access to this endpoint):
$ curl http://<k8s-external-ip>/actuator/loggers/com.netflix.hystrix
{
  "configuredLevel" : "WARN",
  "effectiveLevel" : "WARN"
}
If the level stays the same, wait for a minute and check again: it takes some time for changes to propagate through Kubernetes and Logback. More info on this topic:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With