Kubernetes API Server accesses Webhook Server via HTTPS POST, that is, Webhook Server must listen on HTTPS protocol.

To use the HTTPS protocol, three things are required: CA, key, and cert. Ca refers to the CA certificate, key refers to the private key used by the server, and cert refers to the public key, also known as the server certificate. When accessing Webhook Server, apI-server must specify the CA certificate. When Webhook Server is started, the key and cert must be loaded.

The community recommends using cert-Manager to provide certificate management services for Webhook. This article does not discuss how cert-Manager works, but how to use cert-Manager to configure certificates for Webhook from a user’s perspective.

cert-manager is a native Kubernetes certificate management controller. It can help with issuing certificates from a variety of sources, such as Let’s Encrypt, HashiCorp Vault, Venafi, a simple signing key pair, or self signed.

Basic concepts of cert-Manager

To use cert-Manager, you need to understand the following concepts: Issuers, Certificate, and CA Injector.

Issuers

Issuers is a K8S resource defined by cert-Manager, which is equivalent to a certificate authority and used to generate certificates. Issuers is divided into Issuer and ClusterIssuer:

Issuer is the Issuer of the namespace level and can provide the certificate for the namespace where the Issuer resides.

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  .
spec:
  .
Copy the code

ClusterIssuer is the issuer of the Cluster level and can provide certificates for all namespaces in the cluster.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  .
spec:
  .
Copy the code

Certificate

Certificate is a resource defined by cert-Manager in K8S and belongs to namespace level.

Cert-manager will create a real certificate pair (cert-pair) based on the certificate definition and issuer.

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: webhook-cert
  namespace: {{ .Release.Namespace }}
spec:
  dnsNames:
  - webhook.{{ .Release.Namespace }}.svc
  - webhook.{{ .Release.Namespace }}.svc.cluster.local
  issuerRef:
    kind: Issuer
    name: selfsigned-issuer
  secretName: webhook-server-cert
Copy the code

CA Injector

CA Injector is a controller of cert-Manager. It can write the caBundle field to the three K8S resources:

  • ValidatingWebhookConfiguration
  • MutatingWebhookConfiguration
  • CustomResourceDefinition

To use CA Injector, add the annotation: cert-manager. IO /inject-ca-from to webhook yamL. This tells the CA Injector which certificate to write into cabundle.

Such as:

apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
  ...
annotations:
  cert-manager.io/inject-ca-from: example1/webhook1-certificate
webhooks:
  ...
Copy the code

This example represents populating the CABundle with a CA that uses secret Webhook-certificate under Namespace example1.

Give it a try

1. The deployment of Cert – Manager

Kubectl apply - validate = false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.3/cert-manager.yamlCopy the code

2. Create the Issuer

In general, self-signed certificates are used to issue certificates to Webhook-Server, because no external services will access Webhook other than K8S API Server.

issuer.yaml:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: selfsigned-issuer
  namespace: default
spec:
  selfSigned: {}
Copy the code

create

$ kubectl apply -f issuer.yaml

$ kubectl get issuers selfsigned-issuer -o wide
NAME                READY   STATUS   AGE
selfsigned-issuer   True             2m7s
Copy the code

3. Create a Certificate

IssuerRef: issuerRef: issuerRef: issuerRef: issuerRef: issuerRef: issuerRef: dnsNames: issuerRef: issuerRef: issuerRef: issuerRef: issuerRef: issuerRef Finally, we need the secretName, which secret the certificate will be stored in.

cert.yaml

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: luna-cert
  namespace: default
spec:
  dnsNames:
  - luna-webhook.default.svc
  - luna-webhook.default.svc.cluster.local
  issuerRef:
    kind: Issuer
    name: selfsigned-issuer
  secretName: luna-cert
Copy the code

Create a certificate

$ kubectl apply -f cert.yaml

$ k get certificate luna-cert
NAME        READY   SECRET      AGE
luna-cert   True    luna-cert   1m
Copy the code

4. Create Webhook

webhook.yaml

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  annotations:
    cert-manager.io/inject-ca-from: default/luna-cert
  name: luna-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
  - v1beta1
  clientConfig:
    service:
      name: luna-webhook
      namespace: default
      path: /luna-validate-webhook
      port: 443
  failurePolicy: Fail
  matchPolicy: Equivalent
  name: vservice
  rules:
  - apiGroups:
    - ""
    apiVersions:
    - v1
    operations:
    - CREATE
    - UPDATE
    resources:
    - services
    scope: '*'
  sideEffects: None
  timeoutSeconds: 10

Copy the code

create

kubectl apply -f webhook.yaml
Copy the code

Now look at the newly created Webhook and see that the caBundle has been filled in.

apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: ... annotations: cert-manager.io/inject-ca-from: default/luna-cert webhooks: - admissionReviewVersions: - v1beta1 clientConfig: caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrakNDQWVLZ0F3SUJBZ0lRSjFwc3ZsdmZsNlNabUhvWFI3SUVBekFOQmdrcWhraUc5dzBCQVFzRkFE QUEKTUI0WERUSXdNVEF5TWpFeU1ESXdOMW9YRFRJeE1ERXlNREV5TURJd04xb3dBRENDQVNJd0RRWUpLb1pJaHZjTgpBUUVCQlFBRGdnRVBBRENDQVFvQ2dn RUJBS3M2czAxR1FRa3R6VGZUQXRBTkV3RnJ1RS95WEVINmxQaVhwTGoyCnIzQjBQZkFLem1wZDdYd2QrbUxaNnA1aytDdEFKc293ZU5lRUNDd3prZE1Ha3p0 cE1zK1huZ1d1dTVsajJZVUwKaW81Tm5TMjVYaHkxYlZOb0Y0SENuMGlrMWxLTXZBZnBEMXlKeDBkalY4TzcrdkMwL2NkN25BanMzbFcrVnVCcwpUT2tlY1g4 elJ2YVBnd1pGRUd3SjR2MmRITGVsZjBvbkdRU25yRWZvMEE5am9DaGFGWkdzcEUrTEwwdm5mOWhXCkYzVVVLaFIrd25PdnZOajJYa2dzaktPYmRtUVpEaENB bDJxekw2cGNYZ2xPc21hTjVTMEJaYm5SSWRIZERBU1gKVGN1Nk42QzJjcUlHNnA3OW5ZeXZMajFaM0diTFdnODl0M3hSRGhxUkZleDdVaDBDQXdFQUFhTndN RzR3RGdZRApWUjBQQVFIL0JBUURBZ1dnTUF3R0ExVWRFd0VCL3dRQ01BQXdUZ1lEVlIwUkFRSC9CRVF3UW9JWWJIVnVZUzEzClpXSm9iMjlyTG1SbFptRjFi SFF1YzNaamdpWnNkVzVoTFhkbFltaHZiMnN1WkdWbVlYVnNkQzV6ZG1NdVkyeDEKYzNSbGNpNXNiMk5oYkRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQW8w OS9QWGR2OCtYV0RMd1k5S2tTRjYyNApySGpoQkJpL0RMWExLTGFMa1NlUEpuSCtwcGQ2cmt4ejJudkpKWnVBTzhKYmlrR3o0ZkFsUkhqSmFxR3oxV1JhCkQ2 ellXZ0NmWHQ3RVlJejJXZm50OVpNbnBWRU9wcEUrUnJ1QURBcnVsRGlJTk5Xc1dtOFluK3lWc3gvbkF5MVYKRk9HbEJ3aE1FNEdHLzZlNERFd2hFalpWR3FO MVlxcFFWOUJCQXhrZVhBcHMzTWMwS1EzTDlJMHlUZzdrdHdNYQp1eVdaU0t0SDZtMTFoNE1ueFBXcHJHTlNTTExwMytNcXlvMnI1Q25Rd0J3QmR4Rmg4NWFC aWhyOVd4K2NxejZkCjFrKzdxSEc2SEFVQjVCVGtRZ0hvWnpkR2VJN3pldXFsSG8wa2lZMlRNdkIvSEVSd21WQ3BsNXNsTXB1azJRPT0KLS0tLS1FTkQgQ0VS VElGSUNBVEUtLS0tLQo=Copy the code

Conclusion:

I showed above that you can use cert-Manager to automatically issue certificates to Webhooks. A Certificate actually contains three aspects, you can check the secret of Certificate.

$ kubectl describe secrets luna-cert
Name:         luna-cert
Namespace:    default
Labels:       <none>
Annotations:  cert-manager.io/alt-names: luna-webhook.default.svc,luna-webhook.default.svc.cluster.local
              cert-manager.io/certificate-name: luna-cert
              cert-manager.io/common-name:
              cert-manager.io/ip-sans:
              cert-manager.io/issuer-group:
              cert-manager.io/issuer-kind: Issuer
              cert-manager.io/issuer-name: selfsigned-issuer
              cert-manager.io/uri-sans:

Type:  kubernetes.io/tls

Data
====
ca.crt:   1094 bytes
tls.crt:  1094 bytes
tls.key:  1675 bytes
Copy the code

This shows cert-Manager populating ca.crt into webhook cabundle. The other two tls. CRT and tlS. key need to be mounted to the pod where webhook is located. If you are using KubeBuilder, the directory should be/TMP/k8S-webhook-server /serving-certs

luna-deployment.yaml
  template:
    spec:
      containers:
      - name: luna
        image: harbor.inner.galaxy.ksyun.com/galaxy/luna-controller:0.1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8443
          name: webhook
          protocol: TCP
        volumeMounts:
        - mountPath: /tmp/k8s-webhook-server/serving-certs
          name: cert
          readOnly: true
      volumes:
      - name: cert
        secret:
          defaultMode: 420
          secretName: luna-cert
Copy the code

reference

cert-manager.io/docs/