-
Notifications
You must be signed in to change notification settings - Fork 2.1k
kube-updater: Wire up main executable #23565
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
Changes from all commits
c048682
26cd639
670e8cf
b6744bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| ## Debugging tips for the kube-agent-updater | ||
|
|
||
| ### Running locally the updater against a remote Kubernetes cluster | ||
|
|
||
| Running locally let you attach a debugger while still working against a real | ||
| cluster. This can be used to reproduce most complex issues and troubleshoot | ||
| specific cases. | ||
|
|
||
| - Validate your current context works | ||
| ```shell | ||
| kubectl cluster-info | ||
| ``` | ||
| - Open a proxy to the api-server, then let the shell open and running | ||
| ```shell | ||
| kubectl proxy | ||
| ``` | ||
| - open a new terminal, create a new temporary directory and create your new kubeconfig | ||
| ```shell | ||
| export kubeconfig="$(mktemp)" | ||
| kubectl config set-credentials myself --username=foo | ||
| kubectl config set-cluster local-server --server=http://localhost:8001 | ||
| kubectl config set-context default-context --cluster=local-server --user=myself | ||
| kubectl config use-context default-context | ||
| echo "$KUBECONFIG" | ||
| ``` | ||
| - run the controller with the `KUBECONFIG` environment variable set |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /* | ||
| Copyright 2023 Gravitational, Inc. | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| */ | ||
|
|
||
| package main | ||
|
|
||
| // teleportProdOCIPubKey is the key used to sign Teleport distroless images. | ||
| // The key lives in the Teleport production AWS KMS. | ||
| // In case of controlled rotation, we will want to add a second validator with | ||
| // the new key to support the transition period. | ||
| var teleportProdOCIPubKey = []byte(`-----BEGIN PUBLIC KEY----- | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where does it come from? (missing license header) Can we add that as a comment?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I fetched this from the prod KMS, @tcsc asked at some point how we will share our signature key, so I suspect we'll advertise it somewhere in the docs at least. I'll add a comment explaining where to find they key and what to do in case of rotation.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hugoShaka @tcsc Would it make sense to store this public key as a separate file somewhere in the repo and embed using
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but if we dynamically load it we must be very careful not to update the file in place. In case of rotation, we might want to add a new validator for the new key instead of just replacing the key.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we share the key using a Teleport cdn endpoint? I mean, you developed the updater to update our kube-agents but it still requires that someone updates the updater each time we pretend to rotate secrets. Or worst, if they rely 100% on the updater and it stops updating images can lead to security vulnerabilities. We can share both keys using the endpoint |
||
| MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAx+9UZboMl9ibwu/IWqbX | ||
| +wEJeKJqVpaLEsy1ODRpzIgcgaMh2n3BWtFEIoEszR3ZNlGdfqoPmb0nNnWx/qSf | ||
| eEsoSXievXa63M/gAUBB+jecbGEJH+SNaJPMVuvjabPqKtoMT2Spw3cacqpINzq1 | ||
| rkWU8IawY333gXbwzgsuK7izT7ymgOLPO9qPuX7Q3EBaGw3EvY7u6UKtqhvSGdyr | ||
| MirEErOERQ8EP8TrkCcJk0UfPAukzIcj91uHlXaqYBD/IyNYiC70EOlSLoN5/EeA | ||
| I4jQnGRfaKF6H6K+WieX9tP9k8/02S+1EVJW592pdQZhJZEq1B/dMc8UR3IjPMMC | ||
| qCT2xT6TsinaVzDaAbaRf0hvp311GxwrckNofGm/OSLn1+HqM6q4/A7qHubeRXGO | ||
| byabRr93CHSLegZ7OBMswHqqnu6/DuXjc6gOsQkH09dVTFeh34rQy4GKrvnpmOwj | ||
| Er1ccxzKcF/pw+lxi07hkpihR/uHUPxFboA/Wl7H2Jub21MFwIFQrDJv7z8yQgxJ | ||
| EuIXJJox2oAL7NzdSi9VIUYnEnx+2EtkU/spAFRR6i1BnT6aoIy3521B76wnmRr9 | ||
| atCSKjt6MdRxgj4htCjBWWJAGM9Z/avF4CYFmK7qiVxgpdrSM8Esbt2Ta+Lu3QMJ | ||
| T8LjqFu3u3dxVOo9RuLk+BkCAwEAAQ== | ||
| -----END PUBLIC KEY-----`) | ||
|
hugoShaka marked this conversation as resolved.
Outdated
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| /* | ||
| Copyright 2023 Gravitational, Inc. | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| */ | ||
|
|
||
| package img | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| "github.com/docker/distribution/reference" | ||
| "github.com/gravitational/trace" | ||
| "github.com/opencontainers/go-digest" | ||
| ) | ||
|
|
||
| type insecureValidator struct { | ||
| name string | ||
| } | ||
|
|
||
| // Name returns the validator name | ||
| func (v *insecureValidator) Name() string { | ||
| return v.name | ||
| } | ||
|
|
||
| // TODO: cache this to protect against registry quotas | ||
| // The image validation is only invoked when we are in a maintenance window and | ||
| // the target version is different than our current version. In regular usage we | ||
| // are called only once per update. However, Kubernetes controllers failure mode | ||
| // is usually infinite retry loop. If something fails after the image validation, | ||
| // we might get called in a loop indefinitely. To mitigate the impact of such | ||
| // failure, ValidateAndResolveDigest should cache its result. | ||
|
|
||
| // ValidateAndResolveDigest resolves the image digest and always return the | ||
| // image is valid. Using this validator makes you vulnerable in case of image | ||
| // registry compromise. | ||
| func (v *insecureValidator) ValidateAndResolveDigest(ctx context.Context, image reference.NamedTagged) (NamedTaggedDigested, error) { | ||
| ref, err := NamedTaggedToDigest(image) | ||
| if err != nil { | ||
| return nil, trace.Wrap(err) | ||
| } | ||
|
|
||
| digestedImage := NewImageRef(ref.RegistryStr(), ref.RepositoryStr(), image.Tag(), digest.Digest(ref.DigestStr())) | ||
| return digestedImage, nil | ||
| } | ||
|
|
||
| // NewInsecureValidator returns an img.Validator that only resolves the image | ||
| // but does not check its signature. | ||
| func NewInsecureValidator(name string) Validator { | ||
| return &insecureValidator{ | ||
| name: name, | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.