エントリーからドロップまでのDocker(3):コンテナーが多すぎる、オーケストレーションを最適化

    前の2つの記事では、Dockerデプロイメントに基づくSpringBootコンテナーについて説明しましたが、この記事を読む前に関連する基礎がない場合は、前のチュートリアルを確認できます。

エントリーからピットまでのDocker

入門から落とし穴へのDocker(2):Dockerに基づいてSpringBootマイクロサービスを構築する

    初めてdockerを使用したときにこのシナリオに遭遇したかどうかはわかりません。マイクロサービスをデプロイするたびに、コンテナーを操作するためにdocker run xxx、docker kill xxxなどのコマンドを実行する必要があります。システムが複数のDockerコンテナーに依存していると仮定すると、各Dockerコンテナーの展開は、開始およびシャットダウンするコマンドを手動で書き込む必要がありますか?これを行うと、運用および保守担当者の開発作業負荷が増加し、エラーが発生しやすくなります。

Docker Composeオーケストレーションテクノロジー

前回の記事では、我々はドッカーのコンテナ化技術の開発を説明したが、私たちが持っているとして、より多くのドッカーをして、コンテナの管理は、また、特に厄介であるドッカーのCompose技術が生まれました。

Docker Composeテクノロジーは、ファイルを介して一連の複雑なアプリケーションを定義および実行し、Docker-composeファイルを介して複数のコンテナーを開始するDockerツールです。インターネット上での実際のDocker-composeの事例は多数ありますが、一部の詳細は省略されています。 、そのため、以下では、Docker-composeを簡単なケースを通してより浅いものからより深いものへと順を追って説明します。

SpringBootマイクロサービスアプリケーションをパッケージ化して統合するDocker Composeに基づく

いつものように基本的なSpringBootマイクロサービスプロジェクトを構築しましょうまず、基本バージョンのプロジェクト構造を見てみましょう。

1つ目は、pomファイルの構成内容です。

 

<?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プログラムのコンテンツコードがあります。従来のコントローラクラスとアプリケーションクラスがあります。コードは次のとおりです。

クラスアプリケーションの開始

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 ComposeでSpringBootを管理する方法を見てみましょう。以下は、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構成ファイルには特別なルールがあり、通常は最初にバージョン番号を定義してから、一連のコンテナー関連サービスをリストします。

次に、このDockerサービスをパッケージ化して、関連するLinuxサーバーにデプロイします。ここでは、Alibaba Cloudから購入したサーバーを使用してデモを行います。

現在、ファイルはパッケージ化されていないため、ターゲットディレクトリはありません。したがって、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ファイル専用に設計されており、コンテナーがバックグラウンドで実行されていることを示します。docker-composeファイルのナレッジはSpringBootコンテナーのパッケージングを書き込むため、起動時に1つのdockerコンテナーのみが表示されます。

docker-composeコマンドが有効かどうかを確認するには、docker--compose psコマンドを使用して確認できます。

ここでは、docker logs [container id]  コマンドを使用して  コンテナーにアクセスし、ログの印刷を表示します。

docker logs ad83c82b014d

 

 

最後に、リクエストの前に記述されたインターフェースを介して、関連する応答が表示されます。  

 

SpringBoot + Docker構成ケースの基本バージョンが作成されました。最初に描いた絵を思い出してください。

 

通常、実際の開発では、私たちが直面しているDockerコンテナーはそれほど単純ではなく、複数のコンテナーに依存している可能性があります。

以下ではMySQLMongoDBへの依存関係を元のSpringBootプロジェクト追加ます。次のシナリオのシミュレーションを容易にするために、2つのエンティティークラスを追加します。

ユーザークラス

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ファイルを区別しようとしています。

 

前の記事での読者の質問への回答として、異なる環境での異なる構成の指定について考える方法があります。Springbootは、元のプロファイルを維持して、異なる環境の構成を識別します。特定のパッケージング後に読み取られた構成は、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を介して対応するデータベースにアクセスするのではなく、サービス名マッピングを介して目的を達成します。

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-compose指令的打包操作即可:

docker-compose up

 

启动之后,可以通过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版本信息

最后对相应的接口做检测:

相关的完整代码我已经上传到了gitee地址,如果有需要的朋友可以前往进行下载。

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

实践完毕之后,你可能会觉得有了docker-compose之后,对于多个docker容器来进行管理显得就特别轻松了。

但是往往现实中并没有这么简单,docker-compose存在着一个弊端,那就是不能做跨机器之间的docker容器进行管理

因此随者技术的发展,后边也慢慢出现了一种叫做Kubernetes的技术。Kubernetes(俗称k8s)是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。

Kubernetes这类技术对于小白来说入门的难度较高,后边可能会抽空专门来写一篇适合小白阅读的k8s入门文章。

 

 

 

おすすめ

転載: blog.csdn.net/bj_chengrong/article/details/103234077