diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 79c3d131..94471721 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -87,15 +87,14 @@ jobs: All images are available for both \`linux/amd64\` and \`linux/arm64\` platforms: - - Kubernetes Controller: \`ghcr.io/${{ github.repository_owner }}/streamspace-kubernetes-controller:${{ steps.version.outputs.VERSION }}\` - API: \`ghcr.io/${{ github.repository_owner }}/streamspace-api:${{ steps.version.outputs.VERSION }}\` - UI: \`ghcr.io/${{ github.repository_owner }}/streamspace-ui:${{ steps.version.outputs.VERSION }}\` + - K8s Agent: \`ghcr.io/${{ github.repository_owner }}/streamspace-k8s-agent:${{ steps.version.outputs.VERSION }}\` ## Documentation - [Installation Guide](https://github.com/${{ github.repository }}/blob/main/README.md) - [Architecture Docs](https://github.com/${{ github.repository }}/blob/main/docs/ARCHITECTURE.md) - - [Controller Guide](https://github.com/${{ github.repository }}/blob/main/docs/CONTROLLER_GUIDE.md) - [Helm Chart README](https://github.com/${{ github.repository }}/blob/main/chart/README.md) ## Upgrade Instructions @@ -171,7 +170,7 @@ jobs: needs: release strategy: matrix: - component: [kubernetes-controller, api, ui] + component: [api, ui, k8s-agent] steps: - name: Extract version id: version diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 21815a19..f30ec487 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - component: [api, ui, kubernetes-controller] + component: [api, ui, k8s-agent, docker-agent] steps: - name: Checkout code uses: actions/checkout@v4 @@ -35,8 +35,10 @@ jobs: docker build -t streamspace-api:scan ./api elif [ "${{ matrix.component }}" = "ui" ]; then docker build -t streamspace-ui:scan ./ui - elif [ "${{ matrix.component }}" = "kubernetes-controller" ]; then - docker build -t streamspace-kubernetes-controller:scan ./k8s-controller + elif [ "${{ matrix.component }}" = "k8s-agent" ]; then + docker build -t streamspace-k8s-agent:scan ./agents/k8s-agent + elif [ "${{ matrix.component }}" = "docker-agent" ]; then + docker build -t streamspace-docker-agent:scan ./agents/docker-agent fi - name: Run Trivy vulnerability scanner diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt index 635e3303..8f9ffced 100644 --- a/chart/templates/NOTES.txt +++ b/chart/templates/NOTES.txt @@ -114,21 +114,8 @@ Connection Status: kubectl logs -n {{ .Release.Namespace }} -l app.kubernetes.io/component=api \ | grep "Agent registered" -The K8s Agent connects to the Control Plane via WebSocket for session management. -This replaces the v1.x controller-based architecture. - -{{- else if .Values.controller.enabled }} - -⚙️ V1.X CONTROLLER ARCHITECTURE -──────────────────────────────────────────────────────────────────────────── - -StreamSpace is deployed with the v1.x Controller architecture. - -To upgrade to v2.0-beta agent architecture: - helm upgrade {{ .Release.Name }} {{ .Chart.Name }} \ - --reuse-values \ - --set k8sAgent.enabled=true \ - --set controller.enabled=false +The K8s Agent connects to the Control Plane via WebSocket for session +management. (The v1.x controller-based architecture was removed in v2.0.) {{- end }} @@ -147,7 +134,7 @@ To upgrade to v2.0-beta agent architecture: View metrics: kubectl port-forward -n {{ .Release.Namespace }} \ - svc/{{ include "streamspace.fullname" . }}-controller 8080:8080 + svc/{{ include "streamspace.fullname" . }}-api 8080:8080 curl http://localhost:8080/metrics diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl index 8ff70a56..51a3c178 100644 --- a/chart/templates/_helpers.tpl +++ b/chart/templates/_helpers.tpl @@ -51,14 +51,6 @@ app.kubernetes.io/name: {{ include "streamspace.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} -{{/* -Controller labels -*/}} -{{- define "streamspace.controller.labels" -}} -{{ include "streamspace.labels" . }} -app.kubernetes.io/component: controller -{{- end }} - {{/* API labels */}} @@ -91,17 +83,6 @@ PostgreSQL labels app.kubernetes.io/component: database {{- end }} -{{/* -Create the name of the controller service account to use -*/}} -{{- define "streamspace.controller.serviceAccountName" -}} -{{- if .Values.controller.serviceAccount.create }} -{{- default (printf "%s-controller" (include "streamspace.fullname" .)) .Values.controller.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.controller.serviceAccount.name }} -{{- end }} -{{- end }} - {{/* Create the name of the API service account to use */}} @@ -194,20 +175,6 @@ Get the PostgreSQL secret key for password {{- end }} {{- end }} -{{/* -Image name for controller -*/}} -{{- define "streamspace.controller.image" -}} -{{- $registry := .Values.global.imageRegistry | default .Values.controller.image.registry }} -{{- $repository := .Values.controller.image.repository }} -{{- $tag := .Values.controller.image.tag | default .Chart.AppVersion }} -{{- if $registry }} -{{- printf "%s/%s:%s" $registry $repository $tag }} -{{- else }} -{{- printf "%s:%s" $repository $tag }} -{{- end }} -{{- end }} - {{/* Image name for API */}} diff --git a/chart/templates/controller-deployment.yaml b/chart/templates/controller-deployment.yaml deleted file mode 100644 index 2134bdc4..00000000 --- a/chart/templates/controller-deployment.yaml +++ /dev/null @@ -1,120 +0,0 @@ -{{- if .Values.controller.enabled }} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "streamspace.controller.serviceAccountName" . }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "streamspace.controller.labels" . | nindent 4 }} - {{- with .Values.controller.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "streamspace.fullname" . }}-controller - namespace: {{ .Release.Namespace }} - labels: - {{- include "streamspace.controller.labels" . | nindent 4 }} -spec: - replicas: {{ .Values.controller.replicaCount }} - selector: - matchLabels: - {{- include "streamspace.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: controller - template: - metadata: - annotations: - {{- with .Values.controller.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "streamspace.selectorLabels" . | nindent 8 }} - app.kubernetes.io/component: controller - spec: - {{- with .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "streamspace.controller.serviceAccountName" . }} - securityContext: - {{- toYaml .Values.controller.podSecurityContext | nindent 8 }} - containers: - - name: controller - image: {{ include "streamspace.controller.image" . }} - imagePullPolicy: {{ .Values.controller.image.pullPolicy }} - command: - - /manager - args: - - --metrics-bind-address={{ .Values.controller.config.metricsBindAddress }} - - --health-probe-bind-address={{ .Values.controller.config.healthProbeBindAddress }} - {{- if and (gt (.Values.controller.replicaCount | int) 1) .Values.controller.leaderElection.enabled }} - - --leader-elect - {{- end }} - env: - - name: INGRESS_DOMAIN - value: {{ .Values.controller.config.ingressDomain | quote }} - - name: INGRESS_CLASS - value: {{ .Values.controller.config.ingressClass | quote }} - - name: NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: CONTROLLER_ID - value: {{ include "streamspace.fullname" . }}-controller-1 - ports: - - name: metrics - containerPort: 8080 - protocol: TCP - - name: health - containerPort: 8081 - protocol: TCP - resources: - {{- toYaml .Values.controller.resources | nindent 10 }} - livenessProbe: - httpGet: - path: /healthz - port: health - initialDelaySeconds: 15 - periodSeconds: 20 - readinessProbe: - httpGet: - path: /readyz - port: health - initialDelaySeconds: 5 - periodSeconds: 10 - securityContext: - {{- toYaml .Values.controller.securityContext | nindent 10 }} - {{- with .Values.controller.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.controller.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.controller.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ include "streamspace.fullname" . }}-controller - namespace: {{ .Release.Namespace }} - labels: - {{- include "streamspace.controller.labels" . | nindent 4 }} -spec: - type: {{ .Values.controller.service.type }} - ports: - - port: {{ .Values.controller.service.metricsPort }} - targetPort: metrics - protocol: TCP - name: metrics - selector: - {{- include "streamspace.selectorLabels" . | nindent 4 }} - app.kubernetes.io/component: controller -{{- end }} diff --git a/chart/templates/networkpolicy.yaml b/chart/templates/networkpolicy.yaml index cbc15c63..2fcd8baf 100644 --- a/chart/templates/networkpolicy.yaml +++ b/chart/templates/networkpolicy.yaml @@ -1,53 +1,4 @@ {{- if .Values.networkPolicy.enabled }} -{{- if .Values.controller.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ include "streamspace.fullname" . }}-controller - namespace: {{ .Release.Namespace }} - labels: - {{- include "streamspace.controller.labels" . | nindent 4 }} -spec: - podSelector: - matchLabels: - {{- include "streamspace.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: controller - policyTypes: - - Ingress - - Egress - ingress: - # Allow Prometheus to scrape metrics - - from: - - namespaceSelector: - matchLabels: - name: {{ .Values.networkPolicy.monitoring.namespace | default "observability" }} - ports: - - protocol: TCP - port: 8080 - egress: - # Allow access to Kubernetes API - - to: - - namespaceSelector: {} - podSelector: - matchLabels: - component: apiserver - ports: - - protocol: TCP - port: 443 - # Allow DNS - - to: - - namespaceSelector: - matchLabels: - name: kube-system - ports: - - protocol: UDP - port: 53 - # Allow all egress if not restricted - {{- if not .Values.networkPolicy.controller.restrictEgress }} - - {} - {{- end }} ---- -{{- end }} {{- if .Values.api.enabled }} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy diff --git a/chart/templates/pdb.yaml b/chart/templates/pdb.yaml index d58e7d78..aae208e4 100644 --- a/chart/templates/pdb.yaml +++ b/chart/templates/pdb.yaml @@ -1,24 +1,3 @@ -{{- if and .Values.controller.enabled .Values.controller.podDisruptionBudget.enabled }} -apiVersion: policy/v1 -kind: PodDisruptionBudget -metadata: - name: {{ include "streamspace.fullname" . }}-controller - namespace: {{ .Release.Namespace }} - labels: - {{- include "streamspace.controller.labels" . | nindent 4 }} -spec: - {{- if .Values.controller.podDisruptionBudget.minAvailable }} - minAvailable: {{ .Values.controller.podDisruptionBudget.minAvailable }} - {{- end }} - {{- if .Values.controller.podDisruptionBudget.maxUnavailable }} - maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }} - {{- end }} - selector: - matchLabels: - {{- include "streamspace.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: controller ---- -{{- end }} {{- if and .Values.api.enabled .Values.api.podDisruptionBudget.enabled }} apiVersion: policy/v1 kind: PodDisruptionBudget diff --git a/chart/templates/rbac.yaml b/chart/templates/rbac.yaml index 70485601..f5b94678 100644 --- a/chart/templates/rbac.yaml +++ b/chart/templates/rbac.yaml @@ -1,63 +1,9 @@ {{- if .Values.rbac.create }} --- -# Controller RBAC -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ include "streamspace.fullname" . }}-controller - labels: - {{- include "streamspace.controller.labels" . | nindent 4 }} -rules: - # Sessions and Templates CRDs - - apiGroups: ["stream.space"] - resources: ["sessions", "templates"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - - apiGroups: ["stream.space"] - resources: ["sessions/status", "templates/status"] - verbs: ["get", "update", "patch"] - - apiGroups: ["stream.space"] - resources: ["sessions/finalizers", "templates/finalizers"] - verbs: ["update"] - - # Core resources - - apiGroups: [""] - resources: ["services", "persistentvolumeclaims"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - - apiGroups: ["apps"] - resources: ["deployments"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - - apiGroups: ["networking.k8s.io"] - resources: ["ingresses"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - - # Events - - apiGroups: [""] - resources: ["events"] - verbs: ["create", "patch"] - - # Leader election - - apiGroups: [""] - resources: ["configmaps"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - - apiGroups: ["coordination.k8s.io"] - resources: ["leases"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ include "streamspace.fullname" . }}-controller - labels: - {{- include "streamspace.controller.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ include "streamspace.fullname" . }}-controller -subjects: - - kind: ServiceAccount - name: {{ include "streamspace.controller.serviceAccountName" . }} - namespace: {{ .Release.Namespace }} ---- +# (v1 Controller RBAC removed in v2: ClusterRole, ClusterRoleBinding, and +# the controller ServiceAccount are no longer rendered. The K8s Agent has +# its own RBAC bundle (k8s-agent-rbac.yaml); the API only needs the +# namespaced Role/RoleBinding below for log streaming.) # API RBAC apiVersion: rbac.authorization.k8s.io/v1 kind: Role diff --git a/chart/templates/servicemonitor.yaml b/chart/templates/servicemonitor.yaml index a2189cae..77f4bf5b 100644 --- a/chart/templates/servicemonitor.yaml +++ b/chart/templates/servicemonitor.yaml @@ -1,29 +1,4 @@ {{- if and .Values.monitoring.enabled .Values.monitoring.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ include "streamspace.fullname" . }}-controller - namespace: {{ .Release.Namespace }} - labels: - {{- include "streamspace.controller.labels" . | nindent 4 }} - {{- with .Values.monitoring.serviceMonitor.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: - {{- include "streamspace.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: controller - endpoints: - - port: metrics - path: /metrics - interval: {{ .Values.monitoring.serviceMonitor.interval }} - scrapeTimeout: {{ .Values.monitoring.serviceMonitor.scrapeTimeout }} - {{- with .Values.monitoring.serviceMonitor.relabelings }} - relabelings: - {{- toYaml . | nindent 8 }} - {{- end }} ---- {{- if .Values.api.enabled }} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor diff --git a/chart/values.yaml b/chart/values.yaml index a04c4ae4..3f74d8c4 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -11,88 +11,11 @@ global: # Storage class for all PVCs storageClass: "" -## StreamSpace Kubernetes Controller -## DEPRECATED: Controller is not needed in v2.0-beta architecture. -## In v2.0-beta, the API creates Session CRDs directly and dispatches commands to agents via WebSocket. -## The controller-based architecture was replaced by the agent-based architecture. -controller: - enabled: false # Disabled for v2.0-beta (agent-based architecture) - - image: - registry: ghcr.io - repository: streamspace-dev/streamspace-kubernetes-controller - tag: "v0.2.0" - pullPolicy: IfNotPresent - - # Number of controller replicas (use 3+ with leader election for HA) - replicaCount: 1 - - # Leader election for high availability - leaderElection: - enabled: false # Enable when replicaCount > 1 - - resources: - requests: - memory: 256Mi - cpu: 200m - limits: - memory: 512Mi - cpu: 1000m - - # Controller configuration - config: - # Ingress settings for created sessions - ingressDomain: streamspace.local - ingressClass: traefik - - # Metrics and health - metricsBindAddress: ":8080" - healthProbeBindAddress: ":8081" - - # Service for metrics - service: - type: ClusterIP - metricsPort: 8080 - - # Service account - serviceAccount: - create: true - annotations: {} - name: "" - - # Pod annotations - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8080" - prometheus.io/path: "/metrics" - - # Security context - podSecurityContext: - fsGroup: 65532 - runAsNonRoot: true - runAsUser: 65532 - - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - - # Node selector - nodeSelector: {} - - # Tolerations - tolerations: [] - - # Affinity - affinity: {} - - # Pod Disruption Budget - podDisruptionBudget: - enabled: false - minAvailable: 1 - # maxUnavailable: 1 +## (Removed in v2: the v1 Kubernetes controller was replaced by the K8s Agent +## below. Templates referencing .Values.controller and the old image +## streamspace-dev/streamspace-kubernetes-controller were deleted in the same +## change. If you're upgrading from v1, set k8sAgent.enabled=true and remove +## any --set controller.* flags.) ## K8s Agent (v2.0-beta) # The K8s Agent connects to the Control Plane and manages sessions on Kubernetes @@ -689,9 +612,6 @@ networkPolicy: # Monitoring namespace monitoring: namespace: observability - # Controller network restrictions - controller: - restrictEgress: false ## Common labels commonLabels: {} diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index 000df1e7..a7e2ecc8 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -52,7 +52,8 @@ The Helm chart has been updated with the following changes: 1. **Removed v1.x Components:** - `chart/templates/nats.yaml` (122 lines) - v1.x event system - - `controller` now disabled by default + - `chart/templates/controller-deployment.yaml` and the `controller` + values block — fully removed (was disabled-by-default, now gone) 2. **Added v2.0 Components:** - `chart/templates/k8s-agent-deployment.yaml` (118 lines) diff --git a/scripts/local-deploy.sh b/scripts/local-deploy.sh index 360e8470..3e93c21f 100755 --- a/scripts/local-deploy.sh +++ b/scripts/local-deploy.sh @@ -76,7 +76,7 @@ check_images() { local missing_images=0 - # v2.0: K8s Agent REPLACES kubernetes-controller + # K8s Agent (the v1 kubernetes-controller was removed in v2) for image in "streamspace/streamspace-api" "streamspace/streamspace-ui" "streamspace/streamspace-k8s-agent"; do if docker images "${image}:${VERSION}" --format "{{.Repository}}:{{.Tag}}" | grep -q "${image}:${VERSION}"; then log_success "Found ${image}:${VERSION}"