SpringBoot 使用Docker部署

現在 Docker 的使用已經很是廣泛,特別是在一線互聯網公司,使用 Docker 技術能夠幫助企業快速水平擴展服務,從而達到彈性部署業務的能力。在雲服務概念興起以後,Docker 的使用場景和範圍進一步發展,現在在微服務架構愈來愈流行的狀況下,微服務 + Docker 的完美組合,更加方便微服務架構運維部署落地。java

1、什麼是 Docker

  • Docker 最初是 dotCloud 公司創始人 Solomon Hykes 在法國期間發起的一個公司內部項目,它是基於 dotCloud 公司多年雲服務技術的一次革新,並於 2013 年 3 月以 Apache 2.0 受權協議開源,主要項目代碼在 GitHub 上進行維護。Docker 項目後來還加入了 Linux 基金會,併成立推進 開放容器聯盟(OCI)。

Docker 屬於 Linux 容器的一種封裝,提供簡單易用的容器使用接口,它是目前最流行的 Linux 容器解決方案。Docker 將應用程序與該程序的依賴打包在一個文件裏面,運行這個文件,就會生成一個虛擬容器。程序在這個虛擬容器裏運行,就好像在真實的物理機上運行同樣,有了 Docker,就不用擔憂環境問題了。nginx

  • 整體來講,Docker 的接口至關簡單,用戶能夠方便地建立和使用容器,把本身的應用放入容器。容器還能夠進行版本管理、複製、分享、修改,就像管理普通的代碼同樣。

一、爲何要使用 Docker

  • 容器除了運行其中應用外,基本不消耗額外的系統資源,使得應用的性能很高,同時系統的開銷儘可能小。傳統虛擬機方式是運行 10 個不一樣的應用就要啓動 10 個虛擬機,而 Docker 只須要啓動 10 個隔離的應用便可。web

  • 具體說來,Docker 在以下幾個方面具備較大的優點:spring

    • 更快速的交付和部署,開發者可使用一個標準的鏡像來構建一套開發容器,開發完成以後,運維人員能夠直接使用這個容器來部署代碼。
    • 更高效的虛擬化,Docker 容器的運行不須要額外的 hypervisor 支持,它是內核級的虛擬化,所以能夠實現更高的性能和效率。
    • 更輕鬆的遷移和擴展,Docker 容器幾乎能夠在任意的平臺上運行,包括物理機、虛擬機、公有云、私有云、我的電腦、服務器等。
    • 更簡單的管理,使用 Docker,只須要小小的修改,就能夠替代以往大量的更新工做。

二、Docker 相關概念

  • Docker 是 CS 架構,主要有兩個概念,具體以下:docker

    • Docker daemon:運行在宿主機上,Docker 守護進程,用戶經過 Docker client(Docker 命令)與 Docker daemon 交互。
    • Docker client:Docker 命令行工具,是用戶使用 Docker 的主要方式,Docker client 與 Docker daemon 通訊並將結果返回給用戶,Docker client 也能夠經過 socket 或者 RESTful API 訪問遠程的 Docker daemon。
  • Docker 的組成有三個主要概念,具體以下:apache

    • Docker image:鏡像是隻讀的,鏡像中包含有須要運行的文件。鏡像用來建立 container,一個鏡像能夠運行多個 container;鏡像能夠經過 Dockerfile 建立,也能夠從 Docker hub/registry 上下載。
    • Docker container:容器是 Docker 的運行組件,啓動一個鏡像就是一個容器,容器是一個隔離環境,多個容器之間不會相互影響,保證容器中的程序運行在一個相對安全的環境中。
    • Docker hub/registry:共享和管理 Docker 鏡像,用戶能夠上傳或者下載上面的鏡像,官方地址可點擊這裏(https://hub.docker.com/)查看,也能夠搭建本身私有的 Docker registry。

鏡像就至關於打包好的版本,鏡像啓動以後運行在容器中,倉庫就是裝存儲鏡像的地方json

2、建立 Spring Boot 項目

  • 在 pom.xml 中,使用 Spring Boot 2.x 相關依賴:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.0.RELEASE</version>
</parent>
  • 添加 web 和測試依賴:
<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>
  • 建立一個 DockerController,在其中有一個 index() 方法,訪問時返回:Hello Docker!
@RestController
public class DockerController {

    @RequestMapping("/")
    public String index() {
        return "Hello Docker!";
    }
}
  • 啓動類
@SpringBootApplication
public class DockerApplication {

    public static void main(String[] args) {
        SpringApplication.run(DockerApplication.class, args);
    }
}

添加完畢後啓動項目,啓動成功後瀏覽器訪問網址:http://localhost:8080/,頁面返回:Hello Docker!,說明 Spring Boot 項目配置正常。ubuntu

3、項目添加 Docker 支持

一、添加 Docker 配置

  • 在 pom.xml 中添加 Docker 鏡像名稱:
<properties>
    <docker.image.prefix>springboot</docker.image.prefix>
</properties>
  • plugins 中添加 Docker 構建插件:
    • ${docker.image.prefix},自定義的鏡像名稱
    • ${project.artifactId},項目的 artifactId
    • ${project.build.directory},構建目錄,缺省爲 target
    • ${project.build.finalName},產出物名稱,缺省爲 ${project.artifactId}-${project.version}
<build>
    <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>
  • 在目錄 src/main/docker 下建立 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"]
  • 這個 Dockerfile 文件很簡單,構建 JDK 基礎環境,添加 Spring Boot Jar 到鏡像中,簡單解釋一下:
    • FROM,表示使用 JDK 8 環境爲基礎鏡像,若是鏡像不是本地的將會從 DockerHub 進行下載。
    • VOLUME,VOLUME 指向了一個 /tmp 的目錄,因爲 Spring Boot 使用內置的 Tomcat 容器,Tomcat 默認使用 /tmp 做爲工做目錄,這個命令的效果是:在宿主機的 /var/lib/docker 目錄下建立一個臨時文件並把它連接到容器中的 /tmp 目錄。
    • ADD,複製文件而且重命名。
    • ENTRYPOINT,爲了縮短 Tomcat 的啓動時間,添加 java.security.egd 的系統屬性指向 /dev/urandom 做爲 ENTRYPOINT。

這樣 Spring Boot 項目添加 Docker 依賴就完成了,下面解釋一下什麼是 Dockerfile?vim

二、Dockerfile 介紹

  • Docker 鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建以後也不會被改變。centos

  • 鏡像的定製實際上就是定製每一層所添加的配置、文件。若是能夠把每一層修改、安裝、構建、操做的命令都寫入一個腳本,用這個腳原本構建、定製鏡像,那麼以前說起的沒法重複的問題、鏡像構建透明性的問題、體積的問題就都會解決,這個腳本就是 Dockerfile。

  • Dockerfile 是一個文本文件,其內包含了一條條的指令(Instruction),每一條指令構建一層,所以每一條指令的內容,就是描述該層應當如何構建。有了 Dockerfile,當須要定製本身額外的需求時,只需在 Dockerfile 上添加或者修改指令,從新生成 image 便可,省去了敲命令的麻煩。

  • Dockerfile 文件格式以下:

##Dockerfile 文件格式

# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..

#(1)第一行必須指定基礎鏡像信息
FROM ubuntu

# (2)維護者信息
MAINTAINER docker_user docker_user@email.com

# (3)鏡像操做指令
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

# (4)容器啓動執行指令
CMD /usr/sbin/nginx
  • Dockerfile 分爲四部分:

    • 基礎鏡像信息
    • 維護者信息
    • 鏡像操做指令
    • 容器啓動執行指令。
  • 一開始必需要指明所基於的鏡像名稱,接下來通常會說明維護者信息;後面則是鏡像操做指令,如 RUN 指令。每執行一條 RUN 指令,鏡像添加新的一層,並提交;最後是 CMD 指令,來指明運行容器時的操做命令。

Spring Boot 應用 Docker 部署須要使用 Dockerfile 定義部署方案。

3、構建環境

建議在 Linux 環境下安裝 Docker,Window 環境搭建比較複雜且容易出錯,使用 Centos7 + yum 來安裝 Docker 環境很方便。

一、Docker 安裝

  • Docker 軟件包已經包括在默認的 CentOS-Extras 軟件源裏,所以想要安裝 Docker,只須要運行下面的 yum 命令:
yum install docker
  • 安裝完成後,使用下面的命令來啓動 docker 服務,並將其設置爲開機啓動:
service docker start
chkconfig docker on
  • LCTT 譯註,此處採用了舊式的 sysv 語法,如採用 CentOS 7 中支持的新式 systemd 語法,以下:
systemctl start docker.service
systemctl enable docker.service
  • 使用"Docker 中國"加su器:
vi  /etc/docker/daemon.json

#添加後:
{
    "registry-mirrors": ["https://registry.docker-cn.com"],
    "live-restore": true
}
  • 從新啓動:
systemctl restart docker
  • 測試
docker version

輸入上述命令,返回 docker 的版本相關信息,證實 docker 安裝成功。

二、安裝 JDK

  • 安裝命令:
yum -y install java-1.8.0-openjdk*
  • 配置環境變量
    • 打開 vim /etc/profile
    • 添加如下內容
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64 
export PATH=$PATH:$JAVA_HOME/bin
  • 修改完成以後,使其生效:
source /etc/profile
  • 輸入 java -version 返回版本信息則安裝正常。

三、安裝 MAVEN

  • 解壓maven包
## 解壓
tar vxf apache-maven-3.5.2-bin.tar.gz
## 移動
mv apache-maven-3.5.2 /usr/local/maven3
  • 修改環境變量,在 /etc/profile 中添加如下幾行:
MAVEN_HOME=/usr/local/maven3
export MAVEN_HOME
export PATH=${PATH}:${MAVEN_HOME}/bin
  • 執行 source /etc/profile 使環境變量生效
  • 輸入 mvn -version 返回版本信息則安裝正常

4、使用 Docker 部署 Spring Boot 項目

一、使用Docker構建

  • 將項目 spring-boot-docker 複製到服務器中,進入項目路徑下進行打包測試。
#打包
mvn clean package
#啓動
java -jar target/spring-boot-docker-1.0.jar
  • 看到 Spring Boot 的啓動日誌後代表環境配置沒有問題,接下來使用 DockerFile 構建鏡像。
mvn package docker:build
  • 第一次構建可能有點慢,當看到如下內容的時候代表構建成功:
...
Step 1 : FROM openjdk:8-jdk-alpine
 ---> 224765a6bdbe
Step 2 : VOLUME /tmp
 ---> Using cache
 ---> b4e86cc8654e
Step 3 : ADD spring-boot-docker-1.0.jar app.jar
 ---> a20fe75963ab
Removing intermediate container 593ee5e1ea51
Step 4 : ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /app.jar
 ---> Running in 85d558a10cd4
 ---> 7102f08b5e95
Removing intermediate container 85d558a10cd4
Successfully built 7102f08b5e95
[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 命令查看構建好的鏡像:
docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
springboot/spring-boot-docker   latest              99ce9468da74        6 seconds ago       117.5 MB
  • springboot/spring-boot-docker 就是咱們構建好的鏡像,下一步就是運行該鏡像:
docker run -p 8080:8080 -t springboot/spring-boot-docker
  • 啓動完成以後使用 docker ps 查看正在運行的鏡像:
docker ps
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS                    NAMES
049570da86a9        springboot/spring-boot-docker   "java -Djava.security"   30 seconds ago      Up 27 seconds       0.0.0.0:8080->8080/tcp   determined_mahavira
  • 能夠看到構建的容器正在在運行,訪問瀏覽器:http://192.168.0.x:8080/,返回:
Hello Docker!

說明使用 Docker 部署 Spring Boot 項目成功!

二、Docker經常使用命令

  • 除過以上使用的 Docker 命令外,還有一些其餘經常使用的命令,經過這些命令能夠查看容器的相關狀態。

  • 拉取 docker 鏡像:

docker pull image_name
  • 查看宿主機上的鏡像,Docker 鏡像保存在 /var/lib/docker 目錄下:
docker images
  • 刪除鏡像:
docker rmi  docker.io/tomcat:7.0.77-jre7   或者  docker rmi b39c68b7af30
  • 查看當前有哪些容器正在運行:
docker ps
  • 查看全部容器:
docker ps -a
  • 啓動、中止、重啓容器命令:
docker start container_name/container_id
docker stop container_name/container_id
docker restart container_name/container_id
  • 後臺啓動一個容器後,若是想進入到這個容器,可使用 attach 命令:
docker attach container_name/container_id
  • 刪除容器命令:
docker rm container_name/container_id
  • 刪除全部中止的容器:
docker rm $(docker ps -a -q)
  • 查看當前系統 Docker 信息:
docker info
  • 從 Docker hub 上下載某個鏡像:
docker pull centos:latest

經過這些命令能夠發現 Docker 的使用方式很是靈活,能夠把項目作成鏡像來管理,部署的時候直接下載對應版本的鏡像直接運行便可。

5、總結

Docker 是容器化技術的基礎,服務編排、彈性水平擴充都依賴於 Docker 的使用,使用 Docker 部署 Spring Boot 項目,能夠把項目當作版本庫同樣管理,不須要關注環境、遷移等問題。Spring Boot 是微服務開發的基礎,Docker 是容器化部署的基礎,二者結合使用更加方便微服務架構運維部署落地。

相關文章
相關標籤/搜索