At present, more Internet companies are trying to move microservices to the cloud, so that it is more convenient to manage microservice clusters through some mature cloud container management platforms, thus improving the stability of microservices and improving team development efficiency.

However, there are certain technical difficulties in migrating cloud, today this article mainly introduces how to build a set of SpringBoot case tutorial based on K8s deployment from 0.

Basic environment Preparation:

  • MAC Operating System
  • Simple Web project for SpringBoot

Minikube environment setup

To install a k8S environment suitable for our beginners, a good recommendation is to use the minikube tool, and use this tool to better lower our k8S learning threshold. First we need to download the minikube file:

The curl - Lo minikube https://github.com/kubernetes/minikube/releases/download/v1.5.0/minikube-linux-amd64 && chmod + x minikube && sudo mv minikube /usr/local/bin/Copy the code

When installing minikube, you may get stuck trying to download the image, such as the following exception:

Mac 】 【 idea @ > > > > > > minikube start - registry-mirror=https://w4i0ckag.mirror.aliyuncs.com πŸ˜„ Darwin 10.15.3 minikube V1.16.0 ✨ Using the docker driver πŸ‘ Starting Control plane node minikube in cluster minikube 🚜 Pulling base image according to the existing configuration files... E0126 17:03:30.131026 34416 Cache. Go :180] Error Downloading kic artifacts Failed to download kic base image or any fallback image πŸ”₯ Creating docker container (CPUs=2, Memory=1988MB)... 🀦 StartHost failed, but will try again: creating host: creating: setting up container node: preparing volume for minikube container: docker run --rm --entrypoint /usr/bin/test -v minikube:/var GCR. IO/k8s - minikube kicbase: v0.0.15 - snapshot4 @ sha256: ef1f485b5a1cfa4c989bc05e153f0a8525968ec999e242efff871cbb31649c16 - d  /var/lib: exit status 125 stdout: stderr: Unable to find image 'the GCR. IO/k8s - minikube/kicbase: v0.0.15 - snapshot4 @ sha256: ef1f485b5a1cfa4c989bc05e153f0a8525968ec999e242efff871cbb31649c16' locally docker: Error response from daemon: Get https://gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers). See 'docker run --help'. 🀷 docker "minikube" container is missing, will make. πŸ”₯ Creating docker container (CPUs=2, Memory=1988MB)... 😿 Failed to start docker container. Running "minikube delete" may fix it: Concept: creating host: create: creating: setting up container node: preparing volume for minikube container: docker run --rm --entrypoint /usr/bin/test -v minikube:/var GCR. IO/k8s - minikube kicbase: v0.0.15 - snapshot4 @ sha256: ef1f485b5a1cfa4c989bc05e153f0a8525968ec999e242efff871cbb31649c16 - d  /var/lib: exit status 125 stdout: stderr: Unable to find image 'the GCR. IO/k8s - minikube/kicbase: v0.0.15 - snapshot4 @ sha256: ef1f485b5a1cfa4c989bc05e153f0a8525968ec999e242efff871cbb31649c16' locally docker: Error response from daemon: Get https://gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers). See 'docker run --help'. ❌ Withdraw due to GUEST_PROVISION: Failed to start host: concept: creating host: create: creating: setting up container node: preparing volume for minikube container: docker run --rm --entrypoint /usr/bin/test -v minikube:/var GCR. IO/k8s - minikube kicbase: v0.0.15 - snapshot4 @ sha256: ef1f485b5a1cfa4c989bc05e153f0a8525968ec999e242efff871cbb31649c16 - d  /var/lib: exit status 125 stdout: stderr: Unable to find image 'the GCR. IO/k8s - minikube/kicbase: v0.0.15 - snapshot4 @ sha256: ef1f485b5a1cfa4c989bc05e153f0a8525968ec999e242efff871cbb31649c16' locally docker: Error response from daemon: Get https://gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers). See 'docker run --help'. 😿 If the above advice does not help, do let us know: πŸ‘‰ https://github.com/kubernetes/minikube/issues/new/chooseCopy the code

In this case, you can try to install the corresponding image file on the host first:

docker pull anjone/kicbase
Copy the code

Minikube then starts with a local image, which reduces the time required for the minikube start process. Minikube has been downloaded and it’s time to start:

minikube start --vm-driver=docker --base-image="anjone/kicbase"
Copy the code

If the startup fails, try replacing the specified mirror warehouse, such as the following:

minikube start 
--registry-mirror=https://bmtb46e4.mirror.aliyuncs.com 
--vm-driver=docker 
--base-image="anjone/kicbase" 
--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers
Copy the code

Here I will outline the meanings of startup parameters:

  • --registry-mirrorThe address will be the same as the address of the mirror repository pointed to in the docker.daemon file inside the startup minikube.
  • --vm-driverThe virtual machine engine here refers to the interior of minikube with Docker as the core
  • --base-imageDeclare the base image. If the host has an internal image, no additional pull is required
  • --image-repositoryWarehouse to pull the mirror

When minikube is successfully started, it looks something like this:

【idea @mac 】>>>>>>minikube start -- vM-driver =docker --base-image="anjone/kicbase" πŸ˜„ Minikube v1.16.0 on Darwin 10.15.3 ✨ Use the docker driver πŸ‘ Starting control plane node minikube in cluster minikube 🀷 docker "minikube" container is based on the existing configuration file πŸ”₯ Creating docker container (CPUs=2, Memory=1988MB)... ❗ This container is having trouble accessing https://k8s.gcr.io πŸ’‘ To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/ is 🐳 Docker 19.03.2 prepared Kubernetes v1.20.0... β–ͺ Generating Certificates and Keys... β–ͺ Booting up control plane... \ Configuring RBAC Rules... πŸ”Ž Verifying Kubernetes components... 🌟 Enabled Addons: default-storageclass πŸ„ Done! Kubectl is now configured to use "minikube" cluster and "default" namespace by default [idea @mac] >>>>>>Copy the code

Okay, now it’s time to deploy the SpringBoot application.

Deploy to K8S based on SpringBoot

First we need to build a simple SpringBoot application:

Introducing dependency dependency

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId>  </dependency> </dependencies>Copy the code

Docker image package configuration:

<build> <finalName> <plugins> <plugin> <groupId> org.springFramework. boot</groupId> < artifactId > spring - the boot - maven - plugin < / artifactId > < version > 2.2.5. RELEASE < / version > < / plugin > <! -- Docker maven plugin --> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.0.0</version> < Configuration > <imageName>${project.artifactId}</imageName> <imageTags> <tag>1.0.1</tag> </imageTags> <dockerDirectory>src/main/docker</dockerDirectory> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> <! -- Docker maven plugin --> </plugins> </build>Copy the code

Then there are the simple Controller and startup classes:

@RestController @RequestMapping(value = "/test") public class TestController { @GetMapping(value = "/do-test") public String doTest(){ System.out.println("this is a test"); return "success"; } } @SpringBootApplication public class WebApplication { public static void main(String[] args) { SpringApplication.run(WebApplication.class); }}Copy the code

Dockerfile script:

FROM openJDK :8-jdk-alpine VOLUME/TMP # copy springboot-k8s-template.jar to openboot-k8s-template-v1.jar Jar springboot-k8s-template-v1.jar # is equivalent to running the CMD command in the container to specify the external configuration file ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/springboot-k8s-template-v1.jar"]Copy the code

Then go to the directory of Dockerfile and build the image:

>>>>>>docker build -t Springboot-k8s-template :1.0. [+] Building 0.5s (7/7) FINISHED => [internal] Load Build definition from Dockerfile 2.0s => => Dokerfile: 419B 0.9s => [internal] load.dockerignore 0.9s => => transferring-transferring-context: 2 b 0.0 s = > (internal) load metadata for docker. IO/library/its: 8 - JDK - 0.0 s = > alpine/internal load build context 0.9s => => transferring-window context: 17.60 MB 0.3 s = > CACHED [1/2] FROM docker. IO/library/its: 8 - JDK - 0.0 s = > alpine [2/2] ADD springboot - k8s - the template. The jar Springboot-k8s-template-v1.jar 0.1s => exporting to image 0.1s => => exporting layers 0.1s => => Writing image Sha256:86 d02961c4fa5bb576c91e3ebf031a3d8b140ddbb451b9613a2c4d601ac4d853 0.0 s = > = > naming the to Docker. IO/library/springboot - k8s - template: 1.0 0.0 s Use 'docker scan' to run Snyk tests against images to find Vulnerabilities and learn how to fix them [the idea @ Mac] > > > > > > docker images | grep template springboot - k8s - 1.0 template 86d02961c4fa 48 seconds ago 122MBCopy the code

After the completion of construction, the local image was packaged and published to the mirror warehouse. Here, I processed it by pushing it to the Ali Cloud mirror warehouse.

Recommendation:Spring Advanced source family bucket

Push local image to Ali cloud

The first step is to log in to the Docker warehouse, then record the corresponding tag information, and finally push the image.

$docker login --username=[aliyuncs.com $docker tag [ImageId] Registry.cn-qingdao.aliyuncs.com/idea_hub/idea_resp: [the mirror version number] $docker push Registry.cn-qingdao.aliyuncs.com/idea_hub/idea_resp: [the mirror version number]Copy the code

Such as:

Mac 】 【 idea @ > > > > > > docker images | grep config qiyu - framework - k8s - 1.0 6168639757 e9 config 2 minutes line 122 MB 【 idea @ Mac 】 ξ€€ > > > > > > docker tag 6168639757 e9 registry.cn-qingdao.aliyuncs.com/idea_hub/idea_resp:qiyu-framework-k8s-config-1.0 Mac 】 【 idea @ > > > > > > docker push registry.cn-qingdao.aliyuncs.com/idea_hub/idea_resp:qiyu-framework-k8s-config-1.0 The push  refers to repository [registry.cn-qingdao.aliyuncs.com/idea_hub/idea_resp] 1ace00556b41: Pushed ceaf9e1ebef5: Layer already exists 9b9b7f3d56a0: Layer already exists f1b5933fe4b5: Layer already exists qiyu-framework- k8S-config-1.0: Digest: Sha256:50 c1a87484f6cbec699d65321fa5bbe70f5ad6da5a237e95ea87c7953a1c80da size: 1159 "idea @ Mac" > > > > > >Copy the code

In this example, replace [ImageId] and [Image version] with the actual image information.

After the image file is packaged and pushed to the image repository, you can write the corresponding image address in the YAML file so that the image file can be pulled from the repository when the image is downloaded.

We usually use a unified YAML file to deploy and build pod nodes in projects.

Yaml configuration file:

ApiVersion: apps/v1 #kubectl API -versions this directive can be used to view version information. Kind: Deployment # Springboot-k8s-template-deployment #deloyment Name labels: app: springboot-k8s-template-deployment # tag spec: replicas: Selector: matchLabels: app: springboot-k8s-template-deployment selector: matchLabels: app: springboot-k8s-template-deployment labels: app: springboot-k8s-template-v1 spec: containers: - name: springboot-k8s-template-v1 image: Registry.cn-qingdao.aliyuncs.com/idea_hub/idea_resp:1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 8080Copy the code

Because ali cloud image warehouse requires user account password permission to access, so here we can try some simple strategy, login minikube inside, download the corresponding Ali cloud image in advance.

The minikube SSH command is used to log in to the minikube internals:

Use the Docker pull instruction to download the corresponding resources:

Docker @ minikube: ~ $docker pull registry.cn-qingdao.aliyuncs.com/idea_hub/idea_resp:springboot-k8s-template-1.0 Springboot-k8s-template-1.0: Pulling from idea_hub/idea_resp e7c96DB7181b: Already exists F910a506b6CB: Already exists c2274a1a0e27: Already exists d2fe98fe1e4e: Pull complete Digest: sha256:dc1c9caa101df74159c1224ec4d7dcb01932aa8f4a117bba603ffcf35e91c60c Status: Downloaded newer image for registry.cn-qingdao.aliyuncs.com/idea_hub/idea_resp:springboot-k8s-template-1.0 Registry.cn-qingdao.aliyuncs.com/idea_hub/idea_resp:springboot-k8s-template-1.0 docker @ minikube: ~ $Copy the code

View the image file

Mirror pull strategy can be compared to the official website to understand the system:

Kubernetes. IO/docs/concep…

In the YAML file, I used the IfNotPresent policy, which ensures that if there is a local mirror, the local mirror is selected first, and if there is no local mirror, the network pull is selected.

Finally, find the relevant YAML file to start the pod deployment.

kubectl create -f ./k8s-springboot-template.yaml 
Copy the code

Kubectl get pod node kubectl get pod node

Finally, the Deployment service needs to be exposed:

>>>>>> kubectl expose deployment springboot-k8s-template-deployment --type=NodePort Service /springboot-k8s-template-deployment exposed >>>>>> kubectl get Pods NAME READY STATUS RESTARTS AGE springboot-k8s-template-deployment-687f8bf86d-gqxcp 1/1 Running 0 7m50s Springboot-k8s-template-deployment-687f8bf86d-lcq5p 1/1 Running 0 7m50s 【idea @ tap my iterm2 say 】>>>>>> minikube service springboot-k8s-template-deployment |-----------|------------------------------------|-------------|---------------------------| | NAMESPACE | NAME | TARGET  PORT | URL | |-----------|------------------------------------|-------------|---------------------------| | default | Springboot - k8s - the template - deployment | 8080 | | http://192.168.49.2:31179 | -- -- -- -- -- -- -- -- -- -- - | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | -- -- -- -- -- -- -- -- -- -- -- -- - | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | πŸƒ Starting tunnel for service springboot-k8s-template-deployment. |-----------|------------------------------------|-------------|------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-----------|------------------------------------|-------------|------------------------| | default | Springboot - k8s - the template - deployment | | | http://127.0.0.1:57109 | -- -- -- -- -- -- -- -- -- -- - | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | -- -- -- -- -- -- -- -- -- -- -- -- - | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | πŸŽ‰ are by default browser to open the service default/springboot-k8s-template-deployment... ❗ Because you are using a Docker driver on Darwin, the terminal needs to be open to run it.Copy the code

Access after exposure:

http://127.0.0.1:57109/test/do-test
Copy the code

Verify that the interface is normal.

Minikube log view:

 kubectl logs -f springboot-k8s-template-deployment-687f8bf86d-lcq5p
Copy the code

\