Docker從入門到掉坑(三):容器太多,操做好麻煩

前邊的兩篇文章裏面,咱們講解了基於docker來部署基礎的SpringBoot容器,若是閱讀本文以前沒有相關基礎的話,能夠回看以前的教程。html

Docker 從入門到掉坑java

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

不知道你們在初次使用docker的時候是否有遇到這種場景,每次部署微服務都是須要執行docker run xxx,docker kill xxx 等命令來操做容器。假設說一個系統中依賴了多個docker容器,那麼對於每一個docker容器的部署豈不是都須要手動編寫命令來啓動和關閉,這樣作就會增長運維人員的開發工做量,同時也容易出錯。linux

Docker Compose 編排技術git

在前邊的文章中,咱們講解了Docker容器化技術的發展,可是隨着咱們的Docker愈來愈多的時候,對於容器的管理也是特別麻煩,所以Docker Compose技術也就誕生了。web

Docker Compose技術是經過一份文件來定義和運行一系列複雜應用的Docker工具,經過Docker-compose文件來啓動多個容器,網上有不少關於Docker-compose的實戰案例,可是都會有些細節地方有所遺漏,因此下邊我將經過一個簡單的案例一步步地帶各位從淺入深地對Docker-compose進行學習。spring

基於Docker Compose來進行對SpringBoot微服務應用的打包集成sql

咱們仍是按照老樣子來構建一套基礎的SpringBoot微服務項目,首先咱們來看看基礎版本的項目結構:mongodb

Docker從入門到掉坑(三):容器太多,操做好麻煩


首先是咱們pom文件的配置內容:docker

<?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.idea</groupId>
    <artifactId>springboot-docker</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>spring-boot-docker</name>
    <url>http://maven.apache.org</url>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>springboot-docker</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

 

而後是java程序的內容代碼,這裏面有常規的controller,application類,代碼以下所示:

啓動類Application

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

 

控制器 DockerController

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/20 */ @RestController @RequestMapping(value = "/docker") public class DockerController { @GetMapping(value = "/test") public String test(){ System.out.println("=========docker test========="); return "this is docker test"; } }

 

yml配置文件:

server: port: 7089

 

接下來即是docker-compose打包時候要用到的配置文件了。這裏採用的方式一般都是針對必要的docker容器編寫一份dockerfile,而後統一由Docker Compose進行打包管理,假設咱們的微服務中須要引用到了MySQL,MongoDB等應用,那麼總體架構以下圖所示:

Docker從入門到掉坑(三):容器太多,操做好麻煩


那麼咱們先從簡單的單個容器入手,看看該如何對SpringBoot作Docker Compose的管理,下邊是一份打包SpringBoot進入Docker容器的Dockerfile文件:

#須要依賴的其餘鏡像 FROM openjdk:8-jdk-alpine # Spring Boot應用程序爲Tomcat建立的默認工做目錄。做用是在你的主機」/var/lib/docker」目錄下建立一個臨時的文件,而且連接到容器中#的」/tmp」目錄。 VOLUME /tmp #是指將原先的src文件 添加到咱們須要打包的鏡像裏面 ADD target/springboot-docker.jar app.jar #設置鏡像的時區,避免出現8小時的偏差 ENV TZ=Asia/Shanghai #容器暴露的端口號 和SpringBoot的yml文件暴露的端口號要一致 EXPOSE 7089 #輸入的啓動參數內容 下邊這段內容至關於運行了java -Xms256m -Xmx512m -jar app.jar ENTRYPOINT ["java","-Xms256m","-Xmx512m","-jar","app.jar"]

 

接着即是加入docker-compose.yml文件的環節了,下邊是腳本的內容:

#docker引擎對應所支持的docker-compose文本格式
version: '3' services: #服務的名稱
  springboot-docker: build: context: . # 構建這個容器時所須要使用的dockerfile文件
      dockerfile: springboot-dockerfile ports: # docker容器和宿主機之間的端口映射
      - "7089:7089"

 

docker-compose.ym配置文件有着特殊的規則,一般咱們都是先定義version版本號,而後即是列舉一系列與容器相關的services內容。

接下來將這份docker服務進行打包,部署到相關的linux服務器上邊,這裏我採用的是一臺阿里雲上邊購買的服務器來演示。

Docker從入門到掉坑(三):容器太多,操做好麻煩


目前該文件尚未進行打包處理,因此沒有target目錄,所以dockerfile文件構建的時候是不會成功的,所以須要先進行mvn的打包:

mvn package

 

接着即是進行Docker-Compose命令的輸入了:

[root@izwz9ic9ggky8kub9x1ptuz springboot-docker]# docker-compose up -d
Starting springboot-docker_springboot-docker_1 ... done [root@izwz9ic9ggky8kub9x1ptuz springboot-docker]#

 

你會發現此次輸入的命令和以前教程中說起的docker指令有些出入,變成了docker-compose 指令,這條指令是專門針對Docker compose文件所設計的,加入了一個-d的參數用於表示後臺運行該容器。因爲咱們的docker-compose文件中知識編寫了對於SpringBoot容器的打包,所以啓動的時候只會顯示一個docker容器。

爲了驗證docker-compose指令是否生效,咱們能夠經過docker--compose ps命令來進行驗證。

這裏邊咱們使用 docker logs [容器id] 指令能夠進入容器查看日誌的打印狀況:

 

docker logs ad83c82b014d

 

Docker從入門到掉坑(三):容器太多,操做好麻煩


最後咱們經過請求以前寫好的接口便會看到相關的響應:

 

Docker從入門到掉坑(三):容器太多,操做好麻煩


基礎版本的SpringBoot+Docker compose案例已經搭建好了,還記得我在開頭畫的那張圖片嗎:

Docker從入門到掉坑(三):容器太多,操做好麻煩

一般在實際開發中,咱們所面對的docker容器並非那麼的簡單,還有可能會依賴到多個容器,那麼這個時候該如何來編寫docker compose文件呢?

下邊咱們對原先的SpringBoot項目增長對於MySQLMongoDB的依賴,爲了方便下邊的場景模擬,這裏咱們增長兩個實體類:

用戶類

package com.sise.docker.domain; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author idea * @data 2019/11/23 */ @AllArgsConstructor @NoArgsConstructor @Data public class User { private Integer id; private String username; }

 

汽車類:

package com.sise.docker.domain; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; /** * @author idea * @data 2019/11/23 */ @Data @AllArgsConstructor @NoArgsConstructor public class Car { @Id private Integer id; private String number; }

 

增長對於mongodb,mysql的pom依賴內容

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>

 

編寫相關的dao層:

package com.sise.docker.dao; import com.sise.docker.domain.Car; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; /** * @author idea * @data 2019/11/23 */ @Repository public interface CarDao extends MongoRepository<Car, Integer> { } package com.sise.docker.dao; import com.sise.docker.domain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import java.sql.ResultSet; import java.sql.SQLException; /** * @author idea * @data 2019/11/23 */ @Repository public class UserDao { @Autowired private JdbcTemplate jdbcTemplate; public void insert() { String time = String.valueOf(System.currentTimeMillis()); String sql = "insert into t_user (username) values ('idea-" + time + "')"; jdbcTemplate.update(sql); System.out.println("==========執行插入語句=========="); } class UserMapper implements RowMapper<User> { @Override public User mapRow(ResultSet resultSet, int i) throws SQLException { User unitPO = new User(); unitPO.setId(resultSet.getInt("id")); unitPO.setUsername(resultSet.getString("username")); return unitPO; } } }

 

在控制器中添加相關的函數入口:

package com.sise.docker.controller; import com.sise.docker.dao.CarDao; import com.sise.docker.dao.UserDao; import com.sise.docker.domain.Car; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Random; /** * @author idea * @data 2019/11/20 */ @RestController @RequestMapping(value = "/docker") public class DockerController { @Autowired private UserDao userDao; @Autowired private CarDao carDao; @GetMapping(value = "/insert-mongodb") public String insertMongoDB() { Car car = new Car(); car.setId(new Random().nextInt(15000000)); String number = String.valueOf(System.currentTimeMillis()); car.setNumber(number); carDao.save(car); return "this is insert-mongodb"; } @GetMapping(value = "/insert-mysql") public String insertMySQL() { userDao.insert(); return "this is insert-mysql"; } @GetMapping(value = "/test2") public String test() { System.out.println("=========docker test222========="); return "this is docker test"; } }

 

對原先的docker-compose.yml文件添加相應的內容,主要是增長對於mongodb和mysql的依賴模塊,

#docker引擎對應所支持的docker-compose文本格式
version: '3' services: #服務的名稱
  springboot-docker: container_name: docker-springboot build: context: . dockerfile: springboot-dockerfile ports: - "7089:7089" depends_on: - mongodb mongodb: #容器的名稱
    container_name: docker-mongodb image: daocloud.io/library/mongo:latest ports: - "27017:27017" mysql: #鏡像的版本
    image: mysql:5.7 container_name: docker-mysql ports: - 3309:3306 environment: MYSQL_DATABASE: test MYSQL_ROOT_PASSWORD: root MYSQL_ROOT_USER: root MYSQL_ROOT_HOST: '%'

 

這裏頭我嘗試將application.yml文件經過不一樣的profile來進行區分:

Docker從入門到掉坑(三):容器太多,操做好麻煩


應上篇文章中有讀者問到,不一樣環境不一樣配置的指定問題,這裏有一種思路,springboot依舊保持原有的按照profile來識別不一樣環境的配置,具體打包以後讀取的配置,能夠經過springboot-dockerfile這份文件的ENTRYPOINT 參數來指定,例以下邊這種格式:

FROM openjdk:8-jdk-alpine VOLUME /tmp ADD target/springboot-docker.jar springboot-docker.jar #設置鏡像的時區,避免出現8小時的偏差
ENV TZ=Asia/Shanghai EXPOSE 7089
#這裏能夠經過-D參數在對jar打包運行的時候指定須要讀取的配置問題
ENTRYPOINT ["java","-Xms256m","-Xmx512m","-Dspring.profiles.active=prod","-jar","springboot-docker.jar"]

 

最後即是咱們的yml配置文件內容,因爲配置類docker容器的依賴,因此這裏面對於yml的寫法再也不是經過ip來訪問相應的數據庫了,而是須要經過service-name的映射來達成目標。

application-prod.yml

server: port: 7089 spring: data: mongodb: uri: mongodb://mongodb:27017 database: test datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://mysql:3306/test?useUnicode=true&amp;characterEncoding=UTF-8 username: root password: root

 

當相關的代碼和文件都整理好了以後,將這份代碼發送到服務器上進行打包。

mvn package

 

接着咱們即可以進行docker-compose的啓動了。

這裏有個小坑須要注意一下,因爲以前咱們已經對單獨的springboot容器進行過打包了,因此在執行docker-compose up指令的時候會優先使用已有的容器,而不是從新建立容器。


這個時候須要先將原先的image鏡像進行手動刪除,再打包操做:

[root@izwz9ic9ggky8kub9x1ptuz springboot-docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE springboot-docker                  latest              86f32bd9257f        4 hours ago 128MB <none>                                               <none>              411616c3d7f7        2 days ago 679MB <none>                                               <none>              77044e3ad9c2        2 days ago 679MB <none>                                               <none>              5d9328dd1aca        2 days ago 679MB springbootmongodocker_springappserver latest 36237acf08e1 3 days ago          695MB

 

刪除鏡像的命令:

docker rmi 【鏡像id】

 

Docker從入門到掉坑(三):容器太多,操做好麻煩


此時再從新進行docker-compose指令的打包操做便可:

 

docker-compose up

 

Docker從入門到掉坑(三):容器太多,操做好麻煩


啓動以後,能夠經過docker-compose自帶的一些指令來進行操做,經常使用的一些指令我都概括在了下邊:

 

docker-compose [Command]

Commands: build 構建或重建服務 bundle 從compose配置文件中產生一個docker綁定 config 驗證並查看compose配置文件 create 建立服務 down 中止並移除容器、網絡、鏡像和數據卷 events 從容器中接收實時的事件 exec 在一個運行中的容器上執行一個命令 help 獲取命令的幫助信息 images 列出全部鏡像 kill 經過發送SIGKILL信號來中止指定服務的容器 logs 從容器中查看服務日誌輸出 pause 暫停服務 port 打印綁定的公共端口 ps 列出全部運行中的容器 pull 拉取並下載指定服務鏡像 push Push service images restart 重啓YAML文件中定義的服務 rm 刪除指定已經中止服務的容器 run 在一個服務上執行一條命令 scale 設置指定服務運行容器的個數 start 在容器中啓動指定服務 stop 中止已運行的服務 top 顯示各個服務容器內運行的進程 unpause 恢復容器服務 up 建立並啓動容器 version 顯示Docker-Compose版本信息

 

最後對相應的接口作檢測:

Docker從入門到掉坑(三):容器太多,操做好麻煩

 

Docker從入門到掉坑(三):容器太多,操做好麻煩


相關的完整代碼我已經上傳到了gitee地址,若是有須要的朋友能夠前往進行下載。

代碼地址:https://gitee.com/IdeaHome_admin/wfw

 

Docker從入門到掉坑(三):容器太多,操做好麻煩


實踐完畢以後,你可能會以爲有了docker-compose以後,對於多個docker容器來進行管理顯得就特別輕鬆了。

 

可是每每現實中並無這麼簡單,docker-compose存在着一個弊端,那就是不能作跨機器之間的docker容器進行管理

 

所以隨者技術的發展,後邊也慢慢出現了一種叫作Kubernetes的技術。Kubernetes(俗稱k8s)是一個開源的,用於管理雲平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單而且高效(powerful),Kubernetes提供了應用部署,規劃,更新,維護的一種機制。

 

Kubernetes這類技術對於小白來講入門的難度較高,後邊可能會抽空專門來寫一篇適合小白閱讀的k8s入門文章。

 

原文出處:https://www.cnblogs.com/javazhiyin/p/11926193.html

相關文章
相關標籤/搜索