TLS Configuration Management
GoodData.CN ready for Kubernetes will be published during May 2021. Stay tuned and watch GoodData Developers website.
This page presents available options how to manage TLS certificates for Organization resources. You will create the Orgnazations after you finish the installation of the GoodData.CN. However, you should have clear understanding of the certificate managent required by Organizations prior you start with the installation.
Every Organization has its own
hostname that is bound to Kubernetes Ingress resource and all services for a given organization are available on this hostname.
To keep data secured when transferred between client and server, TLS is used. For clients, it means that they will use HTTPS protocol schema instead of HTTP.
TLS certificate management depends on the way how you decided to deploy the frontend Load Balancer.
Option 1: TLS terminated on Load Balancer
Frontend Load Balancer has a TLS certificate assigned and decrypts incoming traffic. Requests are then routed unencrypted to the Ingress controller.
Many cloud-native Load Balancers support only one certificate, so this method
is suitable only for wildcard certificates, like
*.cust.company.com. All organizations'
hostnames therefore must match this wildcard, like
another.cust.company.com, and so on.
This may be very limiting, but still satisfying for some use cases.
The Organization resource must not contain the
kind: Organization metadata: name: some-org namespace: gooddata-cn ... spec: id: organization1 name: The First Organization hostname: org-one.customers.example.com adminGroup: adminGroup adminUser: admin adminUserToken: "$5$1234567890123456$pA9PBFxCwLbVOB.fImbUCUjoyQblla4EdSkHhVmy9A7" # tls: TLS section must not be present
Option 2: TLS terminated on Ingress controller
Frontend Load Balancer passes encrypted traffic unchanged to Ingress controller. TLS decryption is performed in the Ingress controller, using a certificate matching the Ingress hostname. It means that every organization can have any hostname, provided the certificate for this hostname is available to the ingress controller.
There are three ways how the certificate can be assigned to an Ingress:
Oprtion 2a: Manual certificate management
The certificate for every organization must be manually loaded as a
Secret to the
same namespace where the GoodData.CN is deployed. Assuming you have the customer’s key and
certificate stored in local files
some-org.crt, the Secret can
be created using the command:
$ kubectl create secret tls secret-with-cert-for-some-org \ --cert=some-org.crt --key=some-org.key --namespace=gooddata-cn
In the Organization resource, you need to put a reference to this Secret in
spec.tls.secretName field. Other
tls fields (like
must NOT be used.
kind: Organization metadata: name: some-org namespace: gooddata-cn ... spec: id: organization1 name: The First Organization hostname: analytics.org-one.com adminGroup: adminGroup adminUser: admin adminUserToken: "$5$1234567890123456$pA9PBFxCwLbVOB.fImbUCUjoyQblla4EdSkHhVmy9A7" tls: # this Secret needs to be precreated manually secretName: secret-with-cert-for-some-org # issuerType: is ignored when issuerName is not set # issuerName: must NOT be used
Note: This approach requires manual renewal of the certificate. When certificate nears its expiration, you need to renew the certificate from CA and update values in secret.
Option 2b: Certificates issued by internal CA integrated with cert-manager
If your company has its own Certificate Authority for issuing certificates, you can use these certificates for all Organizations you create. Note that you need to make clients' web browsers trust your CA, so using this method is meaningful only for company-wide deployment where you have control over clients' web browser configuration.
Cert-manager integrates with various CA systems. Refer to cert-manager’s documentation for details. The most interesting Issuer types you can find are:
- CA - cert-manager’s own Certificate Authority
- Vault - CA built on top of existing HashiCorp Vault
- External - contributed projects providing Issuer interface to other systems, like AWS Private CA, FreeIPA, Google Cloud CA, or MS Active Directory.
For a quick start, let’s assume you will use the “CA”-type issuer with the following setup (assuming you already have CA key/certificate pair in
# Kubernetes secret with CA key and certificate. You can # also create this Secret directly from command-line using: # kubectl create secret tls company-ca-key-pair \ # --cert=ca.crt --key=ca.key --namespace=gooddata-cn --- apiVersion: v1 kind: Secret metadata: name: company-ca-key-pair namespace: gooddata-cn data: # base64-encoded CA certificate (PEM) tls.crt: LS0tLS1CRUdJTiBDRVJUSU... # base64-encoded key belonging to CA certificate (PEM) tls.key: LS0tLS1CRUdJTiBSU0EgUF...
Then, create an Issuer of type
# CA Issuer apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: ca-issuer namespace: gooddata-cn spec: ca: secretName: company-ca-key-pair
Note: Cert-manager supports two kinds of issuers:
Issuer: Its operation is limited to a given namespace where this resource is created.
ClusterIssuer: Cluster-wide resource accessible from any namespace.
If you plan to use cert-manager’s CA for other applications running in different namespaces, you can create
ClusterIssuer instead of
# CA ClusterIssuer apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: ca-issuer spec: ca: secretName: company-ca-key-pair
Keep in mind that for the
ClusterIssuer, the referenced Secret
must be in the same namespace where the cert-manager’s controller is deployed
Option 2c: Certificates issued by Let’s Encrypt integrated with cert-manager
The last method of obtaining TLS certificates is to use public CA Let’s Encrypt. Let’s Encrypt CA is trusted by all major web browsers and operating systems. Cert-manager has first-class support for Let’s Encrypt CA and its ACME protocol.
Therefore you can use this method for automated provisioning of certificates for publicly accessible deployments where you can’t manage the clients' browsers trusted certificates.
To use the Let’s Encrypt service for issuing TLS certificates to your customers'
Organization hostnames, you need to configure
ClusterIssuer) for using
ACME protocol and
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-issuer spec: acme: # You must replace this email address with your own. # Let's Encrypt will use this to contact you about expiring # certificates, and issues related to your account. email: email@example.com # After you properly test the Issuer functionality, you should # switch to `https://acme-v02.api.letsencrypt.org/directory` server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: # Secret resource that will be used to store the account's private key. name: letsencrypt-issuer-account-key # Add a single challenge solver, HTTP01 using nginx solvers: - http01: ingress: class: nginx
Creating Organization custom resource
Organization resourceThe Organization creation is carried out after the installation of GoodData.CN helm chart is done. It is mentioned here just for the context.
When the underlying TLS infrastructure is prepared and configured, you may proceed
to create the first organization. When TLS certificates are issued by cert-manager,
the Organization resource must contain the
tls section with three fields:
secretName- the name of Kubernetes Secret where the cert-manager will store the issued certificate.
ClusterIssuer, depending on what kind of issuer you decided to use (namespaced or cluster-wide, see above). Defaults to
issuerName- the name of Issuer or ClusterIssuer resource you want to use for issuing a certificate.
For example with CA Issuer described above (Option 3), your Organization resource should look similar to:
kind: Organization metadata: name: some-org namespace: gooddata-cn ... spec: id: organization1 name: The First Organization hostname: analytics.org-one.com adminGroup: adminGroup adminUser: admin adminUserToken: "$5$1234567890123456$pA9PBFxCwLbVOB.fImbUCUjoyQblla4EdSkHhVmy9A7" tls: # this Secret will be created and populated by cert-manager secretName: some-org-tls # this is the kind of issuer (either "Issuer" or "ClusterIssuer"). If not set, # defaults to "Issuer". issuerType: ClusterIssuer # the name of Issuer (or ClusterIssuer) responsible for issuing certificate for # Organization's hostname issuerName: ca-issuer