Kubernetes Deployment¶
This guide covers deploying the ByteFreezer Proxy in Kubernetes with different networking configurations.
Networking Modes¶
The proxy needs to receive data on specific ports (syslog:514, sFlow:6343, IPFIX:4739, etc.). Kubernetes offers several ways to expose these ports:
| Mode | Port Declaration | Dynamic Ports | Use Case |
|---|---|---|---|
| HostNetwork | Not required | Yes | Recommended for dynamic configs |
| LoadBalancer (MetalLB) | Required in Service | No | Static port allocation |
| NodePort | Required in Service | No | Cloud/bare metal without LB |
| ClusterIP | Required in Service | No | Internal cluster only |
HostNetwork Mode (Recommended)¶
With hostNetwork: true, the pod uses the host's network stack directly. No Service port declaration needed - the proxy binds directly to host ports based on its configuration.
Advantages¶
- Dynamic port allocation from Control
- No Kubernetes manifest changes when adding datasets
- Proxy configuration drives which ports are open
- Simplest for control-only mode
Deployment¶
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: bytefreezer-proxy
namespace: bytefreezer
spec:
selector:
matchLabels:
app: bytefreezer-proxy
template:
metadata:
labels:
app: bytefreezer-proxy
spec:
hostNetwork: true # Use host network - no Service needed for data ports
dnsPolicy: ClusterFirstWithHostNet
containers:
- name: proxy
image: bytefreezer/proxy:latest
securityContext:
capabilities:
add:
- NET_BIND_SERVICE # Allow binding to ports < 1024
volumeMounts:
- name: config
mountPath: /etc/bytefreezer
- name: spool
mountPath: /var/spool/bytefreezer-proxy
- name: cache
mountPath: /var/cache/bytefreezer-proxy
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "1000m"
volumes:
- name: config
configMap:
name: bytefreezer-proxy-config
- name: spool
hostPath:
path: /var/spool/bytefreezer-proxy
type: DirectoryOrCreate
- name: cache
hostPath:
path: /var/cache/bytefreezer-proxy
type: DirectoryOrCreate
ConfigMap¶
apiVersion: v1
kind: ConfigMap
metadata:
name: bytefreezer-proxy-config
namespace: bytefreezer
data:
config.yml: |
app:
name: bytefreezer-proxy
# Control-only mode - proxy receives port configs from Control
config_mode: "control-only"
account_id: "your-account-id"
bearer_token: "your-api-key"
control_url: "https://api.bytefreezer.com"
config_polling:
enabled: true
interval_seconds: 60
receiver:
base_url: "http://your-receiver:8080" # Your Receiver webhook endpoint
batching:
enabled: true
max_bytes: 10485760
timeout_seconds: 60
compression_enabled: true
spooling:
enabled: true
directory: "/var/spool/bytefreezer-proxy"
health_reporting:
enabled: true
report_interval: 30
How It Works¶
- Proxy starts and polls Control:
GET /api/v1/proxy/config?account_id=X&proxy_instance_id=<hostname> - Control returns datasets assigned to this proxy
- Proxy starts listeners on configured ports (e.g., syslog:514, ipfix:4739)
- Ports are immediately available on the host
- No Kubernetes Service or manifest update required
Firewall Configuration¶
Ensure host firewall allows the port range you plan to use:
# Example: Allow common data ports
sudo firewall-cmd --permanent --add-port=514/udp # Syslog
sudo firewall-cmd --permanent --add-port=514/tcp # Syslog TCP
sudo firewall-cmd --permanent --add-port=6343/udp # sFlow
sudo firewall-cmd --permanent --add-port=4739/udp # IPFIX
sudo firewall-cmd --permanent --add-port=2055/udp # NetFlow
sudo firewall-cmd --permanent --add-port=2056/udp # eBPF
sudo firewall-cmd --reload
Or with iptables:
sudo iptables -A INPUT -p udp --dport 514 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 6343 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 4739 -j ACCEPT
LoadBalancer Mode (MetalLB)¶
With LoadBalancer Services, ports must be declared in the Service manifest before deployment. Use this when you need a stable external IP or cannot use hostNetwork.
Limitations¶
- Ports must be pre-declared in Service manifest
- Adding new ports requires Service update and reapply
- Not suitable for dynamic port allocation
Service Definition¶
apiVersion: v1
kind: Service
metadata:
name: bytefreezer-proxy
namespace: bytefreezer
annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.1.100 # Optional: specific IP
spec:
type: LoadBalancer
selector:
app: bytefreezer-proxy
ports:
# Declare ALL ports you need BEFORE deployment
- name: syslog-udp
protocol: UDP
port: 514
targetPort: 514
- name: syslog-tcp
protocol: TCP
port: 514
targetPort: 514
- name: sflow
protocol: UDP
port: 6343
targetPort: 6343
- name: ipfix
protocol: UDP
port: 4739
targetPort: 4739
- name: netflow
protocol: UDP
port: 2055
targetPort: 2055
- name: api
protocol: TCP
port: 8008
targetPort: 8008
Deployment (without hostNetwork)¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: bytefreezer-proxy
namespace: bytefreezer
spec:
replicas: 1
selector:
matchLabels:
app: bytefreezer-proxy
template:
metadata:
labels:
app: bytefreezer-proxy
spec:
containers:
- name: proxy
image: bytefreezer/proxy:latest
ports:
- containerPort: 514
protocol: UDP
- containerPort: 514
protocol: TCP
- containerPort: 6343
protocol: UDP
- containerPort: 4739
protocol: UDP
- containerPort: 2055
protocol: UDP
- containerPort: 8008
protocol: TCP
volumeMounts:
- name: config
mountPath: /etc/bytefreezer
volumes:
- name: config
configMap:
name: bytefreezer-proxy-config
Adding New Ports¶
When you need to add a new data source:
- Update Service manifest with new port
- Update Deployment with new containerPort
- Apply changes:
kubectl apply -f proxy-service.yaml -f proxy-deployment.yaml - Create dataset in Control and assign to proxy
NodePort Mode¶
Similar to LoadBalancer but uses high ports (30000-32767) on every node.
apiVersion: v1
kind: Service
metadata:
name: bytefreezer-proxy
namespace: bytefreezer
spec:
type: NodePort
selector:
app: bytefreezer-proxy
ports:
- name: syslog-udp
protocol: UDP
port: 514
targetPort: 514
nodePort: 30514 # Access via <any-node-ip>:30514
- name: sflow
protocol: UDP
port: 6343
targetPort: 6343
nodePort: 30343
Comparison Summary¶
Use HostNetwork When:¶
- Configuration comes from Control (control-only mode)
- Datasets/ports change frequently
- You want automatic port management
- Running as DaemonSet on dedicated nodes
Use LoadBalancer/NodePort When:¶
- Ports are static and known in advance
- You need a stable external IP (MetalLB)
- Network policies require Service abstraction
- Running multiple replicas behind load balancer
UDP Buffer Tuning¶
For high-throughput UDP sources, tune kernel buffers on the host:
# Increase UDP buffer sizes
sudo sysctl -w net.core.rmem_max=16777216
sudo sysctl -w net.core.rmem_default=8388608
sudo sysctl -w net.core.netdev_max_backlog=50000
# Persist across reboots
cat <<EOF | sudo tee /etc/sysctl.d/99-bytefreezer.conf
net.core.rmem_max=16777216
net.core.rmem_default=8388608
net.core.netdev_max_backlog=50000
EOF
For Kubernetes nodes, apply these settings via DaemonSet init container or node configuration management.
Troubleshooting¶
Port Not Accessible¶
- HostNetwork: Check host firewall, verify proxy is listening (
ss -ulnp | grep <port>) - LoadBalancer: Verify Service has external IP, check port is declared
- Both: Verify dataset is assigned to this proxy in Control
Proxy Not Receiving Data¶
# Check if proxy is listening
kubectl exec -it <proxy-pod> -- ss -ulnp
# Check proxy logs
kubectl logs <proxy-pod> -f
# Verify config from Control
kubectl exec -it <proxy-pod> -- cat /var/cache/bytefreezer-proxy/*.json
UDP Drops¶
If you see "UDP socket drops" in the UI:
- Apply kernel buffer tuning (see above)
- Increase
read_buffer_sizein dataset config - Increase
worker_countfor the plugin - Restart proxy to reset counters
Helm Chart Installation¶
The ByteFreezer Proxy Helm chart simplifies Kubernetes deployment with configurable networking options.
Quick Start with Values File¶
Create proxy-values.yaml:
# Required settings
receiver:
url: "http://your-receiver:8080"
controlService:
url: "https://api.bytefreezer.com"
accountId: "your-account-id"
bearerToken: "your-api-key"
# Network mode: hostNetwork for direct node access
hostNetwork: true
# Pin to specific node (optional)
nodeName: "worker-1"
# UDP configuration
udp:
enabled: true
ports:
- port: 514
name: syslog
- port: 5514
name: syslog-alt
Install:
Network Mode Examples¶
Option 1: HostNetwork (Direct Node Access)
# proxy-hostnetwork.yaml
receiver:
url: "http://your-receiver:8080"
controlService:
url: "https://api.bytefreezer.com"
accountId: "your-account-id"
bearerToken: "your-api-key"
hostNetwork: true
nodeName: "worker-1" # Pin to specific node
udp:
enabled: true
ports:
- port: 514
name: syslog
Option 2: LoadBalancer (MetalLB)
# proxy-loadbalancer.yaml
receiver:
url: "http://your-receiver:8080"
controlService:
url: "https://api.bytefreezer.com"
accountId: "your-account-id"
bearerToken: "your-api-key"
hostNetwork: false
udp:
enabled: true
ports:
- port: 514
name: syslog
service:
type: LoadBalancer
annotations:
metallb.universe.tf/loadBalancerIPs: "192.168.1.100"
Option 3: ClusterIP (Internal Only)
# proxy-internal.yaml
receiver:
url: "http://your-receiver:8080"
controlService:
url: "https://api.bytefreezer.com"
accountId: "your-account-id"
bearerToken: "your-api-key"
hostNetwork: false
udp:
enabled: true
service:
type: ClusterIP
Node Selection¶
When using hostNetwork: true, control which node the proxy runs on:
By node name:
By node label: