-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
(golang/v4) Generate local webhooks for make run
#4477
Comments
Hi @damsien, Thank you for raising this issue. Note that now is possible to pass the certs path. make run ARGS="--webhook-cert-path=/tmp/certs --webhook-cert-name=tls.crt --webhook-cert-key=tls.key" So, I think that what you are suggesting here would be something like Proposed Solution (Example)
LOCALHOST_BRIDGE ?= $(shell docker network inspect bridge --format='{{(index .IPAM.Config 0).Gateway}}')
gen-local-certs:
./hack/gen-certs.sh $(LOCALHOST_BRIDGE)
run-local: gen-local-certs
@echo "Updating webhook manifests with sed..."
CA_BUNDLE=$$(cat /tmp/k8s-webhook-server/serving-certs/ca.crt | base64 -w 0) && \
sed -e "s|service:.*|url: https://$(LOCALHOST_BRIDGE)|" \
-e "s|caBundle:.*|caBundle: $$CA_BUNDLE|" \
config/webhook/manifests.yaml > config/webhook/local-manifests.yaml
kubectl apply -f config/webhook/local-manifests.yaml
ARGS="--webhook-cert-path=/tmp/k8s-webhook-server/serving-certs" make run
Example hack/gen-certs.sh #!/bin/bash
set -e
LOCALHOST_BRIDGE=$1
CERT_DIR="/tmp/k8s-webhook-server/serving-certs"
mkdir -p ${CERT_DIR}
# Generate CA
openssl genrsa -out ${CERT_DIR}/ca.key 2048
openssl req -x509 -new -nodes -key ${CERT_DIR}/ca.key -sha256 -days 365 \
-subj "/CN=Webhook-CA" -out ${CERT_DIR}/ca.crt
# Generate server cert
openssl genrsa -out ${CERT_DIR}/tls.key 2048
cat > ${CERT_DIR}/server.conf <<EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
[req_distinguished_name]
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
IP.1 = ${LOCALHOST_BRIDGE}
EOF
openssl req -new -key ${CERT_DIR}/tls.key -out ${CERT_DIR}/tls.csr -config ${CERT_DIR}/server.conf
openssl x509 -req -in ${CERT_DIR}/tls.csr -CA ${CERT_DIR}/ca.crt -CAkey ${CERT_DIR}/ca.key \
-CAcreateserial -out ${CERT_DIR}/tls.crt -days 365 -extensions v3_req -extfile ${CERT_DIR}/server.conf Then, we could execute Key QuestionsHowever, I believe we might want to think about:
Perhaps we could start by identifying the best and recommended approaches for the concerns raised in #4292. From there, we can evaluate whether changes are needed in the scaffold and decide on the best course of action. I am looking forward to your thoughts. |
Hello @camilamacedo86 , thanks for you answer 😀 Should we provide a patch/overlay?For me, kubebuilder provides 2 levels of testing: run manager directly through the shell ( First, I think that this feature is necessary for the That leads to a question: Do we consider the If the answer is yes, then I think that we could provide a patch/overlay to allow projects to work without cert-manager. I think it is better than writing a documentation that explains how to generate a certificate and use it (especially if it can be automated). If the answer is no, then we can just keep the implementation example of your comment for the In both of the case, I think that we still need to let the option to use cert-manager. When do we scaffold?I don't think that scaffolding at the However, if you consider scaffolding at the first |
Hi @damsien
Yes, it is. Also, you can package it in other ways. But the |
Hello @camilamacedo86 Okay, it confirms what I thought. Patch/overlayConcerning the patch/overlay, I think we could place it in a In the @if [ -d "config/local" ]; then \
$(KUSTOMIZE) build config/local | $(KUBECTL) apply -f - \
fi Webhook targetAlso, we have to think that the webhook should target the docker bridge when running Also, in the case of Conversion webhooksI also wanted to point out that we have to think about CRD's conversion webhooks. We have to do the same injection based on the |
Hi @damsien, What do you think would be the best approach for users who don’t want to use a cert-manager? I believe we might need to address this scenario (see: #4292). To help us make a decision, here are a couple of considerations:
WDYT? |
To make matters more complex, maybe. Please take into account that there are multiple containertails configurable in the makefile. I'm using Podman, which results into an error when using:
|
Hello @camilamacedo86, Yes I think we should provide a default configuration for dev purposes that works without cert-manager. The goal is to make kubebuilder the most user-friendly as possible. Therefore, when an user starts using kubebuilder for creating webhooks, he should be able to easily test it. And yes, we need to make a clear distinction between the development purpose and the production use. Hello @appiepollo14, Concerning your use case, we have two options:
In both use cases, we should document the way to change this variable depending on the user's environment. |
I think it might be worth considering a configuration option for production that operates without CertManager. This wouldn't mean that the configuration itself generates certificates, but rather that it includes the necessary scaffolding to integrate certificates when provided externally. Given this, I believe it's a good idea to explore and study the available alternatives to achieve the same functionality without CertManager. This investigation will provide a better foundation for our discussions on this topic. For reference, see: kubebuilder issue #4292. |
What do you want to happen?
Description of the needs
As a k8s operator developer, I would like to test my webhooks by using
make run
.The "classic way" to quickly test the manager logic is to execute
make run
, create some resources, check the logs at the same time, CTRL+C, change the code,make run
, etc... However, as for today, we cannot test the webhook server logic by executingmake run
since the the manager is launched within the shell and not as a Pod in a container. Therefore, theMutatingWebhookConfiguration
&ValidatingWebhookConfiguration
objects cannot request theService
attached to the manager'sPod
(since there is neitherService
norPod
).Is this really needed?
Today, the only way to test the webhook server logic is either to write tests in the
my_webhook_test.go
file or by deploying the operator logic as aPod
in a cluster by usingmake deploy
. The problem of these two methods is that it takes some time to be run whereasmake run
is fast (because it is meant to be fast to run) and allow us to test our operator the "classic way".Also, as we can we see in this issue #400, even if it has been closed, people still have a discussion about an implementation of this feature.
Solution proposal
My solution is based on this issue comment #400 (comment).
1. Update the
Makefile
Set the
LOCALHOST_BRIDGE
variable. This is the docker0 bridge address that allows any container to make a request the loopback address of the host.Execute a script to generate the caBundle & the server certificate (
make gen-local-certs
?). This script can be located in/hack
?2. Certificate generation script
This script will first generate a CA bundle & certificate using the docker0 bridge host as SAN
The ca.crt & tls.crt will be located int the
/tmp/k8s-webhook-server/serving-certs
directory since controller-runtime will look at it first. Therefore, we do not have to modify ourmain.go
to specify a temporary custom cert dir.https://github.com/kubernetes-sigs/controller-runtime/blob/2484715d39199d4e02628c79e9be7c6f76fae28b/pkg/webhook/server.go#L143-L145
And then, it will generate a local webhook manifest on the flight based on the
config/webhook/manifests.yaml
. Thus,make manifests
must be executed before (the same way as we usemake deploy
). The generation will basically copy paste the content of themanifests.yaml
and update theclientConfig
part.Convert
into
This part of the script removes the
clientConfig.service
specification and placeurl
instead. Also, it will inject the generated CA bundle.3. Apply the webhook
Finally, we have to apply the local webhook manifest on the cluster.
TL;DR
Create a script that generate a certificate and inject it in the webhook object. Then, the webhook make the request toward the docker bridge. The manager that runs within the shell (so it listen on the loopback address) will receive the request an can process the webhook request.
Do no hesitate to ask me questions since I already implemented this mechanism in the operator I am working on.
Extra Labels
No response
The text was updated successfully, but these errors were encountered: