WIP: Introduce mutating webhook for sidecar injection.#1423
WIP: Introduce mutating webhook for sidecar injection.#1423Bedotech wants to merge 2 commits intolinkerd:masterfrom
Conversation
rmars
left a comment
There was a problem hiding this comment.
🎉 thank you for undertaking this, @Bedotech!
This PR is a good starting point for us to start to think about and flesh out some of the design tradeoffs we'll need to make.
I discussed this with the team and the main design considerations we'd like to start thinking about are:
-
how we can integrate this into the install experience such that the user can do minimal work. Can the cert setup be included as part of
linkerd install? How much work would it be to get there from here? Is it worth doing it as a follow up, or can we get it integrated now?
Can we use our existing TLS bootstrapping? -
can the webhook server be another subcomponent in the
cmd/directory? this way we can build and maintain fewer docker images
We'd also like to run the TLS setup we decide on by @briansmith before it merges.
I also had a couple of starting smaller review points. A lot of the code here is likely to change as we think through this together, but this is a great start!
|
|
||
| ## Setup | ||
|
|
||
| Once you have create the secret you can run `linkerd install`, for automatic |
There was a problem hiding this comment.
As mentioned above, eventually we'll want to find a way to have this be run from linkerd install (seeing if gating the admisison controller feature behind a flag is possible)
There was a problem hiding this comment.
Ok i think this can be done after we can effectively inject
| } | ||
|
|
||
| func init() { | ||
| _ = corev1.AddToScheme(runtimeScheme) |
There was a problem hiding this comment.
I think we can omit the _ = if we're just throwing out all these results anyway
| "os/signal" | ||
| "syscall" | ||
|
|
||
| "github.com/golang/glog" |
There was a problem hiding this comment.
note that we use sirupsen/logrus for logging instead of glog- we'll need to move these over.
|
|
||
| func updateAnnotation(target map[string]string, added map[string]string) (patch []patchOperation) { | ||
| for key, value := range added { | ||
| if target == nil || target[key] == "" { |
There was a problem hiding this comment.
should this second || target[key] be here? if target[key] doesn't exist, do we want to re-initialize the entire annotation map?
| } else { | ||
| patch = append(patch, patchOperation{ | ||
| Op: "replace", | ||
| Path: "/metadata/annotations/" + key, |
There was a problem hiding this comment.
Do we need to escape the key here?
// the Path of the JSON patch is a JSON pointer value
// so we need to escape any "/"s in the key we add to the annotation
// https://tools.ietf.org/html/rfc6901
func escapeJSONPointer(s string) string {
esc := strings.Replace(s, "~", "~0", -1)
esc = strings.Replace(esc, "/", "~1", -1)
return esc
}
| @@ -0,0 +1,64 @@ | |||
| +++ | |||
|
|
||
| // get command line parameters | ||
| flag.IntVar(¶meters.port, "port", 443, "Webhook server port.") | ||
| flag.StringVar(¶meters.certFile, "tlsCertFile", "/etc/webhook/certs/cert.pem", "File containing the x509 Certificate for HTTPS.") |
There was a problem hiding this comment.
I think we should follow the convention used by the other controllers' flags i.e. tls-cert-file, instead of tlsCertFile.
|
|
||
| var body []byte | ||
| if r.Body != nil { | ||
| if data, err := ioutil.ReadAll(r.Body); err == nil { |
There was a problem hiding this comment.
I think we should handle the case of err !=nil. Otherwise, the empty body error below will be returned to the user which can be misleading.
| } | ||
|
|
||
| func addContainer(target, added []corev1.Container, basePath string) (patch []patchOperation) { | ||
| first := len(target) == 0 |
There was a problem hiding this comment.
Is it possible for target's length to be 0?
| admissionResponse = whsvr.mutate(&ar) | ||
| } | ||
|
|
||
| admissionReview := v1beta1.AdmissionReview{} |
There was a problem hiding this comment.
Might not need this and re-use ar from line 279. The AdmissionReview type has both a Request and a Response fields.
For manage deployment with linkerd2 with other tools like helm is really important to make the pod injection at the lower level we can. Using MutatingWebhook (new k8s 1.9) we can modify a pod before the pod is created. So far i have created: * new container called 'sidecar-injection' * update install profile for add 'sidecar-injection' * create for now fake webhook for test integration This PR is really WIP, before we have to solve: * Ho we issue certificate for webhook in k8s * Link the webhook inject handler with existing api for sidecar injection. * code review. Signed-off-by: Mattia Rossi <[email protected]>
Trye to solve the SSL problem with .sh script that sign a certificate using kubectl.
a1ac10c to
a720829
Compare
| https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster for | ||
| detailed explantion and additional instructions. | ||
|
|
||
| The server key/cert k8s CA cert are stored in a k8s secret. |
There was a problem hiding this comment.
I don't think this will work as a long-term solution:
-
The private key for the certificate shouldn't ever be outside the cluster, so this script should be run from within the controller, not by the user.
-
The CertificateSigningRequest API isn't always enabled and even when enabled isn't always configured in a usable state. For example and in particular, I don't think minikube enables this in its default configuration.
-
AFAICT, using the CertificateSigningRequest API isn't necessary because the webhook configuration YAML lets you specify the CA to be trusted for the webhook.
The way I was thinking to do this is as follows:
conduit installinstalls the webhook along with the rest of the control plane but it won't work yet because the object properties that indicates the webhook's CA won't be written yet.- When the CA starts up, (and in the future, whenever the root CA certificates change) the CA replaces the webhooks configuration with one that has its own certificate as the trusted CA certificate. This requires the CA to have
editproperties for the webhook configuration object.
After step 2 the webhook should work.
There was a problem hiding this comment.
Yeah, this is really the first implementation, if you look at Istio the setup and creation of the certificate is made at the setup time using k8s api.
The point 1 or 2 are prerequisite.
Only one point, i have made all test against clean minikube environment and all is working , so i think the CertificateSigningRequest it's enabled by default.
There was a problem hiding this comment.
... creation of the certificate is made at the setup time using k8s api.
Not 100% sure, from what I see in the citadel code, they may no longer be relying on the k8s api to generate and sign CSR. Can you confirm?
References:
|
following package https://github.com/knative/pkg/tree/master/webhook might be handy to use for implementation. it got extracted out of few knative components recently cc @mattmoor here it's being used: https://github.com/knative/serving/blob/279424145446338b96c4e5aad9a2700db6b0ea77/cmd/webhook/main.go#L78 |
For manage deployment with linkerd2 with other tools like helm is really
important to make the pod injection at the lower level we can.
#561 Using MutatingWebhook (new k8s 1.9) we can modify a pod before the pod
is created.
So far i have created:
This PR is really WIP, before we have to solve:
injection.
Signed-off-by: Mattia Rossi [email protected]