/kind bug
What steps did you take and what happened:
[A clear and concise description of what the bug is.]
bash scripts/v1beta1/deploy.sh $ kubectl apply -f example/v1beta1/tpe-example.yaml
Error from server (InternalError): error when creating "/Users/tenzen/katib-0.10.0/examples/v1beta1/tpe-example.yaml": Internal error occurred: failed calling webhook "mutating.experiment.katib.kubeflow.org": Post "https://katib-controller.kubeflow.svc:443/mutate-experiments?timeout=30s": x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
What did you expect to happen:
I expected the experiment to start.
Anything else you would like to add:
[Miscellaneous information that will assist in solving the issue.]
I found related topics in the release note for 1.19.0
https://kubernetes.io/docs/setup/release/notes/
Kubernetes is now built with golang 1.15.0-rc.1.
The deprecated, legacy behavior of treating the CommonName field on X.509 serving certificates as a host name when no Subject Alternative Names are present is now disabled by default. It can be temporarily re-enabled by adding the value x509ignoreCN=0 to the GODEBUG environment variable. (#93264, @justaugustus) [SIG API Machinery, Auth, CLI, Cloud Provider, Cluster Lifecycle, Instrumentation, Network, Node, Release, Scalability, Storage and Testing]
Environment:
kfctl version): Noneminikube version): Nonekubectl version): 1.19.4/etc/os-release): ubuntu16.04(4.15.0-72-generic)Hi @tenzen-y, thank you for creating this.
I think this problem happens because K8s 1.19 is using Go 1.15.
Which cluster are you using: GCP, AWS, on-prem ?
Also check this: https://github.com/golang/go/issues/39568#issuecomment-671424481.
/cc @gaocegege @johnugeorge
@andreyvelich
Which cluster are you using: GCP, AWS, on-prem ?
I'm using on-prem.
I think this problem happens because K8s 1.19 is using Go 1.15.
Also check this: golang/go#39568 (comment).
Does that mean that Katib is using some certificates that does not contain SANs?
Thanks.
Same problem here. I'm using on-prem MicroK8s 1.19 probably built using Go 1.15. Any workaround?
Thx in advance!
Same problem.
This may be due to an older version of the vendored controller-runtime library.
As workaround, I create a Secret called katib-controller with a self-signed certificate embedded (it has fields of ca-cert.pem, ca-key.pem, cert.pem, and key.pem) in kubeflow namespace. The certificate generation process by Webhook Bootstrap uses an existing Secret, if one exists.
Sorry for the long reply @tenzen-y.
Thank you @zuiurs, it makes sense. We use 0.1.9 controller-runtime version, which is pretty old. For the default bootstrapping, certificate for the webhook server is located in katib-controller secret in kubeflow namespace, like you create.
Although, you can use your local file system to generate cert, check here.
In the meantime, we are working on removing auto generation for the webhooks from the Katib controller, check this: https://github.com/kubeflow/manifests/issues/1379. cc @knkski
@zuiurs
Thank you for the workaround suggestions!
We succeeded in starting the experiment using the Secret created using the certificates generated by cfssl.
@andreyvelich
Now I understand the cause of the error. And thank you for working on a solution to the problem.
For those who have encountered the same problem, here are the steps I took.
$ kubectl create secret -n $NAMESPACE generic katib-controller --from-file=ca-cert.pem --from-file=ca-key.pem --from-file=cert.pem --from-file=key.pem
Thanks, @tenzen-y @zuiurs and @andreyvelich
I was stuck for a long time at this and creating a self-signed certificate using cfssl helped me too.
Just to save time, here is the quick process of creating certificates using cfssl:
cfssl print-defaults csr > ca-csr.json, edit the required fields in the json file (Common Name etc.)cfssl gencert -initca ca-csr.json | cfssljson -bare ca – (will give ca.pem & ca-key.pem)cfssl print-defaults config > ca-config.json which has signing and profile details.{
"CN": "katib-controller.$NAMESPACE.svc",
"hosts": [
"katib-controller.$NAMESPACE.svc "
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "CA",
"ST": "San Francisco"
}
]
}cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=web-servers \
server-csr.json | cfssljson -bare serverJust rename ca.pem -> ca-cert.pem, server.pem -> cert.pem & server-key.pem -> key.pem
Finally delete the existing katib controller secret, create a new secret using
$ kubectl create secret -n $NAMESPACE generic katib-controller --from-file=ca-cert.pem --from-file=ca-key.pem --from-file=cert.pem --from-file=key.pem
Delete the pod so that new secret will be mounted.
any ideas how to fix you mentioned create certificates ,i get the same issue today on rancher 2.5 with kubernetes 1.19.6
open -ca=ca.pem: no such file or directory
any ideas, i see the file exist in my current folder.
I'm still getting the same issue. I tried the following (for kubeflow namespace):
# Generating CA
openssl genrsa -out ca-key.pem 2048
openssl req -x509 -new -nodes -key ca-key.pem -sha256 -days 1024 -out ca-cert.pem
# Generating client certificate
openssl genrsa -out key.pem 2048
openssl req -new -sha256 -key key.pem -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=katib-controller.kubeflow.svc" -out csr.pem
openssl x509 -req -in csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -days 500 -sha256
# Updateing katib-controller secret
kubectl delete secret -n kubeflow katib-controller
kubectl create secret -n kubeflow generic katib-controller --from-file=ca-cert.pem --from-file=ca-key.pem --from-file=cert.pem --from-file=key.pem
# Check the katib-controller pod name and then
kubectl delete pod katib-controller-7fcc95676b-2nskf -n kubeflow
After that I simply get a connection refused...
Hi @trog-levrai.
After that I simply get a connection refused...
Where did you get it ?
Alright I figured things out for my case. If you're trying to use openssl then you have to find a way to properly support the SAN field in the certificate. cfssl makes it easy but the example above wasn't working for me with cfssl with version 1.5.0.
So here's what worked for me with the kubeflow namespace (inspired from https://github.com/kelseyhightower/kubernetes-the-hard-way/issues/457#issuecomment-665581873).
Write the following files:
ca-csr.json{
"CN": "katib-controller.kubeflow.svc",
"hosts": [
"katib-controller.kubeflow.svc"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "US",
"ST": "CA",
"L": "San Francisco"
}
]
}
server-csr.json (note there is no blankspace in the hosts value){
"CN":"katib-controller.kubeflow.svc",
"hosts":[
"katib-controller.kubeflow.svc"
],
"key":{
"algo":"rsa",
"size":2048
},
"names":[
{
"C":"US",
"L":"CA",
"ST":"San Francisco"
}
]
}
ca-config.json{
"signing": {
"default": {
"expiry": "168h"
},
"profiles": {
"www": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"kubernetes": {
"expiry": "876000h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
From there you can run (note the kubernetes profile used):
# Generating SSL certs
cfssl gencert -initca ca-csr.json | cfssljson -bare ca –
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
# Needed renaming
mv ca.pem ca-cert.pem
mv server.pem cert.pem
mv server-key.pem key.pem
# K8S secret refresh
kubectl delete secret -n kubeflow katib-controller
kubectl create secret -n kubeflow generic katib-controller --from-file=ca-cert.pem --from-file=ca-key.pem --from-file=cert.pem --from-file=key.pem
# Check the katib-controller pod name and then
kubectl delete pod katib-controller-POD_ID -n kubeflow
Most helpful comment
Thanks, @tenzen-y @zuiurs and @andreyvelich
I was stuck for a long time at this and creating a self-signed certificate using cfssl helped me too.
Just to save time, here is the quick process of creating certificates using cfssl:
cfssl print-defaults csr > ca-csr.json, edit the required fields in the json file (Common Name etc.)Generate the CA Key and cert file
cfssl gencert -initca ca-csr.json | cfssljson -bare ca –(will give ca.pem & ca-key.pem)cfssl print-defaults config > ca-config.jsonwhich has signing and profile details.{ "CN": "katib-controller.$NAMESPACE.svc", "hosts": [ "katib-controller.$NAMESPACE.svc " ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "CA", "ST": "San Francisco" } ] }Now create server SSL certificates using
cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=web-servers \ server-csr.json | cfssljson -bare server(will give server.pem and server-key.pem)
Just rename ca.pem -> ca-cert.pem, server.pem -> cert.pem & server-key.pem -> key.pem
Finally delete the existing katib controller secret, create a new secret using
$ kubectl create secret -n $NAMESPACE generic katib-controller --from-file=ca-cert.pem --from-file=ca-key.pem --from-file=cert.pem --from-file=key.pemDelete the pod so that new secret will be mounted.