- imagePullPolicy: Always so :latest actually tracks upstream (nodes were running two different cached digests) - --retries 1: supervisor retries forever; this caps the jittered backoff at ~2s instead of the exponential 1..32s ramp - liveness failureThreshold 30: let cloudflared's own fast retry loop reconnect instead of killing pods into exponential CrashLoopBackOff (pods had 300+ restarts) - maxSurge 0 / maxUnavailable 1: required anti-affinity on 3 workers deadlocked surge-based rollouts - securityContext for restricted:latest PodSecurity (nonroot 65532, drop ALL caps, no privilege escalation, RuntimeDefault seccomp) Co-Authored-By: Claude <noreply@anthropic.com>
84 lines
2.4 KiB
YAML
84 lines
2.4 KiB
YAML
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: cloudflared
|
|
namespace: cloudflared
|
|
spec:
|
|
replicas: 3
|
|
# With required anti-affinity and 3 worker nodes, a surge pod can never
|
|
# schedule — replace in place instead.
|
|
strategy:
|
|
type: RollingUpdate
|
|
rollingUpdate:
|
|
maxSurge: 0
|
|
maxUnavailable: 1
|
|
selector:
|
|
matchLabels:
|
|
app: cloudflared
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: cloudflared
|
|
spec:
|
|
affinity:
|
|
podAntiAffinity:
|
|
requiredDuringSchedulingIgnoredDuringExecution:
|
|
- labelSelector:
|
|
matchLabels:
|
|
app: cloudflared
|
|
topologyKey: kubernetes.io/hostname
|
|
containers:
|
|
- name: cloudflared
|
|
image: cloudflare/cloudflared:latest
|
|
# Always pull so :latest actually tracks upstream instead of a
|
|
# per-node cached digest
|
|
imagePullPolicy: Always
|
|
args:
|
|
- tunnel
|
|
- --no-autoupdate
|
|
- --metrics
|
|
- 0.0.0.0:2000
|
|
# Reconnects retry forever; --retries caps the backoff interval
|
|
# (1s * 2^retries, jittered). 1 = retry every ~2s max, no
|
|
# exponential growth.
|
|
- --retries
|
|
- "1"
|
|
- run
|
|
env:
|
|
- name: TUNNEL_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: tunnel-token
|
|
key: token
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 65532
|
|
allowPrivilegeEscalation: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
ports:
|
|
- name: metrics
|
|
containerPort: 2000
|
|
protocol: TCP
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /ready
|
|
port: 2000
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
# Tolerate long edge outages: let cloudflared's own fast retry
|
|
# loop reconnect instead of killing the pod into CrashLoopBackOff
|
|
# (which backs off exponentially up to 5m).
|
|
failureThreshold: 30
|
|
resources:
|
|
requests:
|
|
memory: "64Mi"
|
|
cpu: "50m"
|
|
limits:
|
|
memory: "256Mi"
|
|
cpu: "200m"
|
|
restartPolicy: Always
|