We will need a Certificate Authority (CA) and an application certificate
Create a separate directory for certificates
mkdir certs
cd certs
Generate a private key for the CA:
openssl genrsa -out ca.key 2048
Generate the configuration for the CA certificate:
cat > ca_config << EOF
[ req ]
default_bits = 2048
default_md = sha512
default_keyfile = ca.key
prompt = no
encrypt_key = yes
# base request
distinguished_name = req_distinguished_name
# distinguished_name
[ req_distinguished_name ]
countryName = "CA" # C=
stateOrProvinceName = "Quebec" # ST=
localityName = "Quebec" # L=
organizationName = "Org " # O=
organizationalUnitName = "Unit" # OU=
commonName = "Common" # CN=
emailAddress = "no-reply@notexist" # CN/emailAddress=
EOF
Generate the public certificate for the CA:
openssl req -new -x509 -key ca.key -out ca.crt -config ca_config
The admission controller app will need to have a certificate signed by a valid CA, in this case, the one we have just created.
Generate a private key for the app:
openssl genrsa -out app.key 2048
The Subject Alternative Name and CN should match the service that will be created later on. Configure an environment variable with the expected values:
SERVICENAME=k8s-admission-demo
NAMESPACE=default
Generate a configuration with extensions for the certificate.
cat > app_config << EOF
[req]
default_bits = 2048
req_extensions = v3_req
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
[ v3_req ]
basicConstraints=CA:FALSE
subjectAltName=@alt_names
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[ alt_names ]
DNS.1 = ${SERVICENAME}
DNS.2 = ${SERVICENAME}.${NAMESPACE}
DNS.3 = ${SERVICENAME}.${NAMESPACE}.svc
DNS.4 = ${SERVICENAME}.${NAMESPACE}.svc.cluster.local
EOF
Generate a certificate request (CSR) for the app:
openssl req -new -key app.key -subj "/CN=${SERVICENAME}.${NAMESPACE}.svc" -config app_config -out app.csr
And finally, sign this CSR with the CA key to generate a public certificate for the app:
openssl x509 -req -in app.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extensions v3_req -extfile app_config -out app.crt
Validate that certificate has a Subject Alternative Name field:
openssl x509 -noout -ext subjectAltName -in app.crt
Expected result:
X509v3 Subject Alternative Name:
DNS:k8s-admission-demo, DNS:k8s-admission-demo.default, DNS:k8s-admission-demo.default.svc, DNS:k8s-admission-demo.default.svc.cluster.local
Since this CA is unknown to Kubernetes we need to provide its public certificate so Kubernetes can validate the application certificate. Let's create a base64 encoded format for the CA.
cat ca.crt | base64 | tr -d '\n' > ca_bundle
Generated files:
app.crt
app.csr
app.key
ca.crt
ca.key
ca.srl
ca_bundle
ca_config