├── .gitignore ├── screenshots ├── success.png ├── dns_entry.png └── non_http_success.png ├── demo-ing.yaml ├── demo-svc.yaml ├── demo-app.yaml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .gcloudrc -------------------------------------------------------------------------------- /screenshots/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlancer/google-managed-certs-gke/master/screenshots/success.png -------------------------------------------------------------------------------- /screenshots/dns_entry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlancer/google-managed-certs-gke/master/screenshots/dns_entry.png -------------------------------------------------------------------------------- /screenshots/non_http_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlancer/google-managed-certs-gke/master/screenshots/non_http_success.png -------------------------------------------------------------------------------- /demo-ing.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: demo-ing 5 | spec: 6 | backend: 7 | serviceName: demo-svc # Name of the Service targeted by the Ingress 8 | servicePort: 333 # Should match the port used by the Service 9 | -------------------------------------------------------------------------------- /demo-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: demo-svc 5 | # annotations: 6 | # ingress.kubernetes.io/target-proxy: https-target 7 | spec: 8 | type: NodePort 9 | selector: 10 | run: https-demo 11 | ports: 12 | - name: http 13 | protocol: TCP 14 | port: 333 15 | targetPort: 9376 -------------------------------------------------------------------------------- /demo-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: https-demo 6 | name: https-demo 7 | spec: 8 | selector: 9 | matchLabels: 10 | run: https-demo 11 | template: 12 | metadata: 13 | labels: 14 | run: https-demo 15 | spec: 16 | containers: 17 | - image: k8s.gcr.io/serve_hostname:v1.4 18 | name: hostname 19 | ports: 20 | - containerPort: 9376 21 | protocol: TCP 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UPDATE — This guide has been deprecated! Refer to: 2 | https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs 3 | 4 | # How to use Google Managed SSL Certificates on GKE 5 | 6 | > Special thanks to [@dannyzen](https://github.com/dannyzen) from Google for helping Collaborizm move to GCP. He did help with this post but neither he nor Google endorse its methods. 7 | 8 | ## Getting HTTPS working on GKE can be challenging 9 | 10 | Currently there are two main options: 11 | 12 | * You can [create certs and add them to your ingress controller](https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-multi-ssl) - 13 | you'll need to manage your own certs, which seems antiquated post [ 14 | Lets Encrypt](https://letsencrypt.org/) 15 | * Install a certificate provisioning system on your cluster such as [Cert Manager](https://github.com/jetstack/cert-manager) - involves installing extra apps on your cluster, which you'll have to maintain and pay for 16 | 17 | There is a third solution: [Google Managed SSL Certs](https://cloud.google.com/load-balancing/docs/ssl-certificates#certificate-resource-status) 18 | 19 | * They auto renew 20 | * Offload all SSL handling to Google's Load Balancer (which every GKE cluster uses) 21 | * Lower infrastructure costs 22 | 23 | Downsides: 24 | 25 | * In beta and not covered by an SLA 26 | * Use with GKE not fully documented (hence this guide) 27 | 28 | **Proceed with caution!!!** 29 | 30 | This guide uses an undocumented GKE annotation. 31 | 32 | ## Part 1 · Setup a Cluster 33 | 34 | Create a new GKE project for this to not pollute anything you have in production. 35 | 36 | Use ```gcloud init``` to create a configuration. 37 | If you have trouble taming your configurations [check out my other repo](https://github.com/rlancer/GCloud-Configuration-Auto-Switcher), it's a small script to help switch configs based on a .gcloudrc file. 38 | 39 | Clone this repo, we'll be using some YAML from it: 40 | 41 | ```bash 42 | $ git clone git@github.com:rlancer/google-managed-certs-gke.git 43 | $ cd gke-https 44 | ``` 45 | 46 | Create a Cluster, for this demo the cluster only needs one small node: 47 | 48 | ```bash 49 | $ gcloud container clusters create https-demo-cluster --zone us-central1-c --machine-type g1-small --num-nodes 1 50 | 51 | >> 52 | NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS 53 | https-demo-cluster us-central1-c 1.9.7-gke.6 35.226.141.220 n1-standard-1 1.9.7-gke.6 3 RUNNING 54 | ``` 55 | 56 | Connect Kubectl: 57 | 58 | ```bash 59 | $ gcloud container clusters get-credentials https-demo-cluster --zone us-central1-c 60 | 61 | >> kubeconfig entry generated for https-demo-cluster. 62 | ``` 63 | Apply configs: 64 | 65 | ```bash 66 | $ kubectl apply -f demo-app.yaml 67 | $ kubectl apply -f demo-svc.yaml 68 | $ kubectl apply -f demo-ing.yaml 69 | ``` 70 | 71 | Get the IP address of your Ingress Controller: 72 | 73 | > Within a few minutes for the IP address should appear 74 | 75 | ```bash 76 | $ kubectl get ingress -w 77 | 78 | >> 79 | NAME HOSTS ADDRESS PORTS AGE 80 | demo-ing * 80 9s 81 | demo-ing * 35.241.35.109 80 68s 82 | ``` 83 | 84 | Visit the IP address in your browser. Hit refresh if does not appear. It may as long as 10 minutes for the app to be fully available. 85 | 86 | The app is simply outputting the name of the host it's running 87 | on. 88 | 89 | ![host name app running on HTTP](screenshots/non_http_success.png) 90 | 91 | 92 | ## Part 2 · Hook up the Google Managed Cert 93 | 94 | Create the Google Managed Cert: 95 | 96 | ```bash 97 | $ gcloud beta compute ssl-certificates create "demo-gmang-cert" --domains demo-gman.collaborizm.com 98 | ``` 99 | 100 | Get existing URL Maps: 101 | > There should only be one URL Map and you'll need the value under NAME when creating the target proxy in the next step 102 | ```bash 103 | $ gcloud compute url-maps list 104 | 105 | >> 106 | NAME DEFAULT_SERVICE 107 | k8s-um-default-demo-ing--3287e1f664ff7581 backendServices/k8s-be-31012--3287e1f664ff7581 108 | ``` 109 | 110 | Create the HTTPS Target Proxy. Make sure to sub out --url-map with your value: 111 | ```bash 112 | $ gcloud compute target-https-proxies create https-target --url-map=URL_MAP_VALUE_FROM_ABOVE --ssl-certificates=demo-gmang-cert 113 | 114 | >> 115 | Created [https://www.googleapis.com/compute/v1/projects/kube-https-demo/global/targetHttpsProxies/https-target]. 116 | 117 | NAME SSL_CERTIFICATES URL_MAP 118 | https-target demo-gmang-cert k8s-um-default-demo-ing--3287e1f664ff7581 119 | ``` 120 | 121 | Create a Global Static IP Address: 122 | ```bash 123 | $ gcloud compute addresses create static-https-ip --global --ip-version IPV4 124 | 125 | >> Created [https://www.googleapis.com/compute/v1/projects/kube-https-demo/global/addresses/static-https-ip]. 126 | ``` 127 | 128 | Create a Global Forwarding Rule linking youre newly created IP Address: 129 | ```bash 130 | $ gcloud compute forwarding-rules create https-global-forwarding-rule --global --ip-protocol=TCP --ports=443 --target-https-proxy=https-target --address static-https-ip 131 | ``` 132 | 133 | Adjust the Service to include the Target Proxy, edit demo-svc.yaml to include the target-proxy Annotation. **This is undocumented, could be a bad move...** 134 | 135 | ```yaml 136 | apiVersion: v1 137 | kind: Service 138 | metadata: 139 | name: demo-svc 140 | # Add this annotation 141 | annotations: 142 | ingress.kubernetes.io/target-proxy: https-target 143 | spec: 144 | type: NodePort 145 | selector: 146 | run: https-demo 147 | ports: 148 | - name: http 149 | protocol: TCP 150 | port: 333 151 | targetPort: 9376 152 | ``` 153 | 154 | Apply the new Service: 155 | ```bash 156 | $ kubetl apply -f demo-svc.yaml 157 | ``` 158 | 159 | Get the IP Address assigned to the Target Proxy: 160 | ```bash 161 | $ gcloud compute addresses list 162 | 163 | >> 164 | NAME REGION ADDRESS STATUS 165 | static-https-ip 35.227.227.95 IN_USE 166 | 167 | ``` 168 | Create an A Record with the IP Address (on CloudFlare we turned off proxying, hence the gray cloud) 169 | 170 | ![dns entry CloudFlare](screenshots/dns_entry.png) 171 | 172 | Watch to see if your Cert has been provisioned, this could take as long as half an hour: 173 | 174 | ```bash 175 | $ watch gcloud beta compute ssl-certificates list 176 | 177 | >> 178 | demo-gmang-cert MANAGED 2018-10-29T10:47:05.450-07:00 2019-01-27T09:48:20.000-08:00 ACTIVE 179 | demo-gman.collaborizm.com: ACTIVE 180 | ``` 181 | 182 | Next visit [https://demo-gman.collaborizm.com](https://demo-gman.collaborizm.com) in your browser and you should see your GKE app running with a Google Managed Cert. 183 | 184 | ![successful](screenshots/success.png) 185 | 186 | ## Interested in Google Cloud Platform? 187 | 188 | Start or join a project on [Collaborizm](https://www.collaborizm.com)! Our partnership with GCP could net you a few grand in credits. 189 | --------------------------------------------------------------------------------