Docker從入門到掉坑(二):基于Docker建構SpringBoot微服務
本篇為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檔案所存放的位置:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIx0DciV2dmADM30zd-cmbw5CRzUyYtJ2d1MVT1EFVPhXW610MVRVT01EVZJjRtFmdFRVT2tGVNdXS6xkeSdVW2h3RjFTODRWdWdEZ1ljMZRXQzQmdwIjYqVTaiBHbYF2bwhVWyYUbhV3YzQ2M5kHT20ESjBjUIF2Lc12bj5SYphXa5VWen5WY35iclN3Ztl2Lc9CX6MHc0RHaiojIsJye.png)
注意有坑:
在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/
在這裡插入圖檔描述
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 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的可視化管理工具有很多:shipyard,DockerUI,Portainer,Rancher等等
我建議是,如果是作為初學者,還是建議使用指令行會好些,可視化工具實際上是會弱化開發人員的動手能力。使用可視化工具的主要目的還是為了提升工作效率和降低實操難度而設計的。