diff --git a/controllers/devbox/api/v1alpha1/runtime_types.go b/controllers/devbox/api/v1alpha1/runtime_types.go index 436e94bb269..cf1e6bf8045 100644 --- a/controllers/devbox/api/v1alpha1/runtime_types.go +++ b/controllers/devbox/api/v1alpha1/runtime_types.go @@ -51,9 +51,13 @@ type Config struct { // +kubebuilder:default={/home/sealos/project/entrypoint.sh} ReleaseArgs []string `json:"releaseArgs,omitempty"` + // TODO: in v1alpha2 api we need fix the port and app port into one field and create a new type for it. // +kubebuilder:validation:Optional // +kubebuilder:default={{name:"devbox-ssh-port",containerPort:22,protocol:TCP}} Ports []corev1.ContainerPort `json:"ports,omitempty"` + // +kubebuilder:validation:Optional + // +kubebuilder:default={{name:"devbox-app-port",port:8080,protocol:TCP}} + AppPorts []corev1.ServicePort `json:"appPorts,omitempty"` // +kubebuilder:validation:Optional VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` diff --git a/controllers/devbox/api/v1alpha1/zz_generated.deepcopy.go b/controllers/devbox/api/v1alpha1/zz_generated.deepcopy.go index a62954292b7..cbf872db25e 100644 --- a/controllers/devbox/api/v1alpha1/zz_generated.deepcopy.go +++ b/controllers/devbox/api/v1alpha1/zz_generated.deepcopy.go @@ -105,6 +105,13 @@ func (in *Config) DeepCopyInto(out *Config) { *out = make([]v1.ContainerPort, len(*in)) copy(*out, *in) } + if in.AppPorts != nil { + in, out := &in.AppPorts, &out.AppPorts + *out = make([]v1.ServicePort, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts *out = make([]v1.VolumeMount, len(*in)) diff --git a/controllers/devbox/config/crd/bases/devbox.sealos.io_runtimes.yaml b/controllers/devbox/config/crd/bases/devbox.sealos.io_runtimes.yaml index 0ed11827a4a..bfaaa6eccbf 100644 --- a/controllers/devbox/config/crd/bases/devbox.sealos.io_runtimes.yaml +++ b/controllers/devbox/config/crd/bases/devbox.sealos.io_runtimes.yaml @@ -77,6 +77,84 @@ spec: additionalProperties: type: string type: object + appPorts: + default: + - name: devbox-app-port + port: 8080 + protocol: TCP + items: + description: ServicePort contains information on service's port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array args: description: kubebuilder:validation:Optional items: @@ -210,6 +288,8 @@ spec: - containerPort: 22 name: devbox-ssh-port protocol: TCP + description: 'TODO: in v1alpha2 api we need fix the port and app + port into one field and create a new type for it.' items: description: ContainerPort represents a network port in a single container. diff --git a/controllers/devbox/config/manager/manager.yaml b/controllers/devbox/config/manager/manager.yaml index 940f2fc9b99..d8098831880 100644 --- a/controllers/devbox/config/manager/manager.yaml +++ b/controllers/devbox/config/manager/manager.yaml @@ -34,7 +34,7 @@ spec: selector: matchLabels: control-plane: controller-manager - replicas: 1 + replicas: 2 template: metadata: annotations: @@ -104,10 +104,10 @@ spec: # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ resources: limits: - cpu: 500m - memory: 128Mi + cpu: 1500m + memory: 2000Mi requests: - cpu: 10m - memory: 64Mi + cpu: 100m + memory: 640Mi serviceAccountName: controller-manager terminationGracePeriodSeconds: 10 diff --git a/controllers/devbox/config/samples/devbox_v1alpha1_runtime.yaml b/controllers/devbox/config/samples/devbox_v1alpha1_runtime.yaml index 1b34a17b207..774a7a5947e 100644 --- a/controllers/devbox/config/samples/devbox_v1alpha1_runtime.yaml +++ b/controllers/devbox/config/samples/devbox_v1alpha1_runtime.yaml @@ -40,13 +40,25 @@ metadata: namespace: devbox-system spec: classRef: go - title: go1.23.0 - description: go1.23.0 config: - image: ghcr.io/cbluebird/devbox/go1.23.0:2f4067 - category: - - ubuntu - - go + image: ghcr.io/labring-actions/devbox/go-1.23.0:409348 + ports: + - containerPort: 22 + name: devbox-ssh-port + protocol: TCP + appPorts: + - name: devbox-app-port + port: 8080 + protocol: TCP + user: sealos + workingDir: /home/sealos/project + releaseCommand: + - /bin/bash + - -c + releaseArgs: + - /home/sealos/project/entrypoint.sh + description: go 1.23.0 + version: "1.23.0" --- apiVersion: devbox.sealos.io/v1alpha1 kind: Runtime diff --git a/controllers/devbox/deploy/manifests/deploy.yaml.tmpl b/controllers/devbox/deploy/manifests/deploy.yaml.tmpl index b9845b8fe92..753ca75c462 100644 --- a/controllers/devbox/deploy/manifests/deploy.yaml.tmpl +++ b/controllers/devbox/deploy/manifests/deploy.yaml.tmpl @@ -2776,37 +2776,66 @@ spec: - time type: object type: array - lastTerminatedState: - description: ContainerStateTerminated is a terminated state of a container. + lastState: + description: |- + ContainerState holds a possible state of container. + Only one of its members may be specified. + If none of them is specified, the default one is ContainerStateWaiting. properties: - containerID: - description: Container's ID in the format '://' - type: string - exitCode: - description: Exit status from the last termination of the container - format: int32 - type: integer - finishedAt: - description: Time at which the container last terminated - format: date-time - type: string - message: - description: Message regarding the last termination of the container - type: string - reason: - description: (brief) reason from the last termination of the container - type: string - signal: - description: Signal from the last termination of the container - format: int32 - type: integer - startedAt: - description: Time at which previous execution of the container - started - format: date-time - type: string - required: - - exitCode + running: + description: Details about a running container + properties: + startedAt: + description: Time at which the container was last (re-)started + format: date-time + type: string + type: object + terminated: + description: Details about a terminated container + properties: + containerID: + description: Container's ID in the format '://' + type: string + exitCode: + description: Exit status from the last termination of the + container + format: int32 + type: integer + finishedAt: + description: Time at which the container last terminated + format: date-time + type: string + message: + description: Message regarding the last termination of the + container + type: string + reason: + description: (brief) reason from the last termination of the + container + type: string + signal: + description: Signal from the last termination of the container + format: int32 + type: integer + startedAt: + description: Time at which previous execution of the container + started + format: date-time + type: string + required: + - exitCode + type: object + waiting: + description: Details about a waiting container + properties: + message: + description: Message regarding why the container is not yet + running. + type: string + reason: + description: (brief) reason the container is not yet running. + type: string + type: object type: object network: properties: @@ -2831,6 +2860,67 @@ spec: description: PodPhase is a label for the condition of a pod at the current time. type: string + state: + description: |- + ContainerState holds a possible state of container. + Only one of its members may be specified. + If none of them is specified, the default one is ContainerStateWaiting. + properties: + running: + description: Details about a running container + properties: + startedAt: + description: Time at which the container was last (re-)started + format: date-time + type: string + type: object + terminated: + description: Details about a terminated container + properties: + containerID: + description: Container's ID in the format '://' + type: string + exitCode: + description: Exit status from the last termination of the + container + format: int32 + type: integer + finishedAt: + description: Time at which the container last terminated + format: date-time + type: string + message: + description: Message regarding the last termination of the + container + type: string + reason: + description: (brief) reason from the last termination of the + container + type: string + signal: + description: Signal from the last termination of the container + format: int32 + type: integer + startedAt: + description: Time at which previous execution of the container + started + format: date-time + type: string + required: + - exitCode + type: object + waiting: + description: Details about a waiting container + properties: + message: + description: Message regarding why the container is not yet + running. + type: string + reason: + description: (brief) reason the container is not yet running. + type: string + type: object + type: object type: object type: object served: true @@ -3092,6 +3182,84 @@ spec: additionalProperties: type: string type: object + appPorts: + default: + - name: devbox-app-port + port: 8080 + protocol: TCP + items: + description: ServicePort contains information on service's port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array args: description: kubebuilder:validation:Optional items: @@ -3225,6 +3393,8 @@ spec: - containerPort: 22 name: devbox-ssh-port protocol: TCP + description: 'TODO: in v1alpha2 api we need fix the port and app + port into one field and create a new type for it.' items: description: ContainerPort represents a network port in a single container. @@ -5507,11 +5677,11 @@ spec: periodSeconds: 10 resources: limits: - cpu: 500m - memory: 128Mi + cpu: 1500m + memory: 2000Mi requests: - cpu: 10m - memory: 64Mi + cpu: 100m + memory: 640Mi securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/controllers/devbox/deploy/manifests/rbac.yaml b/controllers/devbox/deploy/manifests/rbac.yaml index 315d6063700..b94ebf562c9 100644 --- a/controllers/devbox/deploy/manifests/rbac.yaml +++ b/controllers/devbox/deploy/manifests/rbac.yaml @@ -19,7 +19,7 @@ metadata: namespace: devbox-system rules: - apiGroups: [ "devbox.sealos.io" ] - resources: [ "runtimes" ] + resources: [ "runtimes", "runtimeclasses"] verbs: [ "get", "watch", "list" ] --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/controllers/devbox/internal/controller/devbox_controller.go b/controllers/devbox/internal/controller/devbox_controller.go index 3d10a3d5e5f..530a059c9ae 100644 --- a/controllers/devbox/internal/controller/devbox_controller.go +++ b/controllers/devbox/internal/controller/devbox_controller.go @@ -336,7 +336,7 @@ func (r *DevboxReconciler) syncService(ctx context.Context, devbox *devboxv1alph //use the default value servicePorts = []corev1.ServicePort{ { - Name: "tty", + Name: "devbox-ssh-port", Port: 22, TargetPort: intstr.FromInt32(22), Protocol: corev1.ProtocolTCP,