Add example kubernetes deployment

This configuration partially works with kubernetes 1.15 running
locally using Docker Desktop for Mac and kind (k8s in docker).

For completeness, we installed kind & created a cluster like this:

    cd /tmp/ && GO111MODULE="on" go get sigs.k8s.io/kind
    kind create cluster --name workshop
    export KUBECONFIG="$(kind get kubeconfig-path --name="workshop")"

We describe finicky details discovered while creating wiki.yaml.

The persistent volume when mounted in wiki-config begins its life with
all files owned by root. This prevented our node user inside the
container from creating the config files inside .wiki. It took a while
to discover the correct securityContext for the wiki-config container.

We tested this configuration as follows:

    alias k=kubectl
    k apply -f wiki.yaml
    export POD=$(k get pod -lapp=wiki -o jsonpath='{.items[*].metadata.name}')
    export PASSWORD=$(k exec svc/wiki-service -- jq -r .admin .wiki/config.json)
    k port-forward svc/wiki-service 3000:80 > /dev/null &
    pbcopy <<<"$PASSWORD"
    open http://localhost:3000
    # click lock icon in the browser to login to wiki page
    # paste the password from the clipboard
    # click wiki to toggle editing on
    # make a few edits to the wiki page

Something about authentication is NOT working for anything except
localhost. When we try the same tests using http://localtest.me or
configuring foo.local in the MacOS /etc/hosts file, for some reason
the cookies don't seem to be passed through to the server. All edits
on other pages end up in browser localStorage.

Nevertheless, I'll commit what I have for now.
This commit is contained in:
Eric Dobbs 2019-11-16 22:27:45 -07:00
parent fb81d51e29
commit fb2aa0f67c
1 changed files with 130 additions and 0 deletions

130
examples/k8s/wiki.yaml Normal file
View File

@ -0,0 +1,130 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dot-wiki
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 4Gi
---
apiVersion: v1
kind: ConfigMap
metadata:
name: wiki-config
data:
config.json: |
{
"admin": "ADMIN",
"farm": true,
"cookieSecret": "RANDOM",
"security_type": "friends",
"secure_cookie": false,
"wikiDomains": {
"local": {
"id": "/home/node/.wiki/local.owner.json"
},
"localhost": {
"id": "/home/node/.wiki/local.owner.json"
},
"localtest.me": {
"id": "/home/node/.wiki/local.owner.json"
},
"local.dbbs.co": {
"id": "/home/node/.wiki/local.owner.json"
}
}
}
local.owner.json: |
{
"name": "The Owner",
"friend": {
"secret": "ADMIN"
}
}
install-config: |
#!/bin/sh
randomstring() {
node -e 'console.log(require("crypto").randomBytes(64).toString("hex"))'
}
readonly ADMIN=$(randomstring)
readonly COOKIE=$(randomstring)
readonly CONFIG=/home/node/.wiki/config.json
readonly OWNER=/home/node/.wiki/local.owner.json
[ -f $CONFIG ] || {
jq --arg admin $ADMIN \
--arg cookie $COOKIE \
'.admin = $admin | .cookieSecret = $cookie' \
/etc/config/config.json \
> $CONFIG
}
[ -f $OWNER ] || {
jq --arg admin $ADMIN \
'.friend.secret = $admin' \
/etc/config/local.owner.json \
> $OWNER
}
chown -R 1000:1000 /home/node/.wiki
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wiki-deployment
spec:
replicas: 1
selector:
matchLabels:
app: wiki
template:
metadata:
labels:
app: wiki
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
initContainers:
- name: wiki-config
image: dobbs/farm:1.0.0
securityContext:
runAsUser: 0
runAsGroup: 0
allowPrivilegeEscalation: false
volumeMounts:
- name: dot-wiki
mountPath: /home/node/.wiki
- name: config-templates
mountPath: /etc/config
command: ["sh", "/etc/config/install-config"]
containers:
- name: farm
image: dobbs/farm:1.0.0
command: ["wiki", "--config", "/home/node/.wiki/config.json"]
ports:
- containerPort: 3000
volumeMounts:
- name: dot-wiki
mountPath: /home/node/.wiki
volumes:
- name: dot-wiki
persistentVolumeClaim:
claimName: dot-wiki
- name: config-templates
configMap:
name: wiki-config
---
apiVersion: v1
kind: Service
metadata:
name: wiki-service
spec:
ports:
- name: http
targetPort: 3000
port: 80
selector:
app: wiki