鍍金池/ 教程/ Java/ Docker with Spring Boot
通過JMX監(jiān)控Spring Boot應用
Spring Boot:定制PropertyEditors
配置是否初始化Bean的方法
Spring Boot的自動配置、Command-line Runner
Spring Boot:定制URL匹配規(guī)則
Spring Boot的自動配置、Command-line Runner
利用Mockito模擬DB
Spring Boot應用的打包和部署
了解Spring Boot的自動配置
Spring Boot應用的健康監(jiān)控
了解Spring Boot的自動配置
初始化數據庫和導入數據
Spring Boot應用的健康監(jiān)控
Docker with Spring Boot
RESTful by Spring Boot with MySQL
Spring Boot:定制攔截器
Spring Boot:定制static path mappings
Spring Boot with Mysql
Spring Boot:定制自己的starter
在測試中使用內存數據庫
Restful: Spring Boot with Mongodb
Spring Boot with Redis
Spring Boot:定制HTTP消息轉換器
Spring Boot: Data Rest Service
Spring Boot:定制type Formatters
在Spring Boot項目中使用Spock框架
選擇Spring Boot項目的內嵌容器
通過EmbeddedServletContainerCustomizer接口調優(yōu)Tomcat
Spring Boot應用的打包和部署
Spring Boot Admin的使用
讓你的Spring Boot工程支持HTTP和HTTPS
Spring Boot:定制servlet filters
Spring Boot:定制URL匹配規(guī)則
Spring Boot應用的測試——Mockito
Spring Boot應用的測試——Mockito
Spring Boot:定制servlet filters
通過@Enable*注解觸發(fā)Spring Boot配置

Docker with Spring Boot

前段時間在我廠卷爺的指導下將Docker在我的實際項目中落地,最近幾個小demo都盡量熟悉docker的使用,希望通過這篇文章分享我截止目前的使用經驗(如有不準確的表述,歡迎幫我指出)。本文的主要內容是關于Java應用程序的docker化,首先簡單介紹了docker和docker-compose,然后利用兩個案例進行實踐說明。

簡單說說Docker,現(xiàn)在云計算領域火得一塌糊涂的就是它了吧。Docker的出現(xiàn)是為了解決PaaS的問題:運行環(huán)境與具體的語言版本、項目路徑強關聯(lián),因此干脆利用lxc技術進行資源隔離,構造出跟隨應用發(fā)布的運行環(huán)境,這樣就解決了語言版本的限制問題。PaaS的出現(xiàn)是為了讓運維人員不需要管理一臺虛擬機,IaaS的出現(xiàn)是為了讓運維人員不需要管理物理機。云計算,說到底都是倆字——運維。

云計算領域的技術分為虛擬化技術和資源管理兩個方面,正好對應我們今天要講的兩個工具:Docker和docker-compose。Docker的主要概念有:容器、鏡像、倉庫;docker-compose是fig的后續(xù)版本,負責將多個docker服務整合起來,對外提供一致服務。

1. Spring Boot應用的docker化

首先看Spring Boot應用程序的docker化,由于Spring Boot內嵌了tomcat、Jetty等容器,因此我們對docker鏡像的要求就是需要java運行環(huán)境。我的應用代碼的的Dockerfile文件如下:

#基礎鏡像:倉庫是java,標簽用8u66-jdk
FROM java:8u66-jdk
#當前鏡像的維護者和聯(lián)系方式
MAINTAINER duqi duqi@example.com
#將打包好的spring程序拷貝到容器中的指定位置
ADD target/bookpub-0.0.1-SNAPSHOT.jar /opt/bookpub-0.0.1-SNAPSHOT.jar
#容器對外暴露8080端口
EXPOSE 8080
#容器啟動后需要執(zhí)行的命令
CMD java -Djava.security.egd=file:/dev/./urandom -jar /opt/bookpub-0.0.1-SNAPSHOT.jar

因為目前的示例程序比較簡單,這個dockerfile并沒有在將應用程序的數據存放在宿主機上。如果你的應用程序需要寫文件系統(tǒng),例如日志,最好利用VOLUME /tmp命令,這個命令的效果是:在宿主機的/var/lib/docker目錄下創(chuàng)建一個臨時文件并把它鏈接到容器中的/tmp目錄。

把這個Dockerfile放在項目的根目錄下即可,后續(xù)通過docker-compose build統(tǒng)一構建:基礎鏡像是只讀的,然后會在該基礎鏡像上增加新的可寫層來供我們使用,因此java鏡像只需要下載一次。

docker-compose是用來做docker服務編排,參看《Docker從入門到實踐》中的解釋:

Compose 項目目前在 Github 上進行維護,目前最新版本是 1.2.0。Compose 定位是“defining and running complex applications with Docker”,前身是 Fig,兼容 Fig 的模板文件。

Dockerfile 可以讓用戶管理一個單獨的應用容器;而 Compose 則允許用戶在一個模板(YAML 格式)中定義一組相關聯(lián)的應用容器(被稱為一個 project,即項目),例如一個 Web 服務容器再加上后端的數據庫服務容器等。

單個docker用起來確實沒什么用,docker技術的關鍵在于持續(xù)交付,通過與jekins的結合,可以實現(xiàn)這樣的效果:開發(fā)人員提交push,然后jekins就自動構建并測試剛提交的代碼,這就是我理解的持續(xù)交付。

2. spring boot + redis + mongodb

在這個項目中,我啟動三個容器:web、redis和mongodb,然后將web與redis連接,web與mongodb連接。首先要進行redis和mongodb的docker化,redis鏡像的Dockerfile內容是:

FROM        ubuntu:14.04
RUN         apt-get update
RUN         apt-get -y install redis-server
EXPOSE      6379
ENTRYPOINT  ["/usr/bin/redis-server"]

Mongodb鏡像的Dockerfile內容是,docker官方給了mongodb的docker化教程,我直接拿來用了,參見Dockerizing MongoDB

# Format: FROM repository[:version]
FROM       ubuntu:14.04
# Format: MAINTAINER Name <email@addr.ess>
MAINTAINER duqi duqi@example.com
# Installation:
# Import MongoDB public GPG key AND create a MongoDB list file
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
RUN echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.0.list
# Update apt-get sources AND install MongoDB
RUN apt-get update && apt-get install -y mongodb-org
# Create the MongoDB data directory
RUN mkdir -p /data/db
# Expose port 27017 from the container to the host
EXPOSE 27017
# Set usr/bin/mongod as the dockerized entry-point application
ENTRYPOINT ["/usr/bin/mongod"]

使用docker-compose編排三個服務,具體的模板文件如下:

web:
  build: .
  ports:
   - "49161:8080"
  links:
   - redis
   - mongodb

redis:
    image: duqi/redis
    ports:
      - "6379:6379"

mongodb:
    image: duqi/mongodb
    ports:
      - "27017:27017"

架構比較簡單,第一個區(qū)塊的build,表示docker中的命令“docker build .”,用于構建web鏡像;ports這塊表示將容器的8080端口與宿主機(IP地址是:192.168.99.100)的49161對應。因為現(xiàn)在docker不支持原生的osx,因此在mac下使用docker,實際上是在mac上的一臺虛擬機(docker-machine)上使用docker,這臺機器的地址就是192.168.99.100。參見:在mac下使用docker

links表示要連接的服務,redis與下方的redis區(qū)塊對應、mongodb與下方的mongodb區(qū)塊對應。redis和mongodb類似,首先說明要使用的鏡像,然后規(guī)定端口映射。

那么,如何運行呢?

  1. 命令docker-compose build,表示構建web服務,目前我用得比較土,就是編譯jar之后還需要重新更新docker,優(yōu)雅點不應該這樣。 http://wiki.jikexueyuan.com/project/spring-boot-cookbook-zh/images/ef.png" alt="docker-compose build" />
  2. 命令docker-compose up,表示啟動web服務,可以看到mongodb、redis和web依次啟動,啟動后用docker ps查看當前的運行容器。 http://wiki.jikexueyuan.com/project/spring-boot-cookbook-zh/images/ab.png" alt="docker ps" />

特別注意,在配置文件中寫redis和mongodb的url時,要用虛擬機的地址,即192.168.99.100。例如,redis的一個配置應該為:spring.redis.host=192.168.99.100。

3. spring boot + mysql

拉取mysql鏡像的指令是:docker run --name db001 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admin -d mysql:5.7,表示啟動的docker容器名字是db001,登錄密碼一定要設定, -d表示設置Mysql版本。

我的docker-compose模板文件是:

web:
  build: .
  ports:
   - "49161:8080"
  links:
   - mysql

mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: admin
      MYSQL_DATABASE: springbootcookbook
    ports:
      - "3306:3306"

主要內容跟之前的類似,主要講下mysql部分,通過environement來設置進入mysql容器后的環(huán)境變量,即連接數據庫的密碼MYSQL_ROOT_PASSWORD,使用的數據庫名稱MSYQL_DATABASE等等。

一直想寫這篇文章做個總結,寫來發(fā)現(xiàn)還是有點薄,對于docker我還需要系統(tǒng)得學習,不過,針對上面的例子,我都是親自實踐過的,大家有什么問題可以與我聯(lián)系。

參考資料

  1. Docker從入門到實踐
  2. Docker - Initialize mysql database with schema
  3. 使用Docker搭建基礎的mysql應用
  4. Spring Boot with docker