Skip to content

Commit 9c4d2d2

Browse files
authored
Merge pull request #98047 from zr-msft/ds-nginx-ingress
[Dev Spaces] added nginx ingress and https
2 parents d252d45 + 2acc70a commit 9c4d2d2

File tree

2 files changed

+326
-0
lines changed

2 files changed

+326
-0
lines changed
Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
---
2+
title: "Use a custom NGINX ingress controller and configure HTTPS"
3+
services: azure-dev-spaces
4+
ms.date: "12/10/2019"
5+
ms.topic: "conceptual"
6+
description: "Learn how to configure Azure Dev Spaces to use a custom NGINX ingress controller and configure HTTPS using that ingress controller"
7+
keywords: "Docker, Kubernetes, Azure, AKS, Azure Kubernetes Service, containers, Helm, service mesh, service mesh routing, kubectl, k8s"
8+
---
9+
10+
# Use a custom NGINX ingress controller and configure HTTPS
11+
12+
This article shows you how to configure Azure Dev Spaces to use a custom NGINX ingress controller. This article also shows you how to configure that custom ingress controller to use HTTPS.
13+
14+
## Prerequisites
15+
16+
* An Azure subscription. If you don't have one, you can create a [free account][azure-account-create].
17+
* [Azure CLI installed][az-cli].
18+
* [Azure Kubernetes Service (AKS) cluster with Azure Dev Spaces enabled][qs-cli].
19+
* [kubectl][kubectl] installed.
20+
* [Helm 3 installed][helm-installed].
21+
* [A custom domain][custom-domain] with a [DNS Zone][dns-zone] in the same resource group as your AKS cluster.
22+
23+
## Configure a custom NGINX ingress controller
24+
25+
Connect to your cluster using [kubectl][kubectl], the Kubernetes command-line client. To configure `kubectl` to connect to your Kubernetes cluster, use the [az aks get-credentials][az-aks-get-credentials] command. This command downloads credentials and configures the Kubernetes CLI to use them.
26+
27+
```azurecli-interactive
28+
az aks get-credentials --resource-group myResourceGroup --name myAKS
29+
```
30+
31+
To verify the connection to your cluster, use the [kubectl get][kubectl-get] command to return a list of the cluster nodes.
32+
33+
```console
34+
$ kubectl get nodes
35+
NAME STATUS ROLES AGE VERSION
36+
aks-nodepool1-12345678-vmssfedcba Ready agent 13m v1.14.1
37+
```
38+
39+
Add the [official stable Helm repository][helm-stable-repo], which contains the NGINX ingress controller Helm chart.
40+
41+
```console
42+
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
43+
```
44+
45+
Create a Kubernetes namespace for the NGINX ingress controller and install it using `helm`.
46+
47+
```console
48+
kubectl create ns nginx
49+
helm install nginx stable/nginx-ingress --namespace nginx
50+
```
51+
52+
Get the IP address of the NGINX ingress controller service using [kubectl get][kubectl-get].
53+
54+
```console
55+
kubectl get svc -n nginx --watch
56+
```
57+
58+
The sample output shows the IP addresses for all the services in the *nginx* name space.
59+
60+
```console
61+
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
62+
nginx-nginx-ingress-controller LoadBalancer 10.0.19.39 <pending> 80:31314/TCP,443:30521/TCP 10s
63+
nginx-nginx-ingress-default-backend ClusterIP 10.0.210.231 <none> 80/TCP 10s
64+
...
65+
nginx-nginx-ingress-controller LoadBalancer 10.0.19.39 MY_EXTERNAL_IP 80:31314/TCP,443:30521/TCP 26s
66+
```
67+
68+
Add an *A* record to your DNS zone with the external IP address of the NGINX service using [az network dns record-set a add-record][az-network-dns-record-set-a-add-record].
69+
70+
```console
71+
az network dns record-set a add-record \
72+
--resource-group myResourceGroup \
73+
--zone-name MY_CUSTOM_DOMAIN \
74+
--record-set-name *.nginx \
75+
--ipv4-address MY_EXTERNAL_IP
76+
```
77+
78+
The above example adds an *A* record to the *MY_CUSTOM_DOMAIN* DNS zone.
79+
80+
In this article, you use the [Azure Dev Spaces Bike Sharing sample application](https://github.com/Azure/dev-spaces/tree/master/samples/BikeSharingApp) to demonstrate using Azure Dev Spaces. Clone the application from GitHub and navigate into its directory:
81+
82+
```cmd
83+
git clone https://github.com/Azure/dev-spaces
84+
cd dev-spaces/samples/BikeSharingApp/charts
85+
```
86+
87+
Open [values.yaml][values-yaml] and replace all instances of *<REPLACE_ME_WITH_HOST_SUFFIX>* with *nginx.MY_CUSTOM_DOMAIN* using your domain for *MY_CUSTOM_DOMAIN*. Also replace *kubernetes.io/ingress.class: nginx-azds # Dev Spaces-specific* with *kubernetes.io/ingress.class: nginx # Custom Ingress*. Below is an example of an updated `values.yaml` file:
88+
89+
```yaml
90+
# This is a YAML-formatted file.
91+
# Declare variables to be passed into your templates.
92+
93+
bikesharingweb:
94+
ingress:
95+
annotations:
96+
kubernetes.io/ingress.class: nginx # Custom Ingress
97+
hosts:
98+
- dev.bikesharingweb.nginx.MY_CUSTOM_DOMAIN # Assumes deployment to the 'dev' space
99+
100+
gateway:
101+
ingress:
102+
annotations:
103+
kubernetes.io/ingress.class: nginx # Custom Ingress
104+
hosts:
105+
- dev.gateway.nginx.MY_CUSTOM_DOMAIN # Assumes deployment to the 'dev' space
106+
```
107+
108+
Save your changes and close the file.
109+
110+
Create the *dev* space with your sample application using `azds space select`.
111+
112+
```console
113+
azds space select -n dev -y
114+
```
115+
116+
Deploy the sample application using `helm install`.
117+
118+
```console
119+
helm install bikesharing . --dependency-update --namespace dev --atomic
120+
```
121+
122+
The above example deploys the sample application to the *dev* namespace.
123+
124+
Display the URLs to access the sample application using `azds list-uris`.
125+
126+
```console
127+
azds list-uris
128+
```
129+
130+
The below output shows the example URLs from `azds list-uris`.
131+
132+
```console
133+
Uri Status
134+
--------------------------------------------------- ---------
135+
http://dev.bikesharingweb.nginx.MY_CUSTOM_DOMAIN/ Available
136+
http://dev.gateway.nginx.MY_CUSTOM_DOMAIN/ Available
137+
```
138+
139+
Navigate to the *bikesharingweb* service by opening the public URL from the `azds list-uris` command. In the above example, the public URL for the *bikesharingweb* service is `http://dev.bikesharingweb.nginx.MY_CUSTOM_DOMAIN/`.
140+
141+
Use the `azds space select` command to create a child space under *dev* and list the URLs to access the child dev space.
142+
143+
```console
144+
azds space select -n dev/azureuser1 -y
145+
azds list-uris
146+
```
147+
148+
The below output shows the example URLs from `azds list-uris` to access the sample application in the *azureuser1* child dev space.
149+
150+
```console
151+
Uri Status
152+
--------------------------------------------------- ---------
153+
http://azureuser1.s.dev.bikesharingweb.nginx.MY_CUSTOM_DOMAIN/ Available
154+
http://azureuser1.s.dev.gateway.nginx.MY_CUSTOM_DOMAIN/ Available
155+
```
156+
157+
Navigate to the *bikesharingweb* service in the *azureuser1* child dev space by opening the public URL from the `azds list-uris` command. In the above example, the public URL for the *bikesharingweb* service in the *azureuser1* child dev space is `http://azureuser1.s.dev.bikesharingweb.nginx.MY_CUSTOM_DOMAIN/`.
158+
159+
## Configure the NGINX ingress controller to use HTTPS
160+
161+
Use [cert-manager][cert-manager] to automate the management of the TLS certificate when configuring your NGINX ingress controller to use HTTPS. Use `helm` to install the *certmanager* chart.
162+
163+
```console
164+
kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml --namespace nginx
165+
kubectl label namespace nginx certmanager.k8s.io/disable-validation=true
166+
helm repo add jetstack https://charts.jetstack.io
167+
helm repo update
168+
helm install cert-manager --namespace nginx --version v0.12.0 jetstack/cert-manager --set ingressShim.defaultIssuerName=letsencrypt --set ingressShim.defaultIssuerKind=ClusterIssuer
169+
```
170+
171+
Create a `letsencrypt-clusterissuer.yaml` file and update the email field with your email address.
172+
173+
```yaml
174+
apiVersion: cert-manager.io/v1alpha2
175+
kind: ClusterIssuer
176+
metadata:
177+
name: letsencrypt
178+
spec:
179+
acme:
180+
server: https://acme-v02.api.letsencrypt.org/directory
181+
email: MY_EMAIL_ADDRESS
182+
privateKeySecretRef:
183+
name: letsencrypt
184+
solvers:
185+
- http01:
186+
ingress:
187+
class: nginx
188+
```
189+
190+
> [!NOTE]
191+
> For testing, there is also a [staging server][letsencrypt-staging-issuer] you can use for your *ClusterIssuer*.
192+
193+
Use `kubectl` to apply `letsencrypt-clusterissuer.yaml`.
194+
195+
```console
196+
kubectl apply -f letsencrypt-clusterissuer.yaml --namespace nginx
197+
```
198+
199+
Update [values.yaml][values-yaml] to include the details for using *cert-manager* and HTTPS. Below is an example of an updated `values.yaml` file:
200+
201+
```yaml
202+
# This is a YAML-formatted file.
203+
# Declare variables to be passed into your templates.
204+
205+
bikesharingweb:
206+
ingress:
207+
annotations:
208+
kubernetes.io/ingress.class: nginx # Custom Ingress
209+
cert-manager.io/cluster-issuer: letsencrypt
210+
hosts:
211+
- dev.bikesharingweb.nginx.MY_CUSTOM_DOMAIN # Assumes deployment to the 'dev' space
212+
tls:
213+
- hosts:
214+
- dev.bikesharingweb.nginx.MY_CUSTOM_DOMAIN
215+
secretName: dev-bikesharingweb-secret
216+
217+
gateway:
218+
ingress:
219+
annotations:
220+
kubernetes.io/ingress.class: nginx # Custom Ingress
221+
cert-manager.io/cluster-issuer: letsencrypt
222+
hosts:
223+
- dev.gateway.nginx.MY_CUSTOM_DOMAIN # Assumes deployment to the 'dev' space
224+
tls:
225+
- hosts:
226+
- dev.gateway.nginx.MY_CUSTOM_DOMAIN
227+
secretName: dev-gateway-secret
228+
```
229+
230+
Upgrade the sample application using `helm`:
231+
232+
```console
233+
helm upgrade bikesharing . --namespace dev --atomic
234+
```
235+
236+
Navigate to the sample application in the *dev/azureuser1* child space and notice you are redirected to use HTTPS. Also notice that the page loads, but the browser shows some errors. Opening the browser console shows the error relates to an HTTPS page trying to load HTTP resources. For example:
237+
238+
```console
239+
Mixed Content: The page at 'https://azureuser1.s.dev.bikesharingweb.nginx.MY_CUSTOM_DOMAIN/devsignin' was loaded over HTTPS, but requested an insecure resource 'http://azureuser1.s.dev.gateway.nginx.MY_CUSTOM_DOMAIN/api/user/allUsers'. This request has been blocked; the content must be served over HTTPS.
240+
```
241+
242+
To fix this error, update [BikeSharingWeb/azds.yaml][azds-yaml] similar to the below:
243+
244+
```yaml
245+
...
246+
ingress:
247+
annotations:
248+
kubernetes.io/ingress.class: nginx
249+
cert-manager.io/cluster-issuer: letsencrypt
250+
hosts:
251+
# This expands to [space.s.][rootSpace.]bikesharingweb.<random suffix>.<region>.azds.io
252+
- $(spacePrefix)$(rootSpacePrefix)bikesharingweb.nginx.MY_CUSTOM_DOMAIN
253+
tls:
254+
- hosts:
255+
- $(spacePrefix)$(rootSpacePrefix)bikesharingweb.nginx.MY_CUSTOM_DOMAIN
256+
secretName: dev-bikesharingweb-secret
257+
...
258+
```
259+
260+
Update [BikeSharingWeb/package.json][package-json] with a dependency for the *url* package.
261+
262+
```json
263+
{
264+
...
265+
"react-responsive": "^6.0.1",
266+
"universal-cookie": "^3.0.7",
267+
"url": "0.11.0"
268+
},
269+
...
270+
```
271+
272+
Update the *getApiHostAsync* method in [BikeSharingWeb/pages/helpers.js][helpers-js] to use HTTPS:
273+
274+
```javascript
275+
...
276+
getApiHostAsync: async function() {
277+
const apiRequest = await fetch('/api/host');
278+
const data = await apiRequest.json();
279+
280+
var urlapi = require('url');
281+
var url = urlapi.parse(data.apiHost);
282+
283+
console.log('apiHost: ' + "https://"+url.host);
284+
return "https://"+url.host;
285+
},
286+
...
287+
```
288+
289+
Navigate to the `BikeSharingWeb` directory and use `azds up` to run your updated *BikeSharingWeb* service.
290+
291+
```console
292+
cd ../BikeSharingWeb/
293+
azds up
294+
```
295+
296+
Navigate to the sample application in the *dev/azureuser1* child space and notice you are redirected to use HTTPS without any errors.
297+
298+
## Next steps
299+
300+
Learn how Azure Dev Spaces helps you develop more complex applications across multiple containers, and how you can simplify collaborative development by working with different versions or branches of your code in different spaces.
301+
302+
> [!div class="nextstepaction"]
303+
> [Team development in Azure Dev Spaces][team-development-qs]
304+
305+
306+
[az-cli]: /cli/azure/install-azure-cli?view=azure-cli-latest
307+
[az-aks-get-credentials]: /cli/azure/aks?view=azure-cli-latest#az-aks-get-credentials
308+
[az-network-dns-record-set-a-add-record]: /cli/azure/network/dns/record-set/a?view=azure-cli-latest#az-network-dns-record-set-a-add-record
309+
[custom-domain]: ../../app-service/manage-custom-dns-buy-domain.md#buy-the-domain
310+
[dns-zone]: ../../dns/dns-getstarted-cli.md
311+
[qs-cli]: ../quickstart-cli.md
312+
[team-development-qs]: ../quickstart-team-development.md
313+
314+
[azds-yaml]: https://github.com/Azure/dev-spaces/blob/master/samples/BikeSharingApp/BikeSharingWeb/azds.yaml
315+
[azure-account-create]: https://azure.microsoft.com/free
316+
[cert-manager]: https://cert-manager.io/
317+
[helm-installed]: https://helm.sh/docs/intro/install/
318+
[helm-stable-repo]: https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository
319+
[helpers-js]: https://github.com/Azure/dev-spaces/blob/master/samples/BikeSharingApp/BikeSharingWeb/pages/helpers.js#L7
320+
[kubectl]: https://kubernetes.io/docs/user-guide/kubectl/
321+
[kubectl-get]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#get
322+
[letsencrypt-staging-issuer]: https://cert-manager.io/docs/configuration/acme/#creating-a-basic-acme-issuer
323+
[package-json]: https://github.com/Azure/dev-spaces/blob/master/samples/BikeSharingApp/BikeSharingWeb/package.json
324+
[values-yaml]: https://github.com/Azure/dev-spaces/blob/master/samples/BikeSharingApp/charts/values.yaml

articles/dev-spaces/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@
9191
href: how-to/run-dev-spaces-windows-containers.md
9292
- name: Use traefik for custom ingress and HTTPS
9393
href: how-to/ingress-https-traefik.md
94+
- name: Use NGINX for custom ingress and HTTPS
95+
href: how-to/ingress-https-nginx.md
9496
- name: Connect your development machine to an AKS cluster (preview)
9597
href: how-to/connect.md
9698
- name: Troubleshooting

0 commit comments

Comments
 (0)