Skip to content
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

Leader election events are recorded with the wrong HTTP client #2454

Closed
rubofelipe opened this issue Aug 22, 2023 · 1 comment · Fixed by #2464
Closed

Leader election events are recorded with the wrong HTTP client #2454

rubofelipe opened this issue Aug 22, 2023 · 1 comment · Fixed by #2464
Labels
kind/bug Categorizes issue or PR as related to a bug.

Comments

@rubofelipe
Copy link

rubofelipe commented Aug 22, 2023

The version v0.15.0 introduced an issue for controllers that use a separated kubeconfig for leader election:

mgr, err := ctrl.NewManager(configA, manager.Options{
    ...
    LeaderElectionConfig: configB,
})

The lease object is correctly created in the cluster pointed by the configB and the controller is able to acquire the leadership. However, an error is returned on creation of the Event object associated to the coordination object (e.g Lease):

E0821 20:38:02.494486       1 event.go:289] Unable to write event: '&v1.Event{*****}': 'Post "https://api.****:443/api/v1/namespaces/my-namespace/events": tls: failed to verify certificate: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "ca")'(may retry after sleeping)

The kubernetes API server is not trusting the certificate authority presented by the HTTP client.

The origin of this problem is the commit 4fd4f6e

A new an unique HTTP client was created into Options struct:

// setOptionsDefaults set default values for Options fields.
func setOptionsDefaults(options Options, config *rest.Config) (Options, error) {
if options.HTTPClient == nil {
var err error
options.HTTPClient, err = rest.HTTPClientFor(config)
if err != nil {
return options, err
}
}

This HTTP client is being copied to the Cluster struct and being passed as argument to the function that creates the leaderRecorderProvider:

if options.LeaderElectionConfig == nil {
leaderConfig = rest.CopyConfig(config)
leaderRecorderProvider = recorderProvider
} else {
leaderConfig = rest.CopyConfig(options.LeaderElectionConfig)
leaderRecorderProvider, err = options.newRecorderProvider(leaderConfig, cluster.GetHTTPClient(), cluster.GetScheme(), options.Logger.WithName("events"), options.makeBroadcaster)
if err != nil {
return nil, err
}
}

So the options.newRecorderProvider is receiving the LeaderElectionConfig (i.e. configB) and an HTTPClient based on configA. The options.newRecorderProvider is a function pointer that is pointing to NewProvider function:

func NewProvider(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster EventBroadcasterProducer) (*Provider, error) {
if httpClient == nil {
panic("httpClient must not be nil")
}
corev1Client, err := corev1client.NewForConfigAndClient(config, httpClient)
if err != nil {
return nil, fmt.Errorf("failed to init client: %w", err)
}
p := &Provider{scheme: scheme, logger: logger, makeBroadcaster: makeBroadcaster, evtClient: corev1Client.Events("")}
return p, nil
}

The documentation of NewForConfigAndClient function gives us an important info:

// NewForConfigAndClient creates a new CoreV1Client for the given config and http client.
// Note the http client provided takes precedence over the configured transport values.
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*CoreV1Client, error) {

The HTTP Client transport configurations have precedence in relation to the rest.Config argument. Because this HTTP Client was created with configA (which has different TLS certificate chain of trust), that means that is impossible to create Events on cluster informed on LeaderElectionConfig option, since the HTTP client won't use CA informed on LeaderElectionConfig.

@alvaroaleman
Copy link
Member

/kind bug

@k8s-ci-robot k8s-ci-robot added the kind/bug Categorizes issue or PR as related to a bug. label Aug 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants