Source: the qingmu. IO / 2020/04/08 /…

preface

While deploying Spring Boot applications in Kubernetes is generally a chore, Spring Boot Operator provides a cleaner and simpler experience.

Spring Boot Operator based on Kubernetes Custom Resource Definitions (CRDs) extension API for development.

Package the Docker image

Before we can talk about deployment we need to package our SpringBoot application as a standard DockerImage.

The recommendation of a Spring foundation of the Boot will not introduced, the actual combat tutorial: www.javastack.cn/categories/…

Java project package image with Maven/Gradle plug-in is more, my other article to build SpringBoot Docker image, here introduces a new Google open source plug-in Jib, which is more convenient to use.

Note: The jib packed image causes the Java application to have a pid=1, and when published using SpringBootOperator, Operator sets the Kubernetes ShareProcessNamespace parameter to true (available in v1.10+ versions) to resolve the problem.

IO to generate a standard SpringBoot project operator-demo, and then use the JIB plug-in for image packaging

scriptmvn com.google.cloud.tools:jib-maven-plugin:build \ -Djib.to.auth.username=${{ secrets.MY_USERNAME }} \ -Djib.to.auth.password=${{ secrets.MY_PASSWORD }} \ - Djib. Container. JvmFlags = -- -- add - opens, Java. The base/sun. Nio. Ch = ALL - UNNAMED \ - Djib. From the image = freemanliu/oprenjre: 11.0.5 \ - Dimage=registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0Copy the code

After executing the above command, we will get a standard Docker image, which will be pushed to the remote repository.

Quick Operator experience

After constructing the image, we will install our Operator to the Kubernetes cluster. Of course, you need a cluster first, please refer to my previous article.

Fast installation

This quick installation is just for a quick demo experience

scriptkubectl apply -f https://raw.githubusercontent.com/goudai/spring-boot-operator/master/manifests/deployment.yaml
Copy the code

Console output after apply succeeds

namespace/spring-boot-operator-system created
customresourcedefinition.apiextensions.k8s.io/springbootapplications.springboot.qingmu.io created
role.rbac.authorization.k8s.io/spring-boot-operator-leader-election-role created
clusterrole.rbac.authorization.k8s.io/spring-boot-operator-manager-role created
clusterrole.rbac.authorization.k8s.io/spring-boot-operator-proxy-role created
clusterrole.rbac.authorization.k8s.io/spring-boot-operator-metrics-reader created
rolebinding.rbac.authorization.k8s.io/spring-boot-operator-leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/spring-boot-operator-manager-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/spring-boot-operator-proxy-rolebinding created
service/spring-boot-operator-controller-manager-metrics-service created
deployment.apps/spring-boot-operator-controller-manager created
Copy the code

Wait for a moment to check whether the installation is successful

scriptkubectl  get po -n spring-boot-operator-system
Copy the code

Successful output is as follows

NAME                                                       READY   STATUS    RESTARTS   AGE
spring-boot-operator-controller-manager-7f498596bb-wcwtn   2/2     Running   0          2m15s
Copy the code

Deploy OperatorDemo

With Operator deployed, we will deploy our first application, which we will release with opreator-Demo, the Springboot application we wrote above. First we need to write a Spring Boot Application CRD deployment yamL, as follows

# Demo.yaml
apiVersion: springboot.qingmu.io/v1alpha1
kind: SpringBootApplication
metadata:
  name: operator-demo 
spec:
  springBoot:
    version: v1.0.0
#    image: registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0
Copy the code

Careful students may have noticed, why there is no Image? How can I publish this, just name, version? Yes, it is! And we’ll talk more about how he did that. And then let’s apply

scriptkubectl apply -f Demo.yaml
Copy the code

See the console output

springbootapplication.springboot.qingmu.io/operator-demo created
Copy the code

validation

After that, let’s look at the first application we deployed, where we can filter by name in YAML above. Check the pod

script~# kubectl  get po | grep operator-demo
operator-demo-7574f4789c-mg58m             1/1     Running   0          76s
operator-demo-7574f4789c-ssr8v             1/1     Running   0          76s
operator-demo-7574f4789c-sznww             1/1     Running   0          76s
Copy the code

Kubernetes ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace = ShareProcessNamespace

Scriptkubectl exec it operator-demo-7574f4789c-mg58m bash bash-5.0# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 02:06? 00:00:00 /pause root 6 0 26 02:06 ? 00:00:09 java --add-opens java.base/sun.nio.ch=ALL-UNNAMED -cp /app/resources:/app/classes:/app/libs/* io.qingmu.operator.operatordemo.Oper... root 38 0 0 02:07 pts/0 00:00:00 bash root 44 38 0 02:07 pts/0 00:00:00 ps -efCopy the code

View the SVC

Script ~ # kubectl get SVC | grep operator - demo operator - demo ClusterIP 10.101.128.6 < none > 2 m52s 8080 / TCPCopy the code

Let’s try it out.

scriptroot@server1:~# curl -i http://10.101.128.6:8080 HTTP/1.1 200 Content-type: text/plain; charset=UTF-8 Content-Length: 9 Date: Wed, 08 Apr 2020 08:45:46 GMT hello !!!Copy the code

Let’s try to reduce the number of replicas to 1 by editing our demo. yaml and adding a new property replicas

# Demo.yaml
apiVersion: springboot.qingmu.io/v1alpha1
kind: SpringBootApplication
metadata:
  name: operator-demo 
spec:
  springBoot:
    version: v1.0.0
    replicas: 1
Copy the code

The application

scriptroot@server1:~# kubectl apply -f Demo.yaml 
springbootapplication.springboot.qingmu.io/operator-demo configured
Copy the code

Looking at the POD again, you will see that our POD has been scaled to a copy

script~# kubectl  get po | grep operator-demo
operator-demo-7574f4789c-sznww             1/1     Running   0          8m29s
Copy the code

Clean up the operator – demo

To delete the pod, simply execute delete

script~# kubectl delete -f Demo.yaml 
springbootapplication.springboot.qingmu.io "operator-demo" deleted
Copy the code

Check the POD again. It’s gone

scriptkubectl  get po | grep operator-demo
Copy the code

Deploy your own applications

Create the Secret of docker-Registry if you have already created one

scriptkubectl create  \
secret docker-registry aliyun-registry-secret \
--docker-server=registry-vpc.cn-hangzhou.aliyuncs.com \
--docker-username=*** \
--docker-password=*** \
--docker-email=***
Copy the code

Their own application of CRD Yaml

ApiVersion: springboot. Qingmu. IO/v1alpha1 kind: SpringBootApplication metadata: name: the name of your application spec: springboot: Version: v1.0.0 replicas: 1 image: your image address imagePullSecrets: - Create secret aboveCopy the code

A complete Spring Boot Application Yaml

Here is a complete yamL attribute structure, most of which can be used with the default configuration. By default, the general values set in Operator are used. For details, see Customizing Operator installation later.

The recommendation of a Spring foundation of the Boot will not introduced, the actual combat tutorial: www.javastack.cn/categories/…

apiVersion: springboot.qingmu.io/v1alpha1 kind: SpringBootApplication metadata: name: operator-demo namespace: default spec: springBoot: # image can be left unset, If they are not used to set the default IMAGE_REPOSITORY + / + mate. The name + : + spec. SpringBoot. The version # registry.cn-shanghai.aliyuncs.com/qingmuio + / + Operator - demo + : + v1.0.0 image: registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo:v1.0.0 clusterIp: Version: v1.0.0 Replicas: 1 Resource: CPU: request: 50m limit: "" Memory: Request: 1Gi limit: 1Gi path: liVENESS: /actuator/health readiness: /actuator/health hostLog: /var/applog shutdown: /spring/shutdown imagePullSecrets: - aliyun-docker-registry-secret env: - name: EUREKA_SERVERS value: http://eureka1:8761/eureka/,http://eureka2:8761/eureka/,http://eureka3:8761/eureka/ nodeAffinity: key: "failure-domain.beta.kubernetes.io/zone" operator: "In" values: - "cn-i" - "cn-h" - "cn-g"Copy the code

The path to elegant downtime

Since elegant downtime is turned off by default and does not support Get requests, we need to enable and bridge it first in application.yml

management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    shutdown:
      enabled: true
Copy the code

Then bridge over a Get method

@RestController public class ShutdownController { @Autowired private ShutdownEndpoint shutdownEndpoint; @GetMapping("/spring/shutdown") public Map<String, String> shutdown(HttpServletRequest request) { return shutdownEndpoint.shutdown(); }}Copy the code

Node affinity use

For example, we have a Springboot application user-Service that we want to distribute to six nodes in three availability zones: first we divide the machine into multiple availability zones

Cn-i area (Node-i1, Node-i02) CN-H area (Node-G1, Node-g02) CN-G area (Node-h1, Node-h02)Copy the code

Now we have three workload zones with 2 workload units in each zone, 6 workload units in total. Then we need to label these machines separately. Mark all machines in zone I as CN-I

scriptkubectl label node node-i1 failure-domain.beta.kubernetes.io/zone=cn-i
kubectl label node node-i2 failure-domain.beta.kubernetes.io/zone=cn-i
Copy the code

In the same way, label area H as h, and area G as well

scriptkubectl label node node-h1 failure-domain.beta.kubernetes.io/zone=cn-i
kubectl label node node-ih2 failure-domain.beta.kubernetes.io/zone=cn-i
Copy the code

Now that we’re ready, let’s set it up to do what we want it to do, as follows.

Spec: springBoot: nodeAffinity: "failure-domain.beta.kubernetes.io/zone" operator: "In" values: - "cn-i" - "cn-h" - "cn-g"Copy the code

Operator Custom installation

Now that we’ve done a quick setup, we’re going to show you how to customize the setup, and what kind of custom parameters are available, which we can use as environment variables to inject. Let’s change the Deployment to complete our personalized Deployment. Pull back from the Deployment YAML I provided and find the Deployment whose name is Spring-boot-operator-controller-manager and we will change it.

apiVersion: apps/v1 kind: Deployment metadata: labels: control-plane: controller-manager name: spring-boot-operator-controller-manager namespace: spring-boot-operator-system ..... # note: The following configuration applies to the general and global Spring Boot default configuration, which is valid for CRD Spring Boot. Such as my final packaging image address registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0 # configuration value is Registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo # configuration after this value, we if we don't write in distribution of yaml image, IMAGE_REPOSITORY+"/"+mate.name+ spec.springboot. version-name: IMAGE_REPOSITORY value: Registry.cn-shanghai.aliyuncs.com/qingmuio # request CPU limits - name: REQUEST_CPU value: - name: LIMIT_CPU value: "" # REQUEST_MEMORY value: - name: LIMIT_MEMORY value: 500Mi # Check Path, Spring boot actuator default path-name: READINESS_PATH value: # / physical health in order to survive the Path, spring boot default Path - name: physical LIVENESS_PATH value: / skeletonoid /health # Standby standby Path - name: SHUTDOWN_PATH value: /spring/shutdown # REPLICAS value: - name: HOST_LOG_PATH value: /var/applog # IMAGE_PULL_SECRETS value: "" # pull_secrets name: SPRING_BOOT_DEFAULT_PORT value Name: NODE_AFFINITY_KEY value: "" - name: NODE_AFFINITY_KEY NODE_AFFINITY_OPERATOR value: "" - name: NODE_AFFINITY_VALUES value: "" K1 = v2, # as EUREKA_SERVERS = http://eureka1:8761/eureka/, http://eureka2:8761/eureka/, http://eureka3:8761/eureka/; k=v - name: SPRING_BOOT_ENV value: "" image: registry.cn-shanghai.aliyuncs.com/qingmuio/spring-boot-operator-controller:latest .....Copy the code

Deploy after custom installation

Yaml can be simplified as follows.

ApiVersion: springboot. Qingmu. IO/v1alpha1 kind: SpringBootApplication metadata: name: the name of your application spec: springboot: Version: v1.0.0Copy the code

The appendix

Table of environment variables

Environment variable name Is it ok to empty The default value instructions
IMAGE_REPOSITORY true “” The address of the private warehouse
REQUEST_CPU true 50m Request CPU limit
LIMIT_CPU true “” Maximum CPU Usage Maximum CPU Usage Java applications can be used without limitation, which results in slow startup
REQUEST_MEMORY true 2Gi Requested memory size
LIMIT_MEMORY true 2Gi The maximum memory size is usually the same as the request size
READINESS_PATH true /actuator/health Ready Check the Path. Spring Boot Actuator default Path
LIVENESS_PATH true /actuator/health Live check Path, Spring Boot Actuator default Path
SHUTDOWN_PATH true /spring/shutdown Ready survival Path, graceful shutdown Path
REPLICAS true 3 replications
HOST_LOG_PATH true /var/applog Mount logs to host disk Path. By default, they are the same
IMAGE_PULL_SECRETS true There is no Secrets for pull images
SPRING_BOOT_DEFAULT_PORT true 8080 Secrets for pull images
NODE_AFFINITY_KEY true “” Node affinity key, for example, I can set pod as far as possible in different available areas CN-I, CN-g, CN-H area
NODE_AFFINITY_OPERATOR true “” Node affinity operator
NODE_AFFINITY_VALUES true “” The node and the value
SPRING_BOOT_ENV true “” The global environment variable is appended to each pod in each Spring Boot in the format k=v; k1=v2

Recent hot articles recommended:

1.1,000+ Java Interview Questions and Answers (2021)

2. Don’t use if/ else on full screen again, try strategy mode, it smells good!!

3. Oh, my gosh! What new syntax is xx ≠ null in Java?

4.Spring Boot 2.6 is out with a lot of new features.

5. “Java Development Manual (Songshan version)” the latest release, quick download!

Feel good, don’t forget to click on + forward oh!