Skip to content

Commit 618dddd

Browse files
yankeexealexellis
authored andcommitted
Add tutorial for a local registry with KinD
Editorial changes and updates by Alex Ellis. Signed-off-by: Yankee Maharjan <yankee.exe@gmail.com> Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
1 parent df470fe commit 618dddd

2 files changed

Lines changed: 227 additions & 0 deletions

File tree

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
# Use a local registry with KinD
2+
3+
A local registry can save on bandwidth costs and means your OpenFaaS functions don't leave your local computer when running `faas-cli up`
4+
5+
Not only is it much quicker, but it's also simple to configure if you're using KinD.
6+
7+
## Prerequisite:
8+
9+
You need to have **Docker** installed on your machine.
10+
11+
### Install arkade
12+
13+
We will use [arkade](https://github.com/alexellis/arkade) to install and deploy apps and services to Kubernetes.
14+
15+
```bash
16+
$ curl -sLS [https://dl.get-arkade.dev](https://dl.get-arkade.dev) | sudo sh
17+
```
18+
19+
**arkade commands:**
20+
21+
* use `arkade get` to download CLI tools and applications.
22+
23+
* use `arkade install` to install applications using [helm charts](https://helm.sh/docs/topics/charts/) or vanilla YAML files.
24+
25+
### Install kubectl
26+
27+
[kubectl](https://kubernetes.io/docs/reference/kubectl/overview/) is a command line tool that talks to the Kubernetes API for performing actions on our cluster.
28+
29+
```bash
30+
$ arkade get kubectl
31+
```
32+
33+
## Create the KinD cluster with a local registry enabled
34+
35+
We will set up our local Kubernetes cluster using [**KinD**](https://github.com/kubernetes-sigs/kind) (Kubernetes in Docker).
36+
37+
### Install KinD
38+
39+
These instructions are adapted from the KinD documentation. Our goal is to keep everything locally including a local Docker registry.
40+
41+
> The official KinD docs provides a [shell script](https://kind.sigs.k8s.io/docs/user/local-registry/) to create a Kubernetes cluster with local Docker registry enabled.
42+
43+
```bash
44+
#!/bin/sh
45+
set -o errexit
46+
47+
# create registry container unless it already exists
48+
reg_name='kind-registry'
49+
reg_port='5000'
50+
running="$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)"
51+
if [ "${running}" != 'true' ]; then
52+
docker run \
53+
-d --restart=always -p "${reg_port}:5000" --name "${reg_name}" \
54+
registry:2
55+
fi
56+
57+
# create a cluster with the local registry enabled in containerd
58+
cat <<EOF | kind create cluster --config=-
59+
kind: Cluster
60+
apiVersion: kind.x-k8s.io/v1alpha4
61+
containerdConfigPatches:
62+
- |-
63+
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"]
64+
endpoint = ["http://${reg_name}:${reg_port}"]
65+
EOF
66+
67+
# connect the registry to the cluster network
68+
docker network connect "kind" "${reg_name}"
69+
70+
# tell https://tilt.dev to use the registry
71+
# https://docs.tilt.dev/choosing_clusters.html#discovering-the-registry
72+
for node in $(kind get nodes); do
73+
kubectl annotate node "${node}" "kind.x-k8s.io/registry=localhost:${reg_port}";
74+
done
75+
```
76+
77+
> View the shell script in the [KinD docs](https://kind.sigs.k8s.io/examples/kind-with-registry.sh)
78+
79+
---
80+
81+
### Note:
82+
83+
You can find similar solutions for other local Kubernetes distributions:
84+
85+
* [k3d](https://k3d.io/usage/guides/registries/#using-a-local-registry) - local registries
86+
* [minikube](https://minikube.sigs.k8s.io/docs/handbook/registry/) - registry add-on
87+
* [microk8s](https://microk8s.io/docs/registry-built-in) - built-in registry
88+
---
89+
90+
Make the script executable:
91+
92+
```bash
93+
$ chmod +x kind-with-registry.sh
94+
```
95+
96+
Run it to create your local cluster with registry:
97+
98+
```bash
99+
$ ./kind-with-registry.sh
100+
```
101+
102+
Make sure the `kubectl` context is set to the newly created cluster:
103+
104+
```bash
105+
$ kubectl config current-context
106+
```
107+
108+
If the result is not `kind-kind` then execute:
109+
110+
```bash
111+
$ kubectl config use kind-kind
112+
```
113+
114+
Make sure the cluster is running:
115+
116+
```bash
117+
$ kubectl cluster-info
118+
```
119+
120+
Make sure Docker registry is running.
121+
122+
```bash
123+
$ docker logs -f kind-registry
124+
```
125+
126+
### Deploy OpenFaaS
127+
128+
Deploy OpenFaaS and its CLI:
129+
130+
```bash
131+
$ arkade install openfaas
132+
$ arkade get faas-cli
133+
```
134+
135+
Then log in and port-forward OpenFaaS using the instructions given, or run `arkade info openfaas` to get them a second time.
136+
137+
### Create a Function
138+
139+
We will take an example of a simple function; a dictionary that returns the meaning of word you query. We will be using the [PyDictionary](https://pypi.org/project/PyDictionary/) module for this setup.
140+
141+
Pull python language template from store:
142+
143+
```bash
144+
$ faas-cli template store pull python3-flask
145+
```
146+
147+
We will be using the [python3-flask-debian](https://github.com/openfaas-incubator/python-flask-template/tree/master/template/python3-flask-debian) template.
148+
149+
Setup your `OPENFAAS_PREFIX` variable to configure the address of your registry:
150+
151+
```bash
152+
export OPENFAAS_PREFIX=localhost:5000
153+
```
154+
155+
> Note: Docker for Mac users may need to change "localhost" to the IP address of their LAN or WiFi adapter as shown on `ifconfig` such as `192.168.0.14`
156+
157+
Create a new function using the template:
158+
159+
```bash
160+
$ export FN=pydict
161+
$ faas-cli new $FN --lang python3-flask-debian
162+
```
163+
164+
This will create a directory for your function and a YAML config file with the function name you provided:
165+
166+
* pydict/
167+
* pydict.yml
168+
169+
Add dependency to the `pydict/requirements.txt` file:
170+
171+
```txt
172+
PyDictionary
173+
```
174+
175+
Update `handler.py` with the following code.
176+
177+
```python
178+
from PyDictionary import PyDictionary
179+
180+
dictionary = PyDictionary()
181+
182+
def handle(word):
183+
return dictionary.meaning(word)
184+
```
185+
186+
Our minimal function is complete.
187+
188+
### Stack file
189+
190+
You will see that the OpenFaaS stack YAML file `pydict.yml` has `localhost:5000` in its image destination.
191+
192+
```yaml
193+
version: 1.0
194+
provider:
195+
name: openfaas
196+
gateway: http://127.0.0.1:8080
197+
functions:
198+
pydict:
199+
lang: python3-flask-debian
200+
handler: ./pydict
201+
image: localhost:5000/pydict:latest
202+
```
203+
204+
## Build Push Deploy
205+
206+
With our setup ready; we can now build our image, push it to the registry, and deploy it to Kubernetes. And using `faas-cli` it is possible with a single command!
207+
208+
```bash
209+
faas-cli up -f pydict.yml
210+
```
211+
212+
## Test the function
213+
214+
We can invoke our function from CLI using `faas-cli` or `curl`.
215+
216+
```bash
217+
$ echo "advocate" | faas-cli invoke pydict
218+
219+
{"Noun":["a person who pleads for a cause or propounds an idea","a lawyer who pleads cases in court"],"Verb":["push for something","speak, plead, or argue in favor of"]}
220+
```
221+
222+
### Wrapping Up
223+
224+
Now that you have a local registry, you can speed up your local development of functions by keeping the container images within your local computer.
225+
226+
> This tutorial is based upon the KinD docs and [a post by Yankee Maharjan](https://dev.to/yankee/deploy-your-serverless-python-function-locally-with-openfaas-in-kubernetes-18jf).

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ nav:
169169
- Test Drive: ./tutorials/test-drive.md
170170
- Kubernetes HPAv2: ./tutorials/kubernetes-hpa.md
171171
- Kubernetes HPAv2 Custom Metrics: ./tutorials/kubernetes-hpa-custom-metrics.md
172+
- Local Registry with KinD: ./tutorials/local-kind-registry.md
172173
- Featured: ./tutorials/featured.md
173174
- Contributing:
174175
- Get Started: ./contributing/get-started.md

0 commit comments

Comments
 (0)