在API网关和微服务开发中使用Docker

原文作者:Everett Griffiths

原文地址:https://dzone.com/articles/using-docker-in-api-gateway-and-microservice-devel


随着您作为开发人员的教育进步,您迟早会了解像Docker这样的容器系统所带来的好处:您可以使用代码指定您的开发环境,而不必向系统工程师发送所有Slack消息或者遇到的麻烦站在一贯需要配置的服务器。同样,您可能已经理解了微服务作为解决单片应用程序自身债务缠身问题的解决方案的吸引力。

本文提供了一些关于如何在微服务的开发流程中利用Docker的见解。

Docker支持一个独立的微服务

开发微服务本身应该是相当直接的; 从环境的角度来看,开发一个微服务不应该像开发一个传统的应用程序那么不同。也许你的微服务需要支持一个或两个API端口 - 你需要它连接到几个数据模型,比如MySQL或Redis,并且你可以很快进入正轨。这是Docker 101的东西。您可以利用良好支持现有Docker项目,如LaradockNoDock(分别针对PHP和Node.js),它们为开发人员提供了一个集成的Docker环境,该环境支持通过docker-compose联网在一起的一系列常见技术。

快速迅速

我想告诉任何使用Docker的人的第一个提示是,它的开发速度非常快:即使是最近的课程也可能涉及到已经被弃用的命令或实用程序(例如docker-machine)。准备好咬紧牙关,然后浏览一些不熟悉的错误消息。然而,一旦你通过难关,在Docker俱乐部的会员资格是值得的。

Docker独立

当然,在我们开始之前,请确保您的计算机上有Docker工具箱。请参阅Docker.com为您的主机操作系统下载客户端(CE社区版本适用于我们的操作)。

如果您需要运行特定技术(如脚本语言或操作系统),那么很可能有人已经为其创建了Docker映像。DockerHub是您重复使用其他人如此慷慨分享的代码的朋友。记住:不要重复造轮子!请注意,出于某种原因,当您实际上搜索图像时,该网站会被标记为搜索容器。请记住:容器是模板 - 可以从单个图像模板创建多个容器实例。

简而言之,您在这里的交互应该围绕克隆容器(使用clone命令),然后运行它的一个实例(使用run命令)。例如,您只需要获取Postgres的工作副本即可:

docker pull postgres docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres

如果您查看任何容器的相应Git存储库,那么Dockerfile它包含从图像构建容器实例所需的步骤,例如,用于Postgres容器。

通常,Dockerfile中的第一条指令,使用命令FROM:这扩展了指定的容器,因此您可以从一开始就看到,对于作者来说,重用现有映像是一种巨大的激励。

Docker撰写

在很多情况下,您会发现将单独的Docker容器连接在一起很有用。如果您的应用程序需要特定版本的PHP和特定版本的Postgres,则没有任何问题:找到Docker镜像并在docker-compose.yml文件中引用它们。

对于许多使用案例来说,docker-compose将是将容器捆绑在一起的最重要的工具。对于每个微服务,您将能够引用新的和现有的Docker映像并通过您的docker-compose.yml文件定义它们的关系。

例如,下面是我们如何定义一个环境来在NGINX Web服务器上支持PHP 7和Postgres。假设我们的存储库根目录有一个名为的公用Web文件的文件夹public/和一个文件composer.json

# PHP + Postgres microservice docker-compose.yml version: '2' services: nginx: image: nginx:1.13-alpine ports: - 3000:80 volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf web: # This build command is what # builds the neighboring Dockerfile build: . ports: - 9000:9000 volumes: - .:/var/www - /var/www/vendor depends_on: - postgres environment: DATABASE_URL: postgres://todoapp@postgres/todos postgres: image: postgres:9.6.2-alpine environment: POSTGRES_USER: todoapp POSTGRES_DB: todos

其中大部分是端口和卷映射。那么PHP在哪里?build: .这个命令有点模糊。更详细地说,该命令运行docker build .,所以它期望在Dockerfile这个文件旁边有一个Dockerfiledocker-compose.yml。PHP Dockerfile可能看起来如下:

FROM php:7.1-fpm-alpine RUN apk update && apk add build-base RUN apk add postgresql postgresql-dev \ && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ && docker-php-ext-install pdo pdo_pgsql pgsql RUN apk add zlib-dev git zip \ && docker-php-ext-install zip RUN curl -sS https://getcomposer.org/installer | php \ && mv composer.phar /usr/local/bin/ \ && ln -s /usr/local/bin/composer.phar /usr/local/bin/composer # References the virtual path COPY . /var/www WORKDIR /var/www RUN composer install --prefer-source --no-interaction ENV PATH="~/.composer/vendor/bin:./vendor/bin:${PATH}"

根据你的需求,你可能完全不需要Dockerfile。不是一个build命令,docker-compose.yml可能会引用一个image,但由于PHP是使用的服务器端语言,很可能它需要一些定制。这在Dockerfile最容易实现,因此通过build属性引用它可能是最好的方法。

你需要做的最后一件事是一个NGINX配置文件。像下面这行命令应该就足够了:

server { listen 80; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /var/www/public/; location / { try_files $uri /index.php$is_args$args; } location ~ ^/.+\.php(/|$) { fastcgi_pass web:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }

如果您正在关注在存储库根目录在容器内的对应位置上进行的映射,则可以看到按写入的方式,该文件位于存储库的根目录。docker-compose.yml/var/www/nginx.conf

你可能很容易被文件中的虚拟路径所迷惑,所以你必须将它与你的文件进行比较。具体而言,它将映射(存储库根目录)到虚拟机上。所以NGINX从这一点开始拿起并定义它的web根目录- 这是你的版本库中的文件夹。nginx.confdocker-compose.yml./var/www/var/www/public/public/

要下载这些图像并将它们构建到容器中,您可以运行。下载和构建图像可能需要一段时间,但如果一切顺利,您应该可以打开新的PHP应用程序docker-compose uphttp://localhost:3000

种子数据

在开发微服务时,您需要编写测试。当使用像Docker这样的技术,您可以很容易且一致地提供相关服务时,您应该认识到一个很好的机会,可以根据策划的种子数据集合进行集成测试和功能测试。

当您可以访问一个真实的数据库并得到真实的响应时,为什么仅仅依靠单元测试和模拟服务呢?尽管设置起来比较麻烦,但是集成测试的优点是它们测试更彻底全面——当然有时会有一些意外和细微的差别,而mock不能涵盖这些。

在这种情况下的测试运行将从重新启动您的容器开始,并使用您的策划种子数据加载它们。这确实需要比执行简单的单元测试更长的时间,但它不会比浏览器自动化或其他最终用户测试慢。

执行种子操作的最简单方法之一是使用docker-composeexec函数,该函数在指定的容器中执行命令。例如,如果我们的PHP应用程序是Laravel应用程序,那么我们可以利用其artisan命令行工具来迁移和生成我们的数据库。

docker-compose exec web php artisan migrate

无论您使用的是哪种语言,都应该有一种可行的方法来支持您的数据库迁移,并为您的集成测试使用一些可行的种子数据对数据库进行种子处理。

API网关的Docker

当你退一步,开始开发API网关本身时,或者如果你需要处理一个与多个数据源交互的更复杂的服务时,你最终可能会试图想出来您生态系统中所有相关应用程序的工作版本。

您的API网关应用程序的Docker镜像可能与我们针对单个微服务所讨论的内容并没有太大的不同。它需要一些环境来处理通过服务器端代码(可能是Go或Elixir)的请求和响应,并且它通常会附加到认证/授权服务,以便在将代理代理到微服务之前验证请求。

这可能就足够了:您可以在API Gateway内测试任何权限逻辑或错误处理方式,这与您在任何微服务应用程序中的方式几乎相同。如果您使用身份验证服务,您可以测试每条路线的适当权限。您还可以验证传入的请求是否代理了特定的服务,如果需要,您可以模拟响应。

但这并不代表端到端测试。如果我们想确定具体的请求能够产生特定的响应,我们将不得不做一些改进。这就是我们回到Docker和Docker Compose的地方。

如果我们将docker-compose.yml用作我们微服务的“记录文档”,您可以很容易想象它可能会列出大量服务(例如,每个微服务都有一个服务)。如果每个服务都构建为Docker镜像,那么您可以将这些镜像作为公共(或私人)存储库在Docker Hub上发布,以便其他开发人员可以轻松地克隆和构建应用程序所需的容器。

专用测试图像

解决播种数据和运行集成测试问题的一个解决方案是为该任务创建专用的Docker镜像。这个Docker映像可能会很好地利用您docker-compose.yml文件中的depends_on关键字。您用来编写测试的语言可以是最适合当前任务的语言:测试。只要您可以轻松地使用种子数据填充数据模型,编写使用HTTP请求访问API网关的测试,这就可以工作。

将这些测试放在相同的图像和代码库中作为API网关是完全可能的,但对于很多用例来说,将它们分开可能更有意义。最重要的是,对测试或种子数据的任何更改都不应要求升级和部署API网关本身。其次,API网关的语言可能不适合编写测试或使用种子数据填充模型。因此,为任务提供一个专用的映像应该有助于隔离更改并为任务提供最佳的工具。

这种安排有时可能需要更多的人力,但它确实促进了测试驱动开发和良好的测试覆盖,包括代码和服务,也包括环境本身。如果我们将每个微服务看作是应用程序“主体”中的某种处理“单元”,那么将集成测试和与之相关的种子数据与微服务分离开来就很有意义。

在某种程度上,这提供了网关和它的微服务之间的强契约。如果您更新服务或完全替换它,您的集成测试将为您提供更改兼容的可靠保证。

结论

这只触及到了联网、填充和测试相互连接的微服务可能遇到的复杂性的表面,里面的水还很深。本文概述的方法已经暗示了在某些场景中可能出现的一些缺点,因此您可能已经了解其他技术(如Kubernetes)可能对您有用。希望它为您提供了一些关于如何解决您自己的应用程序环境中的一些问题的想法。

本文的版权归 阿小庆 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏性能与架构

模拟利用Redis入侵系统

昨天的文章写了系统被黑过程,原因是redis安全配置没做好,让黑客轻松通过redis设置了ssh免密码登陆,从而成功入侵 对这个攻击过程有点好奇,就查了下相关...

3277
来自专栏编程坑太多

跟我一起学docker(九)--持续系统集成了解下git

1317

版本控制简介

在“ 托管网站”指南中,您了解了如何通过安装和配置Web服务器,数据库和PHP来托管您的网站。现在是时候用版本控制来保护您的数据并顺利处理代码更新。当您学习完本...

622
来自专栏EAWorld

为什么有了Docker registry还需要Harbor?

目录: 一、Harbor的安全机制 二、Harbor的镜像同步 三、Harbor与K8s的集成实践 四、两个小贴士 五、总结 Habor是由VMWare公司开源...

3995
来自专栏云计算教程系列

如何在Ubuntu 14.04上为SSH设置多重身份验证

一个认证因素是单件的使用信息,以证明你有权要执行的操作,如登录到系统中。的认证信道是认证系统提供了一个因子给用户或要求用户回答的方式。密码和安全令牌是身份验证因...

140
来自专栏岑志军的专栏

iOS逆向-ipa包重签名及非越狱手机安装多个微信

2673
来自专栏友弟技术工作室

全平台最佳密码管理工具大全:支持 Windows、Linux、Mac、Android、iOS 以及企业应用

原文 当谈到网络安全的防护时,从各种网络威胁的角度来看,仅安装一个防病毒软件或运行一个安全的 Linux 操作系统,并不意味你就是足够安全的。 今天大多数网络...

63511
来自专栏安智客

FIDO U2F认证器简明原理

U2F ( Universal 2nd Factor ) 是 Yubico, Yahoo 和 Google 联合开发的基于物理设备的双因素认证协议。这个物理设备...

912
来自专栏FreeBuf

如何使用加密的Payload来识别并利用SQL注入漏洞

写在前面的话 密码学具有诸多优点,信息的保密性同样离不开密码学,但是从历史经验来看,在保护应用和数据安全方面我们绝对不能过分依赖于密码学。在这篇文章中,安全教育...

1846
来自专栏沈唁志

HTTPS时代到来-七月开始Chrome 68将会把所有HTTP站点标记为不安全

谷歌在2018年2月初的时候就宣布:自2018年7月份开始,Chrome浏览器将会标记所有依然使用HTTP的网站为“不安全”

981

扫码关注云+社区