mirror of
https://github.com/fosrl/docs-v2.git
synced 2026-09-08 07:01:32 +02:00
703 lines
15 KiB
Plaintext
703 lines
15 KiB
Plaintext
---
|
|
title: "Troubleshooting"
|
|
description: "Diagnose and resolve common Newt Kubernetes deployment issues."
|
|
---
|
|
|
|
Use this guide to troubleshoot Newt Kubernetes deployments installed with Helm, Kustomize, Argo CD, or Flux.
|
|
|
|
Start with the basic checks, then move to the section that matches the symptom.
|
|
|
|
## Quick checks
|
|
|
|
Set the namespace and release name used by your installation:
|
|
|
|
```bash
|
|
export NEWT_NAMESPACE=pangolin
|
|
export NEWT_RELEASE=newt
|
|
```
|
|
|
|
Check the Helm release:
|
|
|
|
```bash
|
|
helm status "$NEWT_RELEASE" --namespace "$NEWT_NAMESPACE"
|
|
helm history "$NEWT_RELEASE" --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
Check Newt pods:
|
|
|
|
```bash
|
|
kubectl get pods --namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt
|
|
```
|
|
|
|
Check recent events:
|
|
|
|
```bash
|
|
kubectl get events --namespace "$NEWT_NAMESPACE" \
|
|
--sort-by=.lastTimestamp
|
|
```
|
|
|
|
Check logs:
|
|
|
|
```bash
|
|
kubectl logs --namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt \
|
|
--tail=100
|
|
```
|
|
|
|
Check the applied Helm values:
|
|
|
|
```bash
|
|
helm get values "$NEWT_RELEASE" --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
<Note>
|
|
Do not assume the pod or Deployment name. Chart-generated names can change with the Helm release name, instance name, `nameOverride`, or `fullnameOverride`.
|
|
</Note>
|
|
|
|
## Get the generated resource names
|
|
|
|
List Newt resources:
|
|
|
|
```bash
|
|
kubectl get deploy,sts,svc,secret,cm --namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt
|
|
```
|
|
|
|
List pods with labels:
|
|
|
|
```bash
|
|
kubectl get pods --namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt \
|
|
--show-labels
|
|
```
|
|
|
|
Store the first Newt pod name:
|
|
|
|
```bash
|
|
export NEWT_POD="$(kubectl get pod --namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt \
|
|
-o jsonpath='{.items[0].metadata.name}')"
|
|
```
|
|
|
|
Then use:
|
|
|
|
```bash
|
|
echo "$NEWT_POD"
|
|
```
|
|
|
|
## Pod fails to start
|
|
|
|
### Symptoms
|
|
|
|
```text
|
|
STATUS RESTARTS
|
|
CrashLoopBackOff 5
|
|
Error 3
|
|
CreateContainerConfigError
|
|
ImagePullBackOff
|
|
```
|
|
|
|
### Check pod details
|
|
|
|
```bash
|
|
kubectl describe pod "$NEWT_POD" --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
Check logs:
|
|
|
|
```bash
|
|
kubectl logs "$NEWT_POD" --namespace "$NEWT_NAMESPACE" --tail=100
|
|
```
|
|
|
|
If the container restarts quickly, check the previous logs:
|
|
|
|
```bash
|
|
kubectl logs "$NEWT_POD" --namespace "$NEWT_NAMESPACE" --previous --tail=100
|
|
```
|
|
|
|
### Common causes
|
|
|
|
| Symptom | Likely cause | Check |
|
|
| ----------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------- |
|
|
| `Secret "..." not found` | Secret name does not match `auth.existingSecretName` | `kubectl get secret -n "$NEWT_NAMESPACE"` |
|
|
| Missing env var or empty credential | Secret exists but key names do not match `auth.keys.*` | `kubectl describe secret <secret> -n "$NEWT_NAMESPACE"` |
|
|
| Authentication failure | Wrong `NEWT_ID`, `NEWT_SECRET`, or provisioning key | Check credentials in Pangolin |
|
|
| Endpoint connection errors | `PANGOLIN_ENDPOINT` is wrong or unreachable | Test DNS and HTTPS from the pod |
|
|
| Image pull failure | Registry or image settings are wrong | `kubectl describe pod` |
|
|
|
|
## Secret issues
|
|
|
|
### Verify the Secret exists
|
|
|
|
```bash
|
|
kubectl get secret newt-auth --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
### Check Secret keys
|
|
|
|
```bash
|
|
kubectl describe secret newt-auth --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
The default keys are:
|
|
|
|
```text
|
|
PANGOLIN_ENDPOINT
|
|
NEWT_ID
|
|
NEWT_SECRET
|
|
```
|
|
|
|
If your Secret uses different key names, map them in values:
|
|
|
|
```yaml
|
|
newtInstances:
|
|
- name: main-tunnel
|
|
enabled: true
|
|
auth:
|
|
existingSecretName: newt-auth
|
|
keys:
|
|
endpointKey: PANGOLIN_ENDPOINT
|
|
idKey: NEWT_ID
|
|
secretKey: NEWT_SECRET
|
|
```
|
|
|
|
<Warning>
|
|
Do not paste decoded secrets into issue reports, logs, screenshots, or public repositories.
|
|
</Warning>
|
|
|
|
### Check which Secret the pod uses
|
|
|
|
```bash
|
|
kubectl get pod "$NEWT_POD" --namespace "$NEWT_NAMESPACE" \
|
|
-o jsonpath='{range .spec.containers[*].envFrom[*]}{.secretRef.name}{"\n"}{end}'
|
|
```
|
|
|
|
Also inspect explicit Secret references:
|
|
|
|
```bash
|
|
kubectl get pod "$NEWT_POD" --namespace "$NEWT_NAMESPACE" -o yaml | grep -A5 -B2 secretKeyRef
|
|
```
|
|
|
|
## Newt cannot reach Pangolin
|
|
|
|
### Test DNS from the Newt pod
|
|
|
|
```bash
|
|
kubectl exec "$NEWT_POD" --namespace "$NEWT_NAMESPACE" -- \
|
|
nslookup pangolin.example.com
|
|
```
|
|
|
|
### Test HTTPS from the Newt pod
|
|
|
|
```bash
|
|
kubectl exec "$NEWT_POD" --namespace "$NEWT_NAMESPACE" -- \
|
|
wget -S -O- https://pangolin.example.com 2>&1 | head -40
|
|
```
|
|
|
|
Depending on the image, `curl`, `wget`, `nc`, or `nslookup` may not be available. If needed, run a temporary debug pod in the same namespace:
|
|
|
|
```bash
|
|
kubectl run net-debug \
|
|
--namespace "$NEWT_NAMESPACE" \
|
|
--rm -it \
|
|
--image=curlimages/curl:latest \
|
|
--restart=Never \
|
|
-- sh
|
|
```
|
|
|
|
Then test:
|
|
|
|
```bash
|
|
curl -vk https://pangolin.example.com
|
|
```
|
|
|
|
### Common causes
|
|
|
|
| Problem | What to check |
|
|
| -------------------------------- | --------------------------------------------------------- |
|
|
| DNS fails | CoreDNS, NetworkPolicy egress to DNS, wrong hostname |
|
|
| HTTPS fails | ingress, TLS certificate, firewall, proxy, wrong endpoint |
|
|
| TLS verification fails | certificate chain, hostname mismatch, private CA |
|
|
| Works locally but not in cluster | egress policies, proxy settings, DNS split-horizon |
|
|
|
|
## Newt pod is running but site is offline
|
|
|
|
Check logs:
|
|
|
|
```bash
|
|
kubectl logs "$NEWT_POD" --namespace "$NEWT_NAMESPACE" --tail=200
|
|
```
|
|
|
|
Check the site in the Pangolin dashboard.
|
|
|
|
Verify:
|
|
|
|
* the site credentials belong to the same site
|
|
* the site was not deleted or regenerated in Pangolin
|
|
* `PANGOLIN_ENDPOINT` points to the correct Pangolin URL
|
|
* the cluster can resolve and reach the Pangolin endpoint
|
|
* outbound HTTPS is allowed from the Newt namespace
|
|
* the Secret is in the same namespace as the Newt workload
|
|
|
|
If you use provisioning, also verify:
|
|
|
|
* `provisioningKey` is valid
|
|
* `newtName` is set as expected
|
|
* `configPersistence.enabled=true`
|
|
* the configured `CONFIG_FILE` path is writable
|
|
|
|
## Provisioning issues
|
|
|
|
Provisioning requires writable config persistence.
|
|
|
|
### Symptoms
|
|
|
|
* Newt starts but does not keep generated credentials after restart.
|
|
* Newt provisions repeatedly.
|
|
* Logs mention config file or write errors.
|
|
* Pod restarts cause the site to appear as a new or unconfigured instance.
|
|
|
|
### Check values
|
|
|
|
```bash
|
|
helm get values "$NEWT_RELEASE" --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
Provisioning example:
|
|
|
|
```yaml
|
|
newtInstances:
|
|
- name: main-tunnel
|
|
enabled: true
|
|
auth:
|
|
pangolinEndpoint: https://pangolin.example.com
|
|
provisioningKey: "<provisioning-key>"
|
|
newtName: "my-site"
|
|
configPersistence:
|
|
enabled: true
|
|
type: emptyDir
|
|
mountPath: /var/lib/newt
|
|
fileName: config.json
|
|
```
|
|
|
|
For durable state, use an existing PVC:
|
|
|
|
```yaml
|
|
newtInstances:
|
|
- name: main-tunnel
|
|
enabled: true
|
|
auth:
|
|
pangolinEndpoint: https://pangolin.example.com
|
|
provisioningKey: "<provisioning-key>"
|
|
newtName: "my-site"
|
|
configPersistence:
|
|
enabled: true
|
|
type: persistentVolumeClaim
|
|
existingClaim: my-newt-config
|
|
mountPath: /var/lib/newt
|
|
fileName: config.json
|
|
```
|
|
|
|
<Note>
|
|
`emptyDir` is recreated when the pod is recreated. Use a PVC if the generated configuration must survive pod replacement.
|
|
</Note>
|
|
|
|
## Service not created or not reachable
|
|
|
|
### Important behavior
|
|
|
|
`acceptClients` does not create a Service.
|
|
|
|
A Service is created through:
|
|
|
|
```yaml
|
|
newtInstances:
|
|
- name: main-tunnel
|
|
service:
|
|
enabled: true
|
|
```
|
|
|
|
The chart also has `service.enabledWhenAcceptClients`, but runtime client behavior and Service rendering should still be verified in the rendered manifests.
|
|
|
|
### Check Services
|
|
|
|
```bash
|
|
kubectl get svc --namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt
|
|
```
|
|
|
|
Describe the Service:
|
|
|
|
```bash
|
|
kubectl describe svc <service-name> --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
### LoadBalancer stuck in pending
|
|
|
|
```text
|
|
EXTERNAL-IP <pending>
|
|
```
|
|
|
|
Common causes:
|
|
|
|
* the cluster has no cloud load balancer integration
|
|
* bare-metal cluster without MetalLB or equivalent
|
|
* cloud provider quota or permission issue
|
|
* invalid `loadBalancerClass`
|
|
* invalid `loadBalancerSourceRanges`
|
|
|
|
For bare-metal clusters, use MetalLB or another load balancer implementation, or use `NodePort` if appropriate.
|
|
|
|
## Metrics scraping does not work
|
|
|
|
Metrics are disabled by default.
|
|
|
|
Enable metrics:
|
|
|
|
```yaml
|
|
global:
|
|
metrics:
|
|
enabled: true
|
|
```
|
|
|
|
The chart default admin address is:
|
|
|
|
```yaml
|
|
global:
|
|
metrics:
|
|
adminAddr: ":2112"
|
|
```
|
|
|
|
This listens on all interfaces and allows in-cluster scraping. Do not set it to `127.0.0.1:2112` if Prometheus scrapes from another pod.
|
|
|
|
### Metrics Service
|
|
|
|
Enable the metrics Service:
|
|
|
|
```yaml
|
|
global:
|
|
metrics:
|
|
enabled: true
|
|
service:
|
|
enabled: true
|
|
port: 2112
|
|
```
|
|
|
|
### ServiceMonitor
|
|
|
|
If you use Prometheus Operator:
|
|
|
|
```yaml
|
|
global:
|
|
metrics:
|
|
enabled: true
|
|
service:
|
|
enabled: true
|
|
serviceMonitor:
|
|
enabled: true
|
|
```
|
|
|
|
Check resources:
|
|
|
|
```bash
|
|
kubectl get svc,podmonitor,servicemonitor,prometheusrule \
|
|
--namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt
|
|
```
|
|
|
|
<Note>
|
|
The chart has separate metrics values for container port, admin address, and metrics Service port. Check the rendered manifest when changing these values.
|
|
</Note>
|
|
|
|
## NetworkPolicy blocks traffic
|
|
|
|
If NetworkPolicy is enabled, check that the policy allows required egress.
|
|
|
|
Newt usually needs egress to:
|
|
|
|
* DNS
|
|
* Pangolin endpoint over HTTPS
|
|
* any tunnel or connectivity endpoints used by your deployment
|
|
|
|
Check policies:
|
|
|
|
```bash
|
|
kubectl get networkpolicy --namespace "$NEWT_NAMESPACE"
|
|
kubectl describe networkpolicy --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
If DNS is blocked, enable or add DNS egress rules.
|
|
|
|
Example:
|
|
|
|
```yaml
|
|
global:
|
|
networkPolicy:
|
|
enabled: true
|
|
components:
|
|
dns:
|
|
enabled: true
|
|
```
|
|
|
|
If HTTPS egress is blocked, add an appropriate custom egress rule for your environment.
|
|
|
|
## Multiple Newt instances conflict
|
|
|
|
### Symptoms
|
|
|
|
* Multiple pods run, but only one site connects.
|
|
* Both instances use the same credentials.
|
|
* A site appears to flap between instances.
|
|
* Logs show authentication or registration conflicts.
|
|
|
|
### Check values
|
|
|
|
```bash
|
|
helm get values "$NEWT_RELEASE" --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
Each instance should use its own credentials or provisioning identity:
|
|
|
|
```yaml
|
|
newtInstances:
|
|
- name: site-a
|
|
enabled: true
|
|
auth:
|
|
existingSecretName: newt-auth-site-a
|
|
|
|
- name: site-b
|
|
enabled: true
|
|
auth:
|
|
existingSecretName: newt-auth-site-b
|
|
```
|
|
|
|
Create separate Secrets:
|
|
|
|
```bash
|
|
kubectl create secret generic newt-auth-site-a \
|
|
--namespace "$NEWT_NAMESPACE" \
|
|
--from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
|
|
--from-literal=NEWT_ID=<site-a-newt-id> \
|
|
--from-literal=NEWT_SECRET=<site-a-newt-secret>
|
|
|
|
kubectl create secret generic newt-auth-site-b \
|
|
--namespace "$NEWT_NAMESPACE" \
|
|
--from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
|
|
--from-literal=NEWT_ID=<site-b-newt-id> \
|
|
--from-literal=NEWT_SECRET=<site-b-newt-secret>
|
|
```
|
|
|
|
## RBAC or service account issues
|
|
|
|
Chart `1.4.0` disables RBAC creation by default.
|
|
|
|
Check service account and RBAC:
|
|
|
|
```bash
|
|
kubectl get serviceaccount,role,rolebinding \
|
|
--namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt
|
|
```
|
|
|
|
If your configuration requires Kubernetes API access, enable RBAC:
|
|
|
|
```yaml
|
|
rbac:
|
|
create: true
|
|
clusterRole: false
|
|
```
|
|
|
|
For most Newt deployments, RBAC is not required.
|
|
|
|
## High CPU or memory usage
|
|
|
|
Check resource usage:
|
|
|
|
```bash
|
|
kubectl top pod --namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt
|
|
```
|
|
|
|
Check current resource settings:
|
|
|
|
```bash
|
|
kubectl get pod "$NEWT_POD" --namespace "$NEWT_NAMESPACE" \
|
|
-o jsonpath='{.spec.containers[0].resources}'
|
|
```
|
|
|
|
Tune resources in values:
|
|
|
|
```yaml
|
|
newtInstances:
|
|
- name: main-tunnel
|
|
resources:
|
|
requests:
|
|
cpu: 200m
|
|
memory: 256Mi
|
|
limits:
|
|
cpu: 1000m
|
|
memory: 512Mi
|
|
```
|
|
|
|
Then upgrade:
|
|
|
|
```bash
|
|
helm upgrade "$NEWT_RELEASE" fossorial/newt \
|
|
--namespace "$NEWT_NAMESPACE" \
|
|
--values values-newt.yaml
|
|
```
|
|
|
|
Common causes of high usage:
|
|
|
|
* high tunnel traffic
|
|
* too low resource limits
|
|
* repeated reconnect loops
|
|
* excessive debug logging
|
|
* MTU or network path issues
|
|
|
|
## MTU issues
|
|
|
|
### Symptoms
|
|
|
|
* Connections establish but large transfers fail.
|
|
* Some websites or services work, others hang.
|
|
* Logs show repeated reconnects.
|
|
* Throughput is much lower than expected.
|
|
|
|
Newt defaults to MTU `1280`.
|
|
|
|
Try another MTU only after confirming basic connectivity:
|
|
|
|
```yaml
|
|
newtInstances:
|
|
- name: main-tunnel
|
|
mtu: 1280
|
|
```
|
|
|
|
Upgrade after changing values:
|
|
|
|
```bash
|
|
helm upgrade "$NEWT_RELEASE" fossorial/newt \
|
|
--namespace "$NEWT_NAMESPACE" \
|
|
--values values-newt.yaml
|
|
```
|
|
|
|
## Helm debugging
|
|
|
|
Preview an upgrade:
|
|
|
|
```bash
|
|
helm upgrade "$NEWT_RELEASE" fossorial/newt \
|
|
--namespace "$NEWT_NAMESPACE" \
|
|
--values values-newt.yaml \
|
|
--dry-run
|
|
```
|
|
|
|
Render the chart locally:
|
|
|
|
```bash
|
|
helm template "$NEWT_RELEASE" fossorial/newt \
|
|
--namespace "$NEWT_NAMESPACE" \
|
|
--values values-newt.yaml
|
|
```
|
|
|
|
Show rendered manifests from the live release:
|
|
|
|
```bash
|
|
helm get manifest "$NEWT_RELEASE" --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
Show values from the live release:
|
|
|
|
```bash
|
|
helm get values "$NEWT_RELEASE" --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
Rollback:
|
|
|
|
```bash
|
|
helm rollback "$NEWT_RELEASE" <revision> --namespace "$NEWT_NAMESPACE"
|
|
```
|
|
|
|
## Kustomize debugging
|
|
|
|
Validate the overlay:
|
|
|
|
```bash
|
|
kustomize build overlays/site-a
|
|
```
|
|
|
|
Run a server-side dry run:
|
|
|
|
```bash
|
|
kustomize build overlays/site-a | kubectl apply -f - --dry-run=server
|
|
```
|
|
|
|
Preview live changes:
|
|
|
|
```bash
|
|
kustomize build overlays/site-a | kubectl diff -f -
|
|
```
|
|
|
|
If a patch does not apply, inspect generated resource names:
|
|
|
|
```bash
|
|
kustomize build base | grep -E "^(kind:| name:)"
|
|
```
|
|
|
|
## Collect diagnostics
|
|
|
|
Collect logs and resource information:
|
|
|
|
```bash
|
|
kubectl logs --namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt \
|
|
--tail=200 > newt-logs.txt
|
|
|
|
kubectl get pods --namespace "$NEWT_NAMESPACE" \
|
|
-l app.kubernetes.io/name=newt \
|
|
-o yaml > newt-pods.yaml
|
|
|
|
kubectl get events --namespace "$NEWT_NAMESPACE" \
|
|
--sort-by=.lastTimestamp > newt-events.txt
|
|
|
|
helm get values "$NEWT_RELEASE" \
|
|
--namespace "$NEWT_NAMESPACE" > newt-helm-values.yaml
|
|
|
|
helm get manifest "$NEWT_RELEASE" \
|
|
--namespace "$NEWT_NAMESPACE" > newt-helm-manifest.yaml
|
|
```
|
|
|
|
If using Kustomize:
|
|
|
|
```bash
|
|
kustomize build overlays/site-a > newt-kustomize-output.yaml
|
|
```
|
|
|
|
Before sharing diagnostics, remove:
|
|
|
|
* Newt credentials
|
|
* provisioning keys
|
|
* TLS private keys
|
|
* tokens
|
|
* passwords
|
|
* internal hostnames if sensitive
|
|
|
|
## Next steps
|
|
|
|
<CardGroup cols={2}>
|
|
<Card title="Configuration" href="/manage/sites/kubernetes/configuration" icon="sliders">
|
|
Review Newt chart options.
|
|
</Card>
|
|
<Card title="Helm Install" href="/manage/sites/kubernetes/helm" icon="box">
|
|
Install Newt with Helm.
|
|
</Card>
|
|
<Card title="Kustomize Install" href="/manage/sites/kubernetes/kustomize" icon="layer-group">
|
|
Install Newt with rendered manifests and Kustomize overlays.
|
|
</Card>
|
|
<Card title="GitOps" href="/self-host/manual/kubernetes/gitops/overview" icon="code-branch">
|
|
Deploy Newt with Argo CD or Flux.
|
|
</Card>
|
|
</CardGroup>
|