cockroach-operator: operator incorrectly uses `--logtostderr` + can't use new --log flag with Operator
I attempted to specify the new --log
flag in the custom resource:
additionalArgs:
- "--log='sinks: {file-groups: {ops: {channels: [OPS, HEALTH]}}}'"
This resulted in the pods crashing:
NAME READY STATUS RESTARTS AGE
cockroach-operator-d4df75996-pdpmd 1/1 Running 0 135m
cockroachdb-0 0/1 CrashLoopBackOff 11 34m
cockroachdb-1 0/1 CrashLoopBackOff 11 34m
cockroachdb-2 0/1 CrashLoopBackOff 11 34m
The kubectl logs show:
++ expr 8192 / 4
++ expr 8192 / 4
+ exec /cockroach/cockroach.sh start --join=cockroachdb-0.cockroachdb.default:26258,cockroachdb-1.cockroachdb.default:26258,cockroachdb-2.cockroachdb.default:26258 --advertise-host=cockroachdb-0.cockroachdb.default --logtostderr=INFO --certs-dir=/cockroach/cockroach-certs/ --http-port=8080 --sql-addr=:26257 --listen-addr=:26258 --cache 2048MiB --max-sql-memory 2048MiB '--log=sinks: {file-groups: {ops: {channels: [OPS, HEALTH]}}}'
Flag --logtostderr has been deprecated, use --log instead to specify 'sinks: {stderr: {filter: ...}}'.
E210621 20:27:35.192687 1 1@cli/error.go:399 [-] 1 ERROR: --log is incompatible with legacy discrete logging flags
ERROR: --log is incompatible with legacy discrete logging flags
Since --logtostderr
is deprecated in v21.1 (and according to @knz we shouldn’t be logging to stderr anyway), perhaps this line in the code should be removed. I believe the logging behavior would then default to this configuration.
If we do need to log to stderr
on Kubernetes, I believe the equivalent v21.1 flag is:
--log="sinks: {stderr: {channels: all, filter: INFO}}"
It looks like --logtostderr
is also used in a couple .golden
files, but I’m not sure how relevant those are.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Comments: 23 (9 by maintainers)
Okay, so I took some time to explore the solution space here and I have a few updates.
For version 21.1 and beyond, we can capture the appropriate log messages using the following log config on startup:
cockroach start --log='sinks: {stderr: {channels: OPS, redact: true}}' <other flags>
This will only pass redacted messages from the OPS channel to the stderr sink as Raphael pointed out above.
For versions 20.1 and 20.2 that we are supporting on the Operator the story is a bit more complicated. I spoke with Raphael, Josh on our SRE team for Cloud, and Daniel from the SE team about expectations for K8s logs. On CockroachCloud, we actually do not log anything out to stderr (outside of the initial logs emitted on node startup) in K8s and instead the SREs exec into pods to check logs. Josh noted that this ran against his expectations initially but this has become standard practice and the team is now used to doing this. Of course, this still runs the risk that if the node is crashing, you won’t be able to access logs that are persisted. Josh noted that having the full unredacted logs available somewhere is important as an operator though.
Daniel from our field team had a similar concern. When he has stood up K8s instances for customers, he usually sets up a sidecar pod to separately persist logs or streams them out to a log collection service. This lines up with our long term vision, but the complexity of setting up a sidecar for logging is too much for the GA timeline.
Raphael suggested that we may be able to backport some log redaction functionality into the 20.x releases. @knz would you please share how much of an effort you would expect that to be? I’m very hesitant to go with this route for the GA release for the operator in ~2 weeks.
In sum, we have 3 options here:
Given our time constraints and that the SRE team has been using option 3 in prod in CockroachCloud, I would lean towards option 3. Versions 20.x will only be supported for another year, and depending on our TDB support policy for the operator, we may even sunset those versions earlier. After that, all versions will be able to support the above setting available from v21.1 and beyond.
ok so this is still a “bug” issue, not “enhancement”.
I think we’ve been talking past each other and somehow I have not been successful at conveying how serious the situation is.
I’m going to rephrase this more clearly.
As of today, the current operator code wrt logging has been misdesigned. What is being done was incorrect from the start, and the fact nobody noticed does not detract from the fact it’s a problem and needs to be corrected. (See this definition)
What is wrong exactly?
the flag
--logtostderr
exposes sensitive information to the process’ stderr in a way that does not provide redactability. Consequently, plugging that output to thekubectl log
command can defeat IT policies about confidentiality.This is a serious issue that multiple customers have complained about in the 19.x cycle and we solved in 20.1/20.2 by creating product features and generally documenting that stderr logging should not be used, but somehow this operator project did not get the memo.
the flag
--logtostderr
creates output that cannot be reliably parsed. Presumably, customers who integrate with orchestration wish the ability to process logging data automatically. The output produced by crdb on its stderr stream fails at this. Even though it looks like something parseable on the surface, it is a documented fact that under stress and in problem situations, the log entries become malformed. This is not fixable via stderr logging, but is fixable via file or network logging.Right now the default config used by the k8s operator code is mistakenly giving users the impression they can rely on the logging output by
kubectl log
and automate log monitoring etc based on that data. This is a lie to our users/customers.you and others who are working on the operator project are working under the mistaken impression that “logging” is somehow distinct from “database state”. I see this for example in your suggestion that “if we store log files we’d need ephemeral storage” or the question “how would the operator look at the logs without execing into the node”. That is something we need to work on culturally.
In a nutshell, crdb logging data has the same quality as general stored SQL data.
We don’t think about “how would the operator access the SQL data without execing into the node”, right? To access SQL data, we open a SQL client.
The same applies to crdb logs. To access the log data, we use the log retrieval API (over HTTP).
Generally, the log files should be treated with the same level of care for persistence and confidentiality as the data files: they are absolutely crucial to preserve durably, just like the crdb store data directories, and that’s specificially the reason why crdb choses a
logs
sub-directory of the store directory by default. If the customer cares about at-rest confidentiality, the log files should be encrypted together with the data files.Right now, we are lucky that the flag
--logtostderr
merely copies log data to stderr but still preserves crdb’s default behavior, which is to also create discrete files in thelogs
directory. The statefulset code, either intendedly or not, was not implemented to explicitly disable writing logging data to files in the store directory, and that’s a good thing!starting in v21.2, the
--logtostderr
flag will be removed. So the current startup code will break.the best practice with distributed systems with crdb is to aggregate the logging output from all the nodes into a network logging collector. Arguably, it is the k8s operator’s role to spawn a logging collector, such as Fluentd, alongside the crdb nodes inside the k8s cluster and “plug” the services together by making the logging config inside crdb point to the logging collector. This way the crdb nodes would send their data reliably, in a parseable format, to Fluentd, where it can be stored reliably and confidentially.
This organization for log collection is what both our on-prem customers and our CC teams have requested and we’ve built in 21.1. It is legitimately the best practice for SREs and our k8s operator should definitely exemplify this best practice.
I am surprised this hasn’t been discussed yet.
So these are the problems and now let’s review the suitable actions:
crdb-v2
format or JSON with a network collector--logtostderr
flagLet me know if you have further questions.
@piyush-singh can you please document business requirements. And keep in mind we always need logging to console.