From 2e9039d60795d666096d03cd50ddb27108c12461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=92=E6=9C=A8?= <247687009@qq.com> Date: Thu, 9 Apr 2020 18:57:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4vendor=20=E4=BF=AE=E5=A4=8DEn?= =?UTF-8?q?vbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 6 +- README.md | 32 +- api/v1alpha1/springbootapplication_types.go | 15 +- ...ngboot_v1alpha1_springbootapplication.yaml | 6 +- main.go | 5 +- manifests/deployment.yaml | 138 ++++++- manifests/deployment_ali.yaml | 390 ------------------ 7 files changed, 140 insertions(+), 452 deletions(-) delete mode 100644 manifests/deployment_ali.yaml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 04c7ddd..1ab2725 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,4 +30,8 @@ jobs: docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }} docker login -u ${{ secrets.ALI_DOCKER_USERNAME }} -p ${{ secrets.ALI_DOCKER_PASSWORD }} ${{secrets.ALI_REGISTRY}} docker push freemanliu/spring-boot-operator-controller:${{ steps.create_release.outputs.tag }} - docker push registry.cn-shanghai.aliyuncs.com/qingmuio/spring-boot-operator-controller:${{ steps.create_release.outputs.tag }} \ No newline at end of file + docker tag freemanliu/spring-boot-operator-controller:${{ steps.create_release.outputs.tag }} freemanliu/spring-boot-operator-controller:latest + docker push freemanliu/spring-boot-operator-controller:latest + docker push registry.cn-shanghai.aliyuncs.com/qingmuio/spring-boot-operator-controller:${{ steps.create_release.outputs.tag }} + docker tag registry.cn-shanghai.aliyuncs.com/qingmuio/spring-boot-operator-controller:${{ steps.create_release.outputs.tag }} registry.cn-shanghai.aliyuncs.com/qingmuio/spring-boot-operator-controller:latest + docker push registry.cn-shanghai.aliyuncs.com/qingmuio/spring-boot-operator-controller:latest \ No newline at end of file diff --git a/README.md b/README.md index 49ed73a..1e0eb09 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,4 @@ # spring-boot-operator -快速体验 -```shell script -kubectl apply -f https://raw.githubusercontent.com/goudai/spring-boot-operator/master/manifests/deployment.yaml -``` -对于拉取Docker.io很慢的同学可以使用阿里云镜像仓库 -```shell script -kubectl apply -f https://raw.githubusercontent.com/goudai/spring-boot-operator/master/manifests/deployment_ali.yaml -``` - -等待启动完成 -```shell script -kubectl get po -A | grep spring-boot-operator -``` -编写第一个 spring-boot demo -Demo Github地址:https://github.com/goudai/operator-demo - -```yaml -apiVersion: springboot.qingmu.io/v1alpha1 -kind: SpringBootApplication -metadata: - name: operator-demo - namespace: default -spec: - springBoot: - version: v1.0.0 - replicas: 1 -``` -部署 -```shell script -kubectl apply -f https://raw.githubusercontent.com/goudai/spring-boot-operator/master/manifests/demo1.yaml -``` +文档 [https://qingmu.io/2020/04/08/Spring-Boot-Operator-User-Guide/](https://qingmu.io/2020/04/08/Spring-Boot-Operator-User-Guide/) diff --git a/api/v1alpha1/springbootapplication_types.go b/api/v1alpha1/springbootapplication_types.go index 91061f6..848d9a6 100644 --- a/api/v1alpha1/springbootapplication_types.go +++ b/api/v1alpha1/springbootapplication_types.go @@ -175,13 +175,18 @@ func (s *SpringBoot) Check(Name string) (*SpringBoot, error) { if s.Env == nil { s.Env = []v1.EnvVar{} } + envStringMap := make(map[string]string) + for _, v := range s.Env { + envStringMap[v.Name] = v.Value + } if len(config.Env) > 0 { - for k, v := range config.Env { - s.Env = append(s.Env, v1.EnvVar{ - Name: k, - Value: v, - }) + if _, ok := envStringMap[k]; !ok { + s.Env = append(s.Env, v1.EnvVar{ + Name: k, + Value: v, + }) + } } } diff --git a/config/samples/springboot_v1alpha1_springbootapplication.yaml b/config/samples/springboot_v1alpha1_springbootapplication.yaml index 682c7c8..0209c2c 100644 --- a/config/samples/springboot_v1alpha1_springbootapplication.yaml +++ b/config/samples/springboot_v1alpha1_springbootapplication.yaml @@ -27,8 +27,10 @@ spec: imagePullSecrets: #可以不设置 如果你使用的都是公开仓库的话, 私有仓库请设置该值, - aliyun-docker-registry-secret env: #可以不设置 环境变量 - - name: EUREKA_SERVERS - value: http://eureka1:8761/eureka/,http://eureka2:8761/eureka/,http://eureka3:8761/eureka/ + - name: EUREKA_SERVER + value: http://eureka1:888/eureka/ + - name: k + value: v2 nodeAffinity: #可以不设置 节点亲和 这里演示的是尽量将pod分散到 i h g 三个可用区,默认设置了pod反亲和 key: "failure-domain.beta.kubernetes.io/zone" operator: "In" diff --git a/main.go b/main.go index e8441e7..1cb9d73 100644 --- a/main.go +++ b/main.go @@ -192,12 +192,13 @@ func onStart() { config.ImagePullSecrets = strings.Split(imagePullSecrets, ",") } - Env := os.Getenv("Env") + Env := os.Getenv("SPRING_BOOT_ENV") if Env == "" { setupLog.Info("Not set env Env") } else { + config.Env = make(map[string]string) setupLog.Info("Get user set env value ", "Env", Env) - for _, kv := range strings.Split(imagePullSecrets, ",") { + for _, kv := range strings.Split(Env, ";") { kyarray := strings.Split(kv, "=") if len(kyarray) == 2 { config.Env[kyarray[0]] = kyarray[1] diff --git a/manifests/deployment.yaml b/manifests/deployment.yaml index f01201b..7a6ff34 100644 --- a/manifests/deployment.yaml +++ b/manifests/deployment.yaml @@ -1,10 +1,3 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - name: spring-boot-operator-system ---- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: @@ -48,10 +41,111 @@ spec: cluster ip). "" by default type: string env: - additionalProperties: - type: string description: The spring boot application env. - type: object + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previous defined environment variables in the + container and any service environment variables. If a variable + cannot be resolved, the reference in the input string will + be unchanged. The $(VAR_NAME) syntax can be escaped with + a double $$, ie: $$(VAR_NAME). Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, metadata.labels, metadata.annotations, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array image: description: The spring boot application Image If the value is empty,using fmt.Sprintf("%s/%s:%s", config.ImageRepository, Name, s.Version) @@ -73,9 +167,9 @@ spec: type: string type: array required: - - key - - operator - - values + - key + - operator + - values type: object path: description: The spring boot application path Liveness and Readiness is @@ -135,7 +229,7 @@ spec: type: string type: object required: - - springBoot + - springBoot type: object status: description: SpringBootApplicationStatus defines the observed state of SpringBootApplication @@ -143,15 +237,16 @@ spec: type: object version: v1alpha1 versions: - - name: v1alpha1 - served: true - storage: true + - name: v1alpha1 + served: true + storage: true status: acceptedNames: kind: "" plural: "" conditions: [] storedVersions: [] + --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -353,9 +448,9 @@ spec: - name: LIMIT_CPU value: "" - name: REQUEST_MEMORY - value: 500Mi + value: 512Mi - name: LIMIT_MEMORY - value: 500Mi + value: 512Mi - name: READINESS_PATH value: /actuator/health - name: LIVENESS_PATH @@ -376,9 +471,10 @@ spec: value: "" - name: NODE_AFFINITY_VALUES value: "" - - name: ENV + - name: SPRING_BOOT_ENV value: "" - image: freemanliu/spring-boot-operator-controller:v0.0.2 + image: freemanliu/spring-boot-operator-controller:latest + imagePullPolicy: Always name: manager resources: limits: diff --git a/manifests/deployment_ali.yaml b/manifests/deployment_ali.yaml deleted file mode 100644 index 8f56d1d..0000000 --- a/manifests/deployment_ali.yaml +++ /dev/null @@ -1,390 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - name: spring-boot-operator-system ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.2.5 - creationTimestamp: null - name: springbootapplications.springboot.qingmu.io -spec: - group: springboot.qingmu.io - names: - kind: SpringBootApplication - listKind: SpringBootApplicationList - plural: springbootapplications - singular: springbootapplication - scope: Namespaced - validation: - openAPIV3Schema: - description: SpringBootApplication is the Schema for the springbootapplications - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: SpringBootApplicationSpec defines the desired state of SpringBootApplication - properties: - springBoot: - description: The spring boot body - properties: - clusterIp: - description: The spring boot application service ip (kube-proxy - cluster ip). "" by default - type: string - env: - additionalProperties: - type: string - description: The spring boot application env. - type: object - image: - description: The spring boot application Image If the value is empty,using - fmt.Sprintf("%s/%s:%s", config.ImageRepository, Name, s.Version) - by default - type: string - imagePullSecrets: - description: The pull image secrets. - items: - type: string - type: array - nodeAffinity: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - - values - type: object - path: - description: The spring boot application path Liveness and Readiness is - '/actuator/health' by default HostLog is '/var/applog' by default - Shutdown is '/spring/shutdown' by default - properties: - hostLog: - description: HostLog is '/var/applog' by default - type: string - liveness: - description: Liveness is '/actuator/health' by default - type: string - readiness: - description: ' Readiness is ''/actuator/health'' by default' - type: string - shutdown: - description: Shutdown is '/spring/shutdown' by default - type: string - type: object - port: - description: The spring boot application Port - format: int32 - type: integer - replicas: - description: The spring boot application replicas. 3 by default - format: int32 - type: integer - resource: - description: The spring boot application Resource(Cpu,Memory) 2Gi - Request Memory by default. 2Gi Limit Memory by default. 100m Request - Cpu by default. Un limit Cpu by default. - properties: - cpu: - description: Cpu resource - properties: - limit: - description: Un limit Cpu by default. - type: string - request: - description: 100m Request Cpu by default. - type: string - type: object - memory: - description: Memory resource - properties: - limit: - description: 2Gi Limit Memory by default. - type: string - request: - description: 2Gi Request Memory by default. - type: string - type: object - type: object - version: - description: The spring boot application image version. this is - required - type: string - type: object - required: - - springBoot - type: object - status: - description: SpringBootApplicationStatus defines the observed state of SpringBootApplication - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: spring-boot-operator-leader-election-role - namespace: spring-boot-operator-system -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - configmaps/status - verbs: - - get - - update - - patch -- apiGroups: - - "" - resources: - - events - verbs: - - create ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: spring-boot-operator-manager-role -rules: -- apiGroups: - - springboot.qingmu.io - resources: - - springbootapplications - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - springboot.qingmu.io - resources: - - springbootapplications/status - verbs: - - get - - patch - - update -- apiGroups: - - "" - resources: - - pods - - services - - endpoints - - persistentvolumeclaims - - events - verbs: - - "*" -- apiGroups: - - apps - resources: - - deployments - verbs: - - "*" ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: spring-boot-operator-proxy-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - name: spring-boot-operator-metrics-reader -rules: -- nonResourceURLs: - - /metrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: spring-boot-operator-leader-election-rolebinding - namespace: spring-boot-operator-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: spring-boot-operator-leader-election-role -subjects: -- kind: ServiceAccount - name: default - namespace: spring-boot-operator-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: spring-boot-operator-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: spring-boot-operator-manager-role -subjects: -- kind: ServiceAccount - name: default - namespace: spring-boot-operator-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: spring-boot-operator-proxy-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: spring-boot-operator-proxy-role -subjects: -- kind: ServiceAccount - name: default - namespace: spring-boot-operator-system ---- -apiVersion: v1 -kind: Service -metadata: - labels: - control-plane: controller-manager - name: spring-boot-operator-controller-manager-metrics-service - namespace: spring-boot-operator-system -spec: - ports: - - name: https - port: 8443 - targetPort: https - selector: - control-plane: controller-manager ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - control-plane: controller-manager - name: spring-boot-operator-controller-manager - namespace: spring-boot-operator-system -spec: - replicas: 1 - selector: - matchLabels: - control-plane: controller-manager - template: - metadata: - labels: - control-plane: controller-manager - spec: - containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=2 - image: registry.cn-shanghai.aliyuncs.com/qingmuio/kube-rbac-proxy:v0.5.0 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - - args: - - --metrics-addr=127.0.0.1:8080 - - --enable-leader-election - command: - - /manager - env: - - name: IMAGE_REPOSITORY - value: registry.cn-shanghai.aliyuncs.com/qingmuio - - name: REQUEST_CPU - value: 50m - - name: LIMIT_CPU - value: "" - - name: REQUEST_MEMORY - value: 500Mi - - name: LIMIT_MEMORY - value: 500Mi - - name: READINESS_PATH - value: /actuator/health - - name: LIVENESS_PATH - value: /actuator/health - - name: SHUTDOWN_PATH - value: /spring/shutdown - - name: REPLICAS - value: "3" - - name: HOST_LOG_PATH - value: /var/applog - - name: IMAGE_PULL_SECRETS - value: "" - - name: SPRING_BOOT_DEFAULT_PORT - value: "8080" - - name: NODE_AFFINITY_KEY - value: "" - - name: NODE_AFFINITY_OPERATOR - value: "" - - name: NODE_AFFINITY_VALUES - value: "" - - name: ENV - value: "" - image: registry.cn-shanghai.aliyuncs.com/qingmuio/spring-boot-operator-controller:v0.0.2 - name: manager - resources: - limits: - cpu: 100m - memory: 30Mi - requests: - cpu: 100m - memory: 20Mi - terminationGracePeriodSeconds: 10