298c960808
- Use typed context key for auth context to prevent collisions (auth.go) - Eliminate nested locking in CheckRateLimit to prevent potential deadlock (auth.go) - Add 1MB request body size limit middleware to prevent DoS (router.go) - Return proper gRPC status codes instead of nil errors on failures (handler.go) - Use key name instead of raw API key in admin URL paths to prevent secret leakage (keys.go, router.go, keystore_db.go, keystore_hybrid.go) - Enforce RBAC authorization in service Send/SendBatch for both REST and gRPC (service.go) - Pin runtime Docker image to alpine:3.21 for reproducible builds (Dockerfile) - Enable readOnlyRootFilesystem with /tmp emptyDir in k8s deployment (deployment.yaml) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
207 lines
5.3 KiB
YAML
207 lines
5.3 KiB
YAML
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: notifier
|
|
labels:
|
|
app: notifier
|
|
version: v1
|
|
spec:
|
|
replicas: 3
|
|
selector:
|
|
matchLabels:
|
|
app: notifier
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: notifier
|
|
version: v1
|
|
spec:
|
|
serviceAccountName: notifier
|
|
containers:
|
|
- name: notifier
|
|
image: notifier:latest
|
|
imagePullPolicy: Always
|
|
ports:
|
|
- name: rest
|
|
containerPort: 8080
|
|
protocol: TCP
|
|
- name: grpc
|
|
containerPort: 50051
|
|
protocol: TCP
|
|
- name: metrics
|
|
containerPort: 9090
|
|
protocol: TCP
|
|
- name: health
|
|
containerPort: 8081
|
|
protocol: TCP
|
|
env:
|
|
- name: NOTIFIER_SERVER_MODE
|
|
value: "both"
|
|
- name: NOTIFIER_LOGGING_LEVEL
|
|
value: "info"
|
|
- name: NOTIFIER_LOGGING_FORMAT
|
|
value: "json"
|
|
- name: NOTIFIER_QUEUE_TYPE
|
|
value: "local"
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /app/config.yaml
|
|
subPath: config.yaml
|
|
readOnly: true
|
|
- name: queue-storage
|
|
mountPath: /var/lib/notifier
|
|
- name: tmp
|
|
mountPath: /tmp
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 128Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 512Mi
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: health
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: health
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 5
|
|
timeoutSeconds: 3
|
|
failureThreshold: 3
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1000
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
volumes:
|
|
- name: config
|
|
configMap:
|
|
name: notifier-config
|
|
- name: queue-storage
|
|
emptyDir: {}
|
|
- name: tmp
|
|
emptyDir: {}
|
|
restartPolicy: Always
|
|
---
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: notifier
|
|
labels:
|
|
app: notifier
|
|
---
|
|
# Example deployment with API key authentication and Kubernetes bootstrap enabled
|
|
# Uncomment and apply this deployment instead of the one above to enable auth
|
|
#
|
|
# apiVersion: apps/v1
|
|
# kind: Deployment
|
|
# metadata:
|
|
# name: notifier-with-auth
|
|
# labels:
|
|
# app: notifier
|
|
# version: v1
|
|
# spec:
|
|
# replicas: 3
|
|
# selector:
|
|
# matchLabels:
|
|
# app: notifier
|
|
# template:
|
|
# metadata:
|
|
# labels:
|
|
# app: notifier
|
|
# version: v1
|
|
# spec:
|
|
# serviceAccountName: notifier
|
|
# containers:
|
|
# - name: notifier
|
|
# image: notifier:latest
|
|
# imagePullPolicy: Always
|
|
# ports:
|
|
# - name: rest
|
|
# containerPort: 8080
|
|
# protocol: TCP
|
|
# - name: grpc
|
|
# containerPort: 50051
|
|
# protocol: TCP
|
|
# - name: metrics
|
|
# containerPort: 9090
|
|
# protocol: TCP
|
|
# - name: health
|
|
# containerPort: 8081
|
|
# protocol: TCP
|
|
# env:
|
|
# - name: NOTIFIER_SERVER_MODE
|
|
# value: "both"
|
|
# - name: NOTIFIER_LOGGING_LEVEL
|
|
# value: "info"
|
|
# - name: NOTIFIER_LOGGING_FORMAT
|
|
# value: "json"
|
|
# - name: NOTIFIER_QUEUE_TYPE
|
|
# value: "local"
|
|
# # Optional: set auth config via environment variables instead of config.yaml
|
|
# # - name: NOTIFIER_AUTH_ENABLED
|
|
# # value: "true"
|
|
# # - name: NOTIFIER_AUTH_DEFAULT_RATE_LIMIT
|
|
# # value: "100"
|
|
# # - name: NOTIFIER_AUTH_BOOTSTRAP_ENABLED
|
|
# # value: "true"
|
|
# # - name: NOTIFIER_AUTH_BOOTSTRAP_KUBERNETES_SECRET_NAME
|
|
# # value: "notifier-admin-key"
|
|
# # - name: NOTIFIER_AUTH_BOOTSTRAP_KUBERNETES_SECRET_KEY
|
|
# # value: "admin-key"
|
|
# volumeMounts:
|
|
# - name: config
|
|
# mountPath: /app/config.yaml
|
|
# subPath: config.yaml
|
|
# readOnly: true
|
|
# - name: queue-storage
|
|
# mountPath: /var/lib/notifier
|
|
# resources:
|
|
# requests:
|
|
# cpu: 100m
|
|
# memory: 128Mi
|
|
# limits:
|
|
# cpu: 500m
|
|
# memory: 512Mi
|
|
# livenessProbe:
|
|
# httpGet:
|
|
# path: /health
|
|
# port: health
|
|
# initialDelaySeconds: 30
|
|
# periodSeconds: 10
|
|
# timeoutSeconds: 5
|
|
# failureThreshold: 3
|
|
# readinessProbe:
|
|
# httpGet:
|
|
# path: /health
|
|
# port: health
|
|
# initialDelaySeconds: 10
|
|
# periodSeconds: 5
|
|
# timeoutSeconds: 3
|
|
# failureThreshold: 3
|
|
# securityContext:
|
|
# runAsNonRoot: true
|
|
# runAsUser: 1000
|
|
# allowPrivilegeEscalation: false
|
|
# readOnlyRootFilesystem: false
|
|
# capabilities:
|
|
# drop:
|
|
# - ALL
|
|
# volumes:
|
|
# - name: config
|
|
# configMap:
|
|
# name: notifier-config
|
|
# - name: queue-storage
|
|
# emptyDir: {}
|
|
# restartPolicy: Always
|