Docker從入門到掉坑(二):基於Docker構建SpringBoot微服務

  • 2019 年 11 月 13 日
  • 筆記

本篇為Docker從入門到掉坑第二篇:基於Docker構建SpringBoot微服務,沒有看過上一篇的最好讀過 Docker 從入門到掉坑 之後,閱讀本篇。

在之前的文章裏面介紹了如何基於docker容器部署一些常見的基礎環境,例如MySQL、Redis這些,那麼這篇文章裏面我會介紹一些關於SpringBoot如何打包運行到docker容器中。

先介紹一下需要準備的基礎環境內容:

1.一台centos機器

docker運行在centos7上,要求系統為64位,Linux內核版本為3.10以上

docker運行在centos6.5或更高的版本上,要求系統為64位,系統內核版本為2.6.32-431或更高版本

關於如何查看當前系統的內核版本可以通過uname指令來查詢:

[root@izwz9ic9ggky8kub9x1ptuz target]# uname -r  3.10.0-514.26.2.el7.x86_64  [root@izwz9ic9ggky8kub9x1ptuz target]#

 

2.一份基礎的SpringBoot項目代碼

首先我們來構建一個簡單的springboot模板項目,下邊這份是相關的依賴文件:

<?xml version="1.0" encoding="UTF-8"?>  <project xmlns="http://maven.apache.org/POM/4.0.0"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">      <modelVersion>4.0.0</modelVersion>        <groupId>com.sise</groupId>      <artifactId>docker-springboot</artifactId>      <version>1.0-SNAPSHOT</version>        <parent>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-parent</artifactId>          <version>2.0.0.RELEASE</version>      </parent>        <properties>          <docker.image.prefix>springboot</docker.image.prefix>      </properties>        <dependencies>          <dependency>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-web</artifactId>          </dependency>          <dependency>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-test</artifactId>              <scope>test</scope>          </dependency>      </dependencies>          <build>          <!-- 注意這裡的命名要與後邊編寫DockerFile中的命名一致 -->          <finalName>spring-boot-docker-1.0</finalName>          <plugins>              <plugin>                  <groupId>org.springframework.boot</groupId>                  <artifactId>spring-boot-maven-plugin</artifactId>              </plugin>              <!-- Docker maven plugin -->              <plugin>                  <groupId>com.spotify</groupId>                  <artifactId>docker-maven-plugin</artifactId>                  <version>1.0.0</version>                  <configuration>                      <imageName>${docker.image.prefix}/${project.artifactId}</imageName>                      <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>    </project>

 

注意,這裡有幾個配置點需要仔細注意一下,在上邊的maven配置中有一條叫做dockerDirectory的屬性配置:

               <configuration>                      <imageName>${docker.image.prefix}/${project.artifactId}</imageName>                      <dockerDirectory>src/main/docker</dockerDirectory>                      <resources>                          <resource>                              <targetPath>/</targetPath>                              <directory>${project.build.directory}</directory>                              <include>${project.build.finalName}.jar</include>                          </resource>                      </resources>                  </configuration>

 

這條屬性對應的是指Dockerfile文件所存放的位置:

Docker從入門到掉坑(二):基於Docker構建SpringBoot微服務

注意有坑:

在src/main/docker的目錄底下需要我們編寫一份叫做Dockerfile的文件,注意這份Dockerfile文件的命名一定不能修改,否則會識別不出來,導致後邊會拋出下邊這種異常:

Failed to execute goal com.spotify:docker-maven-plugin:1.0.0:build (default-cli) on project docker-springboot:  Exception caught: Request error: POST unix://localhost:80/build?t=springboot%2Fdocker-springboot: 500, body:  {"message":"Cannot locate specified Dockerfile: Dockerfile"}: HTTP 500 Internal Server Error -> [Help 1]

 

這份Dockerfile文件需要用特殊的語法規則來進行編寫,這裡我給出一份基礎的Dockerfile文件模板:

FROM openjdk:8-jdk-alpine  VOLUME /tmp  ADD spring-boot-docker-1.0.jar app.jar  ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

 

稍微解釋一下這裡的語義含義:

FROM [image]指需要依賴的其他鏡像信息,這裡選擇了jdk鏡像

對於不熟悉的鏡像環境如果需要搜索可以去到docker的官方網站進行查看:
https://hub.docker.com/

Docker從入門到掉坑(二):基於Docker構建SpringBoot微服務在這裡插入圖片描述

ADD 源地址目標地址 是指將原先的src文件 添加到我們需要打包的鏡像裏面

VOLUME /tmp Spring Boot應用程序為Tomcat創建的默認工作目錄。作用是在你的主機”/var/lib/docker”目錄下創建一個臨時的文件,並且鏈接到容器中的”/tmp”目錄。這部分的內容可以進入相應的目錄下邊去詳細查看:

[root@izwz9ic9ggky8kub9x1ptuz docker]# cd /var/lib/docker  [root@izwz9ic9ggky8kub9x1ptuz docker]# ls  builder  buildkit  containers  image  network  overlay2  plugins  runtimes  swarm  tmp  trust  volumes  [root@izwz9ic9ggky8kub9x1ptuz docker]# cd ./tmp/  [root@izwz9ic9ggky8kub9x1ptuz tmp]# ls  docker-builder661781695  [root@izwz9ic9ggky8kub9x1ptuz tmp]# cd docker-builder661781695/  [root@izwz9ic9ggky8kub9x1ptuz docker-builder661781695]# ls  dockerFile  docker-springboot-1.0-SNAPSHOT.jar  [root@izwz9ic9ggky8kub9x1ptuz docker-builder661781695]# 

 

ENTRYPOINT 這條指令的含義是說執行應用的時候默認傳輸的命令內容。

SpringBoot的代碼也比較簡單,分別是Application啟動類:

package com.sise.docker;    import org.springframework.boot.SpringApplication;  import org.springframework.boot.autoconfigure.SpringBootApplication;    /**   * @author idea   * @data 2019/11/10   */  @SpringBootApplication  public class DockerApplication {        public static void main(String[] args) {          SpringApplication.run(DockerApplication.class);      }  }

 

以及相應的SpringBoot控制器:

package com.sise.docker.controller;    import org.springframework.web.bind.annotation.GetMapping;  import org.springframework.web.bind.annotation.RequestMapping;  import org.springframework.web.bind.annotation.RestController;    /**   * @author idea   * @data 2019/11/10   */  @RestController  @RequestMapping(value = "/docker")  public class DockerController {        @GetMapping(value = "/test")      public String test(){          return "this is docker test";      }  }

 

application.yml文件信息:

server:    port: 7089

 

3.服務器上邊需要安裝maven和docker環境

關於docker的環境安裝,在上一篇文章中已經講解到了,沒看上一篇的,點這裡:Docker 從入門到掉坑

maven的環境安裝講解:

首先需要選擇自己機器上邊的安裝地址,然後下載相應的文件包,並且進行解壓:

wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.tar.gz  tar zxf apache-maven-3.1.1-bin.tar.gz

 

然後我們進行相應的環境變量配置:

export MAVEN_HOME=[maven的安裝路徑]  export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin

 

記得刷新一下profile配置文件

source /etc/profile

最後記得驗證一下maven的配置是否正常:

[root@izwz9ic9ggky8kub9x1ptuz docker]# mvn -version  Apache Maven 3.1.1 (0728685237757ffbf44136acec0402957f723d9a; 2013-09-17 23:22:22+0800)  Maven home: /opt/maven/apache-maven-3.1.1  Java version: 1.8.0_151, vendor: Oracle Corporation  Java home: /opt/jdk/jdk1.8.0_151/jre  Default locale: en_US, platform encoding: UTF-8  OS name: "linux", version: "3.10.0-514.26.2.el7.x86_64", arch: "amd64", family: "unix"

 

一切就緒了,現在我們來將原先的準備好的一份SpringBoot項目上傳到centos機器裏面,然後通過maven的命令進行打包:

mvn package docker:build

當構建成功之後會有以下信息出現:

[INFO] Built springboot/spring-boot-docker  [INFO] ------------------------------------------------------------------------  [INFO] BUILD SUCCESS  [INFO] ------------------------------------------------------------------------  [INFO] Total time: 54.346 s  [INFO] Finished at: 2018-03-13T16:20:15+08:00  [INFO] Final Memory: 42M/182M  [INFO] ------------------------------------------------------------------------

 

接着我們便可以通過熟悉的docker images命令來查看當前的鏡像內容了:

最後便是啟動我們的鏡像文件,並且進行測試:

[root@izwz9ic9ggky8kub9x1ptuz springboot-docker]# docker run -p 7089:7089 -d springboot/docker-springboot  38ec31c7a4802d852ee0834e1773136bd58a255875a9fa8cb2898aef0daa3e51  [root@izwz9ic9ggky8kub9x1ptuz springboot-docker]#

 

啟動成功之後,我們通過命令進行測試接口:

[root@izwz9ic9ggky8kub9x1ptuz springboot-docker]# curl 127.0.0.1:7089/docker/test  this is docker test  [root@izwz9ic9ggky8kub9x1ptuz springboot-docker]# 

 

好了,一個基本的基於docker容器運行的SpringBoot容器構建到這裡就告一段落了。

寫在文末

在文末部分,我打算繼上一篇文章中所提到的幾個不足我在這裡進行一些補充:
應 @古名 讀者提到的問題,關於docker鏡像的沒有做官方的介紹:

當我們需要查詢某些特殊鏡像的時候有兩種途徑去搜索有關鏡像的信息,一種是直接進入官網鏡像搜索,還有一種是通過docker search 的方式搜索鏡像。

第一種方式的具體操作為進入https://hub.docker.com 官網,然後在頂部的搜索欄進行相關的搜索。例如說我們要搜索關於mysql的鏡像信息,那麼就可以通過以下操作:

Docker從入門到掉坑(二):基於Docker構建SpringBoot微服務

 

在官網上的搜索和在命令行執行docker search [鏡像關鍵字]的結果基本是一致的:

 

[root@izwz9ic9ggky8kub9x1ptuz springboot-docker]# docker search mysql  NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED  mysql                             MySQL is a widely used, open-source relation…   8787                [OK]  mariadb                           MariaDB is a community-developed fork of MyS…   3080                [OK]  mysql/mysql-server                Optimized MySQL Server Docker images. Create…   652                                     [OK]  percona                           Percona Server is a fork of the MySQL relati…   459                 [OK]  centos/mysql-57-centos7           MySQL 5.7 SQL database server                   64  centurylink/mysql                 Image containing mysql. Optimized to be link…   61                                      [OK]  mysql/mysql-cluster               Experimental MySQL Cluster Docker images. Cr…   56  deitch/mysql-backup               REPLACED! Please use http://hub.docker.com/r…   41                                      [OK]  bitnami/mysql                     Bitnami MySQL Docker Image                      35                                      [OK]  tutum/mysql                       Base docker image to run a MySQL database se…   34  schickling/mysql-backup-s3        Backup MySQL to S3 (supports periodic backup…   28                                      [OK]  prom/mysqld-exporter                                                              23                                      [OK]  linuxserver/mysql                 A Mysql container, brought to you by LinuxSe…   22  centos/mysql-56-centos7           MySQL 5.6 SQL database server                   17  circleci/mysql                    MySQL is a widely used, open-source relation…   16  mysql/mysql-router                MySQL Router provides transparent routing be…   14  arey/mysql-client                 Run a MySQL client from a docker container      13                                      [OK]  imega/mysql-client                Size: 36 MB, alpine:3.5, Mysql client: 10.1.…   9                                       [OK]  openshift/mysql-55-centos7        DEPRECATED: A Centos7 based MySQL v5.5 image…   6  fradelg/mysql-cron-backup         MySQL/MariaDB database backup using cron tas…   4                                       [OK]  genschsa/mysql-employees          MySQL Employee Sample Database                  2                                       [OK]  ansibleplaybookbundle/mysql-apb   An APB which deploys RHSCL MySQL                2                                       [OK]  jelastic/mysql                    An image of the MySQL database server mainta…   1  widdpim/mysql-client              Dockerized MySQL Client (5.7) including Curl…   0                                       [OK]  monasca/mysql-init                A minimal decoupled init container for mysql    0   

 

這裡你可能會疑惑,為何輸入了MySQL關鍵字之後卻出來了這麼多的相關信息,實際上這裡走的是一次全文搜索,會將一些在描述內容中包含有MySQL的鏡像信息都統一查詢出來。

假設我們需要選擇mysql的某一份鏡像進行下載的話,可以直接docker pull mysql,但是這種方式會拉去最新版本的鏡像到宿主機中。如果對版本有要求,我們可以到官網上選擇合適的版本進行指定拉去。

Docker從入門到掉坑(二):基於Docker構建SpringBoot微服務

圖中我也圈起來了拉去不同版本鏡像的命令。

應 @別慌張 讀者問到的docker可視化管理工具的問題。

實際上docker的可視化管理工具有很多:shipyard,DockerUI,Portainer,Rancher等等

我建議是,如果是作為初學者,還是建議使用命令行會好些,可視化工具實際上是會弱化開發人員的動手能力。使用可視化工具的主要目的還是為了提升工作效率和降低實操難度而設計的。