The outcome of this is that we will have three Secrets available in the projectcontour
namespace:
- cacert: contains the CA's public certificate.
- contourcert: contains Contour's keypair, used for serving TLS secured gRPC. This must be a valid certificate for the name
contour
in order for this to work. This is currently hardcoded by Contour. - envoycert: contains Envoy's keypair, used as a client for connecting to Contour.
- Deploy the Job from certgen.yaml.
This will run
contour certgen --kube
for you. - Run
contour certgen --kube
locally. - Run the manual procedure below.
Be very careful with your production certificates!
This is intended as an example to help you get started. For any real deployment, you should carefully manage all the certificates and control who has access to them. Make sure you don't commit them to any git repos either.
First, we need to generate a keypair:
openssl req -x509 -new -nodes \
-keyout certs/cakey.pem -sha256 \
-days 1825 -out certs/cacert.pem \
-subj "/O=Project Contour/CN=Contour CA"
Then, the new CA key will be stored in certs/cakey.pem
and the cert in certs/cacert.pem
.
Then, we need to generate a keypair for Contour. First, we make a new private key:
openssl genrsa -out certs/contourkey.pem 2048
Then, we create a CSR and have our CA sign the CSR and issue a cert. This uses the file _integration/cert-contour.ext, which ensures that at least one of the valid names of the certificate is the bareword contour
. This is required for the handshake to succeed, as contour bootstrap
configures Envoy to pass this as the SNI for the connection.
openssl req -new -key certs/contourkey.pem \
-out certs/contour.csr \
-subj "/O=Project Contour/CN=contour"
openssl x509 -req -in certs/contour.csr \
-CA certs/cacert.pem \
-CAkey certs/cakey.pem \
-CAcreateserial \
-out certs/contourcert.pem \
-days 1825 -sha256 \
-extfile _integration/cert-contour.ext
At this point, the contour cert and key are in the files certs/contourcert.pem
and certs/contourkey.pem
respectively.
Next, we generate a keypair for Envoy:
openssl genrsa -out certs/envoykey.pem 2048
Then, we generated a CSR and have the CA sign it:
openssl req -new -key certs/envoykey.pem \
-out certs/envoy.csr \
-subj "/O=Project Contour/CN=envoy"
openssl x509 -req -in certs/envoy.csr \
-CA certs/cacert.pem \
-CAkey certs/cakey.pem \
-CAcreateserial \
-out certs/envoycert.pem \
-days 1825 -sha256 \
-extfile _integration/cert-envoy.ext
Like the contour cert, this CSR uses the file _integration/cert-envoy.ext. However, in this case, there are no special names required.
Next, we create the required secrets in the target Kubernetes cluster:
kubectl create secret -n projectcontour generic cacert --from-file=./certs/cacert.pem
kubectl create secret -n projectcontour tls contourcert --key=./certs/contourkey.pem --cert=./certs/contourcert.pem
kubectl create secret -n projectcontour tls envoycert --key=./certs/envoykey.pem --cert=./certs/envoycert.pem
Note that we don't put the CA key into the cluster, there's no reason for that to be there, and that would create a security problem. That also means that the cacert
secret can't be a tls
type secret, as they must be a keypair.
Once this process is done, the certificates will be present as Secrets in the projectcontour
namespace, as required by examples/contour
.