-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathk3d.sh
executable file
Β·385 lines (350 loc) Β· 11.5 KB
/
k3d.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
#!/usr/bin/env bash
# (C) 2021 GoodData Corporation
#
# Create K3D cluster with Pulsar and GoodData.CN Helm charts deployed.
# Requirements
# * running docker daemon, containers must be able to access the Internet
# * docker client
# * k3d v4.4.8+ (version v5.x preferred)
# * helm v3.5+
# * kubectl 1.21+
#
# helm, k3d and kubectl can be installed using gofish:
# curl -fsSL https://raw.githubusercontent.com/fishworks/gofish/main/scripts/install.sh | bash
# gofish init
# gofish install kubectl helm k3d
#
# The environment variable GDCN_LICENSE needs to be set and it must contain
# a valid license key for GoodData.CN
#
# Parameters:
# -c : Create cluster - when k3d cluster already exists, it is deleted
# (local docker registry is preserved)
# -n : Do not expose SSL port. Only port 80 (or $LBPORT) can be used for
# exposing k8s apps using Ingress. Cert-manager and TLS stuff will
# not be installed.
# -H authHost : Sets public hostname for Dex Oauth2 provider. Defaults to
# localhost, which makes it convenient for local deployment. If
# you plan to deploy on remote instance, set it to publicly
# accessible hostname.
set -e
# Version of Pulsar image
PULSAR_VERSION="2.7.4"
# Version of Pulsar Helm chart
PULSAR_CHART_VERSION="2.7.8"
# Update to newer version when available
GOODDATA_CN_VERSION="1.7.0"
CLUSTER_NAME="default"
# set to empty string if you want port 80
LBPORT=""
# set to empty string if you want port 443. Ignored with (-n) paramter
LBSSLPORT=""
# LBPORT="8080"
# LBSSLPORT="3443"
CREATE_CLUSTER=""
# Comment chars for ssl-specific settings in manifests
NO_SSL=""
SSL="#"
authHost="localhost"
# Port 5000 is apparently occupied on OSX/Windows
registryPort="5050"
### Functions
usage() {
cat > /dev/stderr <<EOT
Create k3d cluster with GoodData.CN installed.
Usage: $0 [options]
Options are:
-c - create cluster
-n - do not use SSL port
-H authHost - public hostname for Dex [default: localhost]
-p registryPort - port of local docker registry [default: 5050]
EOT
exit 1
}
v() {
echo Running: "$@"
"$@"
}
prepare_registry() {
echo "π Checking for local docker registry volume"
docker volume inspect registry-data -f "{{.Name}}" || docker volume create registry-data
registry_running=$(docker container inspect k3d-registry -f '{{.State.Running}}' || :)
# Check docker registry labels - new k3d expects proper lables to be set
if [ -n "$registry_running" ] ; then
port_label=$(docker inspect k3d-registry -f '{{index .Config.Labels "k3s.registry.port.external"}}')
if [ "$port_label" != "${registryPort}" ] ; then
echo "Outdated local docker registry found, recreating."
docker rm -f k3d-registry
registry_running=''
fi
fi
if [ -z "$registry_running" ] ; then
echo "Registry container doesn't exist, running the new registry container."
docker container run -d --name k3d-registry -v registry-data:/var/lib/registry \
--restart always -p "${registryPort}":5000 -l app=k3d -l k3d.cluster= \
-l k3d.registry.host= -l k3d.registry.hostIP=0.0.0.0 -l k3d.role=registry \
-l k3d.version=5.2.1 -l k3s.registry.port.external="${registryPort}" \
-l k3s.registry.port.internal=5000 registry:2
elif [ "$registry_running" == "false" ] ; then
echo "Registry container stopped, starting."
docker container start k3d-registry
else
echo "Docker registry is already running"
fi
}
pull_images() {
echo "Pre-pulling images from DockerHub to local registry."
apps=(
afm-exec-api auth-service metadata-api result-cache scan-model sql-executor
aqe tools organization-controller dex analytical-designer dashboards home-ui
ldm-modeler measure-editor apidocs calcique
)
for app in "${apps[@]}" ; do
echo " == $app"
docker pull -q "gooddata/${app}:${GOODDATA_CN_VERSION}"
docker tag "gooddata/${app}:${GOODDATA_CN_VERSION}" "localhost:${registryPort}/${app}:${GOODDATA_CN_VERSION}"
docker push -q "localhost:${registryPort}/${app}:${GOODDATA_CN_VERSION}"
done
# Preload pulsar to local registry
# The reason is that it is a huge image and DockerHub token expires before the image
# is pulled by containerd. Furthermore, is is pulled 3-4 times in parallel.
docker pull -q "apachepulsar/pulsar:$PULSAR_VERSION"
docker tag "apachepulsar/pulsar:$PULSAR_VERSION" "localhost:${registryPort}/apachepulsar/pulsar:$PULSAR_VERSION"
docker push -q "localhost:${registryPort}/apachepulsar/pulsar:$PULSAR_VERSION"
}
### Start of script
# Check the license key variable
if [ -z "$GDCN_LICENSE" ] ; then
cat > /dev/stderr <<EOT
The env variable GDCN_LICENSE must be set and it must contain a valid
license key for GoodData.CN
EOT
exit 1
fi
while getopts "cnH:p:" o; do
case "${o}" in
c)
CREATE_CLUSTER=yes
;;
n)
# reverse the comment chars
NO_SSL='#'
SSL=''
;;
H)
authHost="${OPTARG}"
;;
p)
registryPort="${OPTARG}"
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
if ! [[ "$registryPort" =~ ^[1-9][0-9]*$ && "$registryPort" -lt 65536 ]] ; then
echo "π₯ Invalid registry port '$registryPort', positive integer reqiured"
exit 1
fi
echo "π Checking for missing tools"
k3d version
helm version
kubectl version --client
docker ps -q > /dev/null
cd "$(dirname "$0")"
# This is needed to make kubedns working in pods running on the same host
# where kubedns pod is running; valid for Linux
if [[ $(uname) != *"Darwin"* ]];then
echo "π Checking bridge netfilter policy"
if ! grep -q 1 /proc/sys/net/bridge/bridge-nf-call-iptables ; then
echo " Enabling bridge-nf-call-iptables"
echo '1' | sudo tee /proc/sys/net/bridge/bridge-nf-call-iptables
fi
fi
# Create cluster
if [ -n "$CREATE_CLUSTER" ] ; then
k3d cluster delete $CLUSTER_NAME || :
prepare_registry
v k3d cluster create -c /dev/stdin <<EOT
apiVersion: k3d.io/v1alpha3
kind: Simple
name: default
servers: 1
agents: 2
kubeAPI:
hostIP: "0.0.0.0"
hostPort: "6443"
image: rancher/k3s:v1.21.7-k3s1
${NO_SSL}volumes:
${NO_SSL} - volume: $PWD/cert-manager.yaml:/var/lib/rancher/k3s/server/manifests/cert-manager.yaml
${NO_SSL} nodeFilters:
${NO_SSL} - server:0
ports:
- port: ${LBPORT:-80}:${LBPORT:-80}
nodeFilters:
- loadbalancer
${NO_SSL} - port: ${LBSSLPORT:-443}:${LBSSLPORT:-443}
${NO_SSL} nodeFilters:
${NO_SSL} - loadbalancer
registries:
use:
- k3d-registry:5000
options:
k3s:
extraArgs:
- arg: --disable=traefik
nodeFilters:
- server:*
kubeconfig:
updateDefaultKubeconfig: true
switchCurrentContext: true
EOT
echo "β
k3d cluster successfully created."
fi
echo "π Creating namespaces"
kubectl apply -f namespaces.yaml
echo "π Installing Ingress Controller"
kubectl apply -f - <<EOT
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: ingress-nginx
namespace: kube-system
spec:
repo: https://kubernetes.github.io/ingress-nginx
chart: ingress-nginx
version: 4.0.13
targetNamespace: kube-system
valuesContent: |-
controller:
config:
use-forwarded-headers: "true"
# If you plan to put reverse proxy in front of k3d cluster,
# you may want to disable ssl-redirect here:
${SSL}ssl-redirect: "false"
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
service:
ports:
http: ${LBPORT:-80}
https: ${LBSSLPORT:-443}
EOT
[ -z "$SKIP_PULL" ] && pull_images
kubectl config use-context k3d-$CLUSTER_NAME
kubectl cluster-info
if [ -n "$CREATE_CLUSTER" ] && [ -n "$SSL" ] ; then
# Wait for cert-manager. Kubectl is completely happy when listing
# resources in non-existent namespace but it fails when waiting
# on non-existent resources if using selector. Therefore we must
# poll for namespace and some specific resource first and then
# we can wait for deployment to become available.
echo "π Waiting for cert-manager to come up"
while ! kubectl get ns cert-manager &> /dev/null ; do
sleep 10
done
while ! kubectl -n cert-manager get deployment cert-manager &> /dev/null ; do
sleep 10
done
kubectl -n cert-manager wait deployment --for=condition=available \
--selector=app.kubernetes.io/instance=cert-manager
# This script generates key/cert pair (if not already available),
# stores it in secret gooddata/ca-key-pair and registers local
# CA as a new cert-manager Issuer gooddata/ca-issuer
./gen_keys.sh
fi
echo "π¦ Adding missing Helm repositories"
helm repo add pulsar https://pulsar.apache.org/charts
helm repo add gooddata https://charts.gooddata.com/
helm repo update
cat << EOT > /tmp/values-pulsar-k3d.yaml
components:
functions: false
proxy: false
pulsar_manager: false
toolset: false
monitoring:
alert_manager: false
grafana: false
node_exporter: false
prometheus: false
bookkeeper:
replicaCount: 3
resources:
requests:
cpu: 0.2
memory: 128Mi
broker:
configData:
PULSAR_MEM: >
-Xms128m -Xmx256m -XX:MaxDirectMemorySize=128m
subscriptionExpirationTimeMinutes: "5"
webSocketServiceEnabled: "true"
replicaCount: 2
resources:
requests:
cpu: 0.2
memory: 256Mi
volumes:
persistence: false
images:
autorecovery:
tag: $PULSAR_VERSION
repository: k3d-registry:5000/apachepulsar/pulsar
bookie:
tag: $PULSAR_VERSION
repository: k3d-registry:5000/apachepulsar/pulsar
broker:
tag: $PULSAR_VERSION
repository: k3d-registry:5000/apachepulsar/pulsar
zookeeper:
tag: $PULSAR_VERSION
repository: k3d-registry:5000/apachepulsar/pulsar
pulsar_metadata:
image:
tag: $PULSAR_VERSION
repository: k3d-registry:5000/apachepulsar/pulsar
EOT
if [ -n "$CREATE_CLUSTER" ] ; then
initialize=(--set initialize=true)
fi
# Install Apache Pulsar helm chart
echo "π¨ Installing Apache Pulsar"
v helm -n pulsar upgrade --wait --timeout 7m --install pulsar \
--values /tmp/values-pulsar-k3d.yaml "${initialize[@]}" \
--version $PULSAR_CHART_VERSION apache/pulsar
cat << EOT > /tmp/values-gooddata-cn.yaml
replicaCount: 1
authService:
allowRedirect: https://localhost:8443
cookiePolicy: None
dex:
ingress:
authHost: $authHost
${NO_SSL}annotations:
${NO_SSL} cert-manager.io/issuer: ca-issuer
${NO_SSL}tls:
${NO_SSL} authSecretName: gooddata-cn-dex-tls
image:
repositoryPrefix: k3d-registry:5000
ingress:
annotations:
nginx.ingress.kubernetes.io/cors-allow-headers: X-GDC-JS-SDK-COMP, X-GDC-JS-SDK-COMP-PROPS, X-GDC-JS-PACKAGE, X-GDC-JS-PACKAGE-VERSION, x-requested-with, X-GDC-VALIDATE-RELATIONS, DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Authorization
nginx.ingress.kubernetes.io/cors-allow-origin: https://localhost:8443
nginx.ingress.kubernetes.io/enable-cors: "true"
license:
key: "$GDCN_LICENSE"
EOT
# Install GoodData.CN Helm chart
echo "π Installing GoodData.CN"
v helm -n gooddata upgrade --install gooddata-cn --wait --timeout 7m \
--values /tmp/values-gooddata-cn.yaml --version ${GOODDATA_CN_VERSION} \
gooddata/gooddata-cn
[ -n "$CREATE_CLUSTER" ] && [ -n "$SSL" ] && ssl_ingress="and https://localhost${LBSSLPORT:+:$LBSSLPORT}/
If you want to use HTTPS endpoints, install CA certificate to your system as described
above."
cat << EOT
Ingress is available at http://localhost${LBPORT:+:$LBPORT}/ $ssl_ingress
EOT