diff --git a/Makefile b/Makefile index f8288f1828..454179fe17 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ PYTORCH_IMG ?= pytorchserver:latest ALIBI_IMG ?= alibi-explainer:latest STORAGE_INIT_IMG ?= storage-initializer:latest CRD_OPTIONS ?= "crd:trivialVersions=true" +KFSERVING_ENABLE_SELF_SIGNED_CA ?= false all: test manager logger @@ -31,11 +32,24 @@ run: generate fmt vet lint # Deploy controller in the configured Kubernetes cluster in ~/.kube/config deploy: manifests + # Remove the certmanager certificate if KFSERVING_ENABLE_SELF_SIGNED_CA is not false + cd config/default && if [ ${KFSERVING_ENABLE_SELF_SIGNED_CA} != false ]; then \ + kustomize edit remove resource certmanager/certificate.yaml; \ + else kustomize edit add resource certmanager/certificate.yaml; fi; + kustomize build config/default | kubectl apply -f - + if [ ${KFSERVING_ENABLE_SELF_SIGNED_CA} != false ]; then ./hack/self-signed-ca.sh; fi; deploy-dev: manifests ./hack/image_patch_dev.sh development + # Remove the certmanager certificate if KFSERVING_ENABLE_SELF_SIGNED_CA is not false + cd config/default && if [ ${KFSERVING_ENABLE_SELF_SIGNED_CA} != false ]; then \ + kustomize edit remove resource certmanager/certificate.yaml; \ + else kustomize edit add resource certmanager/certificate.yaml; fi; + kustomize build config/overlays/development | kubectl apply -f - + if [ ${KFSERVING_ENABLE_SELF_SIGNED_CA} != false ]; then ./hack/self-signed-ca.sh; fi; + deploy-local: manifests ./hack/image_patch_dev.sh local diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 78b9bc331b..94029cca7c 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -25,6 +25,8 @@ resources: - rbac/auth_proxy_role_binding.yaml - webhook/manifests.yaml - webhook/service.yaml + # Comment the below certmanager if you are using a self-signed CA + # (https://kubernetes.io/docs/concepts/cluster-administration/certificates) - certmanager/certificate.yaml patchesStrategicMerge: diff --git a/docs/DEVELOPER_GUIDE.md b/docs/DEVELOPER_GUIDE.md index 8d6f1ac2f4..204482d959 100644 --- a/docs/DEVELOPER_GUIDE.md +++ b/docs/DEVELOPER_GUIDE.md @@ -140,6 +140,12 @@ You can follow [the cert manager documentation](https://docs.cert-manager.io/en/latest/getting-started/install/kubernetes.html) to install it. +If you don't want to install cert manager, you can set the `KFSERVING_ENABLE_SELF_SIGNED_CA` environment variable to true. +`KFSERVING_ENABLE_SELF_SIGNED_CA` will execute a script to create a self-signed CA and patch it to the webhook config. +```bash +export KFSERVING_ENABLE_SELF_SIGNED_CA=true +``` + After that you can run following command to deploy `KFServing`, you can skip above step once cert manager is installed. ```bash make deploy diff --git a/hack/self-signed-ca.sh b/hack/self-signed-ca.sh new file mode 100755 index 0000000000..52b18a6584 --- /dev/null +++ b/hack/self-signed-ca.sh @@ -0,0 +1,131 @@ +#!/bin/bash + +set -e + +usage() { + cat <> ${tmpdir}/csr.conf +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name +[req_distinguished_name] +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth +subjectAltName = @alt_names +[alt_names] +DNS.1 = ${service} +DNS.2 = ${service}.${namespace} +DNS.3 = ${service}.${namespace}.svc +DNS.4 = ${service}.${namespace}.svc.cluster +DNS.5 = ${service}.${namespace}.svc.cluster.local + +EOF +# Create CA and Server key/certificate +openssl genrsa -out ${tmpdir}/ca.key 2048 +openssl req -x509 -newkey rsa:2048 -key ${tmpdir}/ca.key -out ${tmpdir}/ca.crt -days 365 -nodes -subj "/CN=${service}.${namespace}.svc" + +openssl genrsa -out ${tmpdir}/server.key 2048 +openssl req -new -key ${tmpdir}/server.key -subj "/CN=${service}.${namespace}.svc" -out ${tmpdir}/server.csr -config ${tmpdir}/csr.conf + +# Self sign +openssl x509 -req -days 365 -in ${tmpdir}/server.csr -CA ${tmpdir}/ca.crt -CAkey ${tmpdir}/ca.key -CAcreateserial -out ${tmpdir}/server.crt -extfile ${tmpdir}/csr.conf +# create the secret with server cert/key +kubectl create secret generic ${secret} \ + --from-file=tls.key=${tmpdir}/server.key \ + --from-file=tls.crt=${tmpdir}/server.crt \ + --dry-run -o yaml | + kubectl -n ${namespace} apply -f - +# Webhook pod needs to be restarted so that the service reload the secret +# http://github.com/kueflow/kubeflow/issues/3227 +webhookPod=$(kubectl get pods -n ${namespace} |grep ${webhookDeploymentName} |awk '{print $1;}') +# ignore error if webhook pod does not exist +kubectl delete pod ${webhookPod} -n ${namespace} 2>/dev/null || true +echo "webhook ${webhookPod} is restarted to utilize the new secret" + +echo "CA Certificate:" +cat ${tmpdir}/ca.crt + +# -a means base64 encode +caBundle=$(cat ${tmpdir}/ca.crt | openssl enc -a -A) +echo "Encoded CA:" +echo -e "${caBundle} \n" + +# Patch CA Certificate to webhooks +mutatingPatchString='[{"op": "replace", "path": "/webhooks/0/clientConfig/caBundle", "value":"{{CA_BUNDLE}}"}, {"op": "replace", "path": "/webhooks/1/clientConfig/caBundle", "value":"{{CA_BUNDLE}}"}]' +mutatingPatchString=$(echo ${mutatingPatchString} | sed "s|{{CA_BUNDLE}}|${caBundle}|g") +validatingPatchString='[{"op": "replace", "path": "/webhooks/0/clientConfig/caBundle", "value":"{{CA_BUNDLE}}"}]' +validatingPatchString=$(echo ${validatingPatchString} | sed "s|{{CA_BUNDLE}}|${caBundle}|g") + +echo "patching ca bundle for mutating webhook configuration..." +kubectl patch mutatingwebhookconfiguration ${webhookConfigName} \ + --type='json' -p="${mutatingPatchString}" + +echo "patching ca bundle for validating webhook configuration..." +kubectl patch validatingwebhookconfiguration ${webhookConfigName} \ + --type='json' -p="${validatingPatchString}" \ No newline at end of file