diff --git a/apps/pangolin/controller/controller-deployment.yaml b/apps/pangolin/controller/controller-deployment.yaml new file mode 100644 index 0000000..de629c9 --- /dev/null +++ b/apps/pangolin/controller/controller-deployment.yaml @@ -0,0 +1,103 @@ +--- +# Pangolin Kube Controller Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: pangolin-kube-controller + namespace: pangolin + labels: + app.kubernetes.io/name: pangolin-kube-controller + app.kubernetes.io/component: controller + app.kubernetes.io/part-of: pangolin +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: pangolin-kube-controller + template: + metadata: + labels: + app.kubernetes.io/name: pangolin-kube-controller + app.kubernetes.io/component: controller + app.kubernetes.io/part-of: pangolin + spec: + serviceAccountName: pangolin-kube-controller + securityContext: + runAsNonRoot: true + runAsUser: 65532 + fsGroup: 65532 + seccompProfile: + type: RuntimeDefault + containers: + - name: controller + image: ghcr.io/fosrl/pangolin-kube-controller:0.1.0-alpha.1 + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65532 + capabilities: + drop: + - ALL + env: + # Pangolin API Configuration + - name: CONFIG_ENDPOINT + value: "https://pangolin.basicstack.de/api/v1/traefik-config" + - name: CONFIG_AUTH_HEADER + value: "Bearer 5qid06u9j325kpk.ywd3bpsx34dtxyczgatyxuoxkzwhie7d72k6v4hw" + + # Target namespace for Traefik resources + - name: TARGET_NAMESPACE + value: "pangolin" + + # Metrics server configuration + - name: METRICS_ADDR + value: ":9090" + + # Polling interval + - name: POLL_INTERVAL + value: "15s" + + # Leader election (disabled for single replica) + - name: ENABLE_LEADER_ELECTION + value: "false" + + # Traefik ingress class + - name: INGRESS_CLASS + value: "traefik" + + # Logging configuration + - name: LOG_TRAEFIK_CONFIG + value: "false" + - name: CONFIG_LOG_PREVIEW + value: "false" + - name: FETCH_LOG_INTERVAL + value: "5m" + ports: + - name: metrics + containerPort: 9090 + protocol: TCP + livenessProbe: + httpGet: + path: /livez + port: 9090 + initialDelaySeconds: 15 + periodSeconds: 20 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /readyz + port: 9090 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "256Mi" + cpu: "200m" diff --git a/apps/pangolin/controller/controller-rbac.yaml b/apps/pangolin/controller/controller-rbac.yaml new file mode 100644 index 0000000..33794f2 --- /dev/null +++ b/apps/pangolin/controller/controller-rbac.yaml @@ -0,0 +1,59 @@ +--- +# ClusterRole for pangolin-kube-controller +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pangolin-kube-controller + labels: + app.kubernetes.io/name: pangolin-kube-controller + app.kubernetes.io/component: controller + app.kubernetes.io/part-of: pangolin +rules: + # Traefik CRDs - full access to manage IngressRoutes, Middlewares, and TraefikServices + - apiGroups: ["traefik.io"] + resources: + - ingressroutes + - ingressroutetcps + - ingressrouteudps + - middlewares + - middlewaretcps + - traefikservices + - serverstransports + - serverstransporttcps + - tlsoptions + - tlsstores + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + + # IngressClass - read-only for validation + - apiGroups: ["networking.k8s.io"] + resources: ["ingressclasses"] + verbs: ["get", "list", "watch"] + + # Leader election - requires lease access + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + + # Events - for operational notifications + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch", "get", "list"] + +--- +# ClusterRoleBinding for pangolin-kube-controller +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: pangolin-kube-controller + labels: + app.kubernetes.io/name: pangolin-kube-controller + app.kubernetes.io/component: controller + app.kubernetes.io/part-of: pangolin +subjects: + - kind: ServiceAccount + name: pangolin-kube-controller + namespace: pangolin +roleRef: + kind: ClusterRole + name: pangolin-kube-controller + apiGroup: rbac.authorization.k8s.io diff --git a/apps/pangolin/controller/controller-service.yaml b/apps/pangolin/controller/controller-service.yaml new file mode 100644 index 0000000..63e9d7b --- /dev/null +++ b/apps/pangolin/controller/controller-service.yaml @@ -0,0 +1,20 @@ +--- +# Service for pangolin-kube-controller metrics +apiVersion: v1 +kind: Service +metadata: + name: pangolin-kube-controller + namespace: pangolin + labels: + app.kubernetes.io/name: pangolin-kube-controller + app.kubernetes.io/component: controller + app.kubernetes.io/part-of: pangolin +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: pangolin-kube-controller + ports: + - name: metrics + port: 9090 + targetPort: 9090 + protocol: TCP diff --git a/apps/pangolin/controller/controller-serviceaccount.yaml b/apps/pangolin/controller/controller-serviceaccount.yaml new file mode 100644 index 0000000..22ff23e --- /dev/null +++ b/apps/pangolin/controller/controller-serviceaccount.yaml @@ -0,0 +1,11 @@ +--- +# ServiceAccount for pangolin-kube-controller +apiVersion: v1 +kind: ServiceAccount +metadata: + name: pangolin-kube-controller + namespace: pangolin + labels: + app.kubernetes.io/name: pangolin-kube-controller + app.kubernetes.io/component: controller + app.kubernetes.io/part-of: pangolin