TLS with Bring-Your-Own Certificates
This recipe shows how to configure a wasmCloud host group to serve HTTPS using TLS certificates you provide.
By the end, you will have a kind cluster running wasmCloud with a host group that terminates TLS using a certificate stored in a Kubernetes Secret.
Prerequisites
- A Kubernetes cluster (this recipe uses kind)
kubectl- Helm v3.8.0+
- A TLS certificate and private key (self-signed or CA-issued)
If you do not already have a certificate, you can generate a self-signed one for testing:
openssl req -x509 -newkey rsa:2048 -keyout tls.key -out tls.crt -days 365 -nodes \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:localhost,DNS:*.default.svc.cluster.local"You will also need a CA certificate. For self-signed certificates, the certificate itself serves as the CA:
cp tls.crt ca.crtStep 1: Create the cluster
Create a kind cluster with port 30443 mapped for HTTPS ingress:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30443
hostPort: 8443
protocol: TCPSave this as kind-config.yaml and create the cluster:
kind create cluster --config kind-config.yamlStep 2: Create the TLS Secret
Store your certificate, key, and CA certificate in a Kubernetes Secret:
kubectl create secret generic byoc-cert \
--from-file=tls.crt=tls.crt \
--from-file=tls.key=tls.key \
--from-file=ca.crt=ca.crtThe Secret must contain three keys: tls.crt, tls.key, and ca.crt. The wasmCloud host reads all three when starting its HTTPS listener.
Step 3: Install wasmCloud with TLS enabled
Create a values.yaml file that configures the host group to use your certificate:
global:
tls:
enabled: true
runtime:
hostGroups:
- name: default
replicas: 1
service:
type: ClusterIP
http:
enabled: true
port: 8443
tls:
enabled: true
certificate:
secretName: "byoc-cert"
generate:
enabled: false
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"Key fields:
global.tls.enabled: trueenables TLS for the platform's NATS connections and certificate infrastructure.http.tls.enabled: truetells the host group to serve HTTPS instead of HTTP.http.tls.certificate.secretNamepoints to the Secret created in Step 2.http.tls.certificate.generate.enabled: falsedisables auto-generated certificates so the host uses your Secret.http.port: 8443sets the HTTPS listen port on the host pod.
Install with Helm:
helm install wasmcloud --version 2.0.3 oci://ghcr.io/wasmcloud/charts/runtime-operator \
-f values.yamlWait for the pods to start:
kubectl rollout status deploy -l app.kubernetes.io/instance=wasmcloud -n defaultStep 4: Expose the host group with a NodePort Service
Create a Service that routes external traffic to the host group on port 8443:
apiVersion: v1
kind: Service
metadata:
name: wasmcloud-https
namespace: default
spec:
type: NodePort
selector:
wasmcloud.com/hostgroup: default
wasmcloud.com/name: hostgroup
ports:
- name: https
port: 8443
targetPort: 8443
nodePort: 30443
protocol: TCPkubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: wasmcloud-https
namespace: default
spec:
type: NodePort
selector:
wasmcloud.com/hostgroup: default
wasmcloud.com/name: hostgroup
ports:
- name: https
port: 8443
targetPort: 8443
nodePort: 30443
protocol: TCP
EOFThe nodePort: 30443 maps to hostPort: 8443 on the kind node (from Step 1), making the host group reachable at https://localhost:8443 on your machine.
Step 5: Deploy a workload and verify
Deploy a simple hello-world component:
apiVersion: runtime.wasmcloud.dev/v1alpha1
kind: WorkloadDeployment
metadata:
name: hello-world
spec:
replicas: 1
template:
spec:
hostSelector:
hostgroup: default
components:
- name: hello-world
image: ghcr.io/wasmcloud/components/hello-world:0.1.0
hostInterfaces:
- namespace: wasi
package: http
interfaces:
- incoming-handler
config:
host: example.comkubectl apply -f - <<EOF
apiVersion: runtime.wasmcloud.dev/v1alpha1
kind: WorkloadDeployment
metadata:
name: hello-world
spec:
replicas: 1
template:
spec:
hostSelector:
hostgroup: default
components:
- name: hello-world
image: ghcr.io/wasmcloud/components/hello-world:0.1.0
hostInterfaces:
- namespace: wasi
package: http
interfaces:
- incoming-handler
config:
host: example.com
EOFWait for the workload to become ready:
kubectl get workloaddeployments --watchSend an HTTPS request. Use -k to skip certificate verification (for self-signed certificates) and set the Host header to match the host value in the manifest:
curl -k -H "Host: example.com" https://localhost:8443You should see:
Hello from wasmCloud!To verify that TLS is active, add -v to the curl command:
curl -kv -H "Host: example.com" https://localhost:8443The output should include a TLS handshake showing the certificate's common name:
* Server certificate:
* subject: CN=example.comUsing auto-generated certificates
If you do not have your own certificates, the Helm chart can generate self-signed certificates automatically. Replace the http.tls.certificate section in your values.yaml:
http:
tls:
enabled: true
certificate:
secretName: ""
generate:
enabled: true
validity: 365
commonName: "example.com"
domains:
- "localhost"
- "*.example.com"
- "hostgroup-default.default.svc.cluster.local"When generate.enabled is true and secretName is empty, the chart creates a self-signed certificate with the specified common name and SANs. This is useful for development and testing.
Clean up
kubectl delete workloaddeployment hello-world
kubectl delete svc wasmcloud-https
helm uninstall wasmcloud
kind delete cluster