Merge "Doc improvements in Certificate Management"

This commit is contained in:
Zuul 2021-10-29 16:27:33 +00:00 committed by Gerrit Code Review
commit 5d9414b881
8 changed files with 388 additions and 58 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

@ -80,15 +80,17 @@ NodePort usage restrictions
nodeport-usage-restrictions
------------
Cert Manager
------------
----------------------
Certificate Management
----------------------
.. toctree::
:maxdepth: 1
kubernetes-user-tutorials-cert-manager
letsencrypt-example
internal-ca-and-nodeport-example-2afa2a84603a
issuers-in-distributed-cloud-fbc035675c0f
--------------------------------
Vault secret and data management

View File

@ -0,0 +1,155 @@
.. _internal-ca-and-nodeport-example-2afa2a84603a:
================================
Internal CA and NodePort Example
================================
This section provides an example of how to configure an application to use
NodePort to expose its self-managed |TLS|-based service and to use an Internal
|CA| for signing CERTIFICATEs.
Note that alternatively an External |CA| could be used with a NodePort-based
solution as well.
.. rubric:: |prereq|
This example requires that:
- Ensure that your |prod| administrator has enabled use of the
cert-manager apiGroups in your |RBAC| policies.
.. rubric:: |proc|
#. Create an internal RootCA ISSUER in the default namespace by applying the
following manifest file.
.. code-block:: none
# Create a cluster-wide ISSUER for create self-signed certificates
---
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: system-selfsigning-issuer
spec:
selfSigned: {}
# Create a Certificate (and key) for my RootCA
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: abccompany-starlingx-rootca-certificate
spec:
secretName: abccompany-starlingx-rootca-certificate
duration: 8640h
commonName: "abccompany-starlingx-rootca"
isCA: true
issuerRef:
name: system-selfsigning-issuer
kind: ClusterIssuer
# Create the RootCA ISSUER
---
apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: abccompany-starlingx-rootca-issuer
spec:
ca:
secretName: abccompany-starlingx-rootca-certificate
#. Share the public certificate of your internal RootCA to clients such that
they can trust certificates signed by this RootCA.
.. code-block:: none
CERT64=`kubectl get secret abccompany-starlingx-rootca-certificate -n default -o yaml | fgrep tls.crt | fgrep -v "f:tls.crt" | awk '{print $2}'`
echo $CERT64 | base64 --decode > abccompany-starlingx-rootca-certificate.pem
#. Create a deployment of an example demo application that uses NodePort to
expose its service and therefore manages its |TLS| connection on its own,
using a certificate it creates on its own.
Apply the following manifest.
Where ``10.10.10.45`` is the |OAM| Floating IP of the |prod| and
``abccompany-starlingx.mycompany.com`` is the |FQDN| for this address.
(You should substitute with the IP Address and |FQDN| for the |prod|
installation.)
.. code-block:: none
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: abccompany-starlingx.mycompany.com-certificate
spec:
duration: 2160h # 90d
renewBefore: 360h # 15d
secretName: abccompany-starlingx.mycompany.com-certificate
issuerRef:
name: abccompany-starlingx-rootca-issuer
kind: Issuer
commonName: abccompany-starlingx.mycompany.com
organization:
- abccompany-starlingx
dnsNames:
- abccompany-starlingx.mycompany.com
ipAddresses:
- 10.10.10.45
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-app
spec:
replicas: 1
selector:
matchLabels:
app: example-app
template:
metadata:
labels:
app: example-app
spec:
containers:
- name: example-app
image: example-app # not a real app, could substitute busybox here to look at mounted cert files inside container
imagePullPolicy: Always
ports:
- containerPort: 8443
protocol: TCP
volumeMounts:
- name: mycert
mountPath: "/etc/mycert" # the files tls.crt, tls.key and ca.crt will be under /etc/mycert/ in container
readOnly: true
volumes:
- name: mycert
secret:
secretName: abccompany-starlingx.mycompany.com-certificate
---
apiVersion: v1
kind: Service
metadata:
name: example-app
labels:
app: example-app
spec:
type: NodePort
ports:
- port: 443
protocol: TCP
targetPort: 8443
nodePort: 31118
selector:
app: example-app
#. If example-app existed, you would access it from your browser
with ``https://abccompany-starlingx.mycompany.com:31118``.
If you are using busybox to look at mounted cert files, attach to container
(e.g. ``kubectl exec busybox-... -it -- sh`` and ``cd /etc/mycert; ls``).

View File

@ -0,0 +1,53 @@
.. _issuers-in-distributed-cloud-fbc035675c0f:
============================
Issuers in Distributed Cloud
============================
In a Distributed Cloud environment, end-users applications have a number of
options for the cert-manager ISSUERs they use:
- (Recommended) As part of your application deployment on each subcloud,
create a cert-manager ISSUER for the External |CA| that you wish to use for
signing your certificates.
- The External |CA|-type ISSUER is configured exactly the same way for
each of your application deployments on each subcloud, and
- Your external clients need only trust a single External |CA|s public
certificate.
- As part of your application deployment on each subcloud, create a local
internal RootCA ``ca`` ISSUER for signing your certificates.
- The local internal RootCA ``ca`` ISSUER should ideally be slightly
different (e.g. a unique subject) on each deployment, and
- Your external clients need to trust each application deployments (on
each subcloud) local internal RootCA public certificate.
- This option is not ideal since this could mean 100s of RootCA
Certificates.
.. - As part of your application deployment on each subcloud, use the
|prod|s Intermediate |CA| ISSUER for that subcloud
- In a Distributed Cloud environment, |prod| manages a
hierarchy of |CAs|, anchored by a single RootCA at the
System Controller.
See below:
.. figure:: /usertasks/figures/figure_3_issuers_dist_cloud.png
:scale: 100%
The RootCA Certificate and Intermediate |CA| Certificates are
created/renewed automatically by |prod|.
- Your end-users application deployment on a subcloud can simply
create/sign CERTIFICATEs using the |prod|s
DC-AdminEp-Intermediate-CA on the subcloud.
- Your external clients need only trust the single |prod|
DC-AdminEp-Root-|CA|s public certificate on the system Controller.

View File

@ -2,64 +2,161 @@
.. iac1588347002880
.. _kubernetes-user-tutorials-cert-manager:
============
Cert Manager
============
======================
Certificate Management
======================
|prod| integrates the open source project cert-manager.
|prod| integrates the open source project cert-manager
(http://cert-manager.io), in order to provide certificate management support
for end-users containerized applications.
------------------
Cert Manager Modes
------------------
Cert-manager is a native Kubernetes certificate management controller, that
supports certificate management with external certificate authorities \(CAs\).
nginx-ingress-controller is also integrated with |prod| in support of http-01
challenges from CAs as part of cert-manager certificate requests.
supports the following general modes of operation:
For more information about Cert Manager, see `cert-manager.io
<http://cert-manager.io>`__.
- Interacting with External Certificate Authorities (|CAs|)
.. _kubernetes-user-tutorials-cert-manager-section-lz5-gcw-nlb:
In this mode, a cert-manager ISSUER is configured to interact with an
External |CA| of a particular type. External |CA| types supported by
cert-manager are ACME, Vault or Venafi (note that |prod| has only
tested and validated cert-manager with ACME |CAs|).
------------------------------------
Prerequisites for using Cert Manager
------------------------------------
When a cert-manager CERTIFICATE is created using this External |CA| ISSUER,
cert-manager
.. _kubernetes-user-tutorials-cert-manager-ul-rd3-3cw-nlb:
- creates the private key and public certificate,
- Ensure that your |prod| administrator has shared the local registry's
public repository's credentials/secret with the namespace where you will
create certificates,. This will allow you to leverage the
``registry.local:9001/public/cert-manager-acmesolver`` image.
- sends the Certificate Signing Request to the External |CA| using the
appropriate protocol for the type of External |CA|, and
- Ensure that your |prod| administrator has enabled use of the
cert-manager apiGroups in your RBAC policies.
- responds to any challenges (as specified in the CERTIFICATE specs) from
the |CA|
.. _kubernetes-user-tutorials-cert-manager-section-y5r-qcw-nlb:
The signed certificate is made available in a Kubernetes SECRET specified
in the CERTIFICATE spec.
----------------------------------------------
Resources on Creating Issuers and Certificates
----------------------------------------------
Cert-Manager will also automatically monitor CERTIFICATE expiry dates and
automatically send an updated Certificate Signing Request messages to the
External |CA|, prior to expiry of the CERTIFICATE (as specified in the
CERTIFICATE specs), in order to renew the CERTIFICATE and update the
Kubernetes SECRET holding the certificate.
.. _kubernetes-user-tutorials-cert-manager-ul-uts-5cw-nlb:
.. figure:: /usertasks/figures/figure_1_cert_manager.png
:scale: 100%
- Configuration documentation:
- Providing an Internal Certificate Authority
- `https://cert-manager.io/docs/configuration
<https://cert-manager.io/docs/configuration/>`__/
In this mode, a cert-manager ``selfsigned`` type ISSUER and ``ca`` type
ISSUER provides a non-challenging Root |CA| for signing certificates local to
the Kubernetes cluster.
This link provides details on creating different types of certificate
issuers or CAs.
A ``selfsigned`` type ISSUER is created to automatically create a private key
and certificate pair for the internal Root |CA|.
- Usage documentation:
Then a ``ca`` type ISSUER is created with this generated Root |CA|s
private-key/certificate pair for signing.
- `https://cert-manager.io/docs/usage/certificate/
<https://cert-manager.io/docs/usage/certificate/>`__
When a cert-manager CERTIFICATE is created using this Internal ``ca``
ISSUER, cert-manager
This link provides details on creating a standalone certificate.
- creates the private key and public certificate, and
- `https://cert-manager.io/docs/usage/ingress/
<https://cert-manager.io/docs/usage/ingress/>`__
- simply signs the certificate with the ``ca`` ISSUERs
private-key/certificate pair.
This link provides details on adding a cert-manager annotation to an
Ingress in order to specify the certificate issuer for the ingress to
use to request the certificate for its https connection.
The signed certificate is made available in a Kubernetes SECRET specified
in the CERTIFICATE spec.
- :ref:`LetsEncrypt Example <letsencrypt-example>`
Again, cert-Manager will automatically monitor CERTIFICATE expiry dates and
automatically request the internal ``ca`` ISSUER to sign an updated
certificate, prior to expiry of the CERTIFICATE (as specified in the
CERTIFICATE specs), in order to renew the CERTIFICATE and update the
Kubernetes SECRET holding the certificate.
.. figure:: /usertasks/figures/figure_2_cert_manager.png
:scale: 100%
- Combination of the above two modes
For example in a particular RootCA - IntermediateCA - Server certificate
chain,
- The RootCA ISSUER in cert-manager could be of type ``acme`` for
requesting the IntermediateCAs certificate from an external ACME |CA|,
- While the IntermediateCA ISSUER in cert-manager could be of type ``ca``
for signing the server certificates based on the intermediateCA
certificate (from the external ACME |CA|).
---------------------------------------------------
Using Cert Manager CERTIFICATES in your Application
---------------------------------------------------
How CERTIFICATEs (and their |TLS| type SECRETs) are created and integrated into
an end-users application depends on how the end-user has chosen to expose its
service externally. There are typically two options:
- The end-users application uses ingress controller to expose its service
(the most common approach)
In this scenario, the end-users application uses |prod|s
integrated nginx ingress-controller to both originate/terminate the HTTPS
connection as well as deal with cert-manager for requesting the required
CERTIFICATE.
Specifically, in this scenario, the end-users applications helm chart or
yaml file must
- create an INGRESS object that
- specifies the details on ingress forwarding based on the URL
(hostname, port and path), and
- specifies ``|TLS|`` mode along with cert-manager -specific
annotations for details on creating the CERTIFICATE for this
ingress connection with cert-manager; minimally the cert-manager
ISSUER to use must be specified.
Nginx Ingress Controller will automatically detect when cert-manager renews
the server certificate and update its HTTPS connection to use the new
certificate.
The end-users application does not deal with HTTPS or certificates at all.
- The end-users application exposes its service with a NodePort and
originates/terminates HTTPS itself
In this scenario, the end-users application is originating/terminating
HTTPS on its own, so it needs access to the Kubernetes SECRET holding the
|TLS| certificate, in order to establish the HTTPS connection.
In this scenario, the end-users applications helm chart or yaml file must
- create the CERTIFICATE (referencing the desired ISSUER to use, and
indicating the SECRET to store the certificate in),
- include the SECRET as a mounted volume in the pod spec
- such that the applications container can access the |TLS|
certificate as a |PEM| file for use in establishing the HTTPS
connection.
Note that in this scenario, the applications container must detect when
the mounted SECRET file changes due to cert-manager auto-renewing the
CERTIFICATE (and the associated SECRET), and update its HTTPS connection to
use the updated certificate.
.. seealso::
See :ref:`External CA and Ingress Controller Example <letsencrypt-example>`
section for an example of how to configure an application to use Ingress
Controller to both expose its TLS-based service and to use an External |CA|
for signing CERTIFICATEs.
See :ref:`Internal CA and NodePort Example
<internal-ca-and-nodeport-example-2afa2a84603a>` section for an example of
how to configure an application to use NodePort to expose its self-managed
|TLS|-based service and to use an Internal |CA| for signing CERTIFICATEs.

View File

@ -2,11 +2,16 @@
.. nst1588348086813
.. _letsencrypt-example:
===================
LetsEncrypt Example
===================
==========================================
External CA and Ingress Controller Example
==========================================
The LetsEncrypt example illustrates cert-manager usage.
This section describes how to configure an application to use Ingress
Controller to both expose its |TLS|-based service and to use an External |CA|
for signing CERTIFICATEs.
NOTE that alternatively an Internal |CA| could be used with an Ingress
Controller -based solution as well.
.. rubric:: |prereq|
@ -14,15 +19,28 @@ This example requires that:
.. _letsencrypt-example-ul-h3j-f2w-nlb:
- the LetsEncrypt CA in the public internet can send an http01 challenge to
the FQDN of your |prod|'s floating OAM IP Address.
- The LetsEncrypt |CA| in the public internet can send an http01 challenge to
the |FQDN| of the |prod|'s floating |OAM| IP Address.
- your |prod| has access to the kuard demo application at
gcr.io/kuar-demo/kuard-amd64:blue
- The |prod| has access to the kuard demo application at
`gcr.io/kuar-demo/kuard-amd64:blue <gcr.io/kuar-demo/kuard-amd64:blue>`__
- Ensure that your |prod| administrator has shared the local
registrys public repositorys credentials/secret with the namespace where
you will create certificates. This will allow you to leverage the
:command:`registry.local:9001/public/cert-manager-acmesolver` image. See
:ref:`Set up a Public Repository in Local Docker Registry
<setting-up-a-public-repository>`.
- Ensure that your |prod| administrator has enabled use of the
cert-manager apiGroups in your |RBAC| policies.
- Ensure that your |prod| administrator has opened port 80 and 443 in
GlobalNetworkPolicy.
.. rubric:: |proc|
#. Create a LetsEncrypt Issuer in the default namespace by applying the
#. Create a LetsEncrypt ISSUER in the default namespace by applying the
following manifest file.
.. code-block:: none
@ -48,10 +66,15 @@ This example requires that:
#. Create a deployment of the kuard demo application
\(`https://github.com/kubernetes-up-and-running/kuard
<https://github.com/kubernetes-up-and-running/kuard>`__\) with an ingress
<https://github.com/kubernetes-up-and-running/kuard>`__\) with an INGRESS
using cert-manager by applying the following manifest file:
Substitute values in the example as required for your environment.
Where both ``starlingx.mycompany.com`` and
``kuard.starlingx.mycompany.com`` are |FQDNs| that map to the |OAM|
Floating IP of |prod|.
(You should substitute these for |FQDNs| for the |prod| installation.)
.. parsed-literal::
@ -101,10 +124,10 @@ This example requires that:
spec:
tls:
- hosts:
- kuard.my-fqdn-for-|prefix|.company.com
- kuard.starlingx.mycompany.com
secretName: kuard-ingress-tls
rules:
- host: kuard.my-fqdn-for-|prefix|.company.com
- host: kuard.starlingx.mycompany.com
http:
paths:
- backend:
@ -113,5 +136,5 @@ This example requires that:
path: /
#. Access the kuard demo from your browser to inspect and verify that the
certificate is signed by LetsEncrypt CA. For this example, the URL
would be https://kuard.my-fqdn-for-|prefix|.company.com.
certificate is signed by LetsEncrypt |CA|. For this example, the URL
would be https://kuard.starlingx.mycompany.com.