Skip to content
This repository has been archived by the owner on Aug 29, 2022. It is now read-only.

Consider adding an admission control webhook sample deployment with '-include-unqualified' #32

Open
fred-vogt opened this issue Aug 15, 2020 · 3 comments

Comments

@fred-vogt
Copy link

Specifically kube api server expects admission control webhooks to a have SAN entry for <service-name>.kube-system.svc

...
initContainers:
...
    args:
      - -namespace=$(NAMESPACE)
      - -pod-name=$(POD_NAME)
      - -query-k8s
      - -include-unqualified
...

Results in an issued cert with the necessary SAN entry for the "un-qualified" <service-name>.kube-system.svc:

# kubectl -n kube-system logs deployment/<name>-webhook -c certificate-init-container
# openssl x509 -in certificate.crt -text -noout

Certificate Information:
Common Name: 100-96-2-2.kube-system.pod.cluster.local
Subject Alternative Names: 
  100-96-2-2.kube-system.pod.cluster.local
  <service-name>.kube-system.svc.cluster.local
  <service-name>.kube-system.svc
  IP Address:100.96.2.2
  IP Address:100.69.175.40
Valid From: August 14, 2020
Valid To: August 14, 2021
Serial Number: 8f618d0c4564d8233bc158d097534b03

Without -include-unqualified kube-apiserver will reject the created certificate:

Failed calling webhook, 
  failing open <name>: 
     failed calling webhook "<name>": 
     Post https://<service-name>.kube-system.svc:443/mutate?timeout=10s: x509: certificate is valid for 
       <service-name>.kube-system.svc.cluster.local, (fully qualified service name)
not <service-name>.kube-system.svc
@johngmyers
Copy link
Member

Yeah, that's really a bug in kube-apiserver. I don't believe svc is a reserved top-level domain, so theoretically someone could register it and create interesting mischief. I should get around to filing the bug sometime.

I don't like recommending people run things in less secure configurations, but as we found out when we deployed our first admission control webhook, Kubernetes kinda forces them to.

@fred-vogt
Copy link
Author

Good points.

I looked into the clientConfig field of the webhook spec.

It looks like you can specify either a service or a url:

I'll try with that today. I'm not so happy about -include-unqualifed and .svc domains now.

Kudos for making this tool flexible enough to work with unqualified *.svc URLs regardless.

@fred-vogt
Copy link
Author

fred-vogt commented Aug 16, 2020

TL;DR - you correct, you have to have a TLS cert with a SAN entry for unqualified svc DNS when the webhook runs in cluster.

clientConfig:
  service:
    name: <name>
    namespace: kube-system
    path: "/mutate"

# vs

clientConfig:
  url: https://<name>.kube-system.svc.cluster.local/mutate

According to the API documentation url is for external webhooks.

`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). 
...
The `host` should not refer to a service running in the cluster; use the `service` field instead. 

The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation).
`host` may also be an IP address. 
...
The scheme must be "https"; the URL must begin with "https://". 
A path is optional, and if present may be any string permissible in a URL. 
You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier. 
...

This matches the behavior kube-apiserver tries to lookup the name using non cluster aware DNS:

failed calling webhook <webhook-fqdn>": 
 Post https://<name>.kube-system.svc.cluster.local/mutate?timeout=30s:
  dial tcp: lookup 
    <name>.kube-system.svc.cluster.local 
    on <(master) private-ip>:53: 
      no such host

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants