Skip to content

Commit 05d5c60

Browse files
committed
Add blog post on Istio
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
1 parent ee29efa commit 05d5c60

File tree

2 files changed

+335
-0
lines changed

2 files changed

+335
-0
lines changed

_posts/2021-05-19-istio.md

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
---
2+
title: "Learn how to integrate Istio service mesh with your Functions"
3+
description: "Learn how to enable Istio for OpenFaaS to take advantage of Mutual TLS and the Istio Gateway"
4+
date: 2021-05-12
5+
image: /images/2021-05-istio/background.jpg
6+
categories:
7+
- live
8+
- use-cases
9+
- functions
10+
author_staff_member: alex
11+
dark_background: true
12+
13+
---
14+
15+
Learn how to enable Istio for OpenFaaS to take advantage of Mutual TLS and the Istio Gateway
16+
17+
## Introduction
18+
19+
Service meshes have become popular add-ons for Kubernetes, so much so that they have their [own ServiceMeshCon days](https://events.linuxfoundation.org/servicemeshcon/) at [KubeCon](https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/), the official Kubernetes conference.
20+
21+
A service mesh can be used to apply policies to network communication, encrypt traffic between endpoints and for advanced routing.
22+
23+
<img src="https://istio.io/latest/img/istio-bluelogo-whitebackground-unframed.svg" width="10%" alt="Istio logo">
24+
25+
[Istio](https://istio.io) is one of the most popular service meshes available for use with Kubernetes and with help from the team at Google, we've recently updated the support and documentation for using Istio with OpenFaaS.
26+
27+
The value for users is:
28+
* Providing more advanced and flexible policy than Kubernetes' NetworkPolicies
29+
* Encrypting traffic between all OpenFaaS components and functions for "zero trust"
30+
* Providing advanced networking like retries, and weighting for canaries and gradual rollouts of new functions
31+
32+
Thank you to [John Howard](https://github.com/howardjohn) from Google for helping us with this work and to [Lucas Roesler](https://github.com/lucasroesler) for reviewing and testing the work.
33+
34+
In this blog post we'll give you a quick introduction so that you can start integrating Istio with OpenFaaS. We'll then go on to show you how to measure the resource consumption of the cluster, and how to create a TLS certificate for the Istio Gateway.
35+
36+
There are many service mesh products available. Other popular options include: [Linkerd](https://linkerd.io), [Kuma](https://kuma.io/) and [Consul](https://learn.hashicorp.com/tutorials/consul/service-mesh).
37+
38+
> You may also like the workshop we created to show how to do mutual TLS and traffic shifting with [OpenFaaS and Linkerd](https://github.com/openfaas/openfaas-linkerd-workshop).
39+
40+
## Tutorial
41+
42+
We are using arkade, the open source marketplace to download CLIs and to install the apps we need. You can also do this the hard way if you prefer, just refer to the documentation or the helm chart for more.
43+
44+
### Bootstrap the cluster
45+
46+
Create a local cluster for testing:
47+
48+
```bash
49+
arkade get kind
50+
51+
kind create cluster \
52+
--name openfaas-istio
53+
```
54+
55+
### Add Istio
56+
57+
Once up and running, install Istio:
58+
59+
```bash
60+
arkade install istio
61+
```
62+
63+
At time of writing this installs Istio 1.9.
64+
65+
### Install OpenFaaS
66+
67+
Now install OpenFaaS using the following changes:
68+
69+
The `gateway.directFunctions=true` flag prevents OpenFaaS from trying to do its own endpoint load-balancing between function replicas, and defers to Envoy instead. Envoy is configured for each pod by Istio and handles routing and retries.
70+
71+
The `istio.mtls` flag is optional, but when set encrypts the traffic between each of the pods in the `openfaas` and `openfaas-fn` namespace.
72+
73+
```bash
74+
arkade install openfaas \
75+
--set gateway.directFunctions=true \
76+
--set istio.mtls=true
77+
```
78+
79+
At this point everything is configured and you can use OpenFaaS.
80+
81+
### Deploy a test function
82+
83+
Create an Istio Gateway so that we can connect to the OpenFaaS Gateway and log in.
84+
85+
```bash
86+
# gateway.yaml
87+
cat > gateway.yaml <<EOF
88+
apiVersion: networking.istio.io/v1alpha3
89+
kind: Gateway
90+
metadata:
91+
name: openfaas-gateway
92+
namespace: openfaas
93+
spec:
94+
selector:
95+
istio: ingressgateway # use istio default controller
96+
servers:
97+
- port:
98+
number: 80
99+
name: http
100+
protocol: HTTP
101+
hosts:
102+
- "*"
103+
---
104+
apiVersion: networking.istio.io/v1alpha3
105+
kind: VirtualService
106+
metadata:
107+
name: openfaas-api
108+
namespace: openfaas
109+
spec:
110+
hosts:
111+
- "*"
112+
gateways:
113+
- openfaas-gateway
114+
http:
115+
- match:
116+
- uri:
117+
prefix: /
118+
route:
119+
- destination:
120+
host: gateway
121+
port:
122+
number: 8080
123+
EOF
124+
125+
kubectl apply -f gateway.yaml
126+
```
127+
128+
Port-forward the Istio Ingress Gateway:
129+
130+
```bash
131+
kubectl port-forward -n istio-system \
132+
svc/istio-ingressgateway \
133+
8080:80 \
134+
8443:443 &
135+
```
136+
137+
Log in:
138+
139+
```bash
140+
PASSWORD=$(kubectl get secret -n openfaas basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode; echo)
141+
echo -n $PASSWORD | faas-cli login --username admin --password-stdin
142+
```
143+
144+
```bash
145+
# Find something you are interested in with:
146+
faas-cli store list
147+
148+
# Deploy one of the functions
149+
faas-cli store deploy nodeinfo
150+
```
151+
152+
Invoke the function via the Istio Ingress gateway:
153+
154+
```bash
155+
echo | faas-cli invoke nodeinfo
156+
```
157+
158+
Describe the Function's deployment, so you can see that the Istio proxy (Envoy) has been configured:
159+
160+
```
161+
kubectl describe pod -n openfaas-fn
162+
163+
Events:
164+
Type Reason Age From Message
165+
---- ------ ---- ---- -------
166+
Normal Scheduled 48s default-scheduler Successfully assigned openfaas-fn/nodeinfo-857d9c469b-ww66k to openfaas-istio-control-plane
167+
Normal Pulling 47s kubelet Pulling image "docker.io/istio/proxyv2:1.9.1"
168+
Normal Pulled 46s kubelet Successfully pulled image "docker.io/istio/proxyv2:1.9.1" in 938.690323ms
169+
Normal Created 46s kubelet Created container istio-init
170+
Normal Started 46s kubelet Started container istio-init
171+
Normal Pulling 46s kubelet Pulling image "ghcr.io/openfaas/nodeinfo:latest"
172+
Normal Pulled 38s kubelet Successfully pulled image "ghcr.io/openfaas/nodeinfo:latest" in 8.160064746s
173+
Normal Created 38s kubelet Created container nodeinfo
174+
Normal Started 38s kubelet Started container nodeinfo
175+
Normal Pulling 38s kubelet Pulling image "docker.io/istio/proxyv2:1.9.1"
176+
Normal Pulled 37s kubelet Successfully pulled image "docker.io/istio/proxyv2:1.9.1" in 925.80937ms
177+
Normal Created 37s kubelet Created container istio-proxy
178+
Normal Started 37s kubelet Started container istio-proxy
179+
```
180+
181+
## Going Further
182+
183+
### Measuring the effects
184+
185+
There is a cost involved with installing a service mesh like Istio. There will be additional RAM required, additional control-plane components to configure and keep updated, along with additional latency and cold-start times for scaling functions from zero.
186+
187+
If you would like to understand the quiescent load on the cluster, you can install the Kubernetes metrics-server through arkade:
188+
189+
```bash
190+
arkade install metrics-server
191+
192+
# Wait a few minutes for data collection, then run:
193+
kubectl top node
194+
kubectl top pod -A
195+
```
196+
197+
### Getting a TLS certificate
198+
199+
Let's now get a TLS certificate so that we can serve traffic to clients securely.
200+
201+
First, create a DNS A record for the IP address of the Istio Ingress gateway using your preferred cloud dashboard and DNS service.
202+
203+
```bash
204+
kubectl get svc -n istio-system istio-ingressgateway
205+
NAME TYPE CLUSTER-IP EXTERNAL-IP
206+
istio-ingressgateway LoadBalancer 10.106.200.195 <pending>
207+
```
208+
If you're running within a private VPC, on-premises or on your laptop, then you will need to get a public IP for Istio through the inlets-operator. See a full guide to [setting up the inlets-operator with Istio](https://blog.alexellis.io/a-bit-of-istio-before-tea-time/) to provide an IP via a secure tunnel. That will then change `<pending>` to a fully accessible IP.
209+
210+
Otherwise, copy the IP or CNAME issued to you under `EXTERNAL-IP` and create your DNS entry. I'll be using the domain `faas.o6s.io`.
211+
212+
You can get a TLS certificate to serve traffic over HTTPS using cert-manager.
213+
214+
```bash
215+
arkade install cert-manager
216+
```
217+
218+
Now create an `Issuer` and register it with [Let's Encrypt](https://letsencrypt.org/):
219+
220+
```bash
221+
export EMAIL="you@example.com"
222+
223+
cat > issuer.yaml <<EOF
224+
apiVersion: cert-manager.io/v1
225+
kind: Issuer
226+
metadata:
227+
name: letsencrypt-prod
228+
namespace: istio-system
229+
spec:
230+
acme:
231+
server: https://acme-v02.api.letsencrypt.org/directory
232+
email: $EMAIL
233+
privateKeySecretRef:
234+
name: letsencrypt-prod
235+
solvers:
236+
- selector: {}
237+
http01:
238+
ingress:
239+
class: istio
240+
EOF
241+
kubectl apply -f issuer.yaml
242+
```
243+
244+
Define a certificate:
245+
246+
```bash
247+
export DOMAIN="faas.o6s.io"
248+
249+
cat > cert.yaml <<EOF
250+
apiVersion: cert-manager.io/v1alpha2
251+
kind: Certificate
252+
metadata:
253+
name: ingress-cert
254+
namespace: istio-system
255+
spec:
256+
secretName: ingress-cert
257+
commonName: $DOMAIN
258+
dnsNames:
259+
- $DOMAIN
260+
issuerRef:
261+
name: letsencrypt-prod
262+
kind: Issuer
263+
EOF
264+
kubectl apply -f cert.yaml
265+
```
266+
267+
You can then check the status of the issuer and certificate:
268+
269+
```bash
270+
kubectl get issuer -n istio-system -o wide
271+
NAME READY STATUS AGE
272+
letsencrypt-prod True The ACME account was registered with the ACME server 2m22s
273+
274+
kubectl get certificate -n istio-system -o wide
275+
NAME READY SECRET ISSUER STATUS AGE
276+
ingress-cert True ingress-cert letsencrypt-prod Certificate is up to date and has not expired 30s
277+
```
278+
279+
Now finally update the IngressGateway we created earlier so that it uses the domain we have defined such as `faas.o6s.io`.
280+
281+
```bash
282+
# gateway.yaml
283+
cat > gateway.yaml <<EOF
284+
apiVersion: networking.istio.io/v1alpha3
285+
kind: Gateway
286+
metadata:
287+
name: openfaas-gateway
288+
namespace: openfaas
289+
spec:
290+
selector:
291+
istio: ingressgateway
292+
servers:
293+
- port:
294+
number: 443
295+
name: https
296+
protocol: HTTPS
297+
tls:
298+
mode: SIMPLE
299+
credentialName: ingress-cert
300+
hosts:
301+
- faas.o6s.io
302+
EOF
303+
304+
kubectl apply -f gateway.yaml
305+
```
306+
307+
At this point you can log into OpenFaaS via its public URL and access the nodeinfo function:
308+
309+
```bash
310+
export OPENFAAS_URL="https://faas.o6s.io"
311+
echo -n $PASSWORD | faas-cli login --username admin --password-stdin
312+
313+
Calling the OpenFaaS server to validate the credentials...
314+
315+
credentials saved for admin https://faas.o6s.io
316+
```
317+
318+
Invoke the function:
319+
320+
```bash
321+
curl -s -d "" $OPENFAAS_URL/function/nodeinfo
322+
```
323+
324+
## Wrapping up
325+
326+
In a short period of time we were able to deploy Istio and OpenFaaS on a local KinD cluster and see Envoy's sidecar providing mutual TLS encryption. We then went on to explore the additional resource consumption added by using Istio, and finally showed you how to create a TLS certificate for external traffic using a free certificate from Let's Encrypt.
327+
328+
If you wanted to take things further, you could look into more advanced policies for routing and traffic shifting or partial weighting using [VirtualServices](https://istio.io/latest/docs/reference/config/networking/virtual-service/) for individual functions.
329+
330+
> You may also like the workshop we created to show how to do mutual TLS and traffic shifting with [OpenFaaS and Linkerd](https://github.com/openfaas/openfaas-linkerd-workshop).
331+
332+
Do you have questions, comments or suggestions?
333+
334+
* Find out more about [Istio](https://istio.io)
335+
* Join [OpenFaaS Slack](https://slack.openfaas.io/)

images/2021-05-istio/background.jpg

213 KB
Loading

0 commit comments

Comments
 (0)