-
Notifications
You must be signed in to change notification settings - Fork 21
Description
Hi,
Trying to deploy self-hosted ZROK with openziti. The idea and the product seems nice but there is clear lack of documentation for properly secured and working configuration and seems like it is still in PoC stages. First of all helm charts don't support adding extraEnv variables from Secret Mounts (We are using external-secrets operator that pulls in secret data from GCP Secret Manager so we don't expose keys and secrets in plaintext manifests) which means that enrollmentJWT, ziti admin secret needs to be passed into helm chart as plaintext values.
Secondly, the helm hooks which create users, etc sometimes misbehave when deploying with ArgoCD. Having so many configuration issues that I keep redeploying zrok/ ziti and the users get created as part of bootstrap process and this leads to config drift from secrets/ ziti controller. Biggest issue is that secrets get regenerated and what is written in Ziti controller database doesn't match up to what is in the K8S secrets so initial login doesn't work. I see that there is support for postgres database for Zrok, so it can be scaled horizontally and still retain the same data, however the config part responsible for data store doesn't provide any flexibility to make required changes, it is hardcoded to use sqlite3. Also it is also unclear wether ziti-router is needed or is it enough to set ziti-controller-edge api as LoadBalancer service (docs say one thing but after testing it, conclusion is that ziti-router is required).
I tried mounting enrollmentJWT as additionalVolume and set .Values.enrollJwtFile to the mounted volume but that fails miserably. I can see and read the mounted token on the pod filesystem but for some reason Zrok controller fails, fallback to setting the same token explicitly in enrollmentJwt works fine. I might be wrong but feels like enrollmentJwt for ziti-router could also be bootstrapped from a script, so there is no need to manually login to ziti controller and create the router.
Another problem I ran into was creating new identities configs. When Zrok initially starts it tries to bootstrap and create required identity - ran into issue that identity "public" already exists so I had to manually drop the identity and create again. Additionally the new identity was created with ID -D3xLHGw2
and when zrok frontend tried to start it was failing because it doesn't recognise configuration flag "-D3xLHGw2" passed on cli, this needs some proper escaping as seems like this is one of edge cases. In a DR scenario when these resources would be recreated, then all persistent data would be lost and all clients would have to reauthenticate with new tokens/ passwords, correct me if I'm wrong.
The initial config might be good enough to server Zrok/ ziti locally but it is far from production-ready or even just to serve dev resources on GKE cluster.
Below added our current config for helm chart, however we will probably have to keep our own version of these helm charts since they seem to be lacking vital configuration options. My only concern is with maintaining scripts which are called for bootstrap etc. I could open a PR for helm charts to include support for mount envFrom: secrets/ configmaps properly if existingSecret is defined and also option to configure zrok ctrl.yaml with postgres DB.
--- ziti-controller values
clientApi:
advertisedHost: ziti-controller-client.ziti
advertisedPort: 443
service:
enabled: true
type: ClusterIP
ingress:
enabled: false
ctrlPlaneCasBundle:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: "ziti"
trust-manager:
enabled: true
crds:
enabled: true
app:
trust:
namespace: ziti
--- ziti-router values
advertisedHost: ziti.dev.company
# enrollJwtFile: /etc/enrollment-jwt/enrollmentJwt # NOT working
enrollmentJwt: plainTextToken
edge:
advertisedPort: 443
service:
enabled: true
type: ClusterIP
ctrl:
endpoint: ziti-controller-ctrl.ziti:443
tunnel:
mode: host
additionalVolumes:
- name: enrollment-jwt
volumeType: secret
mountPath: /etc/enrollment-jwt
secretName: ziti-router-secret
env:
DEBUG: "1"
--- ziti-router IngressRouteTCP (for Traefik)
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: ziti-router-ingress-dev
namespace: ziti
annotations:
kubernetes.io/ingress.class: traefik-public
spec:
entryPoints:
- websecure
routes:
- match: HostSNI(`ziti.dev.company`)
services:
- name: ziti-router-edge
port: 443
tls:
passthrough: true
--- zrok values
controller:
ingress:
enabled: true
className: "traefik-public"
hosts:
- "zrok.dev.company"
tls:
- secretName: wildcard-cert
hosts:
- zrok.dev.company
frontend:
ingress:
enabled: true
className: "traefik-public"
tls:
- secretName: wildcard-cert
ziti:
advertisedHost: ziti-controller-client.ziti
password: plainTextPassword
dnsZone: "zrok.dev.company"