Files
Maison/arti-api/kubernetes-with-network-policy.yaml
2026-02-10 12:12:11 +01:00

405 lines
9.0 KiB
YAML

apiVersion: v1
kind: Namespace
metadata:
name: artifactory
labels:
name: artifactory
---
# Network Policy for Artifactory Services
# Allows internal network (192.168.100.0/24) full access
# Restricts external access to health endpoints only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: artifactory-access-control
namespace: artifactory
spec:
podSelector:
matchLabels:
tier: artifactory
policyTypes:
- Ingress
- Egress
ingress:
# Rule 1: Allow full access from internal network
- from:
- ipBlock:
cidr: 192.168.100.0/24
ports:
- protocol: TCP
port: 8000 # Arti-API
- protocol: TCP
port: 8080 # Chart Museum
- protocol: TCP
port: 5000 # Docker Registry
# Rule 2: Allow inter-pod communication within namespace
- from:
- namespaceSelector:
matchLabels:
name: artifactory
- podSelector: {}
ports:
- protocol: TCP
port: 8000
- protocol: TCP
port: 8080
- protocol: TCP
port: 5000
# Rule 3: Allow external access to health endpoints only
# Note: This allows access to all ports but should be combined
# with Ingress controller path filtering for full security
- from: []
ports:
- protocol: TCP
port: 8000 # For /health endpoint
- protocol: TCP
port: 8080 # For /health endpoint
- protocol: TCP
port: 5000 # For /v2/ endpoint
egress:
# Allow DNS resolution
- to: []
ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
# Allow outbound HTTP/HTTPS for package downloads
- to: []
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
# Allow inter-pod communication
- to:
- namespaceSelector:
matchLabels:
name: artifactory
- podSelector: {}
---
# Ingress with path-based restrictions
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: artifactory-ingress
namespace: artifactory
annotations:
kubernetes.io/ingress.class: "nginx"
# Configuration to restrict external access to specific paths
nginx.ingress.kubernetes.io/configuration-snippet: |
# Allow internal network full access
if ($remote_addr ~ "^192\.168\.100\.") {
set $internal_access 1;
}
# For external access, only allow specific paths
if ($internal_access != 1) {
# Block access to management endpoints
if ($uri ~ "^/(users|debian|helm|refresh|docs|redoc|openapi\.json)") {
return 403 "Access denied - Internal network only";
}
# Block Chart Museum API endpoints
if ($uri ~ "^/api/") {
return 403 "Access denied - Internal network only";
}
# Block Docker Registry push/pull (only allow health check)
if ($uri ~ "^/v2/.*/(manifests|blobs)") {
return 403 "Access denied - Internal network only";
}
}
spec:
rules:
- host: artifactory.local
http:
paths:
# Arti-API
- path: /
pathType: Prefix
backend:
service:
name: arti-api-service
port:
number: 8000
- host: charts.artifactory.local
http:
paths:
# Chart Museum
- path: /
pathType: Prefix
backend:
service:
name: chartmuseum-service
port:
number: 8080
- host: registry.artifactory.local
http:
paths:
# Docker Registry
- path: /
pathType: Prefix
backend:
service:
name: docker-registry-service
port:
number: 5000
---
# Update existing deployments to include tier label
apiVersion: apps/v1
kind: Deployment
metadata:
name: arti-api
namespace: artifactory
labels:
app: arti-api
tier: artifactory
spec:
replicas: 1
selector:
matchLabels:
app: arti-api
tier: artifactory
template:
metadata:
labels:
app: arti-api
tier: artifactory
spec:
containers:
- name: arti-api
image: hexah/arti-api:1.0.1
ports:
- containerPort: 8000
env:
- name: PYTHONUNBUFFERED
value: "1"
volumeMounts:
- name: artifactory-storage
mountPath: /data
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
volumes:
- name: artifactory-storage
persistentVolumeClaim:
claimName: artifactory-pvc
---
apiVersion: v1
kind: Service
metadata:
name: arti-api-service
namespace: artifactory
labels:
app: arti-api
tier: artifactory
spec:
type: ClusterIP
ports:
- port: 8000
targetPort: 8000
protocol: TCP
selector:
app: arti-api
tier: artifactory
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: chartmuseum
namespace: artifactory
labels:
app: chartmuseum
tier: artifactory
spec:
replicas: 1
selector:
matchLabels:
app: chartmuseum
tier: artifactory
template:
metadata:
labels:
app: chartmuseum
tier: artifactory
spec:
containers:
- name: chartmuseum
image: chartmuseum/chartmuseum:latest
ports:
- containerPort: 8080
env:
- name: STORAGE
value: "local"
- name: STORAGE_LOCAL_ROOTDIR
value: "/data/charts"
- name: PORT
value: "8080"
- name: AUTH_ANONYMOUS_GET
value: "false"
- name: HTPASSWD_PATH
value: "/data/htpasswd"
- name: AUTH_REALM
value: "Chart Museum"
- name: ALLOW_OVERWRITE
value: "true"
- name: DISABLE_API
value: "false"
volumeMounts:
- name: artifactory-storage
mountPath: /data
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
volumes:
- name: artifactory-storage
persistentVolumeClaim:
claimName: artifactory-pvc
---
apiVersion: v1
kind: Service
metadata:
name: chartmuseum-service
namespace: artifactory
labels:
app: chartmuseum
tier: artifactory
spec:
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
protocol: TCP
selector:
app: chartmuseum
tier: artifactory
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: docker-registry
namespace: artifactory
labels:
app: docker-registry
tier: artifactory
spec:
replicas: 1
selector:
matchLabels:
app: docker-registry
tier: artifactory
template:
metadata:
labels:
app: docker-registry
tier: artifactory
spec:
containers:
- name: registry
image: registry:2
ports:
- containerPort: 5000
env:
- name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
value: "/data/docker"
- name: REGISTRY_AUTH
value: "htpasswd"
- name: REGISTRY_AUTH_HTPASSWD_REALM
value: "Registry Realm"
- name: REGISTRY_AUTH_HTPASSWD_PATH
value: "/data/htpasswd"
- name: REGISTRY_HTTP_ADDR
value: "0.0.0.0:5000"
volumeMounts:
- name: artifactory-storage
mountPath: /data
livenessProbe:
httpGet:
path: /v2/
port: 5000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /v2/
port: 5000
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
volumes:
- name: artifactory-storage
persistentVolumeClaim:
claimName: artifactory-pvc
---
apiVersion: v1
kind: Service
metadata:
name: docker-registry-service
namespace: artifactory
labels:
app: docker-registry
tier: artifactory
spec:
type: ClusterIP
ports:
- port: 5000
targetPort: 5000
protocol: TCP
selector:
app: docker-registry
tier: artifactory
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: artifactory-pvc
namespace: artifactory
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: "" # Specify your storage class here