-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add k8s metadata autodetection #13473
Add k8s metadata autodetection #13473
Conversation
b11d4ec
to
fe6f4ca
Compare
92f46a5
to
25e0373
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ChrsMark I haven't executed it (for now), so consider my comments code only.
It would be nice to an update on docs to explain how the autodetection works, maybe in this PR or at a follow up.
Signed-off-by: chrismark <chrismarkou92@gmail.com>
Signed-off-by: chrismark <chrismarkou92@gmail.com>
25e0373
to
7b89d95
Compare
Hey @odacremolbap thank you for reviewing. I think all your comments have been addressed. I would love to hear back if you notice anything else. As far as the docs' update is concerned, if it is needed I would go with a follow up PR. @jsoriano WDYT about his? |
Signed-off-by: chrismark <chrismarkou92@gmail.com>
7b89d95
to
2a9577f
Compare
Signed-off-by: chrismark <chrismarkou92@gmail.com>
4c4898e
to
cbd16eb
Compare
Signed-off-by: chrismark <chrismarkou92@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Let's wait for CI outcome
@jsoriano do you want to take a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that you have added some code to handle in-cluster configuration vs. explicitly specified kubeconfig, I am worried that this can cause some behavioural inconsistencies with other kubernetes features in Beats.
I think this code shouldn't be needed here. If it is needed then this is probably also required in other places and it should be added to some common place so all kubernetes clients are initialized consistently.
return true | ||
} | ||
return false | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be consistent with the logic to configure kubernetes clients along all our kubernetes features.
I think we shouldn't need to add special handling here to get the config path from the environment variables, or to get in-cluster configuration. If we need to add this logic for some reason, we should consider adding it in a common places, so logic is kept consistent along all kubernetes features.
Why did you need to add this logic?
We may need to revisit this conversation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the field InCluster
can be removed.
Regarding the searching of environmental variables or kubeconfig
in $HOME directory:
If we are not in an "incluster" mode then the autodetection will just fail if users have not set kube_config
in their configuration cause it will not be able to create a client etc. So auto-detection will be actually available only in "Incluster" deployments or we should require from the user to set the kubeconfig
.
In addition this code has do only with add_kubernetes_metadata
processor, so is it possible to affect other features too (really not sure about that, just asking).
So what we should do? I'm open on any proposal :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the field
InCluster
can be removed.
👍
Regarding the searching of environmental variables or
kubeconfig
in $HOME directory:
If we are not in an "incluster" mode then the autodetection will just fail if users have not setkube_config
in their configuration cause it will not be able to create a client etc. So auto-detection will be actually available only in "Incluster" deployments or we should require from the user to set thekubeconfig
.
I think that failing if in-cluster configuration is not available and kubeconfig is not set would be perfectly fine, and it would be consistent with the rest of kubernetes features.
Said that, I see that needing to set kubeconfig in all Kubernetes features can be cumbersome, we could try to explore the use of KUBECONFIG
env variable as an alternative to set it everywhere. But if something needs to be done for that I would do it in the common helpers, and in a separate PR.
In addition this code has do only with
add_kubernetes_metadata
processor, so is it possible to affect other features too (really not sure about that, just asking).So what we should do? I'm open on any proposal :)
I'd say to:
- Keep it failing if in-cluster configuration is not available and kubeconfig is not set. In any case the most common case for Kubernetes is to have in-cluster configuration working.
- Consider leveraging
KUBECONFIG
for all our Kubernetes features, but as a separate issue/PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
func isKubernetesAvailable(client k8s.Interface) bool { | ||
server, err := client.Discovery().ServerVersion() | ||
if err != nil { | ||
logp.Err("%v: could not detect kubernetes env: %v", "add_kubernetes_metadata", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be logged as error, as this is going to happen on any non-kubernetes deployment using the default configuration.
func defaultKubernetesAnnotatorConfig() kubeAnnotatorConfig { | ||
return kubeAnnotatorConfig{ | ||
KubeConfig: getSystemKubeConfig(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that in other places we are assuming that if no kubeconfig is specified, then in cluster configuration is wanted. We should keep this behaviour also here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it falls under the same doubts of #13473 (comment)
} else { | ||
logp.Err("%v: could not create kubernetes client using config: %v", "add_kubernetes_metadata", config.KubeConfig) | ||
} | ||
processor.kubernetesAvailable = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit. Set kubernetesAvailable
to false
already when initializing the processor
(or just don't set it as is the zero value), and only set it to true when all checks have been done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also here it is not needed to set processor.kubernetesAvailable = false
.
processor.kubernetesAvailable = false |
"original": "fields", | ||
}, | ||
}, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why initializing the cache if kubernetes is not available?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it is not required. It is just a left-over from copying the above test. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, try to remove it then 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
client, err := kubernetes.GetKubernetesClient(config.KubeConfig) | ||
if err != nil { | ||
return nil, err | ||
if config.InCluster { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config.InCluster
could be replaced by kubernetes.IsInCluster(config.KubeConfig)
as used in other places. Or at least it should be consistent with the result of this call.
So @jsoriano the big deal is about if we decide to have auto enablement of cc: @odacremolbap |
Signed-off-by: chrismark <chrismarkou92@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I have added some extra minor comments, please address them before merging.
CHANGELOG.next.asciidoc
Outdated
@@ -248,6 +248,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d | |||
- Add support for RFC3339 time zone offsets in JSON output. {pull}13227[13227] | |||
- Add autodetection mode for add_docker_metadata and enable it by default in included configuration files{pull}13374[13374] | |||
- Added `monitoring.cluster_uuid` setting to associate Beat data with specified ES cluster in Stack Monitoring UI. {pull}13182[13182] | |||
- Add autodetection mode for add_kubernetes_metadata and enable it by default in included configuration files{pull}13473[13473] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit.
- Add autodetection mode for add_kubernetes_metadata and enable it by default in included configuration files{pull}13473[13473] | |
- Add autodetection mode for add_kubernetes_metadata and enable it by default in included configuration files. {pull}13473[13473] |
libbeat/common/kubernetes/util.go
Outdated
@@ -36,6 +36,7 @@ const defaultNode = "localhost" | |||
// in cluster configuration based on the secrets mounted in the Pod. If kubeConfig is passed, | |||
// it parses the config file to get the config required to build a client. | |||
func GetKubernetesClient(kubeconfig string) (kubernetes.Interface, error) { | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit. Remove this added line.
} else { | ||
logp.Err("%v: could not create kubernetes client using config: %v", "add_kubernetes_metadata", config.KubeConfig) | ||
} | ||
processor.kubernetesAvailable = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also here it is not needed to set processor.kubernetesAvailable = false
.
processor.kubernetesAvailable = false |
if kubernetes.IsInCluster(config.KubeConfig) { | ||
logp.Err("%v: could not create kubernetes client using in_cluster config", "add_kubernetes_metadata") | ||
} else { | ||
logp.Err("%v: could not create kubernetes client using config: %v", "add_kubernetes_metadata", config.KubeConfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also these ones should be logged at debug level, because they are going to be logged in all non-kubernetes deployments.
@@ -26,17 +26,20 @@ import ( | |||
"github.com/elastic/beats/libbeat/common/kubernetes" | |||
"github.com/elastic/beats/libbeat/logp" | |||
"github.com/elastic/beats/libbeat/processors" | |||
|
|||
k8s "k8s.io/client-go/kubernetes" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This import should be placed before beats imports.
"fmt"
"time"
k8s "k8s.io/client-go/kubernetes"
"github.com/elastic/beats/libbeat/beat"
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/common/kubernetes"
"github.com/elastic/beats/libbeat/logp"
"github.com/elastic/beats/libbeat/processors"
And I wonder if we should use another alias, k8s
is basically the same as kubernetes
, maybe k8sclient
... Not sure.
Signed-off-by: chrismark <chrismarkou92@gmail.com>
This PR is a proposal for enabling autodetection mode for
add_kubernetes_metadata
.Currently we configure
add_cloud_metadata
andadd_host_metadata
by default in all Beats.add_cloud_metadata
does autodetection, and it will only enrich events if the beat is running on a known public cloud.It would be useful to have the same for Kubernetes, so if Beats is started in a scenario where Kubernetes is reachable with a default config, it automatically enables metadata for it. If Kubernetes is not reachable with a default config nothing will happen.
Part of: #13068
Depends on #13374
How to test it
a. Run metricbeat or filebeat inside a k8s cluster and without setting
kube_config
.b. Verify that processor is being automatically enabled. (Note that it will create a client in an
in_cluster
mode.)a. Run metricbeat or filebeat outside of a k8s cluster and without setting
kube_config
.b. Verify that processor is not being automatically enabled.
docs: https://www.elastic.co/guide/en/beats/filebeat/master/add-kubernetes-metadata.html#add-kubernetes-metadata