Use new built-in RFC2136 DNS provider
Update dependencies
Add .gitignore
Notariat is narrow-purpose, but therefore extremely simple certificate manager for Kubernetes. It can obtain certificates from any ACME-compatible CA (e.g. Let's Encrypt), but it has the following limitations:
The main input of notariat is the configuration, which, at its core, maps a set of Kubernetes secret references to lists of domain names. The main control loop will continually ensure that each provided secret references a valid TLS certificate (and key) for the corresponding list of domain names.
For notariat to work, you will need to:
Read the rest of this document for more details on each point.
A more detailed explanation of how notariat works is best given by looking at an example config map:
apiVersion: v1
kind: ConfigMap
metadata:
name: notariat-config
data:
certificates: |
- secret: cert-example.com
domains:
- "example.com"
- "www.example.com"
email: admin@example.com
tsigSecretName: tsigkey
In this example, notariat will make sure that the secret cert-example.com
in
its current namespace (see below for more about namespaces) is a secret of type
kubernetes.io/tls
that contains a valid TLS certificate for the domains
example.com and www.example.com. It will do this according to the following
algorithm:
In the configuration, both secret
and tsigSecretName
can be a namespaced
secret reference. The following example will work:
apiVersion: v1
kind: ConfigMap
metadata:
name: notariat-config
data:
certificates: |
- secret: default/cert-example.com
domains:
- "example.com"
- "www.example.com"
email: admin@example.com
tsigSecretName: dns/tsigkey
Note that for this to work, you will need to set up ACLs that allow notariat to access other namespace's secrets. One simple approach might be to run notariat in the namespace of your ingress controller and also as the service account created for your ingress controller, as those generally have the required access already. See the deployment example below.
The TSIG keys required for the DNS updates have to be stored in
[hmac:]name:key
format. Supported HMAC algorithms are hmac-sha1
,
hmac-sha224
, hmac-sha256
, hmac-sha384
, and hmac-sha256
. If the HMAC
part is omitted it defaults to hmac-sha256
. Knot's keymgr for
example will output this format as a comment on the first line when invoking
keymgr -t
.
This key format must be supplied as a value to a key called key
. To create a
valid TSIG secret for notariat:
$ cat key
hmac-sha256:example.com.:PA2svcP/i7sR/etNrqLCR3Ybw4gb1YMmfVGiyyUmYlo=
$ kubectl create secret generic tsigkey --from-file=key
Notariat will create a separate account for each email encountered in the
configuration. This happens on demand, i.e. only once a certificate actually
needs to be obtained. Each account key is stored in a secret notariat-acme-*
in notariat's current namespace.
Notariat takes the following command line arguments:
-acme string
directory URL of ACME server (default "https://acme-staging-v02.api.letsencrypt.org/directory")
-config string
name of ConfigMap to use
-kubeconfig string
path to kubeconfig (default: in-cluster auth)
-namespace string
namespace (default: current pod's namespace)
Note how it by default talks to the Let's Encrypt staging environment. If you
want to issue "real" certificates, make sure to run it with -acme https://acme-v02.api.letsencrypt.org/directory
(or whichever ACME compatible
CA you prefer).
The -config
argument is mandatory and must be set to the name of the config
map that contains notariat's configuration. The config map must be in the same
namespace that notariat is running in.
The -kubeconfig
and -namespace
arguments are intended for running notariat
out-of-cluster, e.g. for development and debugging. They should not be used in
deployments.
Build a docker image with the provided Dockerfile
and push it to a registry
of your choice. You then have two options:
For very small deployments, you can run one instance of notariat in each namespace that needs TLS certificates. Configure each instance accordingly. Notariat will require no special ACLs in this case.
The recommended approach however, is to run notariat along with your ingress controller, as it is the primary consumer of the TLS certificates. Here is an example deployment that will run with a mostly-default HAProxy ingress controller:
apiVersion: apps/v1
kind: Deployment
metadata:
name: notariat
namespace: haproxy-controller
labels:
app: notariat
spec:
replicas: 1
selector:
matchLabels:
app: notariat
template:
metadata:
labels:
app: notariat
spec:
# Account created for the ingress controller
serviceAccountName: haproxy-kubernetes-ingress
containers:
- name: notariat
image: registry.example.org/notariat:latest
imagePullPolicy: Always
args:
- --config=notariat-config
- --acme=https://acme-v02.api.letsencrypt.org/directory
This will run notariat in the same namespace and as the same service account as the ingress controller. As the ingress controller needs access to other namespaces' secrets already, no further ACLs need to be set up.
Patches, questions, or other feedback can be sent to my public inbox.