You can do this with MiniKube for development and testing, or Google Cloud's GKE for the real thing.
# Make sure you have MiniKube installed and it's the latest
brew update
minikube delete || echo "You don't have MiniKube installed yet."
brew cask reinstall minikube
# Start it up
minikube start --memory=4096 --cpus=2
# Grab a hostname from ngrok with forwarding to MiniKube
brew cask install ngrok
ngrok http $(minikube ip):80
# Head over to https://console.cloud.google.com/ and create a project
gcloud config set project foobar-app
gcloud services enable container.googleapis.com
gcloud container clusters create foobar --num-nodes 1 --machine-type g1-small
gcloud container clusters get-credentials foobar
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-binding --clusterrole=cluster-admin --serviceaccount kube-system:tiller
helm init --service-account tiller --wait --upgrade
export CERT_ISSUER="letsencrypt-staging" # this can also be letsencrypt-prod
# Don't `--set controller.hostNetwork=true` on minikube
helm install stable/nginx-ingress --namespace kube-system --name ingress --set rbac.create=true --set controller.hostNetwork=true
helm install stable/cert-manager --name cert --namespace kube-system --wait --set ingressShim.extraArgs=\{--default-issuer-name=${CERT_ISSUER},--default-issuer-kind=ClusterIssuer\}
# Before running this you should replace instances of "[email protected]" with your own email
kubectl apply -f cert-issuers.yaml
# Before running this you should replace instances of
# 1. "foobar" with your own app name
# 2. "foo.example.com" with your own hostname or the ngrok hostname if you're using that
# 3. "letsencrypt-staging" with "letsencrypt-prod" if that's the issuer you're using
kubectl apply -f app-deployment.yaml
If you're using a real domain and not ngrok
, at this point you need to grab the ingress IP using the following command and update your DNS with an A record pointing to it. You might have to wait a few minutes for everything to be ready and the IP to show up.
kubectl get ingress
If your tests fail, keep trying for a few minutes until cert-manager
has gone through the motions and provisioned your cert with Let's Encrypt. You can always check the cert-manager
pod container logs with kubectl logs
to see if there's a problem.
First notice that a request to the HTTP endpoint will result in a redirect to the HTTPS version.
$ curl -v 64c3c5b3.ngrok.io
* Rebuilt URL to: 64c3c5b3.ngrok.io/
...
< Location: https://64c3c5b3.ngrok.io/
<
<html>
<head><title>308 Permanent Redirect</title></head>
<body bgcolor="white">
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>nginx/1.13.12</center>
</body>
</html>
* Connection #0 to host 64c3c5b3.ngrok.io left intact
Then try the same thing but using curl -L
so that we follow the redirect.
$ curl -L 64c3c5b3.ngrok.io
Hello, world!
Version: 1.0.0
Hostname: foobar-666c49cb6d-b7hdp
And similarly if you hit the HTTPS endpoint directly.
$ curl https://64c3c5b3.ngrok.io
Hello, world!
Version: 1.0.0
Hostname: foobar-666c49cb6d-b7hdp
minikube delete
gcloud container clusters delete foobar
gcloud projects delete foobar-app # if you don't want it anymore
There's a bit too much manual work happening here, this is where https://github.com/ksonnet/ksonnet and https://github.com/ksonnet/kubecfg can play a role, or even just a custom / local Helm package.