mirror of
https://github.com/fosrl/docs-v2.git
synced 2026-09-22 13:59:08 +02:00
Move the k8s docs under the site
This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user