Move the k8s docs under the site

This commit is contained in:
Owen
2026-08-25 17:04:09 -04:00
parent 4abafba3dd
commit 8ee0505275
11 changed files with 47 additions and 57 deletions
+2 -2
View File
@@ -148,7 +148,7 @@ controller:
```
<Note>
Helm values for Newt are documented on the [Kubernetes Newt configuration page](/self-host/manual/kubernetes/newt/configuration). Controller and Gerbil ServiceMonitor values are documented on the [Kubernetes Pangolin configuration page](/self-host/manual/kubernetes/pangolin/configuration).
Helm values for Newt are documented on the [Kubernetes Newt configuration page](/manage/sites/kubernetes/configuration). Controller and Gerbil ServiceMonitor values are documented on the [Kubernetes Pangolin configuration page](/self-host/manual/kubernetes/pangolin/configuration).
</Note>
</Tab>
@@ -520,7 +520,7 @@ increase(pangolin_kube_controller_reconcile_errors_total[10m]) > 5
<Card title="Community Metrics Guide" icon="chart-simple" href="/self-host/community-guides/metrics">
Traefik and metrics collection with Prometheus and Grafana.
</Card>
<Card title="Newt Kubernetes Monitoring" icon="cubes" href="/self-host/manual/kubernetes/newt/configuration">
<Card title="Newt Kubernetes Monitoring" icon="cubes" href="/manage/sites/kubernetes/configuration">
Verified Newt chart values for metrics, Services, and ServiceMonitor resources.
</Card>
<Card title="Controller Monitoring Values" icon="cubes" href="/self-host/manual/kubernetes/pangolin/configuration">
-11
View File
@@ -55,7 +55,6 @@ It is recommended to create the namespace explicitly before installation. This a
For detailed installation steps, see:
* [Pangolin Helm Quick-Start](/self-host/manual/kubernetes/pangolin/helm) — Install Pangolin
* [Site (Newt) Helm Quick-Start](/self-host/manual/kubernetes/newt/helm) — Install Site (Newt)
## Install command patterns
@@ -162,7 +161,6 @@ Common value sources:
Full configuration options are documented here:
* [Pangolin Configuration](/self-host/manual/kubernetes/pangolin/configuration)
* [Newt Configuration](/self-host/manual/kubernetes/newt/configuration)
## Artifact Hub and chart discovery
@@ -337,10 +335,7 @@ Uninstalling a Helm release does not always remove persistent volumes, externall
## Troubleshooting
For component-specific troubleshooting, see:
* [Pangolin Troubleshooting](/self-host/manual/kubernetes/pangolin/troubleshooting)
* [Newt Troubleshooting](/self-host/manual/kubernetes/newt/troubleshooting)
Useful Helm commands:
@@ -367,15 +362,9 @@ kubectl logs <pod-name> -n pangolin
<Card title="Pangolin Helm Install" href="/self-host/manual/kubernetes/pangolin/helm" icon="server">
Install Pangolin with the Helm chart.
</Card>
<Card title="Site (Newt) Helm Install" href="/self-host/manual/kubernetes/newt/helm" icon="globe">
Install Site (Newt) with the Helm chart.
</Card>
<Card title="Pangolin Configuration" href="/self-host/manual/kubernetes/pangolin/configuration" icon="sliders">
Configure Pangolin chart values for your cluster.
</Card>
<Card title="Newt Configuration" href="/self-host/manual/kubernetes/newt/configuration" icon="sliders">
Configure Newt chart values and credentials.
</Card>
<Card title="Argo CD" href="/self-host/manual/kubernetes/gitops/argocd" icon="code-branch">
Deploy the charts with Argo CD.
</Card>
+1 -1
View File
@@ -359,7 +359,7 @@ kubectl get events -n pangolin --sort-by=.lastTimestamp
<Card title="Pangolin Kustomize Install" href="/self-host/manual/kubernetes/pangolin/kustomize" icon="server">
Install Pangolin with rendered manifests and Kustomize overlays.
</Card>
<Card title="Newt Kustomize Install" href="/self-host/manual/kubernetes/newt/kustomize" icon="globe">
<Card title="Newt Kustomize Install" href="/manage/sites/kubernetes/kustomize" icon="globe">
Install Newt with rendered manifests and Kustomize overlays.
</Card>
<Card title="Argo CD" href="/self-host/manual/kubernetes/gitops/argocd" icon="code-branch">
@@ -1,763 +0,0 @@
---
title: "Configuration"
description: "Configuration reference for Newt Kubernetes deployments."
---This page covers the main Newt Kubernetes configuration options for Helm and Kustomize workflows.
For exhaustive option coverage, refer to the chart resources:
<CardGroup cols={3}>
<Card title="README" href="https://github.com/fosrl/helm-charts/blob/main/charts/newt/README.md" />
<Card title="values.yaml" href="https://github.com/fosrl/helm-charts/blob/main/charts/newt/values.yaml" />
<Card title="values.schema.json" href="https://github.com/fosrl/helm-charts/blob/main/charts/newt/values.schema.json" />
</CardGroup>
## Version context
This page is aligned with the Newt Helm chart `1.4.0`.
| Item | Value |
| --- | --- |
| Chart version | `1.4.0` |
| App version | `1.12.3` |
| Kubernetes version | `>=1.30.14-0` |
| Default image | `docker.io/fosrl/newt:1.12.3` |
Chart `1.4.0` also publishes the Newt image metadata for Docker Hub and GHCR and includes Artifact Hub signing metadata.
## Configuration sections
<AccordionGroup>
<Accordion title="Image and global defaults" defaultOpen>
Use `global.image` to control the Newt container image used by all instances.
```yaml
global:
image:
registry: docker.io
repository: fosrl/newt
tag: ""
digest: ""
imagePullPolicy: IfNotPresent
imagePullSecrets: []
logLevel: INFO
```
Recommendations:
- Leave `tag` empty to use the chart `appVersion`.
- Use `digest` when you need immutable image pinning.
- Use `imagePullSecrets` when pulling from a private registry.
- Use per-instance overrides only when `allowGlobalOverride` is enabled for that instance.
</Accordion>
<Accordion title="Namespace and Pod Security Admission">
The chart can render Namespace resources, including Pod Security Admission labels.
```yaml
namespace:
create: false
name: ""
labels: {}
podSecurity:
enforce: ""
warn: ""
audit: ""
```
Recommended production pattern:
1. Create the namespace manually.
2. Apply required Pod Security Admission labels or policy labels.
3. Install the chart into that namespace.
```bash
kubectl create namespace pangolin
```
Example namespace labels:
```bash
kubectl label namespace pangolin \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
```
Per-instance namespace overrides are available when `allowGlobalOverride: true` is set:
```yaml
newtInstances:
- name: main-tunnel
allowGlobalOverride: true
namespace:
name: pangolin
create: false
labels: {}
podSecurity:
enforce: ""
warn: ""
audit: ""
```
<Note>
Creating the namespace manually is recommended when your cluster uses Pod Security Admission, policy labels, admission webhooks, or namespace annotations.
</Note>
</Accordion>
<Accordion title="Credentials and authentication">
For production, use an existing Kubernetes Secret.
```yaml
newtInstances:
- name: main-tunnel
enabled: true
auth:
existingSecretName: newt-auth
```
Create the Secret before installing the chart:
```bash
kubectl create secret generic newt-auth \
--namespace pangolin \
--from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
--from-literal=NEWT_ID=<newt-id> \
--from-literal=NEWT_SECRET=<newt-secret>
```
The default Secret keys are:
```yaml
PANGOLIN_ENDPOINT
NEWT_ID
NEWT_SECRET
```
Use `auth.keys.*` only when your Secret uses different key names:
```yaml
newtInstances:
- name: main-tunnel
enabled: true
auth:
existingSecretName: newt-auth
keys:
endpointKey: PANGOLIN_ENDPOINT
idKey: NEWT_ID
secretKey: NEWT_SECRET
```
`auth.keys.*` are Secret key names, not credential values.
Inline credentials are supported, but should only be used for local testing:
```yaml
newtInstances:
- name: main-tunnel
enabled: true
auth:
pangolinEndpoint: "https://pangolin.example.com"
id: "<newt-id>"
secret: "<newt-secret>"
```
<Warning>
Inline credentials can appear in rendered manifests and Helm release history. Use `auth.existingSecretName` for production.
</Warning>
<Warning>
Do not commit plaintext credentials to Git. For GitOps workflows, use encrypted or external secret backends such as SOPS, Sealed Secrets, External Secrets Operator, Vault, or Infisical.
</Warning>
Chart `1.4.0` also includes `auth.createSecret` and `auth.envVarsDirect` modes for generated Secret and direct environment-variable workflows. Use these only when they match your operational model.
</Accordion>
<Accordion title="Provisioning">
Provisioning supports installs where Newt bootstraps credentials from a provisioning key.
Use provisioning when Newt should bootstrap credentials from a provisioning key instead of using a static `NEWT_ID` and `NEWT_SECRET`.
```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
```
Provisioning requires writable config persistence so Newt can store the generated configuration.
For durable storage, 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
```
You can also provide a provisioning blueprint:
```yaml
newtInstances:
- name: main-tunnel
enabled: true
auth:
pangolinEndpoint: https://pangolin.example.com
provisioningKey: "<provisioning-key>"
newtName: "my-site"
configPersistence:
enabled: true
type: emptyDir
provisioningBlueprintFile: /etc/newt/provisioning-blueprint.yaml
provisioningBlueprintData: |
version: 1
routes: []
```
</Accordion>
<Accordion title="Instance runtime settings">
Each Newt instance is configured under `newtInstances[]`.
```yaml
newtInstances:
- name: main-tunnel
enabled: true
replicas: 1
logLevel: INFO
mtu: 1280
dns: ""
pingInterval: ""
pingTimeout: ""
acceptClients: false
useNativeInterface: false
interface: newt
keepInterface: false
noCloud: false
disableClients: false
```
Key settings:
| Setting | Purpose |
| ------------------------------ | ----------------------------------------------------------- |
| `replicas` | Number of replicas for this Newt instance |
| `mtu` | WireGuard interface MTU |
| `dns` | Optional DNS server address pushed to the client |
| `pingInterval` / `pingTimeout` | Optional Newt ping timing overrides |
| `acceptClients` | Allows client connections at runtime |
| `useNativeInterface` | Uses native WireGuard interface when native mode is enabled |
| `noCloud` | Disables cloud connectivity |
| `disableClients` | Disables client connections |
<Note>
Newt 1.11 changed upstream ping defaults. Set `pingInterval` and `pingTimeout` explicitly if you need older timing behavior.
</Note>
</Accordion>
<Accordion title="Service and connectivity">
Service exposure is controlled separately from `acceptClients`.
```yaml
newtInstances:
- name: main-tunnel
enabled: true
service:
enabled: false
type: ClusterIP
port: 51820
testerPort: ""
externalTrafficPolicy: ""
loadBalancerSourceRanges: []
```
Important behavior:
- `acceptClients` does not create a Service.
- `newtInstances[].service.enabled` controls whether a Service is created.
- Tester port exposure is disabled by default unless enabled through test settings or explicit legacy tester-port configuration.
Common Service types:
| Type | Use case |
| -------------- | --------------------------------------------- |
| `ClusterIP` | Internal cluster access |
| `LoadBalancer` | External exposure through cloud load balancer |
| `NodePort` | Node-level port exposure |
</Accordion>
<Accordion title="Configuration persistence">
Use `configPersistence` when Newt needs writable configuration storage.
```yaml
newtInstances:
- name: main-tunnel
configPersistence:
enabled: false
type: emptyDir
mountPath: /var/lib/newt
fileName: config.json
existingClaim: ""
```
Storage types:
| Type | Behavior |
| ----------------------- | ----------------------------------------- |
| `emptyDir` | Ephemeral storage, recreated with the pod |
| `persistentVolumeClaim` | Durable storage using an existing PVC |
Provisioning-based installs should enable config persistence. For production provisioning, prefer a PVC over `emptyDir`.
<Warning>
`emptyDir` is recreated when a pod is replaced. Newt can require a reconnect and handshake after restart, which may briefly interrupt active traffic.
</Warning>
<Tip>
For production, prefer an existing PersistentVolumeClaim to keep writable Newt configuration across restarts and rescheduling.
</Tip>
</Accordion>
<Accordion title="Blueprints, mTLS, and scripts">
The chart supports blueprints, provisioning blueprints, mTLS certificate mounts, Docker socket mounts, and up/down scripts.
Blueprint example:
```yaml
newtInstances:
- name: main-tunnel
blueprintFile: /etc/newt/blueprint.yaml
blueprintData: |
version: 1
routes: []
```
Provisioning blueprint example:
```yaml
newtInstances:
- name: main-tunnel
provisioningBlueprintFile: /etc/newt/provisioning-blueprint.yaml
provisioningBlueprintData: |
version: 1
routes: []
```
mTLS using an existing PEM Secret:
```yaml
newtInstances:
- name: main-tunnel
mtls:
enabled: true
mode: pem
pem:
secretName: newt-mtls
clientCertPath: /certs/client.crt
clientKeyPath: /certs/client.key
caPath: /certs/ca.crt
```
Up/down scripts:
```yaml
global:
updownScripts:
route.sh: |
#!/bin/sh
echo "Newt interface changed"
newtInstances:
- name: main-tunnel
updown:
enabled: true
mountPath: /opt/newt/updown
```
<Note>
Use Secrets for certificates and sensitive script inputs. Avoid inline private keys or credentials in values files.
</Note>
</Accordion>
<Accordion title="Service accounts and RBAC">
ServiceAccount creation is enabled by default.
```yaml
serviceAccount:
create: true
name: ""
automountServiceAccountToken: false
```
RBAC is disabled by default in chart `1.4.0`:
```yaml
rbac:
create: false
clusterRole: false
```
Enable RBAC only when your selected configuration needs Kubernetes API permissions:
```yaml
rbac:
create: true
clusterRole: false
```
Per-instance ServiceAccount overrides are available when `allowGlobalOverride: true` is set:
```yaml
newtInstances:
- name: main-tunnel
allowGlobalOverride: true
serviceAccount:
create: true
name: newt-main-tunnel
automountServiceAccountToken: false
```
<Warning>
Chart `1.4.0` changed the RBAC default to `rbac.create=false`. Existing installations that relied on auto-created RBAC must opt in explicitly during upgrade.
</Warning>
</Accordion>
<Accordion title="Resources and scheduling">
Global resource requests and limits apply to Newt workloads.
```yaml
global:
resources:
requests:
cpu: 100m
memory: 128Mi
ephemeral-storage: 128Mi
limits:
cpu: 200m
memory: 256Mi
ephemeral-storage: 256Mi
```
Scheduling defaults:
```yaml
global:
priorityClassName: ""
nodeSelector: {}
tolerations: []
affinity:
nodeAffinity: {}
podAffinity: {}
podAntiAffinity: {}
topologySpreadConstraints: []
```
Pod Disruption Budget:
```yaml
global:
podDisruptionBudget:
enabled: false
minAvailable: 1
maxUnavailable: ""
```
Recommendations:
- Start with the chart defaults.
- Increase requests and limits based on traffic volume.
- Use node selectors, tolerations, affinity, or topology spread constraints when you need placement control.
- Enable a PodDisruptionBudget only when your replica count and maintenance policy support it.
<Warning>
Avoid CPU limits unless you explicitly need hard caps. CPU limits can trigger throttling even when spare node CPU exists. For most deployments, use CPU requests and memory limits as the starting point.
</Warning>
</Accordion>
<Accordion title="Health probes and Helm tests">
Health probes are disabled by default.
```yaml
global:
health:
enabled: false
path: /tmp/healthy
readinessFailureThreshold: 3
```
Per-instance health options:
```yaml
newtInstances:
- name: main-tunnel
healthFile: /tmp/healthy
enforceHcCert: false
```
Helm test jobs are disabled by default:
```yaml
global:
tests:
enabled: false
image:
repository: registry.k8s.io/kubectl
tag: "1.30.14"
pullPolicy: IfNotPresent
```
Enable tests only when you want chart test jobs and tester-port related resources.
</Accordion>
<Accordion title="Metrics and monitoring">
Metrics are disabled by default.
```yaml
global:
metrics:
enabled: false
port: 9090
path: /metrics
adminAddr: ":2112"
asyncBytes: false
region: ""
otlpEnabled: false
pprofEnabled: false
```
The default `adminAddr` is `:2112`, which listens on all interfaces and allows in-cluster scraping. Use `127.0.0.1:2112` only when scraping from other pods is not required.
Metrics Service:
```yaml
global:
metrics:
service:
enabled: false
type: ClusterIP
port: 2112
portName: metrics
```
Prometheus Operator resources:
```yaml
global:
metrics:
podMonitor:
enabled: false
serviceMonitor:
enabled: false
prometheusRule:
enabled: false
```
Example with ServiceMonitor:
```yaml
global:
metrics:
enabled: true
service:
enabled: true
serviceMonitor:
enabled: true
```
Optional pprof endpoint:
```yaml
global:
metrics:
pprofEnabled: true
```
</Accordion>
<Accordion title="Network policy">
NetworkPolicy rendering is disabled by default.
```yaml
global:
networkPolicy:
enabled: false
defaultMode: merge
components:
defaultApp:
enabled: true
dns:
enabled: false
kubeApi:
enabled: false
custom:
enabled: false
ruleSets: {}
```
Per-instance NetworkPolicy overrides:
```yaml
newtInstances:
- name: main-tunnel
networkPolicy:
enabled: null
mode: merge
useGlobalComponents:
defaultApp: true
dns: false
kubeApi: false
custom: true
components:
dns:
enabled: false
custom:
enabled: false
includeRuleSets: []
```
Modes:
| Mode | Behavior |
| --------- | ------------------------------------------------- |
| `inherit` | Use global components and rule sets only |
| `merge` | Combine global and instance-level policy settings |
| `replace` | Use only the instance-level policy settings |
Enable DNS egress rules if your default network policy blocks DNS.
</Accordion>
</AccordionGroup>
## Configuration by install method
### Helm
Use a values file:
```bash
helm upgrade --install newt fossorial/newt \
--namespace pangolin \
--values values-newt.yaml
```
Use inline values only for small tests:
```bash
helm upgrade --install newt fossorial/newt \
--namespace pangolin \
--set 'newtInstances[0].name=main-tunnel' \
--set 'newtInstances[0].auth.existingSecretName=newt-auth'
```
See [Site (newt) Helm](/self-host/manual/kubernetes/newt/helm) for the installation flow.
### Kustomize
Render the chart with Helm, then use Kustomize overlays:
```bash
helm template newt fossorial/newt \
--namespace pangolin \
--values values-newt.yaml \
> base/newt.yaml
```
Then apply an overlay:
```bash
kubectl apply -k overlays/site-a
```
See [Newt Kustomize](/self-host/manual/kubernetes/newt/kustomize) for the Kustomize workflow.
### GitOps
Store Helm values or Kustomize overlays in Git. Argo CD or Flux reconciles the desired state.
Argo CD Helm example:
```yaml
spec:
source:
helm:
values: |
newtInstances:
- name: main-tunnel
enabled: true
auth:
existingSecretName: newt-auth
```
Flux HelmRelease example:
```yaml
spec:
values:
newtInstances:
- name: main-tunnel
enabled: true
auth:
existingSecretName: newt-auth
```
See [GitOps](/self-host/manual/kubernetes/gitops/overview) for GitOps guidance.
## Next steps
<CardGroup cols={2}>
<Card title="Helm Install" href="/self-host/manual/kubernetes/newt/helm" icon="box">
Install Newt with Helm.
</Card>
<Card title="Kustomize Install" href="/self-host/manual/kubernetes/newt/kustomize" icon="layer-group">
Install Newt with rendered manifests and Kustomize overlays.
</Card>
<Card title="Troubleshooting" href="/self-host/manual/kubernetes/newt/troubleshooting" icon="circle-question">
Debug Newt deployment and connection issues.
</Card>
<Card title="GitOps" href="/self-host/manual/kubernetes/gitops/overview" icon="code-branch">
Deploy Newt with Argo CD or Flux.
</Card>
</CardGroup>
-410
View File
@@ -1,410 +0,0 @@
---
title: "Helm"
description: "Quick-start guide for installing Site (newt) on Kubernetes using Helm."
---
This guide installs and manages Site (newt) in Kubernetes using Helm.
See [Version Matrix](https://github.com/fosrl/helm-charts/VERSION_MATRIX.md) for chart and default app version references.
## What the chart supports
The Newt chart can deploy one or more Newt instances through `newtInstances[]`.
Newt chart `1.4.0` includes support for:
- provisioning with `NEWT_PROVISIONING_KEY` and `NEWT_NAME`
- legacy credential installs with `NEWT_ID` and `NEWT_SECRET`
- existing Kubernetes Secrets for production credentials
- writable config persistence with `emptyDir` or an existing PVC
- optional metrics, PodMonitor, ServiceMonitor, and PrometheusRule
- optional NetworkPolicy
- multi-instance deployments with per-instance overrides
The chart README lists these features for version `1.4.0`.
## Prerequisites
Before installing Newt, you need:
- Kubernetes `1.30.14` or newer
- Helm 3.x
- `kubectl` access to the target cluster
- a reachable Pangolin instance
- either:
- Newt credentials from Pangolin: `NEWT_ID` and `NEWT_SECRET`
- or a provisioning key for provisioning installs
The chart quickstart lists Kubernetes `>=1.30.14`, Helm 3.x, configured `kubectl`, and Newt credentials from Pangolin as prerequisites.
See [Prerequisites](/self-host/manual/kubernetes/prerequisites) for cluster, namespace, storage, networking, and security planning.
## Authentication options
Newt chart `1.4.0` supports three credential patterns:
| Method | Recommended for | Notes |
| --- | --- | --- |
| Existing Secret | Production | Credentials are stored in a Kubernetes Secret created outside Helm |
| Provisioning key | Provisioning installs | Requires writable config persistence |
| Inline values | Local testing only | Credentials may be stored in Helm release history |
For production, use `auth.existingSecretName` or a GitOps-safe secret workflow. The chart values explicitly warn that inline credentials can be stored in Helm release history and recommend existing Secrets for production.
## Quick install with existing Secret
This is the recommended simple production pattern.
### Step 1: Create the namespace
Create the namespace before installing the chart:
```bash
kubectl create namespace pangolin
```
If your cluster uses Pod Security Admission labels, namespace labels, or policy annotations, apply them before installing Newt.
Example:
```bash
kubectl label namespace pangolin \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
```
<Note>
The chart can create namespaces through `namespace.create`, but creating the namespace explicitly is recommended when your cluster uses Pod Security Admission, namespace labels, or policy annotations.
</Note>
### Step 2: Create the Newt Secret
Create a Secret with the credentials from Pangolin:
```bash
kubectl create secret generic newt-auth \
--namespace pangolin \
--from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
--from-literal=NEWT_ID=<your-newt-id> \
--from-literal=NEWT_SECRET=<your-newt-secret>
```
<Tip>
Get the Newt credentials from the Pangolin dashboard for the site you want this Newt instance to connect to.
</Tip>
### Step 3: Create a values file
Create `values-newt.yaml`:
```yaml
newtInstances:
- name: main-tunnel
enabled: true
auth:
existingSecretName: newt-auth
replicas: 1
```
The default Secret keys are:
```yaml
PANGOLIN_ENDPOINT
NEWT_ID
NEWT_SECRET
```
You only need to set `auth.keys.*` if your Secret uses different key names.
Example with custom Secret keys:
```yaml
newtInstances:
- name: main-tunnel
enabled: true
auth:
existingSecretName: newt-auth
keys:
endpointKey: PANGOLIN_ENDPOINT
idKey: NEWT_ID
secretKey: NEWT_SECRET
replicas: 1
```
`auth.keys.*` are key names inside the Kubernetes Secret, not the credential values themselves. ([GitHub][2])
### Step 4: Install Newt
Add the Helm repository:
```bash
helm repo add fossorial https://charts.fossorial.io
helm repo update fossorial
```
Install Newt:
```bash
helm upgrade --install newt fossorial/newt \
--namespace pangolin \
--values values-newt.yaml
```
Do not use `--create-namespace` here if you created and labeled the namespace manually.
### Step 5: Verify the deployment
Check the Helm release:
```bash
helm status newt --namespace pangolin
```
Check the pods:
```bash
kubectl get pods --namespace pangolin \
-l app.kubernetes.io/name=newt
```
Check the logs:
```bash
kubectl logs --namespace pangolin \
-l app.kubernetes.io/name=newt \
--tail=50
```
Wait for the Newt pod to become ready:
```bash
kubectl wait --for=condition=ready pod \
-l app.kubernetes.io/name=newt \
--namespace pangolin \
--timeout=60s
```
## Quick install with provisioning key
Provisioning-based installs bootstrap credentials from a provisioning key.
Provisioning requires writable config persistence so Newt can store the generated configuration. The chart quickstart explicitly notes that provisioning requires a writable `CONFIG_FILE` target and that the chart provides this through `newtInstances[x].configPersistence`. ([GitHub][3])
Create `values-newt.yaml`:
```yaml
newtInstances:
- name: main-tunnel
enabled: true
pangolinEndpoint: https://pangolin.example.com
provisioningKey: "<your-provisioning-key>"
newtName: "my-site"
configPersistence:
enabled: true
type: emptyDir
mountPath: /var/lib/newt
fileName: config.json
```
Install Newt:
```bash
helm upgrade --install newt fossorial/newt \
--namespace pangolin \
--values values-newt.yaml
```
<Note>
`emptyDir` is enough for testing, but it is ephemeral. For durable provisioning state, use `type: persistentVolumeClaim` with an existing PVC.
</Note>
Example with an existing PVC:
```yaml
newtInstances:
- name: main-tunnel
enabled: true
pangolinEndpoint: https://pangolin.example.com
provisioningKey: "<your-provisioning-key>"
newtName: "my-site"
configPersistence:
enabled: true
type: persistentVolumeClaim
existingClaim: my-newt-config
mountPath: /var/lib/newt
fileName: config.json
```
The Newt README includes both `emptyDir` and existing PVC provisioning examples. ([GitHub][4])
## Verifying connectivity
Follow the Newt logs:
```bash
kubectl logs --namespace pangolin \
-l app.kubernetes.io/name=newt \
--follow
```
In the Pangolin dashboard, verify that the site connected by this Newt instance is online.
If the pod is running but the site does not connect, check:
* `PANGOLIN_ENDPOINT`
* Newt credentials or provisioning key
* DNS resolution from inside the cluster
* outbound network access from the Newt pod
* TLS validity for the Pangolin endpoint
## Upgrade
Update the Helm repository:
```bash
helm repo update fossorial
```
Upgrade the release:
```bash
helm upgrade newt fossorial/newt \
--namespace pangolin \
--values values-newt.yaml
```
Check upgrade status:
```bash
helm status newt --namespace pangolin
helm history newt --namespace pangolin
```
Rollback to a previous revision if needed:
```bash
helm rollback newt <revision> --namespace pangolin
```
## Multiple Newt instances
You can deploy multiple Newt instances with one chart release.
Example:
```yaml
newtInstances:
- name: site-a
enabled: true
auth:
existingSecretName: newt-auth-site-a
replicas: 1
- name: site-b
enabled: true
auth:
existingSecretName: newt-auth-site-b
replicas: 1
```
Create a separate Secret for each site:
```bash
kubectl create secret generic newt-auth-site-a \
--namespace pangolin \
--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 pangolin \
--from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
--from-literal=NEWT_ID=<site-b-newt-id> \
--from-literal=NEWT_SECRET=<site-b-newt-secret>
```
## Architecture notes
### Instance-based deployment
* `newtInstances[]` defines the Newt instances rendered by the chart.
* Each enabled instance creates its own workload.
* Each instance can use its own Secret, provisioning settings, resources, service settings, and network policy settings.
* Per-instance namespace and service account overrides require `allowGlobalOverride: true`.
The chart values include `newtInstances[]`, per-instance namespace settings, and per-instance service account overrides. ([GitHub][2])
### RBAC
Newt chart `1.4.0` defaults `rbac.create` to `false`. Enable RBAC only when your selected Newt configuration requires Kubernetes API permissions.
```yaml
rbac:
create: true
```
The chart changelog for `1.4.0` marks this as a breaking change: installations that relied on auto-created RBAC must explicitly enable `rbac.create=true` during upgrade. ([GitHub][1])
### Helm tests
Helm test Jobs are disabled by default.
Enable them only when you want to run chart test jobs:
```yaml
global:
tests:
enabled: true
```
The chart quickstart notes that test Jobs are gated behind `global.tests.enabled`, which defaults to `false`. ([GitHub][3])
## OCI install
The Newt chart is also published as an OCI chart in GHCR.
Pull the chart:
```bash
helm pull oci://ghcr.io/fosrl/helm-charts/newt \
--version 1.4.0
```
Install from OCI:
```bash
helm upgrade --install newt oci://ghcr.io/fosrl/helm-charts/newt \
--version 1.4.0 \
--namespace pangolin \
--values values-newt.yaml
```
OCI changes where Helm pulls the chart from. It does not change the values file or the release behavior.
## References
<CardGroup cols={2}>
<Card title="Chart README" href="https://github.com/fosrl/helm-charts/blob/main/charts/newt/README.md" icon="book" />
<Card title="values.yaml" href="https://github.com/fosrl/helm-charts/blob/main/charts/newt/values.yaml" icon="file-code" />
<Card title="values.schema.json" href="https://github.com/fosrl/helm-charts/blob/main/charts/newt/values.schema.json" icon="file-code" />
<Card title="Artifact Hub" href="https://artifacthub.io/packages/helm/fosrl/newt" icon="box" />
<Card title="Issues" href="https://github.com/fosrl/helm-charts/issues" icon="circle-question" />
</CardGroup>
## Next steps
<CardGroup cols={2}>
<Card title="Full Configuration" href="/self-host/manual/kubernetes/newt/configuration" icon="sliders">
Review all Newt chart options.
</Card>
<Card title="Troubleshooting" href="/self-host/manual/kubernetes/newt/troubleshooting" icon="circle-question">
Debug Newt deployment and connection issues.
</Card>
<Card title="Kustomize Install" href="/self-host/manual/kubernetes/newt/kustomize" icon="layer-group">
Install Newt with rendered manifests and Kustomize overlays.
</Card>
<Card title="Pangolin Helm" href="/self-host/manual/kubernetes/pangolin/helm" icon="server">
Install the Pangolin control plane.
</Card>
</CardGroup>
@@ -1,610 +0,0 @@
---
title: "Kustomize"
description: "Deploy Newt on Kubernetes using Helm-rendered manifests and Kustomize overlays."
---Use Kustomize when you want to manage Newt with rendered manifests, environment-specific overlays, and explicit patches in Git.
For Newt, the supported Kustomize workflow is:
1. Render the Newt Helm chart to manifests.
2. Use the rendered output as the Kustomize base.
3. Create overlays per site, cluster, or environment.
4. Apply the overlay with `kubectl apply -k` or reconcile it with Argo CD or Flux.
## When to use Kustomize for Newt
Use Kustomize if you:
- want site-specific or environment-specific overlays
- need explicit patches committed to Git
- prefer reviewing rendered Kubernetes manifests before applying them
- use Argo CD or Flux with Kustomize sources
- want to customize Helm-rendered output without forking the chart
For a simpler single-site setup, use [Newt Helm](/self-host/manual/kubernetes/newt/helm).
## Supported approach
The Newt chart does not provide native Kustomize bases. Render the Helm chart first, then use Kustomize on the rendered manifests.
<Warning>
Do not manage the same Newt resources with both a live Helm release and Kustomize. Pick one ownership model per environment.
</Warning>
Recommended ownership model:
- Use Helm only to render the Newt chart.
- Use Kustomize, Argo CD, or Flux to apply and reconcile the rendered manifests.
- Re-render the base when upgrading the chart or changing Helm values.
## Example directory structure
```text
newt-deployment/
├── base/
│ ├── kustomization.yaml
│ └── newt.yaml
├── overlays/
│ ├── site-a/
│ │ ├── kustomization.yaml
│ │ └── patches/
│ │ └── deployment-resources.patch.yaml
│ └── site-b/
│ ├── kustomization.yaml
│ └── patches/
│ └── deployment-resources.patch.yaml
└── values/
├── values-base.yaml
├── values-site-a.yaml
└── values-site-b.yaml
```
## Step 1: Create the namespace
Create the namespace before applying rendered manifests:
```bash
kubectl create namespace pangolin
```
If your cluster uses Pod Security Admission, namespace labels, or other policy labels, apply them before creating workloads.
Example:
```bash
kubectl label namespace pangolin \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
```
## Step 2: Create Newt credentials
Create a Kubernetes Secret for each Newt site or instance.
```bash
kubectl create secret generic newt-auth-site-a \
--namespace pangolin \
--from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
--from-literal=NEWT_ID=<site-a-newt-id> \
--from-literal=NEWT_SECRET=<site-a-newt-secret>
```
For a second site:
```bash
kubectl create secret generic newt-auth-site-b \
--namespace pangolin \
--from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
--from-literal=NEWT_ID=<site-b-newt-id> \
--from-literal=NEWT_SECRET=<site-b-newt-secret>
```
<Note>
Use existing Kubernetes Secrets for production. Do not commit Newt credentials into Helm values, rendered manifests, or Kustomize patches.
</Note>
## Step 3: Create base values
Create `values/values-base.yaml`:
```yaml
newtInstances:
- name: main-tunnel
enabled: true
replicas: 1
auth:
existingSecretName: newt-auth-site-a
```
This values file uses an existing Secret. The default Secret keys are:
```text
PANGOLIN_ENDPOINT
NEWT_ID
NEWT_SECRET
```
Use `auth.keys.*` only when your Secret uses different key names.
## Step 4: Render Newt to the base
Add and update the Helm repository:
```bash
helm repo add fossorial https://charts.fossorial.io
helm repo update fossorial
```
Render the Newt chart:
```bash
mkdir -p base overlays/site-a/patches overlays/site-b/patches values
helm template newt fossorial/newt \
--namespace pangolin \
--values values/values-base.yaml \
> base/newt.yaml
```
You can also render from the GHCR OCI chart:
```bash
helm template newt oci://ghcr.io/fosrl/helm-charts/newt \
--version 1.4.0 \
--namespace pangolin \
--values values/values-base.yaml \
> base/newt.yaml
```
## Step 5: Create the base kustomization
```yaml
# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- newt.yaml
```
<Note>
The namespace is already rendered by Helm through `--namespace pangolin`. You can also set `namespace: pangolin` in Kustomize, but avoid changing namespaces in overlays unless you have verified all rendered resources and references.
</Note>
## Step 6: Inspect the rendered resource names
Before writing patches, check the generated names:
```bash
kustomize build base | grep -E "^(kind:| name:)"
```
Or list the deployments:
```bash
kustomize build base | yq '. | select(.kind == "Deployment") | .metadata.name'
```
Use the actual rendered Deployment name in your patch targets.
<Warning>
Do not assume the rendered Deployment name without checking the generated manifests. Helm naming can change with release name, chart name, `nameOverride`, or `fullnameOverride`.
</Warning>
## Step 7: Create site-specific overlays
Example overlay for Site A:
```yaml
# overlays/site-a/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
labels:
- pairs:
app.kubernetes.io/site: site-a
app.kubernetes.io/environment: production
patches:
- path: patches/deployment-resources.patch.yaml
target:
group: apps
version: v1
kind: Deployment
name: newt-main-tunnel
```
Example resource patch:
```yaml
# overlays/site-a/patches/deployment-resources.patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: newt-main-tunnel
spec:
replicas: 1
template:
spec:
containers:
- name: newt
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
```
<Note>
Replace `newt-main-tunnel` with the actual Deployment name from your rendered manifests.
</Note>
Example overlay for Site B with a different Secret is usually better handled by rendering a second base with a different values file.
Create `values/values-site-b.yaml`:
```yaml
newtInstances:
- name: main-tunnel
enabled: true
replicas: 1
auth:
existingSecretName: newt-auth-site-b
```
Then render a separate base for Site B:
```bash
mkdir -p site-b/base
helm template newt-site-b fossorial/newt \
--namespace pangolin \
--values values/values-site-b.yaml \
> site-b/base/newt.yaml
```
<Info>
For different credentials, endpoints, provisioning keys, or instance names, prefer separate Helm-rendered bases. Use Kustomize patches for environment-level changes such as labels, annotations, resources, scheduling, or NetworkPolicy adjustments.
</Info>
## Common Kustomize patches for Newt
### Patch resource requests and limits
```yaml
# overlays/site-a/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- path: patches/resources.patch.yaml
target:
group: apps
version: v1
kind: Deployment
name: newt-main-tunnel
```
```yaml
# overlays/site-a/patches/resources.patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: newt-main-tunnel
spec:
template:
spec:
containers:
- name: newt
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
memory: 512Mi
```
### Patch log level
Prefer configuring log level through Helm values before rendering. If you still need a manifest patch, patch the generated environment variable carefully after inspecting the rendered Deployment.
Example JSON6902-style patch:
```yaml
# overlays/site-a/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- target:
group: apps
version: v1
kind: Deployment
name: newt-main-tunnel
patch: |-
- op: add
path: /spec/template/spec/containers/0/env/-
value:
name: LOG_LEVEL
value: DEBUG
```
<Warning>
Only use index-based JSON patches after checking the rendered manifest. Container order and environment variable layout can change between chart versions.
</Warning>
### Add node affinity
```yaml
# overlays/site-a/patches/node-affinity.patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: newt-main-tunnel
spec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: site
operator: In
values:
- site-a
```
Reference the patch:
```yaml
# overlays/site-a/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- path: patches/node-affinity.patch.yaml
target:
group: apps
version: v1
kind: Deployment
name: newt-main-tunnel
```
### Add annotations
```yaml
# overlays/site-a/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- target:
group: apps
version: v1
kind: Deployment
name: newt-main-tunnel
patch: |-
- op: add
path: /metadata/annotations
value:
example.com/owner: platform
```
## Do not rename rendered Helm resources by default
Avoid Kustomize options such as `namePrefix` and `nameSuffix` for Helm-rendered bases unless you have validated every generated reference.
Renaming rendered resources can break:
* Service selectors
* Secret references
* ConfigMap references
* ServiceAccount references
* NetworkPolicy selectors
* Prometheus monitor selectors
If you need different resource names, prefer changing the Helm release name or chart naming values before rendering.
## Apply the overlay
Preview the rendered output:
```bash
kustomize build overlays/site-a
```
Compare with the live cluster:
```bash
kustomize build overlays/site-a | kubectl diff -f -
```
Apply the overlay:
```bash
kubectl apply -k overlays/site-a
```
Verify the deployment:
```bash
kubectl get pods --namespace pangolin \
-l app.kubernetes.io/name=newt
kubectl logs --namespace pangolin \
-l app.kubernetes.io/name=newt \
--tail=50
```
## Updating the rendered base
When upgrading the Newt chart, re-render the base and review the changes.
```bash
helm repo update fossorial
```
Render the updated chart output:
```bash
helm template newt fossorial/newt \
--namespace pangolin \
--values values/values-base.yaml \
> base/newt.yaml
```
Or with OCI:
```bash
helm template newt oci://ghcr.io/fosrl/helm-charts/newt \
--version 1.4.0 \
--namespace pangolin \
--values values/values-base.yaml \
> base/newt.yaml
```
Validate the overlay:
```bash
kustomize build overlays/site-a
```
Review the diff:
```bash
git diff
kustomize build overlays/site-a | kubectl diff -f -
```
Commit the updated base and overlays:
```bash
git add base/ overlays/ values/
git commit -m "Update Newt rendered manifests"
```
Apply after review:
```bash
kubectl apply -k overlays/site-a
```
## Ownership model
Do not run `helm upgrade` against a release that is managed by Kustomize.
Avoid this pattern:
```bash
helm upgrade newt fossorial/newt --namespace pangolin
kubectl apply -k overlays/site-a
```
Use one of these models instead:
| Model | Description |
| ----------------- | ------------------------------------------------------------------------------------------ |
| Helm-managed | Helm installs and upgrades the live release. Kustomize is not used for the same resources. |
| Kustomize-managed | Helm renders manifests only. Kustomize applies and owns the live resources. |
| GitOps-managed | Argo CD or Flux applies the Kustomize overlay and owns reconciliation. |
## Validation
Validate Kustomize output:
```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 -
```
Check live resources:
```bash
kubectl get all --namespace pangolin
kubectl get events --namespace pangolin --sort-by=.lastTimestamp
```
## Troubleshooting
### The patch does not apply
Check the rendered resource name and kind:
```bash
kustomize build base | grep -E "^(kind:| name:)"
```
Then verify the patch target in your overlay.
### The pod does not start
Check pod status and events:
```bash
kubectl get pods --namespace pangolin
kubectl describe pod <pod-name> --namespace pangolin
kubectl get events --namespace pangolin --sort-by=.lastTimestamp
```
### Newt does not connect
Check logs:
```bash
kubectl logs --namespace pangolin \
-l app.kubernetes.io/name=newt \
--tail=100
```
Verify:
* the Secret exists in the same namespace
* `PANGOLIN_ENDPOINT` is reachable from the pod
* `NEWT_ID` and `NEWT_SECRET` are correct
* outbound DNS and HTTPS are allowed
* TLS certificates for the Pangolin endpoint are valid
## Next steps
<CardGroup cols={2}>
<Card title="Helm Install" href="/self-host/manual/kubernetes/newt/helm" icon="box">
Install Newt with Helm.
</Card>
<Card title="Configuration" href="/self-host/manual/kubernetes/newt/configuration" icon="sliders">
Review Newt chart options.
</Card>
<Card title="Troubleshooting" href="/self-host/manual/kubernetes/newt/troubleshooting" icon="circle-question">
Debug Newt deployment and connection issues.
</Card>
<Card title="GitOps" href="/self-host/manual/kubernetes/gitops/overview" icon="code-branch">
Deploy Kustomize overlays with Argo CD or Flux.
</Card>
</CardGroup>
@@ -1,700 +0,0 @@
---
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="/self-host/manual/kubernetes/newt/configuration" icon="sliders">
Review Newt chart options.
</Card>
<Card title="Helm Install" href="/self-host/manual/kubernetes/newt/helm" icon="box">
Install Newt with Helm.
</Card>
<Card title="Kustomize Install" href="/self-host/manual/kubernetes/newt/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>
+3 -3
View File
@@ -67,13 +67,13 @@ flowchart LR
<Card title="Pangolin Troubleshooting" href="/self-host/manual/kubernetes/pangolin/troubleshooting" icon="circle-question">
Diagnose and resolve Pangolin deployment issues.
</Card>
<Card title="Site (Newt) Helm" href="/self-host/manual/kubernetes/newt/helm" icon="server">
<Card title="Site (Newt) Helm" href="/manage/sites/kubernetes/helm" icon="server">
Install a Site connector with the Newt Helm chart.
</Card>
<Card title="Site (Newt) Configuration" href="/self-host/manual/kubernetes/newt/configuration" icon="sliders">
<Card title="Site (Newt) Configuration" href="/manage/sites/kubernetes/configuration" icon="sliders">
Configure Site connector credentials and runtime settings.
</Card>
<Card title="Site (Newt) Troubleshooting" href="/self-host/manual/kubernetes/newt/troubleshooting" icon="circle-question">
<Card title="Site (Newt) Troubleshooting" href="/manage/sites/kubernetes/troubleshooting" icon="circle-question">
Diagnose and resolve Site connector deployment issues.
</Card>
</CardGroup>