From 384b91aa13df9d2aa197c79b9ce51448be8389b4 Mon Sep 17 00:00:00 2001 From: George Kechagias Date: Mon, 19 May 2025 10:02:05 +0300 Subject: [PATCH 1/8] K8SPSMDB-297 support persistent logs --- build/Dockerfile | 1 + build/init-entrypoint.sh | 5 +- build/logcollector/entrypoint.sh | 21 ++++ .../logcollector/fluentbit/custom/defaul.conf | 0 build/logcollector/fluentbit/fluentbit.conf | 2 + .../fluentbit/fluentbit_mongo.conf | 27 ++++ build/logcollector/logrotate/logrotate.conf | 10 ++ build/ps-entry.sh | 5 + ...mdb.percona.com_perconaservermongodbs.yaml | 116 +++++++++++++++++ deploy/bundle.yaml | 116 +++++++++++++++++ deploy/cr.yaml | 7 ++ deploy/crd.yaml | 116 +++++++++++++++++ deploy/cw-bundle.yaml | 116 +++++++++++++++++ e2e-tests/version-service/conf/crd.yaml | 116 +++++++++++++++++ pkg/apis/psmdb/v1/psmdb_types.go | 12 ++ pkg/apis/psmdb/v1/zz_generated.deepcopy.go | 26 ++++ .../perconaservermongodb/psmdb_controller.go | 2 - .../reconcile-statefulset/cfg-arbiter.yaml | 39 ++++++ .../reconcile-statefulset/cfg-mongod.yaml | 39 ++++++ .../reconcile-statefulset/cfg-nv.yaml | 39 ++++++ .../reconcile-statefulset/rs0-arbiter.yaml | 2 + .../reconcile-statefulset/rs0-mongod.yaml | 39 ++++++ .../reconcile-statefulset/rs0-nv.yaml | 39 ++++++ pkg/psmdb/config/const.go | 10 +- pkg/psmdb/container.go | 7 ++ pkg/psmdb/logcollector/container.go | 117 ++++++++++++++++++ pkg/psmdb/logcollector/container_test.go | 56 +++++++++ pkg/psmdb/statefulset.go | 9 ++ 28 files changed, 1087 insertions(+), 7 deletions(-) create mode 100755 build/logcollector/entrypoint.sh create mode 100644 build/logcollector/fluentbit/custom/defaul.conf create mode 100644 build/logcollector/fluentbit/fluentbit.conf create mode 100644 build/logcollector/fluentbit/fluentbit_mongo.conf create mode 100644 build/logcollector/logrotate/logrotate.conf create mode 100644 pkg/psmdb/logcollector/container.go create mode 100644 pkg/psmdb/logcollector/container_test.go diff --git a/build/Dockerfile b/build/Dockerfile index c07770ce3b..8cff2c7c45 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -53,5 +53,6 @@ COPY build/init-entrypoint.sh /init-entrypoint.sh COPY build/ps-entry.sh /ps-entry.sh COPY build/physical-restore-ps-entry.sh /physical-restore-ps-entry.sh COPY build/pbm-entry.sh /pbm-entry.sh +COPY build/logcollector /logcollector USER 2 diff --git a/build/init-entrypoint.sh b/build/init-entrypoint.sh index c36a17446d..ec1e05f6c1 100755 --- a/build/init-entrypoint.sh +++ b/build/init-entrypoint.sh @@ -6,4 +6,7 @@ set -o xtrace install -o "$(id -u)" -g "$(id -g)" -m 0755 -D /ps-entry.sh /opt/percona/ps-entry.sh install -o "$(id -u)" -g "$(id -g)" -m 0755 -D /physical-restore-ps-entry.sh /opt/percona/physical-restore-ps-entry.sh install -o "$(id -u)" -g "$(id -g)" -m 0755 -D /mongodb-healthcheck /opt/percona/mongodb-healthcheck -install -o "$(id -u)" -g "$(id -g)" -m 0755 -D /pbm-entry.sh /opt/percona/pbm-entry.sh \ No newline at end of file +install -o "$(id -u)" -g "$(id -g)" -m 0755 -D /pbm-entry.sh /opt/percona/pbm-entry.sh +cp -a /logcollector /opt/percona/ +chown -R "$(id -u)":"$(id -g)" /opt/percona/logcollector +chmod -R 0755 /opt/percona/logcollector diff --git a/build/logcollector/entrypoint.sh b/build/logcollector/entrypoint.sh new file mode 100755 index 0000000000..d9a69b8b30 --- /dev/null +++ b/build/logcollector/entrypoint.sh @@ -0,0 +1,21 @@ +#!/bin/sh +set -e +set -o xtrace + +export PATH="$PATH":/opt/fluent-bit/bin + +if [ "$1" = 'logrotate' ]; then + if [[ $EUID != 1001 ]]; then + # logrotate requires UID in /etc/passwd + sed -e "s^x:1001:^x:$EUID:^" /etc/passwd >/tmp/passwd + cat /tmp/passwd >/etc/passwd + rm -rf /tmp/passwd + fi + exec go-cron "0 0 * * *" sh -c "logrotate -s /data/logs/logrotate.status /opt/percona/logcollector/logrotate/logrotate.conf;/usr/bin/find /data/logs/ -mtime +7 ! -name logrotate.status -delete" +else + if [ "$1" = 'fluent-bit' ]; then + fluentbit_opt+='-c /opt/percona/logcollector/fluentbit/fluentbit.conf' + fi + + exec "$@" "$fluentbit_opt" +fi diff --git a/build/logcollector/fluentbit/custom/defaul.conf b/build/logcollector/fluentbit/custom/defaul.conf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/logcollector/fluentbit/fluentbit.conf b/build/logcollector/fluentbit/fluentbit.conf new file mode 100644 index 0000000000..75ff9d06fe --- /dev/null +++ b/build/logcollector/fluentbit/fluentbit.conf @@ -0,0 +1,2 @@ +@INCLUDE fluentbit_*.conf +@INCLUDE custom/*.conf diff --git a/build/logcollector/fluentbit/fluentbit_mongo.conf b/build/logcollector/fluentbit/fluentbit_mongo.conf new file mode 100644 index 0000000000..12958aaf61 --- /dev/null +++ b/build/logcollector/fluentbit/fluentbit_mongo.conf @@ -0,0 +1,27 @@ +[SERVICE] + Flush 1 + Log_Level debug + Daemon off + parsers_file json + +[INPUT] + Name tail + Path ${LOG_DATA_DIR}/mongod.log + Tag ${POD_NAMESPACE}.${POD_NAME}.mongod.log + Refresh_Interval 5 + DB /tmp/flb_kube.db + multiline.parser multiline-regex-test + read_from_head true + Path_Key file + +[OUTPUT] + Name stdout + Match * + Format json_lines + json_date_key false + +[OUTPUT] + Name file + Match ${POD_NAMESPACE}.${POD_NAME}.mongod.log + File mongod.full.log + Path ${LOG_DATA_DIR}/ diff --git a/build/logcollector/logrotate/logrotate.conf b/build/logcollector/logrotate/logrotate.conf new file mode 100644 index 0000000000..aab10cea61 --- /dev/null +++ b/build/logcollector/logrotate/logrotate.conf @@ -0,0 +1,10 @@ +/data/logs/*.log { + daily + minsize 10M + maxsize 100M + rotate 10 + missingok + nocompress + notifempty + sharedscripts +} diff --git a/build/ps-entry.sh b/build/ps-entry.sh index 98c4efe542..7af373c811 100755 --- a/build/ps-entry.sh +++ b/build/ps-entry.sh @@ -480,6 +480,11 @@ if [[ $originalArgOne == mongo* ]]; then _mongod_hack_rename_arg_save_val --sslDisabledProtocols --tlsDisabledProtocols "${mongodHackedArgs[@]}" fi + if [[ $originalArgOne == "mongod" ]]; then + _mongod_hack_ensure_arg_val --logpath "/data/logs/mongod.log" "${mongodHackedArgs[@]}" + _mongod_hack_ensure_arg --logappend "${mongodHackedArgs[@]}" + fi + set -- "${mongodHackedArgs[@]}" # MongoDB 3.6+ defaults to localhost-only binding diff --git a/config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml b/config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml index 2bc2c8fa14..9fc840a780 100644 --- a/config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml +++ b/config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml @@ -534,6 +534,122 @@ spec: type: object initImage: type: string + logcollector: + properties: + configuration: + type: string + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + enabled: + type: boolean + image: + type: string + imagePullPolicy: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object multiCluster: properties: DNSSuffix: diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index 4312065d7b..f48adc09a4 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -1247,6 +1247,122 @@ spec: type: object initImage: type: string + logcollector: + properties: + configuration: + type: string + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + enabled: + type: boolean + image: + type: string + imagePullPolicy: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object multiCluster: properties: DNSSuffix: diff --git a/deploy/cr.yaml b/deploy/cr.yaml index 13d2858c5d..8640e04728 100644 --- a/deploy/cr.yaml +++ b/deploy/cr.yaml @@ -743,3 +743,10 @@ spec: # storageName: s3-us-west # compressionType: gzip # compressionLevel: 6 + logcollector: + enabled: true + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + resources: + requests: + memory: 100M + cpu: 200m diff --git a/deploy/crd.yaml b/deploy/crd.yaml index b41742a74f..f06ccdfabb 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -1247,6 +1247,122 @@ spec: type: object initImage: type: string + logcollector: + properties: + configuration: + type: string + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + enabled: + type: boolean + image: + type: string + imagePullPolicy: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object multiCluster: properties: DNSSuffix: diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index debf6c4f93..a5297950c3 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -1247,6 +1247,122 @@ spec: type: object initImage: type: string + logcollector: + properties: + configuration: + type: string + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + enabled: + type: boolean + image: + type: string + imagePullPolicy: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object multiCluster: properties: DNSSuffix: diff --git a/e2e-tests/version-service/conf/crd.yaml b/e2e-tests/version-service/conf/crd.yaml index b41742a74f..f06ccdfabb 100644 --- a/e2e-tests/version-service/conf/crd.yaml +++ b/e2e-tests/version-service/conf/crd.yaml @@ -1247,6 +1247,122 @@ spec: type: object initImage: type: string + logcollector: + properties: + configuration: + type: string + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + enabled: + type: boolean + image: + type: string + imagePullPolicy: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object multiCluster: properties: DNSSuffix: diff --git a/pkg/apis/psmdb/v1/psmdb_types.go b/pkg/apis/psmdb/v1/psmdb_types.go index f36c9e519b..b450723816 100644 --- a/pkg/apis/psmdb/v1/psmdb_types.go +++ b/pkg/apis/psmdb/v1/psmdb_types.go @@ -97,6 +97,7 @@ type PerconaServerMongoDBSpec struct { Users []User `json:"users,omitempty"` Roles []Role `json:"roles,omitempty"` VolumeExpansionEnabled bool `json:"enableVolumeExpansion,omitempty"` + LogCollector *LogCollectorSpec `json:"logcollector,omitempty"` } type UserRole struct { @@ -1356,3 +1357,14 @@ func (cr *PerconaServerMongoDB) PBMResyncInProgress() bool { v, ok := cr.Annotations[AnnotationResyncInProgress] return ok && v != "" } + +// LogCollectorSpec defines the configuration for enabling and customizing +// the log collection component that stores logs in a PVC. +type LogCollectorSpec struct { + Enabled bool `json:"enabled,omitempty"` + Image string `json:"image,omitempty"` + Resources corev1.ResourceRequirements `json:"resources,omitempty"` + Configuration string `json:"configuration,omitempty"` + ContainerSecurityContext *corev1.SecurityContext `json:"containerSecurityContext,omitempty"` + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` +} diff --git a/pkg/apis/psmdb/v1/zz_generated.deepcopy.go b/pkg/apis/psmdb/v1/zz_generated.deepcopy.go index d77375368a..f6150cb826 100644 --- a/pkg/apis/psmdb/v1/zz_generated.deepcopy.go +++ b/pkg/apis/psmdb/v1/zz_generated.deepcopy.go @@ -451,6 +451,27 @@ func (in *LivenessProbeExtended) DeepCopy() *LivenessProbeExtended { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LogCollectorSpec) DeepCopyInto(out *LogCollectorSpec) { + *out = *in + in.Resources.DeepCopyInto(&out.Resources) + if in.ContainerSecurityContext != nil { + in, out := &in.ContainerSecurityContext, &out.ContainerSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LogCollectorSpec. +func (in *LogCollectorSpec) DeepCopy() *LogCollectorSpec { + if in == nil { + return nil + } + out := new(LogCollectorSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MongodSpecInMemory) DeepCopyInto(out *MongodSpecInMemory) { *out = *in @@ -1347,6 +1368,11 @@ func (in *PerconaServerMongoDBSpec) DeepCopyInto(out *PerconaServerMongoDBSpec) (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.LogCollector != nil { + in, out := &in.LogCollector, &out.LogCollector + *out = new(LogCollectorSpec) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PerconaServerMongoDBSpec. diff --git a/pkg/controller/perconaservermongodb/psmdb_controller.go b/pkg/controller/perconaservermongodb/psmdb_controller.go index 500f05c0f1..7d46011529 100644 --- a/pkg/controller/perconaservermongodb/psmdb_controller.go +++ b/pkg/controller/perconaservermongodb/psmdb_controller.go @@ -46,8 +46,6 @@ import ( "github.com/percona/percona-server-mongodb-operator/pkg/version" ) -var secretFileMode int32 = 288 - // Add creates a new PerconaServerMongoDB Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(mgr manager.Manager) error { diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml index 6567f52ef7..dc9263aa73 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml @@ -144,6 +144,8 @@ spec: readOnly: true - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: my-cluster-name-mongodb-encryption-key readOnly: true @@ -201,6 +203,43 @@ spec: readOnly: true - mountPath: /data/db name: mongod-data + - name: logs + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "fluent-bit" ] + env: + - name: LOG_DATA_DIR + value: /data/logs + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin + - name: logrotate + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "logrotate" ] + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin initContainers: - command: - /init-entrypoint.sh diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml index 6567f52ef7..dc9263aa73 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml @@ -144,6 +144,8 @@ spec: readOnly: true - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: my-cluster-name-mongodb-encryption-key readOnly: true @@ -201,6 +203,43 @@ spec: readOnly: true - mountPath: /data/db name: mongod-data + - name: logs + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "fluent-bit" ] + env: + - name: LOG_DATA_DIR + value: /data/logs + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin + - name: logrotate + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "logrotate" ] + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin initContainers: - command: - /init-entrypoint.sh diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml index 6567f52ef7..dc9263aa73 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml @@ -144,6 +144,8 @@ spec: readOnly: true - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: my-cluster-name-mongodb-encryption-key readOnly: true @@ -201,6 +203,43 @@ spec: readOnly: true - mountPath: /data/db name: mongod-data + - name: logs + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "fluent-bit" ] + env: + - name: LOG_DATA_DIR + value: /data/logs + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin + - name: logrotate + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "logrotate" ] + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin initContainers: - command: - /init-entrypoint.sh diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml index 68597bedd7..f2cc061f04 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml @@ -145,6 +145,8 @@ spec: readOnly: true - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: my-cluster-name-mongodb-encryption-key readOnly: true diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml index f0e28a4f50..94509b21df 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml @@ -144,6 +144,8 @@ spec: readOnly: true - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: my-cluster-name-mongodb-encryption-key readOnly: true @@ -201,6 +203,43 @@ spec: readOnly: true - mountPath: /data/db name: mongod-data + - name: logs + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "fluent-bit" ] + env: + - name: LOG_DATA_DIR + value: /data/logs + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin + - name: logrotate + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "logrotate" ] + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin initContainers: - command: - /init-entrypoint.sh diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml index 17dc3e5683..b34b3ab7bb 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml @@ -143,6 +143,8 @@ spec: readOnly: true - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: my-cluster-name-mongodb-encryption-key readOnly: true @@ -200,6 +202,43 @@ spec: readOnly: true - mountPath: /data/db name: mongod-data + - name: logs + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "fluent-bit" ] + env: + - name: LOG_DATA_DIR + value: /data/logs + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin + - name: logrotate + image: perconalab/percona-xtradb-cluster-operator:main-logcollector + command: [ "/opt/percona/logcollector/entrypoint.sh" ] + args: [ "logrotate" ] + resources: + requests: + cpu: 200m + memory: 100M + volumeMounts: + - mountPath: /data/logs + name: mongod-data-logs + - mountPath: /opt/percona + name: bin initContainers: - command: - /init-entrypoint.sh diff --git a/pkg/psmdb/config/const.go b/pkg/psmdb/config/const.go index 3f4dbbe566..386e086ea7 100644 --- a/pkg/psmdb/config/const.go +++ b/pkg/psmdb/config/const.go @@ -15,12 +15,14 @@ const ( MinWiredTigerCacheSizeGB float64 = 0.25 // MongodDataVolClaimName is a PVC Claim name - MongodDataVolClaimName = "mongod-data" + MongodDataVolClaimName = "mongod-data" + MongodDataLogsVolClaimName = "mongod-data-logs" // MongodContainerDataDir is a mongo data path in container MongodContainerDataDir = "/data/db" - - BinVolumeName = "bin" - BinMountPath = "/opt/percona" + // MongodContainerDataLogsDir is a mongo data path in container for logs. + MongodContainerDataLogsDir = "/data/logs" + BinVolumeName = "bin" + BinMountPath = "/opt/percona" LDAPConfVolClaimName = "ldap" LDAPConfDir = "/etc/openldap" diff --git a/pkg/psmdb/container.go b/pkg/psmdb/container.go index 27ebc11e64..c502b37127 100644 --- a/pkg/psmdb/container.go +++ b/pkg/psmdb/container.go @@ -66,6 +66,13 @@ func container(ctx context.Context, cr *api.PerconaServerMongoDB, replset *api.R }...) } + if cr.CompareVersion("1.20.0") >= 0 { // TODO change this to 1.21 + volumes = append(volumes, corev1.VolumeMount{ + Name: config.MongodDataLogsVolClaimName, + MountPath: config.MongodContainerDataLogsDir, + }) + } + encryptionEnabled, err := isEncryptionEnabled(cr, replset) if err != nil { return corev1.Container{}, err diff --git a/pkg/psmdb/logcollector/container.go b/pkg/psmdb/logcollector/container.go new file mode 100644 index 0000000000..7d6ca76824 --- /dev/null +++ b/pkg/psmdb/logcollector/container.go @@ -0,0 +1,117 @@ +package logcollector + +import ( + "github.com/pkg/errors" + corev1 "k8s.io/api/core/v1" + + api "github.com/percona/percona-server-mongodb-operator/pkg/apis/psmdb/v1" + "github.com/percona/percona-server-mongodb-operator/pkg/psmdb/config" +) + +func Containers(cr *api.PerconaServerMongoDB) ([]corev1.Container, error) { + if cr.Spec.LogCollector == nil || !cr.Spec.LogCollector.Enabled { + return nil, nil + } + + logCont, err := logContainer(cr) + if err != nil { + return nil, err + } + + logRotationCont, err := logRotationContainer(cr) + if err != nil { + return nil, err + } + + return []corev1.Container{*logCont, *logRotationCont}, nil +} + +func logContainer(cr *api.PerconaServerMongoDB) (*corev1.Container, error) { + if cr.Spec.LogCollector == nil { + return nil, errors.New("logcollector can't be nil") + } + + envs := []corev1.EnvVar{ + { + Name: "LOG_DATA_DIR", + Value: config.MongodContainerDataLogsDir, + }, + { + Name: "POD_NAMESPACE", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "metadata.namespace", + }, + }, + }, + { + Name: "POD_NAME", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "metadata.name", + }, + }, + }, + } + + container := corev1.Container{ + Name: "logs", + Image: cr.Spec.LogCollector.Image, + ImagePullPolicy: cr.Spec.LogCollector.ImagePullPolicy, + Env: envs, + Args: []string{ + "fluent-bit", + }, + Command: []string{"/opt/percona/logcollector/entrypoint.sh"}, + SecurityContext: cr.Spec.LogCollector.ContainerSecurityContext, + Resources: cr.Spec.LogCollector.Resources, + VolumeMounts: []corev1.VolumeMount{ + { + Name: config.MongodDataLogsVolClaimName, + MountPath: config.MongodContainerDataLogsDir, + }, + { + Name: config.BinVolumeName, + MountPath: config.BinMountPath, + }, + }, + } + + return &container, nil +} + +func logRotationContainer(cr *api.PerconaServerMongoDB) (*corev1.Container, error) { + if cr.Spec.LogCollector == nil { + return nil, errors.New("logcollector can't be nil") + } + + container := corev1.Container{ + Name: "logrotate", + Image: cr.Spec.LogCollector.Image, + ImagePullPolicy: cr.Spec.LogCollector.ImagePullPolicy, + SecurityContext: cr.Spec.LogCollector.ContainerSecurityContext, + Resources: cr.Spec.LogCollector.Resources, + Args: []string{ + "logrotate", + }, + Command: []string{"/opt/percona/logcollector/entrypoint.sh"}, + VolumeMounts: []corev1.VolumeMount{ + { + Name: config.MongodDataLogsVolClaimName, + MountPath: config.MongodContainerDataLogsDir, + }, + { + Name: config.BinVolumeName, + MountPath: config.BinMountPath, + }, + }, + } + + if cr.Spec.LogCollector.Configuration != "" { + container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ + Name: "logcollector-config", + MountPath: "/etc/fluentbit/custom", + }) + } + return &container, nil +} diff --git a/pkg/psmdb/logcollector/container_test.go b/pkg/psmdb/logcollector/container_test.go new file mode 100644 index 0000000000..8699259acc --- /dev/null +++ b/pkg/psmdb/logcollector/container_test.go @@ -0,0 +1,56 @@ +package logcollector + +import ( + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + api "github.com/percona/percona-server-mongodb-operator/pkg/apis/psmdb/v1" +) + +func TestContainers(t *testing.T) { + tests := map[string]struct { + logCollector *api.LogCollectorSpec + expectedContainerNames []string + }{ + "nil logcollector": {}, + "logcollector disabled": { + logCollector: &api.LogCollectorSpec{ + Enabled: false, + }, + }, + "logcollector enabled": { + logCollector: &api.LogCollectorSpec{ + Enabled: true, + Image: "test-image", + ImagePullPolicy: corev1.PullIfNotPresent, + }, + expectedContainerNames: []string{"logs", "logrotate"}, + }, + } + + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + cr := &api.PerconaServerMongoDB{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster", + Namespace: "default", + }, + Spec: api.PerconaServerMongoDBSpec{ + LogCollector: tt.logCollector, + }, + } + + containers, err := Containers(cr) + assert.NoError(t, err) + + var gotNames []string + for _, c := range containers { + gotNames = append(gotNames, c.Name) + } + assert.Equal(t, tt.expectedContainerNames, gotNames) + }) + } +} diff --git a/pkg/psmdb/statefulset.go b/pkg/psmdb/statefulset.go index 7dd83d35db..4af6f902b7 100644 --- a/pkg/psmdb/statefulset.go +++ b/pkg/psmdb/statefulset.go @@ -14,6 +14,7 @@ import ( api "github.com/percona/percona-server-mongodb-operator/pkg/apis/psmdb/v1" "github.com/percona/percona-server-mongodb-operator/pkg/naming" "github.com/percona/percona-server-mongodb-operator/pkg/psmdb/config" + "github.com/percona/percona-server-mongodb-operator/pkg/psmdb/logcollector" "github.com/percona/percona-server-mongodb-operator/pkg/psmdb/pmm" ) @@ -274,6 +275,14 @@ func StatefulSpec(ctx context.Context, cr *api.PerconaServerMongoDB, replset *ap if pmmC != nil { containers = append(containers, *pmmC) } + + if cr.CompareVersion("1.20.0") >= 0 { // TODO: change this to 1.21 + logCollectorCs, err := logcollector.Containers(cr) + if err != nil { + log.Error(err, "error preparing logcollector containers") + } + containers = append(containers, logCollectorCs...) + } } volumes = multiAZ.WithSidecarVolumes(logf.FromContext(ctx), volumes) From 5937f7eec768b8e0267a4404eb01ba0a55f5c9dc Mon Sep 17 00:00:00 2001 From: George Kechagias Date: Wed, 21 May 2025 17:35:47 +0300 Subject: [PATCH 2/8] bring back volume creation which was removed accicentally by conflict resolution --- .../reconcile-statefulset/cfg-arbiter.yaml | 11 +++++ .../reconcile-statefulset/cfg-mongod.yaml | 11 +++++ .../reconcile-statefulset/cfg-nv.yaml | 11 +++++ .../reconcile-statefulset/rs0-arbiter.yaml | 2 + .../reconcile-statefulset/rs0-mongod.yaml | 11 +++++ .../reconcile-statefulset/rs0-nv.yaml | 11 +++++ pkg/psmdb/statefulset.go | 40 ++++++++++++++----- 7 files changed, 86 insertions(+), 11 deletions(-) diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml index dc9263aa73..b962faae9d 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml @@ -303,4 +303,15 @@ spec: resources: requests: storage: 3Gi + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: mongod-data-logs + namespace: reconcile-statefulset + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi status: {} diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml index dc9263aa73..b962faae9d 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml @@ -303,4 +303,15 @@ spec: resources: requests: storage: 3Gi + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: mongod-data-logs + namespace: reconcile-statefulset + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi status: {} diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml index dc9263aa73..b962faae9d 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml @@ -303,4 +303,15 @@ spec: resources: requests: storage: 3Gi + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: mongod-data-logs + namespace: reconcile-statefulset + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi status: {} diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml index f2cc061f04..ee24e02804 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml @@ -202,5 +202,7 @@ spec: secretName: internal-reconcile-statefulset-cr-users - emptyDir: {} name: mongod-data + - emptyDir: { } + name: mongod-data-logs updateStrategy: type: OnDelete diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml index 94509b21df..2a48549943 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml @@ -303,3 +303,14 @@ spec: resources: requests: storage: 3Gi + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: mongod-data-logs + namespace: reconcile-statefulset + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml index b34b3ab7bb..550ba59f6f 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml @@ -302,3 +302,14 @@ spec: resources: requests: storage: 3Gi + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: mongod-data-logs + namespace: reconcile-statefulset + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi diff --git a/pkg/psmdb/statefulset.go b/pkg/psmdb/statefulset.go index 4af6f902b7..150072c040 100644 --- a/pkg/psmdb/statefulset.go +++ b/pkg/psmdb/statefulset.go @@ -239,27 +239,45 @@ func StatefulSpec(ctx context.Context, cr *api.PerconaServerMongoDB, replset *ap if ls[naming.LabelKubernetesComponent] == "arbiter" { volumes = append(volumes, - corev1.Volume{ - Name: config.MongodDataVolClaimName, - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, + []corev1.Volume{ + { + Name: config.MongodDataVolClaimName, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, }, - }, + { + Name: config.MongodDataLogsVolClaimName, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + }..., ) } else { if volumeSpec.PersistentVolumeClaim.PersistentVolumeClaimSpec != nil { volumeClaimTemplates = []corev1.PersistentVolumeClaim{ PersistentVolumeClaim(config.MongodDataVolClaimName, cr.Namespace, volumeSpec), + PersistentVolumeClaim(config.MongodDataLogsVolClaimName, cr.Namespace, volumeSpec), } } else { volumes = append(volumes, - corev1.Volume{ - Name: config.MongodDataVolClaimName, - VolumeSource: corev1.VolumeSource{ - HostPath: volumeSpec.HostPath, - EmptyDir: volumeSpec.EmptyDir, + []corev1.Volume{ + { + Name: config.MongodDataVolClaimName, + VolumeSource: corev1.VolumeSource{ + HostPath: volumeSpec.HostPath, + EmptyDir: volumeSpec.EmptyDir, + }, }, - }, + { + Name: config.MongodDataLogsVolClaimName, + VolumeSource: corev1.VolumeSource{ + HostPath: volumeSpec.HostPath, + EmptyDir: volumeSpec.EmptyDir, + }, + }, + }..., ) } From 823d89c3676988dbca244a07d32a14e403f62e1b Mon Sep 17 00:00:00 2001 From: George Kechagias Date: Wed, 21 May 2025 18:17:34 +0300 Subject: [PATCH 3/8] try json parser --- build/logcollector/fluentbit/fluentbit_mongo.conf | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build/logcollector/fluentbit/fluentbit_mongo.conf b/build/logcollector/fluentbit/fluentbit_mongo.conf index 12958aaf61..4315ba49b3 100644 --- a/build/logcollector/fluentbit/fluentbit_mongo.conf +++ b/build/logcollector/fluentbit/fluentbit_mongo.conf @@ -1,8 +1,14 @@ +[PARSER] + Name json + Format json + Time_Key t.$date + Time_Format %Y-%m-%dT%H:%M:%S.%L%z + [SERVICE] Flush 1 Log_Level debug Daemon off - parsers_file json + Parser json [INPUT] Name tail @@ -10,7 +16,7 @@ Tag ${POD_NAMESPACE}.${POD_NAME}.mongod.log Refresh_Interval 5 DB /tmp/flb_kube.db - multiline.parser multiline-regex-test + Parser json read_from_head true Path_Key file From 35507002c57b6de748e84dde82c68d78e75ef180 Mon Sep 17 00:00:00 2001 From: George Kechagias Date: Thu, 22 May 2025 00:58:36 +0300 Subject: [PATCH 4/8] code review fixes and bugs --- build/logcollector/entrypoint.sh | 2 +- .../logcollector/fluentbit/fluentbit_mongo.conf | 10 +--------- .../fluentbit/parsers_multiline.conf | 17 +++++++++++++++++ build/ps-entry.sh | 2 +- pkg/apis/psmdb/v1/psmdb_types.go | 4 ++++ .../reconcile-statefulset/cfg-arbiter.yaml | 2 ++ .../reconcile-statefulset/cfg-mongod.yaml | 2 ++ .../testdata/reconcile-statefulset/cfg-nv.yaml | 2 ++ .../reconcile-statefulset/rs0-arbiter.yaml | 2 ++ .../reconcile-statefulset/rs0-mongod.yaml | 2 ++ .../testdata/reconcile-statefulset/rs0-nv.yaml | 2 ++ pkg/psmdb/container.go | 9 +++++++++ 12 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 build/logcollector/fluentbit/parsers_multiline.conf diff --git a/build/logcollector/entrypoint.sh b/build/logcollector/entrypoint.sh index d9a69b8b30..a601fe620f 100755 --- a/build/logcollector/entrypoint.sh +++ b/build/logcollector/entrypoint.sh @@ -17,5 +17,5 @@ else fluentbit_opt+='-c /opt/percona/logcollector/fluentbit/fluentbit.conf' fi - exec "$@" "$fluentbit_opt" + exec "$@" $fluentbit_opt fi diff --git a/build/logcollector/fluentbit/fluentbit_mongo.conf b/build/logcollector/fluentbit/fluentbit_mongo.conf index 4315ba49b3..beb8ab4073 100644 --- a/build/logcollector/fluentbit/fluentbit_mongo.conf +++ b/build/logcollector/fluentbit/fluentbit_mongo.conf @@ -1,14 +1,7 @@ -[PARSER] - Name json - Format json - Time_Key t.$date - Time_Format %Y-%m-%dT%H:%M:%S.%L%z - [SERVICE] Flush 1 - Log_Level debug + Log_Level error Daemon off - Parser json [INPUT] Name tail @@ -16,7 +9,6 @@ Tag ${POD_NAMESPACE}.${POD_NAME}.mongod.log Refresh_Interval 5 DB /tmp/flb_kube.db - Parser json read_from_head true Path_Key file diff --git a/build/logcollector/fluentbit/parsers_multiline.conf b/build/logcollector/fluentbit/parsers_multiline.conf new file mode 100644 index 0000000000..7409846f7c --- /dev/null +++ b/build/logcollector/fluentbit/parsers_multiline.conf @@ -0,0 +1,17 @@ +[MULTILINE_PARSER] + name multiline-regex-test + type regex + flush_timeout 1000 + # + # Regex rules for multiline parsing + # --------------------------------- + # + # configuration hints: + # + # - first state always has the name: start_state + # - every field in the rule must be inside double quotes + # + # rules | state name | regex pattern | next state + # ------|---------------|-------------------------------------------- + rule "start_state" "/\d{2,4}\-\d{2,4}\-\d{2,4}T\d{2,4}\:\d{2,4}\:\d{2,4}\.\d{1,6}Z(.*)|\d{2,6} \d{2,4}\:\d{2,4}\:\d{2,4}(.*)/" "cont" + rule "cont" "/^\D/" "cont" diff --git a/build/ps-entry.sh b/build/ps-entry.sh index 7af373c811..82e2d73ee2 100755 --- a/build/ps-entry.sh +++ b/build/ps-entry.sh @@ -480,7 +480,7 @@ if [[ $originalArgOne == mongo* ]]; then _mongod_hack_rename_arg_save_val --sslDisabledProtocols --tlsDisabledProtocols "${mongodHackedArgs[@]}" fi - if [[ $originalArgOne == "mongod" ]]; then + if [[ $originalArgOne == "mongod" && "${LOGCOLLECTOR_ENABLED:-}" == "true" ]]; then _mongod_hack_ensure_arg_val --logpath "/data/logs/mongod.log" "${mongodHackedArgs[@]}" _mongod_hack_ensure_arg --logappend "${mongodHackedArgs[@]}" fi diff --git a/pkg/apis/psmdb/v1/psmdb_types.go b/pkg/apis/psmdb/v1/psmdb_types.go index b450723816..da7a53d8c9 100644 --- a/pkg/apis/psmdb/v1/psmdb_types.go +++ b/pkg/apis/psmdb/v1/psmdb_types.go @@ -1368,3 +1368,7 @@ type LogCollectorSpec struct { ContainerSecurityContext *corev1.SecurityContext `json:"containerSecurityContext,omitempty"` ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` } + +func (cr *PerconaServerMongoDB) IsLogCollectorEnabled() bool { + return cr.Spec.LogCollector != nil && cr.Spec.LogCollector.Enabled +} diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml index b962faae9d..03ff7e953c 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml @@ -79,6 +79,8 @@ spec: value: "27017" - name: MONGODB_REPLSET value: cfg + - name: LOGCOLLECTOR_ENABLED + value: "true" envFrom: - secretRef: name: internal-reconcile-statefulset-cr-users diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml index b962faae9d..03ff7e953c 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml @@ -79,6 +79,8 @@ spec: value: "27017" - name: MONGODB_REPLSET value: cfg + - name: LOGCOLLECTOR_ENABLED + value: "true" envFrom: - secretRef: name: internal-reconcile-statefulset-cr-users diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml index b962faae9d..03ff7e953c 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml @@ -79,6 +79,8 @@ spec: value: "27017" - name: MONGODB_REPLSET value: cfg + - name: LOGCOLLECTOR_ENABLED + value: "true" envFrom: - secretRef: name: internal-reconcile-statefulset-cr-users diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml index ee24e02804..5e6e09766b 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml @@ -79,6 +79,8 @@ spec: value: "27017" - name: MONGODB_REPLSET value: rs0 + - name: LOGCOLLECTOR_ENABLED + value: "true" envFrom: - secretRef: name: internal-reconcile-statefulset-cr-users diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml index 2a48549943..851fe2d855 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml @@ -79,6 +79,8 @@ spec: value: "27017" - name: MONGODB_REPLSET value: rs0 + - name: LOGCOLLECTOR_ENABLED + value: "true" envFrom: - secretRef: name: internal-reconcile-statefulset-cr-users diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml index 550ba59f6f..49e76382c7 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml @@ -79,6 +79,8 @@ spec: value: "27017" - name: MONGODB_REPLSET value: rs0 + - name: LOGCOLLECTOR_ENABLED + value: "true" envFrom: - secretRef: name: internal-reconcile-statefulset-cr-users diff --git a/pkg/psmdb/container.go b/pkg/psmdb/container.go index c502b37127..56f5e55e94 100644 --- a/pkg/psmdb/container.go +++ b/pkg/psmdb/container.go @@ -175,6 +175,15 @@ func container(ctx context.Context, cr *api.PerconaServerMongoDB, replset *api.R container.Command = []string{config.BinMountPath + "/ps-entry.sh"} } + if cr.CompareVersion("1.20.0") >= 0 { + if cr.IsLogCollectorEnabled() { + container.Env = append(container.Env, corev1.EnvVar{ + Name: "LOGCOLLECTOR_ENABLED", + Value: "true", + }) + } + } + return container, nil } From cf08be732076977ece73c5653a2e372a37def898 Mon Sep 17 00:00:00 2001 From: George Kechagias Date: Thu, 22 May 2025 01:28:12 +0300 Subject: [PATCH 5/8] bump compare version check to 1.21 --- pkg/psmdb/container.go | 4 ++-- pkg/psmdb/statefulset.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/psmdb/container.go b/pkg/psmdb/container.go index 56f5e55e94..51592ff0ed 100644 --- a/pkg/psmdb/container.go +++ b/pkg/psmdb/container.go @@ -66,7 +66,7 @@ func container(ctx context.Context, cr *api.PerconaServerMongoDB, replset *api.R }...) } - if cr.CompareVersion("1.20.0") >= 0 { // TODO change this to 1.21 + if cr.CompareVersion("1.21.0") >= 0 { volumes = append(volumes, corev1.VolumeMount{ Name: config.MongodDataLogsVolClaimName, MountPath: config.MongodContainerDataLogsDir, @@ -175,7 +175,7 @@ func container(ctx context.Context, cr *api.PerconaServerMongoDB, replset *api.R container.Command = []string{config.BinMountPath + "/ps-entry.sh"} } - if cr.CompareVersion("1.20.0") >= 0 { + if cr.CompareVersion("1.21.0") >= 0 { if cr.IsLogCollectorEnabled() { container.Env = append(container.Env, corev1.EnvVar{ Name: "LOGCOLLECTOR_ENABLED", diff --git a/pkg/psmdb/statefulset.go b/pkg/psmdb/statefulset.go index 150072c040..caa5c2d6b8 100644 --- a/pkg/psmdb/statefulset.go +++ b/pkg/psmdb/statefulset.go @@ -294,7 +294,7 @@ func StatefulSpec(ctx context.Context, cr *api.PerconaServerMongoDB, replset *ap containers = append(containers, *pmmC) } - if cr.CompareVersion("1.20.0") >= 0 { // TODO: change this to 1.21 + if cr.CompareVersion("1.21.0") >= 0 { logCollectorCs, err := logcollector.Containers(cr) if err != nil { log.Error(err, "error preparing logcollector containers") From a4366a238546270819b8494bf7f2742534d6f7ce Mon Sep 17 00:00:00 2001 From: George Kechagias Date: Thu, 22 May 2025 11:46:19 +0300 Subject: [PATCH 6/8] fix e2e tests --- .../compare/statefulset_monitoring-pmm3-cfg-oc.yml | 12 ++++++++++++ .../compare/statefulset_monitoring-pmm3-cfg.yml | 12 ++++++++++++ .../statefulset_monitoring-pmm3-rs0-no-pmm-oc.yml | 12 ++++++++++++ .../statefulset_monitoring-pmm3-rs0-no-pmm.yml | 12 ++++++++++++ .../compare/statefulset_monitoring-pmm3-rs0-oc.yml | 12 ++++++++++++ .../compare/statefulset_monitoring-pmm3-rs0.yml | 12 ++++++++++++ 6 files changed, 72 insertions(+) diff --git a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg-oc.yml b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg-oc.yml index 0720b9596e..00514ca774 100644 --- a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg-oc.yml +++ b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg-oc.yml @@ -141,6 +141,8 @@ spec: name: config - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: monitoring-pmm3-mongodb-encryption-key readOnly: true @@ -329,3 +331,13 @@ spec: storage: 3Gi status: phase: Pending + - metadata: + name: mongod-data-logs + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + status: + phase: Pending diff --git a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg.yml b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg.yml index e73c9939e3..858b53c45e 100644 --- a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg.yml +++ b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg.yml @@ -142,6 +142,8 @@ spec: name: config - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: monitoring-pmm3-mongodb-encryption-key readOnly: true @@ -331,3 +333,13 @@ spec: storage: 3Gi status: phase: Pending + - metadata: + name: mongod-data-logs + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + status: + phase: Pending diff --git a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-no-pmm-oc.yml b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-no-pmm-oc.yml index 73ca5e0e86..c575b85692 100644 --- a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-no-pmm-oc.yml +++ b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-no-pmm-oc.yml @@ -129,6 +129,8 @@ spec: name: config - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: monitoring-pmm3-mongodb-encryption-key readOnly: true @@ -200,3 +202,13 @@ spec: storage: 1Gi status: phase: Pending + - metadata: + name: mongod-data-logs + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + status: + phase: Pending diff --git a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-no-pmm.yml b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-no-pmm.yml index 6247c9542a..351b7f49d8 100644 --- a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-no-pmm.yml +++ b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-no-pmm.yml @@ -130,6 +130,8 @@ spec: name: config - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: monitoring-pmm3-mongodb-encryption-key readOnly: true @@ -202,3 +204,13 @@ spec: storage: 1Gi status: phase: Pending + - metadata: + name: mongod-data-logs + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + status: + phase: Pending diff --git a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-oc.yml b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-oc.yml index 5fcc35f416..1f79bfba42 100644 --- a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-oc.yml +++ b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0-oc.yml @@ -129,6 +129,8 @@ spec: name: config - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: monitoring-pmm3-mongodb-encryption-key readOnly: true @@ -317,3 +319,13 @@ spec: storage: 1Gi status: phase: Pending + - metadata: + name: mongod-data-logs + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + status: + phase: Pending diff --git a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0.yml b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0.yml index daa7b4caf4..11c5104cbf 100644 --- a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0.yml +++ b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-rs0.yml @@ -130,6 +130,8 @@ spec: name: config - mountPath: /opt/percona name: bin + - mountPath: /data/logs + name: mongod-data-logs - mountPath: /etc/mongodb-encryption name: monitoring-pmm3-mongodb-encryption-key readOnly: true @@ -319,3 +321,13 @@ spec: storage: 1Gi status: phase: Pending + - metadata: + name: mongod-data-logs + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + status: + phase: Pending From ef9f35c5ca06d063600c61004b6b8299af60da4d Mon Sep 17 00:00:00 2001 From: George Kechagias Date: Thu, 22 May 2025 13:27:35 +0300 Subject: [PATCH 7/8] fix typo in file name --- build/logcollector/fluentbit/custom/{defaul.conf => default.conf} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename build/logcollector/fluentbit/custom/{defaul.conf => default.conf} (100%) diff --git a/build/logcollector/fluentbit/custom/defaul.conf b/build/logcollector/fluentbit/custom/default.conf similarity index 100% rename from build/logcollector/fluentbit/custom/defaul.conf rename to build/logcollector/fluentbit/custom/default.conf From 40121b4bf4561c837f0f24dc38668e452e6393c9 Mon Sep 17 00:00:00 2001 From: George Kechagias Date: Thu, 22 May 2025 13:48:50 +0300 Subject: [PATCH 8/8] fix cfg pvc storage size --- .../compare/statefulset_monitoring-pmm3-cfg-oc.yml | 2 +- .../monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg-oc.yml b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg-oc.yml index 00514ca774..3529e731ac 100644 --- a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg-oc.yml +++ b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg-oc.yml @@ -338,6 +338,6 @@ spec: - ReadWriteOnce resources: requests: - storage: 1Gi + storage: 3Gi status: phase: Pending diff --git a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg.yml b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg.yml index 858b53c45e..84b595828d 100644 --- a/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg.yml +++ b/e2e-tests/monitoring-pmm3/compare/statefulset_monitoring-pmm3-cfg.yml @@ -340,6 +340,6 @@ spec: - ReadWriteOnce resources: requests: - storage: 1Gi + storage: 3Gi status: phase: Pending