448 lines
8.3 KiB
Markdown
448 lines
8.3 KiB
Markdown
|
|
# Kubernetes Networking
|
||
|
|
|
||
|
|
## Service Types
|
||
|
|
|
||
|
|
### ClusterIP (Default)
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: web-app-service
|
||
|
|
namespace: production
|
||
|
|
labels:
|
||
|
|
app: web-app
|
||
|
|
spec:
|
||
|
|
type: ClusterIP
|
||
|
|
selector:
|
||
|
|
app: web-app
|
||
|
|
tier: frontend
|
||
|
|
ports:
|
||
|
|
- name: http
|
||
|
|
port: 80
|
||
|
|
targetPort: 8080
|
||
|
|
protocol: TCP
|
||
|
|
- name: metrics
|
||
|
|
port: 9090
|
||
|
|
targetPort: metrics
|
||
|
|
protocol: TCP
|
||
|
|
sessionAffinity: ClientIP
|
||
|
|
sessionAffinityConfig:
|
||
|
|
clientIP:
|
||
|
|
timeoutSeconds: 3600
|
||
|
|
```
|
||
|
|
|
||
|
|
### Headless Service (StatefulSet)
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: postgres-headless
|
||
|
|
namespace: database
|
||
|
|
spec:
|
||
|
|
clusterIP: None # Headless
|
||
|
|
selector:
|
||
|
|
app: postgres
|
||
|
|
ports:
|
||
|
|
- name: postgres
|
||
|
|
port: 5432
|
||
|
|
targetPort: 5432
|
||
|
|
```
|
||
|
|
|
||
|
|
### NodePort
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: external-app
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
type: NodePort
|
||
|
|
selector:
|
||
|
|
app: external-app
|
||
|
|
ports:
|
||
|
|
- name: http
|
||
|
|
port: 80
|
||
|
|
targetPort: 8080
|
||
|
|
nodePort: 30080 # Range: 30000-32767
|
||
|
|
protocol: TCP
|
||
|
|
```
|
||
|
|
|
||
|
|
### LoadBalancer
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: public-web
|
||
|
|
namespace: production
|
||
|
|
annotations:
|
||
|
|
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
|
||
|
|
service.beta.kubernetes.io/aws-load-balancer-internal: "false"
|
||
|
|
spec:
|
||
|
|
type: LoadBalancer
|
||
|
|
selector:
|
||
|
|
app: web-app
|
||
|
|
ports:
|
||
|
|
- name: http
|
||
|
|
port: 80
|
||
|
|
targetPort: 8080
|
||
|
|
- name: https
|
||
|
|
port: 443
|
||
|
|
targetPort: 8443
|
||
|
|
loadBalancerSourceRanges:
|
||
|
|
- 203.0.113.0/24 # Restrict source IPs
|
||
|
|
```
|
||
|
|
|
||
|
|
## Ingress Resources
|
||
|
|
|
||
|
|
### NGINX Ingress
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: networking.k8s.io/v1
|
||
|
|
kind: Ingress
|
||
|
|
metadata:
|
||
|
|
name: web-ingress
|
||
|
|
namespace: production
|
||
|
|
annotations:
|
||
|
|
nginx.ingress.kubernetes.io/rewrite-target: /
|
||
|
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||
|
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||
|
|
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||
|
|
nginx.ingress.kubernetes.io/rate-limit: "100"
|
||
|
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||
|
|
spec:
|
||
|
|
ingressClassName: nginx
|
||
|
|
tls:
|
||
|
|
- hosts:
|
||
|
|
- www.example.com
|
||
|
|
- api.example.com
|
||
|
|
secretName: example-tls
|
||
|
|
rules:
|
||
|
|
- host: www.example.com
|
||
|
|
http:
|
||
|
|
paths:
|
||
|
|
- path: /
|
||
|
|
pathType: Prefix
|
||
|
|
backend:
|
||
|
|
service:
|
||
|
|
name: frontend-service
|
||
|
|
port:
|
||
|
|
number: 80
|
||
|
|
- host: api.example.com
|
||
|
|
http:
|
||
|
|
paths:
|
||
|
|
- path: /v1
|
||
|
|
pathType: Prefix
|
||
|
|
backend:
|
||
|
|
service:
|
||
|
|
name: api-service
|
||
|
|
port:
|
||
|
|
number: 8080
|
||
|
|
- path: /v2
|
||
|
|
pathType: Prefix
|
||
|
|
backend:
|
||
|
|
service:
|
||
|
|
name: api-v2-service
|
||
|
|
port:
|
||
|
|
number: 8080
|
||
|
|
```
|
||
|
|
|
||
|
|
### Path-Based Routing
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: networking.k8s.io/v1
|
||
|
|
kind: Ingress
|
||
|
|
metadata:
|
||
|
|
name: app-ingress
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
ingressClassName: nginx
|
||
|
|
rules:
|
||
|
|
- host: app.example.com
|
||
|
|
http:
|
||
|
|
paths:
|
||
|
|
- path: /api
|
||
|
|
pathType: Prefix
|
||
|
|
backend:
|
||
|
|
service:
|
||
|
|
name: backend-api
|
||
|
|
port:
|
||
|
|
number: 8080
|
||
|
|
- path: /
|
||
|
|
pathType: Prefix
|
||
|
|
backend:
|
||
|
|
service:
|
||
|
|
name: frontend
|
||
|
|
port:
|
||
|
|
number: 80
|
||
|
|
```
|
||
|
|
|
||
|
|
## NetworkPolicy (Zero Trust)
|
||
|
|
|
||
|
|
### Default Deny All
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: networking.k8s.io/v1
|
||
|
|
kind: NetworkPolicy
|
||
|
|
metadata:
|
||
|
|
name: default-deny-all
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
podSelector: {}
|
||
|
|
policyTypes:
|
||
|
|
- Ingress
|
||
|
|
- Egress
|
||
|
|
```
|
||
|
|
|
||
|
|
### Allow Frontend to Backend
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: networking.k8s.io/v1
|
||
|
|
kind: NetworkPolicy
|
||
|
|
metadata:
|
||
|
|
name: frontend-to-backend
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
podSelector:
|
||
|
|
matchLabels:
|
||
|
|
tier: backend
|
||
|
|
policyTypes:
|
||
|
|
- Ingress
|
||
|
|
ingress:
|
||
|
|
- from:
|
||
|
|
- podSelector:
|
||
|
|
matchLabels:
|
||
|
|
tier: frontend
|
||
|
|
ports:
|
||
|
|
- protocol: TCP
|
||
|
|
port: 8080
|
||
|
|
```
|
||
|
|
|
||
|
|
### Backend to Database
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: networking.k8s.io/v1
|
||
|
|
kind: NetworkPolicy
|
||
|
|
metadata:
|
||
|
|
name: backend-to-database
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
podSelector:
|
||
|
|
matchLabels:
|
||
|
|
app: postgres
|
||
|
|
policyTypes:
|
||
|
|
- Ingress
|
||
|
|
ingress:
|
||
|
|
- from:
|
||
|
|
- podSelector:
|
||
|
|
matchLabels:
|
||
|
|
tier: backend
|
||
|
|
- namespaceSelector:
|
||
|
|
matchLabels:
|
||
|
|
name: production
|
||
|
|
ports:
|
||
|
|
- protocol: TCP
|
||
|
|
port: 5432
|
||
|
|
```
|
||
|
|
|
||
|
|
### Allow DNS and External HTTPS
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: networking.k8s.io/v1
|
||
|
|
kind: NetworkPolicy
|
||
|
|
metadata:
|
||
|
|
name: allow-dns-and-https
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
podSelector:
|
||
|
|
matchLabels:
|
||
|
|
tier: backend
|
||
|
|
policyTypes:
|
||
|
|
- Egress
|
||
|
|
egress:
|
||
|
|
- to:
|
||
|
|
- namespaceSelector:
|
||
|
|
matchLabels:
|
||
|
|
name: kube-system
|
||
|
|
ports:
|
||
|
|
- protocol: UDP
|
||
|
|
port: 53
|
||
|
|
- to:
|
||
|
|
- namespaceSelector: {}
|
||
|
|
ports:
|
||
|
|
- protocol: TCP
|
||
|
|
port: 443
|
||
|
|
```
|
||
|
|
|
||
|
|
### Cross-Namespace Communication
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: networking.k8s.io/v1
|
||
|
|
kind: NetworkPolicy
|
||
|
|
metadata:
|
||
|
|
name: allow-monitoring
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
podSelector:
|
||
|
|
matchLabels:
|
||
|
|
app: web-app
|
||
|
|
policyTypes:
|
||
|
|
- Ingress
|
||
|
|
ingress:
|
||
|
|
- from:
|
||
|
|
- namespaceSelector:
|
||
|
|
matchLabels:
|
||
|
|
name: monitoring
|
||
|
|
podSelector:
|
||
|
|
matchLabels:
|
||
|
|
app: prometheus
|
||
|
|
ports:
|
||
|
|
- protocol: TCP
|
||
|
|
port: 8080
|
||
|
|
```
|
||
|
|
|
||
|
|
## DNS Configuration
|
||
|
|
|
||
|
|
### Service DNS Names
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# Within same namespace
|
||
|
|
http://web-app-service
|
||
|
|
|
||
|
|
# Cross-namespace
|
||
|
|
http://web-app-service.production.svc.cluster.local
|
||
|
|
|
||
|
|
# Headless service (StatefulSet)
|
||
|
|
postgres-0.postgres-headless.database.svc.cluster.local
|
||
|
|
postgres-1.postgres-headless.database.svc.cluster.local
|
||
|
|
postgres-2.postgres-headless.database.svc.cluster.local
|
||
|
|
```
|
||
|
|
|
||
|
|
### Custom DNS Policy
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Pod
|
||
|
|
metadata:
|
||
|
|
name: custom-dns
|
||
|
|
spec:
|
||
|
|
dnsPolicy: None
|
||
|
|
dnsConfig:
|
||
|
|
nameservers:
|
||
|
|
- 8.8.8.8
|
||
|
|
- 8.8.4.4
|
||
|
|
searches:
|
||
|
|
- production.svc.cluster.local
|
||
|
|
- svc.cluster.local
|
||
|
|
- cluster.local
|
||
|
|
options:
|
||
|
|
- name: ndots
|
||
|
|
value: "2"
|
||
|
|
containers:
|
||
|
|
- name: app
|
||
|
|
image: myapp:latest
|
||
|
|
```
|
||
|
|
|
||
|
|
## Service Mesh (Istio Example)
|
||
|
|
|
||
|
|
### VirtualService
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: networking.istio.io/v1beta1
|
||
|
|
kind: VirtualService
|
||
|
|
metadata:
|
||
|
|
name: web-app-routes
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
hosts:
|
||
|
|
- web-app-service
|
||
|
|
http:
|
||
|
|
- match:
|
||
|
|
- headers:
|
||
|
|
canary:
|
||
|
|
exact: "true"
|
||
|
|
route:
|
||
|
|
- destination:
|
||
|
|
host: web-app-service
|
||
|
|
subset: v2
|
||
|
|
- route:
|
||
|
|
- destination:
|
||
|
|
host: web-app-service
|
||
|
|
subset: v1
|
||
|
|
weight: 90
|
||
|
|
- destination:
|
||
|
|
host: web-app-service
|
||
|
|
subset: v2
|
||
|
|
weight: 10
|
||
|
|
```
|
||
|
|
|
||
|
|
### DestinationRule
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: networking.istio.io/v1beta1
|
||
|
|
kind: DestinationRule
|
||
|
|
metadata:
|
||
|
|
name: web-app-destination
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
host: web-app-service
|
||
|
|
trafficPolicy:
|
||
|
|
connectionPool:
|
||
|
|
tcp:
|
||
|
|
maxConnections: 100
|
||
|
|
http:
|
||
|
|
http1MaxPendingRequests: 50
|
||
|
|
http2MaxRequests: 100
|
||
|
|
loadBalancer:
|
||
|
|
simple: LEAST_REQUEST
|
||
|
|
subsets:
|
||
|
|
- name: v1
|
||
|
|
labels:
|
||
|
|
version: v1.0.0
|
||
|
|
- name: v2
|
||
|
|
labels:
|
||
|
|
version: v2.0.0
|
||
|
|
```
|
||
|
|
|
||
|
|
## EndpointSlice (Modern Alternative to Endpoints)
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: discovery.k8s.io/v1
|
||
|
|
kind: EndpointSlice
|
||
|
|
metadata:
|
||
|
|
name: web-app-abc123
|
||
|
|
namespace: production
|
||
|
|
labels:
|
||
|
|
kubernetes.io/service-name: web-app-service
|
||
|
|
addressType: IPv4
|
||
|
|
ports:
|
||
|
|
- name: http
|
||
|
|
protocol: TCP
|
||
|
|
port: 8080
|
||
|
|
endpoints:
|
||
|
|
- addresses:
|
||
|
|
- "10.244.1.5"
|
||
|
|
conditions:
|
||
|
|
ready: true
|
||
|
|
nodeName: node-1
|
||
|
|
- addresses:
|
||
|
|
- "10.244.2.7"
|
||
|
|
conditions:
|
||
|
|
ready: true
|
||
|
|
nodeName: node-2
|
||
|
|
```
|
||
|
|
|
||
|
|
## Best Practices
|
||
|
|
|
||
|
|
1. **Default Deny**: Start with deny-all NetworkPolicy, then allow specific traffic
|
||
|
|
2. **Least Privilege**: Only open required ports and protocols
|
||
|
|
3. **Service Selection**: Use ClusterIP by default, LoadBalancer sparingly
|
||
|
|
4. **DNS Names**: Use service DNS names, avoid hardcoded IPs
|
||
|
|
5. **TLS Termination**: Terminate TLS at Ingress when possible
|
||
|
|
6. **Health Checks**: Configure proper health check paths
|
||
|
|
7. **Rate Limiting**: Apply rate limits at Ingress level
|
||
|
|
8. **Monitoring**: Expose metrics endpoints for Prometheus
|