Kubernetes 部署 - 外部化日志文件

Kubernetes deployment - Externalizing log file

我有一个 spring 引导应用程序,其中包含以下 docker 文件。

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

我可以使用 kubernetes configMap 或 secrets application.properties 并使用如下的卷装载选项。

"spec": {
        "volumes": [
          {
            "name": "svc-prop",
            "configMap": {
              "name": "svc-app-config",
              "items": [
                {
                  "key": "application.properties",
                  "path": "application.properties"
                }
              ]
            }
          }
         ],
        "containers": [
          "volumeMounts": [
              {
                "name": "svc-prop",
                "mountPath": "/conf"
              }
         ]

我怎样才能为 logback.xml 实现相同的目标?在这种情况下,我需要将机密用作文件吗?

我不想将 logback.xml 文件与图像捆绑在一起,因为我们可能会在运行时更改日志级别。

有没有其他更好的方法可以在 Kubernetes 中为 spring 启动应用程序保留 logback.xml?

您已经完成了...使用 ConfigMap 并在需要更新 logback.xml 时使用 "kubectl edit" 更新 ConfigMap。

当 ConfigMap 或 Secret 更新时,它最终会反映在容器内,如果这样配置,例如通过 scan,那么应用程序最终会接受更改。如果不是,则需要重新启动 pod 以获取更新的 logback.xml.

为 logback 创建一个 configmap。

apiVersion: v1
kind: ConfigMap
metadata:
  name: logback-configmap
data:
  logback.xml: |+
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <include resource="org/springframework/boot/logging/logback/base.xml"/>
      <logger name="org.springframework.web" level="DEBUG"/>
    </configuration>

将 configmap 指定为部署中的卷。

  volumes:
  - configMap:
      name: logback-configmap
    name: logback

在您的容器中安装 configmap 卷。

    volumeMounts:
    - mountPath: /path/to/logback.xml
      name: logback

通常您不想提供整个 logback.xml 文件,而是 logger 需要在运行时最频繁更新的列表。 为了实现这一点,您可以使用 Logback's file inclusion 功能:

  1. 像往常一样编写 logback.xml 文件,但 logger 列表除外。使用 include 元素代替:
    <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>

注意那些 scan* 属性。它们对于在运行时重新加载日志配置至关重要。

  1. loggers-include.xml 数据部分定义 Kubernetes ConfigMap 中的所有记录器:

    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>
    

    注意,所有被包含的内容必须包含在included标签中,才能被Logback正确解析。

  2. 将您的 ConfigMap 数据作为 config/mount/loggers-include.xml 文件装载到容器中:

    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
    

    请注意,mount 目录不得由容器本身或其映像创建。此外,如果存在这样的目录,则其所有内容将在挂载过程中被删除

  3. Apply the ConfigMap and run the declared deployment。要检查记录器文件是否正确安装,请执行以下命令:

    $ 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
    

    此外,如果您在 Logback 的 configuration 元素中设置了 debug=true 属性(参见第 1 步),那么您应该在应用程序启动期间在 STDOUT 中看到以下记录:

    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.
    
  4. 现在您可以编辑您的 ConfigMap(例如将 com.netflix.hystrix 设置为级别 WARN),保存其文件并告诉 Kubernetes 将更改应用到应用程序:

    $ kubectl apply -f microservice-log-configmap.yaml
    configmap "microservice-loggers" configured
    

    同样,Logback 应该通过将以下消息记录到标准输出来反映更改:

        05:59:16,974 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.netflix.hystrix] to WARN
    

    您还可以通过直接从 Spring Boot Actuator(如果您有权访问此端点)询问来检查有效日志记录级别:

    $ curl http://<k8s-external-ip>/actuator/loggers/com.netflix.hystrix
    {
      "configuredLevel" : "WARN",
      "effectiveLevel" : "WARN"
    }
    

如果级别保持不变,请等待一分钟并再次检查:更改通过 Kubernetes 和 Logback 传播需要一些时间。有关此主题的更多信息: