Supervisor listens for HTTPS on port 443 with configurable TLS certs

- TLS certificates can be configured on the OIDCProviderConfig using
  the `secretName` field.
- When listening for incoming TLS connections, choose the TLS cert
  based on the SNI hostname of the incoming request.
- Because SNI hostname information on incoming requests does not include
  the port number of the request, we add a validation that
  OIDCProviderConfigs where the issuer hostnames (not including port
  number) are the same must use the same `secretName`.
- Note that this approach does not yet support requests made to an
  IP address instead of a hostname. Also note that `localhost` is
  considered a hostname by SNI.
- Add port 443 as a container port to the pod spec.
- A new controller watches for TLS secrets and caches them in memory.
  That same in-memory cache is used while servicing incoming connections
  on the TLS port.
- Make it easy to configure both port 443 and/or port 80 for various
  Service types using our ytt templates for the supervisor.
- When deploying to kind, add another nodeport and forward it to the
  host on another port to expose our new HTTPS supervisor port to the
  host.
This commit is contained in:
Ryan Richard
2020-10-26 17:03:26 -07:00
parent 25a91019c2
commit 8b7c30cfbd
17 changed files with 672 additions and 44 deletions
+2
View File
@@ -87,6 +87,8 @@ spec:
ports:
- containerPort: 80
protocol: TCP
- containerPort: 443
protocol: TCP
livenessProbe:
httpGet:
path: /healthz
+41 -11
View File
@@ -4,7 +4,7 @@
#@ load("@ytt:data", "data")
#@ load("helpers.lib.yaml", "defaultLabel", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix")
#@ if data.values.service_nodeport_port:
#@ if data.values.service_http_nodeport_port or data.values.service_https_nodeport_port:
---
apiVersion: v1
kind: Service
@@ -17,15 +17,27 @@ spec:
selector:
app: #@ data.values.app_name
ports:
- protocol: TCP
port: #@ data.values.service_nodeport_port
#@ if data.values.service_http_nodeport_port:
- name: http
protocol: TCP
port: #@ data.values.service_http_nodeport_port
targetPort: 80
#@ if data.values.service_nodeport_nodeport:
nodePort: #@ data.values.service_nodeport_nodeport
#@ if data.values.service_http_nodeport_nodeport:
nodePort: #@ data.values.service_http_nodeport_nodeport
#@ end
#@ end
#@ if data.values.service_https_nodeport_port:
- name: https
protocol: TCP
port: #@ data.values.service_https_nodeport_port
targetPort: 443
#@ if data.values.service_https_nodeport_nodeport:
nodePort: #@ data.values.service_https_nodeport_nodeport
#@ end
#@ end
#@ end
#@ if data.values.service_clusterip_port:
#@ if data.values.service_http_clusterip_port or data.values.service_https_clusterip_port:
---
apiVersion: v1
kind: Service
@@ -37,12 +49,21 @@ spec:
type: ClusterIP
selector: #@ defaultLabel()
ports:
- protocol: TCP
port: #@ data.values.service_clusterip_port
#@ if data.values.service_http_clusterip_port:
- name: http
protocol: TCP
port: #@ data.values.service_http_clusterip_port
targetPort: 80
#@ end
#@ if data.values.service_https_clusterip_port:
- name: https
protocol: TCP
port: #@ data.values.service_https_clusterip_port
targetPort: 443
#@ end
#@ end
#@ if data.values.service_loadbalancer_port:
#@ if data.values.service_http_loadbalancer_port or data.values.service_https_loadbalancer_port:
---
apiVersion: v1
kind: Service
@@ -54,7 +75,16 @@ spec:
type: LoadBalancer
selector: #@ defaultLabel()
ports:
- protocol: TCP
port: #@ data.values.service_loadbalancer_port
#@ if data.values.service_http_loadbalancer_port:
- name: http
protocol: TCP
port: #@ data.values.service_http_loadbalancer_port
targetPort: 80
#@ end
#@ if data.values.service_https_loadbalancer_port:
- name: https
protocol: TCP
port: #@ data.values.service_https_loadbalancer_port
targetPort: 443
#@ end
#@ end
+11 -6
View File
@@ -35,10 +35,15 @@ image_tag: latest
#! Optional.
image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
#! Specify how to expose the Supervisor app as a Service.
#! Typically you would set a value for only one of the following.
#! Specify how to expose the Supervisor app's HTTP and/or HTTPS ports as a Service.
#! Typically you would set a value for only one of the following service types, for either HTTP or HTTPS depending on your needs.
#! An HTTP service should not be exposed outside the cluster. It would not be secure to serve OIDC endpoints to end users via HTTP.
#! Setting any of these values means that a Service of that type will be created.
service_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, e.g. 31234
service_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_nodeport_port` is specified, e.g. 31234
service_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, e.g. 443
service_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, e.g. 443
service_http_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, with port 80 as its `targetPort`; e.g. 31234
service_http_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_http_nodeport_port` is specified; e.g. 31234
service_http_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, with port 80 as its `targetPort`; e.g. 443
service_http_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, with port 80 as its `targetPort`; e.g. 443
service_https_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, with port 443 as its `targetPort`; e.g. 31243
service_https_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_http_nodeport_port` is specified; e.g. 31243
service_https_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, with port 443 as its `targetPort`; e.g. 443
service_https_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, with port 443 as its `targetPort`; e.g. 443