vlambda博客
学习文章列表

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化

Chapter 14. Containerizing Microservices with Docker

在微服务的背景下,容器化部署就像是锦上添花。它通过自包含底层基础设施来帮助微服务进一步自治,从而使微服务成为云中立的。

本章将介绍虚拟机镜像和微服务容器化部署的概念和相关性。然后,本章将进一步让您熟悉如何为使用 Spring Boot 和 Spring Cloud 开发的 BrownField PSS 微服务构建 Docker 镜像。最后,本章还将介绍如何在类生产环境中管理、维护和部署 Docker 镜像。

在本章结束时,您将了解以下内容:

  • The concept of containerization and its relevance in the context of microservices
  • How to build and deploy microservices as Docker images and containers
  • Using AWS as an example of cloud-based Docker deployments

Understanding gaps in the BrownField PSS microservices


第 12 章中,使用 Spring Cloud 组件扩展微服务,BrownField PSS 微服务是使用 Spring Boot 和 Spring Cloud 开发的。这些微服务作为版本化的 fat jar 文件部署在裸机上,特别是在 local 开发机器上。在第13章中,日志和监控微服务,使用集中式日志记录和监控解决方案解决了有关日志记录和监控的挑战。

这对于大多数实现来说已经足够了。但是,我们的 BrownField PSS 实现仍然存在一些差距。到目前为止,该实施还没有使用任何云基础设施。与传统的单体应用程序部署一样,专用机器并不是部署微服务的最佳解决方案。自动配置、按需扩展能力、自助服务和基于使用的支付等自动化是有效管理大规模微服务部署所需的基本功能。通常,云基础设施提供所有这些基本功能。因此,具有前面提到的功能的私有云或公共云更适合部署互联网规模的微服务。

此外,每个裸机运行一个微服务实例并不划算。因此,在大多数情况下,企业最终会在单个裸机服务器上部署多个微服务。在单个裸机上运行多个微服务可能会产生嘈杂的邻居问题。在同一台机器上运行的微服务实例之间不会有任何隔离。结果,部署在单台机器上的服务会占用其他机器的空间,从而影响其他微服务的性能。

另一种方法是在虚拟机上运行微服务。但是,VM 本质上是重量级的。因此,在物理机上运行许多较小的 VM 并不节约资源。这通常会导致资源浪费。在共享一个 VM 来部署多个服务的情况下,开发人员最终将面临共享裸机的相同问题,如前所述。

在基于 Java 的微服务的情况下,共享一个 VM 或裸机来部署多个微服务也会导致在微服务之间共享 JRE。这是因为在我们的 BrownField PSS 中创建的胖 jar 仅抽象应用程序代码及其依赖项,而不抽象 JRE。安装在机器上的 JRE 的任何更新都会影响到该机器上部署的所有微服务。同样,如果存在特定微服务所需的操作系统级参数、库或调优,则很难在共享环境中管理它们。

微服务原则之一坚持通过完全封装其端到端运行时环境来实现自包含和自治。为了符合这一原则,所有组件,例如 OS、JRE 和微服务二进制文件,都必须是自包含和隔离的。实现这一目标的唯一选择是遵循为每个 VM 部署一个微服务的方法。但是,这将导致虚拟机未得到充分利用,并且在许多情况下,由此产生的额外成本可能会抵消微服务的好处。

What are containers?


容器不是革命性的开创性 概念。它已经行动了很长一段时间。然而,世界正在见证容器的重新进入,这主要是由于云计算的广泛采用。传统虚拟机在云计算领域的不足也加速了容器的使用。 Docker等容器提供商在很大程度上简化了容器技术,这也有助于容器技术在当今世界的广泛采用。最近 DevOps 和微服务的流行也成为容器技术重生的催化剂。

那么,什么是容器?容器在操作系统之上提供私有空间。这种技术也称为操作系统虚拟化。在这种方法中,操作系统的内核提供了隔离的虚拟空间。这些虚拟空间中的每一个都称为容器虚拟引擎VEs)。容器允许进程在主机操作系统之上的隔离环境中运行。下图显示了在同一主机上运行的多个容器的表示:

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化

容器是构建、发布和运行分隔软件组件的简单机制。通常,容器会打包运行应用程序所必需的所有二进制文件和库。容器保留自己的文件系统、IP 地址、网络接口、内部进程、名称空间、操作系统库、应用程序二进制文件、依赖项和其他应用程序配置。

组织使用了数十亿个容器。此外,还有许多大型组织在容器技术上进行了大量投资。到目前为止,Docker 领先于 the 竞争,得到许多大型操作系统的支持 system 供应商和 cloud 供应商。 LmctfySystemd Nspawn火箭吊桥LXDKurmaCalico 是 < span>some other 容器化解决方案。开放容器规范也是 正在开发中。

Difference between VM and containers


虚拟机,例如 Hyper-VVMWare 和 <几年前,span class="strong">Zen 是数据中心虚拟化的流行选择。企业经验丰富通过实施节省成本 虚拟化优于传统的裸机使用。它帮助了很多< /a> 企业以更优化的方式利用他们现有的基础设施。由于虚拟机支持自动化,许多企业对虚拟机的管理工作较少。虚拟机还帮助组织获得运行应用程序的隔离环境。

从表面上看,虚拟化和容器化都表现出完全相同的特征。但是,简而言之,容器和虚拟机并不相同。因此,在虚拟机和容器之间进行苹果对苹果的比较是不公平的。虚拟机和容器是解决不同虚拟化问题的两种不同技术。这种差异在下图中很明显:

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化

Virtual Machine (VM) 在 与容器相比, 级别要低得多。 VM 提供硬件虚拟化,例如 CPU、主板、内存等的虚拟化。 VM 是具有嵌入式操作系统的隔离单元,通常称为 Guest OS。虚拟机复制整个操作系统并在虚拟机中运行,而在主机操作系统环境中没有依赖。由于 VM 嵌入了完整的操作系统环境,因此它们本质上是重量级的。这是一个优点,也是一个缺点。优点是虚拟机为在虚拟机上运行的进程提供了完全隔离。缺点是由于 VM 的资源需求,它限制了可以在裸机中启动的 VM 数量。 VM 的大小直接影响启动和停止它们的时间。

Since starting a VM intern will boot the OS, the start time for it is generally high. VMs are more friendly for the infrastructure teams, since they require low-level infrastructure competency to manage VMs. Processes running inside the VMs are completely isolated from the processes on a different VM running on the same host.

在容器世界中,容器不会模拟整个硬件或操作系统。与 VM 不同,容器共享主机内核和操作系统的某些部分。在容器的情况下没有来宾操作系统的概念。容器直接在主机操作系统之上提供一个隔离的执行环境。这是一个优点,也是一个缺点。优点是更轻,速度更快。由于同一台机器上的容器共享主机操作系统,容器的整体资源利用率相当小。因此,与重量级 VM 相比,许多较小的容器可以在同一台机器上运行。由于同一主机上的容器共享主机操作系统,因此也存在限制。例如,无法在容器内设置 iptables 防火墙规则。容器内的进程完全独立于在同一主机上运行的不同容器上的进程。

与 VM 不同,容器映像在社区门户上公开可用。这使开发人员的生活变得更加轻松,因为他们不必从头开始构建镜像,相反,他们现在可以从经过认证的来源获取基础镜像,并在下载的基础镜像之上添加额外的软件组件层。

容器的轻量级特性也带来了大量的机会,例如自动构建、发布、下载、复制等。使用少量命令下载、构建、发布和运行容器的能力使容器对开发人员更加友好。构建一个新容器不会花费超过几秒钟的时间。容器现在也是持续交付管道的一部分。

总之,容器优于虚拟机有很多优势,但虚拟机有其独有的优势。许多组织将这两种容器与 VM 一起使用。例如,通过在虚拟机上运行容器。

Benefits of containers


我们已经看到 containers 相对于 VM 的许多好处。本节将解释容器的整体优势,而不是 VM 的优势。

容器的一些好处总结如下:

  • Self contained: Containers package essential application binaries and its dependencies together to make sure that there is no disparity between different environments, such as development, testing, or production. This promotes the concept of the Twelve-Factor applications and the concept of immutable containers. The Spring Boot microservices bundles all required application dependencies. Containers stretch this boundary further by embedding the JRE and other operating system-level libraries, configurations, and so on, if any.
  • Lightweight: Containers, in general, are smaller in size with a lighter footprint. The smallest container, Alpine, has a size of only less than 5 MB. The simplest Spring Boot microservices packaged with an Alpine container with Java 8 will only come at around 170 MB. Though the size is still on the higher side, it is much less than the VM image size, which will generally be in GBs. Smaller footprint of containers not only helps to spin new containers quickly, but also to make building, shipping, and storing easier.
  • Scalability: Since container images are smaller in size, and there is no OS booting at the startup, containers are generally faster to spin up and shut down. This makes containers a popular choice for cloud-friendly elastic applications.
  • Portability: Containers provide portability across machines and cloud providers. Once containers are built with all dependencies, they can be ported across multiple machines or multiple cloud providers without relying on the underlying machines. Containers are portable from desktops to different cloud environments.
  • License cost: Many software license terms are based on the physical core. Since containers share the operating system and are not virtualized at the physical resources level, there is an advantage in terms of the license cost.
  • DevOps: The lightweight footprint of containers makes them easy for automating builds and publishing and downloading containers from remote repositories. This makes them easy to use in agile and DevOps environments by integrating with automated delivery pipelines. Containers also support the concept of build once by creating immutable containers at build time and moving them across multiple environments. Since containers are not deep into the infrastructure, multi-disciplinary DevOps teams can manage containers as part of their day-to-day life.
  • Version controlled: Containers support versions by default. This helps build versioned artifacts, just like versioned archive files.
  • Reusable: Container images are reusable artifacts. If an image is built by assembling a number of libraries for a purpose, it can be reused in similar situations.
  • Immutable containers: In this concept, the containers are created and disposed of after usage. They are never updated or patched. Immutable containers are used in many environments to avoid complexities in patching deployment units. Patching will result in a lack of traceability and an inability to recreate environments consistently.

Microservices and containers


microservices 和容器之间没有直接关系。微服务可以在没有容器的情况下运行,而容器可以运行单体应用程序。然而,微服务和容器之间有一个甜蜜点。

容器适用于单体应用;然而,单体应用程序的复杂性和规模可能会扼杀容器的一些优势。例如,对于单体应用程序来说,快速旋转新的 containers 可能并不容易。除此之外,单体应用程序通常具有本地环境依赖关系,例如本地磁盘、与其他系统的炉管依赖关系等等。此类应用程序很难使用容器技术进行管理。这就是微服务与容器齐头并进的地方。

下图显示了三个多语言微服务在同一主机上运行并共享同一操作系统,但抽象了运行时环境:

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化

containers 的真正优势在于管理许多多语言微服务。例如,Java 中的一个微服务是 Erlang 或其他语言中的另一个微服务。容器帮助开发人员以统一的方式打包以任何语言或技术编写的微服务。它还可以帮助部署团队在多个环境中进行分发,而无需过多关注此类环境的配置。容器消除了使用不同的部署管理工具来处理多语言微服务的需要。容器不仅抽象了执行环境,还抽象了如何访问服务。无论使用何种技术,容器化微服务都会公开 REST API。一旦容器启动并运行,它就会绑定到某些端口并公开其 API。由于容器是自包含的并提供服务之间的全栈隔离,因此在单个 VM 或裸机中,可以运行多个异构 微服务< /a> 并以统一的方式处理它们。容器确实可以帮助避免开发、测试和生产团队相互指责配置和操作环境的冲突情况。

Introduction to Docker


前面的部分讨论了 containers 及其好处。容器已经存在多年,但 Docker 的流行给容器带来了新的前景。因此,Docker 架构中出现了许多容器定义和观点。 Docker 如此流行,甚至容器化也被称为 Dockerization

Docker 是一个平台,用于构建、发布和运行基于 Linux 内核的轻量级容器。 Docker 默认支持 Linux 平台。他们还支持使用 Boot2Docker 的 Mac 和 Windows,runs 在虚拟盒子的顶部。

Amazon EC2 Container Service (ECS) The-box support 适用于 AWS EC2 实例上的 Docker。 Docker 可以安装在裸机上,也可以安装在 VMWare 或 Hyper-V 等传统虚拟机上。

Key components of Docker

Docker 安装 有两个关键组件。一个 Docker 守护进程 和一个 Docker 客户端。 Docker daemon 和 Docker 客户端都是distributed 作为一个single 二进制文件。

下图显示了 Docker 安装的关键组件:

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化

The Docker daemon

Docker 守护进程是在负责构建、运行和分发 Docker 容器的主机上运行的服务器端 组件 . Docker 守护进程为 Docker 客户端公开 API 以与守护进程交互。这些 API 主要是基于 REST 的端点。可以将 Docker 守护进程想象为运行在主机上的控制器服务。开发人员也可以通过编程方式使用 API 来构建自定义客户端。

The Docker client

Docker 客户端是一个远程命令行程序,它通过套接字或REST API 与Docker 守护进程交互。 CLI 可以在运行守护程序的主机上运行,​​也可以在完全不同的主机上运行并使用 CLI 远程连接到守护程序。 Docker 用户将使用 CLI 来构建、发布和运行 Docker 容器。

Docker 概念——Docker 架构是围绕一些概念构建的,例如镜像、容器、注册表和 Dockerfile。

The Docker image

Docker 的关键概念 之一就是镜像。 Docker 映像是操作系统库和应用程序及其库的只读副本。创建映像后,可以保证在任何 Docker 平台上运行而无需更改。

在 Spring Boot 微服务中,一个 Docker 镜像会打包 Ubuntu、Alpine、JRE 等操作系统,以及 Spring Boot 胖应用 jar 文件。它还包括运行应用程序以及如何公开服务的说明。

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化

如上图所示,Docker 镜像基于分层架构,其中基础镜像将是 Linux 的一种风格。如上图所示,每一层都被添加到基础镜像层,前一个镜像作为父层。 Docker 使用联合文件系统的概念将所有这些层组合成一个镜像,形成一个单一的文件系统。

在典型情况下,开发人员不会从头开始构建 Docker 映像。映像(例如操作系统)或其他常见库(例如 Java 8 映像)可从受信任的来源公开获得。开发人员可以在这些基础镜像之上开始构建。 Spring 微服务中的基础镜像可以是 JRE 8,而不是从 Ubuntu 等 Linux 发行版镜像开始。

每次我们重建应用程序时,只有更改的层被重建,其余的层保持不变。所有中间层都被缓存,因此,如果没有变化,Docker 将使用之前缓存的层并在上面构建它。在同一台机器上运行具有相同类型基础镜像的多个容器将重用基础镜像,从而减少部署的大小。例如,在主机中,如果有多个以 Ubuntu 作为基础镜像运行的容器,它们都会重用同一个基础镜像。这也适用于发布或下载图像。

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化

如上图所示,image的第一层是一个名为的引导文件系统bootfs,类似于Linux kernelboot<一个 id="id326270478" class="indexterm"> 加载器。引导文件系统充当所有映像的虚拟文件系统。

在引导文件系统之上,将放置操作系统的文件系统,称为 rootfs。根文件系统将典型的操作系统目录结构添加到容器中。与 Linux 系统不同,对于 Docker,rootfs 将处于只读模式。

除了 rootfs,其他必需 将根据要求放置图像。在我们的例子中,这些是 JRE 和 Spring Boot 微服务 jar。启动容器时,writable 文件系统将放置在所有其他文件系统之上,以便进程运行。进程对底层文件系统所做的任何更改都不会反映在实际容器中。相反,这些将被写入可写文件系统。这个可写文件系统是易失的。因此,一旦容器停止,数据将丢失。由于这个原因,Docker 容器本质上是短暂的。

打包在 Docker 中的基本操作系统通常是操作系统文件系统的最小副本。实际上,在上面运行的进程可能不会使用整个 OS 服务。在一个 Spring Boot 微服务中,很多情况下,容器只是初始化一个 CMD 和 JVM,然后调用 Spring Boot fat jar。

The Docker container

Docker containers 是 Docker 镜像的运行实例。容器在运行时使用主机操作系统的内核。因此,它们与运行在同一主机上的其他容器共享主机内核。 Docker 运行时使用内核特性(例如 cgroups 和内核 命名空间。除了资源防护之外,containers 将获得自己的 filesystem 和网络配置。

容器在实例化时可以具有特定的资源分配,例如内存和 CPU。容器,当相同的图像启动时,可以有一个不同的 资源分配。默认情况下,Docker 容器会获得一个隔离的 subnetgateway 到网络。

The Docker registry

Docker 注册表是一个 central 地方,Docker 镜像从这里发布和下载。 Docker提供的中央注册表是https://hub.docker.com。 Docker 注册表具有可以下载并用作基本注册表的公共映像。 Docker 还具有专用于在 Docker 注册表中创建的帐户的私有映像。 Docker 注册表截图如下所示:

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化

Docker 还提供 Docker Trusted Registry (DTR),它可以用于在本地设置注册表。

Dockerfile

Dockerfile 是一个构建文件或 scripting 文件,其中包含构建 Docker 映像的指令。 Dockerfile 中可以包含多个步骤,首先是下载基础镜像。 Dockerfile 是一个文本文件,通常命名为 Dockerfiledocker build 命令查找 Dockerfile 以获取构建说明。可以将 Dockerfile 与 Maven 构建中使用的 pom.xml 文件进行比较。

Deploying microservices into Docker


本节将操作我们的学习展示 如何为我们的 BrownField PSS 微服务构建容器。

Note

本章的完整源代码在 chapter9 项目下,在 https://github.com/rajeshrv/Spring5Microservice。将 chapter6.* 复制到新的 STS 工作区并重命名 chapter9.*

按照以下步骤为 BrownField 微服务构建 Docker 容器:

  1. Install Docker from the official Docker site (https://www.docker.com).
  1. Follow the Get Started link for the download and install instructions based on the operating system of choice.
  2. Once installed, run Docker.app and then use the following command to verify the installation:
        Client:
        Version:      17.03.1-ce
        API version:  1.27
        Go version:   go1.7.5
        Git commit:   c6d412e
        Built:        Tue Mar 28 00:40:02 2017
        OS/Arch:      darwin/amd64
        Server:
        Version:      17.03.1-ce
        API version:  1.27 (minimum version 1.12)
        Go version:   go1.7.5
        Git commit:   c6d412e
        Built:        Fri Mar 24 00:00:50 2017
        OS/Arch:      linux/amd64
        Experimental: true
  1. Before we make any changes, we need to edit application.properties of all services to change from localhost to the IP address, since localhost is not resolvable from within the Docker containers. In the real world, this will point to a DNS or load balancer.

application.properties 文件如下所示:

        server.port=8090    
        spring.rabbitmq.host=192.168.0.101
        spring.rabbitmq.port=5672
        spring.rabbitmq.username=guest
        spring.rabbitmq.password=guest

Note

注意:将 IP 地址替换为您机器的 IP 地址。

  1. Update Application.java and BrownFieldSiteController.java in the chapter9.website project to replace localhost with IP address.
  2. Update BookingComponent.java under chapter9.book to reflect the IP address instead of localhost.
  3. Create a Dockerfile under the root directory of all microservices. An example of the Dockerfile to search for a microservice will look like this:
        FROM frolvlad/alpine-oraclejdk8
        VOLUME /tmp
        ADD  target/search-1.0.jar search.jar
        EXPOSE 8090
        ENTRYPOINT ["java","-jar","/search.jar"]
  1. The following is a quick examination of the contents of the Dockerfile:
  • FROM frolvlad/alpine-oraclejdk8 tells the Docker build to use a specific alpine-oraclejdk8 version as the basic image for this build. The frolvlad indicates the repository to locate the alpine-oraclejdk8 image. In this case, this is an image built with Alpine Linux and Oracle JDK 8. This will help layer our application on top of this base image without setting up Java libraries ourselves. In this case, since this image is not available on our local image store, the Docker build will go ahead and download this image from the remote Docker Hub registry.
  • VOLUME /tmp enables access from the container to the directory specified in the host machine. In our case, this is pointing to the tmp directory where the Spring Boot application creates working directories for Tomcat. The tmp directory is a logical directory for the container that will indirectly point to one of the local directories of the host.
  • ADD target/search-1.0.jar search.jar adds the application's binary file to the container with the destination file's name specified. In this case, the Docker build copies target/search-1.0.jar to the container as search.jar.
  • EXPOSE 8090 tells the container how to perform port mapping. This will associate 8090 as the external port binding for the internal Spring Boot service.
  • ENTRYPOINT ["java”,”-jar”, "/search.jar"] tells the container which default application to run when it is started. In this case, we are pointing to the Java process and the Spring Boot fat jar file to initiate the service.
  1. The next step is to run the docker build command from the folder where Dockerfile is stored. This will download the base image and run the entries in the Dockerfile one after the other.

用于搜索的 Docker 构建命令如下所示:

        docker build –t search:1.0 .

前面的命令将导致构建一个用于搜索的 docker 映像。日志如下所示:

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化
  1. Repeat the preceding step for all microservices.
  2. Once the images are created, they can be verified by typing the following command. This command will list the images and their details, including the size of the image files:
        docker images

上述命令将显示所有图像,如下所示:

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化
  1. Next, we will run the Docker container. This can be done using the following command. This command will load and run the container. Upon starting, container calls the Spring Boot executable jar to start the microservice:
        docker run -p 8090:8090 -t search:1.0
        docker run -p 8080:8080 -t fares:1.0
        docker run -p 8060:8060 -t book:1.0
        docker run -p 8070:8070 -t checkin:1.0
        docker run -p 8001:8001 -t website:1.0

上述命令启动 Search and Search API Gateway 微服务和网站。

所有服务完全启动后,使用 docker ps 命令进行验证:

读书笔记《building-microservices-with-spring》使用Docker将微服务集装化

下一步是将浏览器指向以下 URL。这将打开 BrownField 网站:

http://localhost:8001

Running RabbitMQ on Docker


由于我们的示例也使用了 RabbitMQ,让我们来探索如何将 RabbitMQ 设置为 Docker 容器。以下命令从 DockerRabbitMQ 映像"indexterm"> 集线器并启动 RabbitMQ:

docker run rabbitmq

Using the Docker registry


Docker Hub 提供了一个 central 位置来存储所有 Docker 镜像。图像可以存储为公共的也可以是私有的。在许多情况下,出于与安全相关的考虑,组织会在本地部署自己的私有注册表。

按照以下步骤设置和运行本地注册表:

  1. The following command will start a registry that will bind the registry on port 5000:
docker run -d -p 5000:5000 --restart=always --name registry
        registry:latest
  1. Tag search:1.0 to the registry:
docker tag search:1.0 localhost:5000/search:1.0
  1. Push the image to the registry:
docker push localhost:5000/search:1.0
  1. Pull the image back from the registry:
docker pull localhost:5000/search:1.0

Setting up the Docker Hub

在上一章中,我们玩过 与本地Docker 注册表。本节将向我们展示如何设置和使用 Docker Hub 来发布 Docker 容器。这是一种全局访问 Docker 镜像的便捷机制。在本章后面,Docker 镜像将从本地机器发布到 Docker Hub 并从 EC2 实例下载。

setting 执行以下链接中提到的步骤,创建公共 Docker Hub 帐户和存储库:

https://docs.docker.com/engine/installation/

在这种情况下,注册表充当微服务存储库,将存储和访问所有 Dockerized 微服务。这是微服务能力模型中解释的能力之一。

Publish microservices to the Docker Hub

为了将 Dockerized 服务推送到 Docker Hub,请按照以下步骤操作。下面的第一步标记 Docker image 和第二个 command 将 Docker 镜像推送到 Docker hub 仓库:

docker tag search:1.0 brownfield/search:1.0
docker push brownfield/search:1.0

要验证容器映像是否已发布,请使用以下 URL 转到 Docker Hub 存储库:

https://hub.docker.com/u/brownfield

Note

brownfield 替换为上一节中使用的存储库名称。

对所有其他微服务也重复此步骤。在此步骤结束时,所有服务都将发布到 Docker Hub。

Microservices on Cloud


microservices 功能模型中提到的功能之一是将云基础架构用于微服务。在本章前面,我们还探讨了使用云进行微服务部署的必要性。到目前为止,我们还没有将任何东西部署到云端。一旦我们有许多微服务,就很难在本地机器上运行所有微服务。

在本书的其余部分,我们将使用 AWS 作为云平台来部署 BrownField PSS 微服务。

Installing Docker on AWS EC2

在本节中,我们将在 EC2 实例上安装 Docker。按照以下步骤安装 Docker。

此示例假设您熟悉 AWS,并且已经在 AWS 上创建了 account

按照以下步骤在 EC2 上设置 Docker:

  1. Launch a new EC2 instance. In this case, if we have to run all instances together, we may need a large instance. The example uses t2.large.

Note

在此示例中,使用了以下 Ubuntu AMI。 Ubuntu Server 16.04 LTS (HVM),SSD 卷类型 - ami-a58d0dc5

  1. Connect to the EC2 instance and run the following commands:
sudo apt-get update
      sudo apt-get install docker.io
  1. The preceding command will install Docker on the EC2 instance. Verify the installation with the following command:
sudo docker version

Running BrownField services on EC2


在本节中,我们将在创建的 EC2 实例上设置 BrownField 微服务。在这种情况下,构建是在本地桌面 machinebinaries 将部署到 AWS。按照以下步骤在 EC2 实例上设置服务:

  1. Change all IP addresses in *.properties to reflect the IP address of the EC2 instance.
  2. Change the Java files mentioned earlier under chapter9.book and chapter9.website to reflect the IP addresses.
  1. On the local machine, recompile all projects and create Docker images for all microservices. Push all of them to the Docker Hub registry.
  2. Set up Java 8 on the EC2 instance.
  3. Execute the following commands in sequence:
sudo docker run --net=host rabbitmq:3
      sudo docker run -p 8090:8090 rajeshrv/search:1.0
      sudo docker run -p 8001:8001 rajeshrv/website:1.0
  1. Validate whether all services are working by opening the URL of the website and execute search. Note that we will be using the public IP of the EC2 instance in this case.

网站应用程序的 URL 如下:

        http://54.165.128.23:8001

Future of containerization


容器化仍在不断发展,但最近采用容器化技术的组织数量有所增加。在除了到Docker中,微软已经投资了Windows容器。尽管许多组织都在积极采用 Docker 和其他容器技术,但这些技术的缺点仍然是容器的大小和安全问题。容器的可移植性和标准化是另一个挑战。

目前,Docker 镜像通常很重。在弹性自动化环境中,容器的创建和销毁非常频繁,大小仍然是一个问题。更大的尺寸表示更多的代码,更多的代码意味着它们更容易出现安全漏洞。

未来肯定是在小尺寸容器中。 Docker 正在开发 unikernels,这是一种轻量级内核或云操作系统,即使在低功耗物联网设备上也可以运行 Docker。 Unikernel 不是成熟的操作系统,但它们提供了支持已部署应用程序的基本必要库。 Unikernel 提供更好的速度、可扩展性、更小的尺寸和增强的安全性。

许多组织正在转向混合云解决方案以避免供应商锁定。这导致与供应商保持安全距离,这有助于组织快速构建容器并在各种环境中部署。在标准化容器运行时以及容器镜像方面已经做出了一些努力,例如 Open Container Initiative (OCI )。许多 container 供应商已被采用为 OCI 标准。

安全问题和安全问题在容器上被广泛讨论和辩论。关键的安全问题是围绕用户命名空间隔离或用户 ID 隔离。如果容器在 root 上(默认情况下),它可以获得主机的 root 权限。使用来自不受信任来源的 container 图像是另一个安全问题。在大型容器的情况下,攻击面更广,因为每个容器都可能暴露端点。

Docker 正在尽快缩小这些差距,但有许多组织使用虚拟机和容器的组合来规避一些安全问题。 Docker Security Scanning 等工具可以自动识别与图像相关的漏洞。还有其他安全控制工具,例如 Docker Bench、CoreOS 的 Clair 和 Twistlock。

Summary


在本章中,我们了解到在处理互联网规模的微服务时需要有一个云环境。

我们探索了容器的概念,并将它们与传统的虚拟机进行了比较。我们还学习了 Docker 的基础知识,并解释了 Docker 镜像、容器和注册表的概念。在微服务的背景下解释了容器的重要性和好处。

然后本章通过对 BrownField 微服务进行 Dockerizing 切换到一个动手示例。我们演示了如何在 Docker 上部署之前开发的 Spring Boot 微服务。我们通过探索本地注册表以及用于推送和拉取 Dockerized 微服务的 Docker Hub 来了解注册表的概念。

作为最后一步,我们探讨了如何在 AWS 云环境中部署 Dockerized BrownField 微服务。