Many applications log to files. In a container environment this doesn’t work well. The file system is not persisted and logs are lost. In GKE you can persist log files to Cloud Logging with the Cloud Logging agent. The agent, however, doesn’t specify the required resource type. Causing the logs to appear as non-Kubernetes Container logs. This blog shows how to resolve that.
Cloud Logging Agent in GKE
The Cloud Logging agent is a Fluentd service configured with the Google Cloud output plugin. Events sent to the output plugin must include a Cloud Operations for GKE resource types. Since without any resource type, the event will be registered as a VM instance log record in Cloud Logging.
Set the Kubernetes Container resource type
Kubernetes Container events use resource type k8s_container.[namespace].[pod].[container] and are specified by the attribute logging.googleapis.com/local_resource_id using a Fluentd filter.
<filter **>
@type record_transformer
enable_ruby true
<record>
"logging.googleapis.com/local_resource_id" ${"k8s_container.#{ENV['K8S_NAMESPACE']}.#{ENV['K8S_POD']}.#{ENV['K8S_CONTAINER']}"}
</record>
</filter>
The entire configuration file is available on GitHub.
The filter uses Kubernetes’ Downward API to read resource type data from environment variables.
spec:
containers:
- name: application
- name: logging-agent
env:
- name: K8S_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: K8S_POD
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: K8S_CONTAINER
value: application
Deploy the GKE logging agent
The logging agent uses a sidecar container deployment to access application log files.
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
volumeMounts:
- name: logs
mountPath: /app/log
- name: gke-fluentd
env:
- name: K8S_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: K8S_POD
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: K8S_CONTAINER
value: app # Use the application container name
volumeMounts:
- name: logs
mountPath: /app/log
volumes:
- name: logs
emptyDir: {}
Try it yourself with the example application provided at GitHub.
Discussion
The logging agent allows us to persist logs. However, we don’t actually solve the problem of using log files in a container-environment..
In container-environments you should use cloud-native loggers, or stream all logs to the console. Changing the logger should be a dependency configuration-file update; and changing the logger behavior should be a logger configuration-file update.
Conclusion
The Cloud Logging agent allows you to keep using log files in container environments. Since the default configuration doesn’t specify the appropriate GKE resource types, you will have to maintain the agent. Therefore I recommend to fix your application logging. Allow configuration of a cloud-native logger and use structured logging to opt-in to all major log analysis services.
Image by Free-Photos from Pixabay