-
Notifications
You must be signed in to change notification settings - Fork 168
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
Support for multiple replicas with auto-tls #198
Conversation
Uses a leader-elector sidecar to ensure only one injector replica generates the CA and cert+key. The other replicas pick up the cert+key from a k8s secret for use in their TLS listeners. The leader-elector sidecars coordinate using the annotations of a k8s Endpoint object, which is why those extra permissions were added to the role in the deployment yaml. Build a dev image: `make image VERSION=dev` Deploy: `kubectl apply -k deploy/ -n vault`
Added command-line and env option to control leader-elector usage. Using Secrets informer for followers to ensure retrieving timely cert updates without overloading the k8s api.
Added ttl and health checks to leader-elector. Added AGENT_INJECT_USE_LEADER_ELECTOR env option to deployment.
Slightly refactored the leader package so it's more testable
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.
Nice! LGTM
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
…r' into VAULT-84/leader-elector-container
Using the community gcr registry (k8s.gcr.io), election arg to match the endpoint deploy yaml, and updating the secret name to match the code.
To ensure the behavior is unchanged for users not using the leader elector logic.
Passing the CA around in the Secret seemed to prevent followers from recreating a CA if they're promoted to leader. Since the followers don't need the CA, removed it from the Secret.
// For followers, run different function here that reads bundle from Secret, | ||
// and returns that in the result. That will flow through the existing | ||
// notify channel structure, testing if it's the same cert as last, etc. | ||
if !leaderCheck { |
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.
Can we get a log saying whether this pod is the leader or follower? Also wondering if we should apply a label so we can query for the leader (not blocking, future enhancement probably).
Currently I can't tell which is which:
[~] kubectl logs vault-injector-57485f744-24jwd -c sidecar-injector
Using leader elector logic
2020-12-16T15:22:43.623Z [INFO] handler: Starting handler..
Listening on ":8080"...
Updated certificate bundle received. Updating certs...
[~] kubectl logs vault-injector-57485f744-lts8w -c sidecar-injector
Using leader elector logic
2020-12-16T15:22:44.109Z [INFO] handler: Starting handler..
Listening on ":8080"...
Updated certificate bundle received. Updating certs...
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.
Yep, good point, added more logging in ac4b4f4. I set the leader and follower log lines to debug since they are logged pretty frequently. Looks something like this:
❯ kubectl logs -n vault vault-agent-injector-c6d5c7689-6q4w7 -c sidecar-injector
Using leader elector logic
2020-12-17T02:36:22.710Z [INFO] handler: Starting handler..
Listening on ":8080"...
2020-12-17T02:36:22.719Z [INFO] handler.auto-tls: Currently the leader
2020-12-17T02:36:22.726Z [INFO] handler.auto-tls: Generated CA
2020-12-17T02:36:22.734Z [INFO] handler.certwatcher: Updated certificate bundle received. Updating certs...
2020-12-17T02:36:27.711Z [INFO] handler.auto-tls: Currently the leader
❯ kubectl logs -n vault vault-agent-injector-c6d5c7689-lmrjb -c sidecar-injector
Using leader elector logic
2020-12-17T02:36:26.307Z [INFO] handler: Starting handler..
Listening on ":8080"...
2020-12-17T02:36:26.314Z [DEBUG] handler.auto-tls: Currently a follower
2020-12-17T02:36:26.314Z [INFO] handler.certwatcher: Updated certificate bundle received. Updating certs...
2020-12-17T02:36:31.308Z [DEBUG] handler.auto-tls: Currently a follower
...
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.
Minor feedback but LGTM and tested fine!
Added a named logger to GenSource (auto-tls), mostly debug-level for telling which is the leader and which is the follower.
While the leader is waiting for the current certificate to expire, a leadership change could occur, and then the former leader's certificate would be out of sync with the new leader. Added a goroutine that signals a channel on a leadership change.
Uses a leader-elector sidecar to ensure only one injector replica generates the CA and cert+key. The other replicas pick up the cert+key from a k8s secret for use in their TLS listeners. The leader-elector sidecars coordinate using the annotations of a k8s Endpoint object, which is why those extra permissions were added to the role in the deployment yaml. Added command-line and env option to control leader-elector usage. Using Secrets informer for followers to ensure retrieving timely cert updates without overloading the k8s api. Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
Adds a
use-leader-elector
option to vault-k8s to enable use of a leader-elector sidecar, which lets multiple replicas of the injector determine a "leader" which is then in charge of generating the CA, Cert, and Key, distributing them to the followers, and patching the webhook caBundle. Defaults tofalse
.The leader-elector sidecar in use is described in detail here: https://kubernetes.io/blog/2016/01/simple-leader-election-with-kubernetes/
The leader-elector containers determine a leader by modifying an Endpoint object, and they expose this information to the injector pod with a local http service that returns the current leader's hostname.
The followers read the cert and key needed for the webhook listener from a k8s Secret, which is updated by the leader when a certificate is near expiration.