nomad 服务编排
Brendan Burns in his paper Design Patterns for Container-Based Distributed Systems lays out 3 single node patterns that are used in a micro-services architecture. There is some documentation available with examples for implementing these patterns with Kubernetes. However, I couldn’t find a lot of examples using HashiCorp’s Nomad. My goal is to work through them with examples using Nomad as our job scheduler. All the code used here is available in the Github Repository
Brendan Burns在他的论文《 基于容器的分布式系统的设计模式》中列出了在微服务体系结构中使用的3个单节点模式。 有一些示例文档提供了使用Kubernetes实现这些模式的示例 。 但是,使用HashiCorp的Nomad找不到很多示例。 我的目标是通过使用Nomad作为我们的工作计划程序的示例来研究它们。 Github存储库中提供了此处使用的所有代码
Nomad民族快速入门 (Quick Introduction to Nomad)
Nomad is: A simple and flexible workload orchestrator to deploy and manage containers and non-containerized applications across on-prem and clouds at scale. It uses HCL to specify jobs that can be submitted to the cluster. Each job consists of one or more groups and each group can contain one or more tasks. Tasks can be services or batch, docker containers, or binaries. The tasks in the same group are co-located, i.e. placed on the same node.
Nomad是: 一个简单而灵活的工作负载编排器,可以跨内部部署和云大规模部署和管理容器和非容器化应用程序。 它使用HCL指定可以提交到群集的作业。 每个作业包含一个或多个组,每个组可以包含一个或多个任务。 任务可以是服务或批处理,泊坞窗容器或二进制文件。 同一组中的任务位于同一位置,即放置在同一节点上。
job "example" {
group "example" {
task "example-service" {
#...
}
task "example-service2"{
#...
}
}
}
This post assumes that you’re already familiar with Nomad, if not please check Hashicorp’s amazing documentation for it.
这篇文章假定您已经熟悉Nomad,否则请查看Hashicorp的出色文档。
边车图案 (Sidecar pattern)
The sidecar pattern is made up of 2 containers:
边车模式由2个容器组成:
- the application container 应用程序容器
- the sidecar container 边柜
The role of the sidecar is to augment and improve the application container, often without the application container’s knowledge. Sidecar containers are scheduled on the same host machine, which is possible using Nomad’s group
stanza. The group
stanza defines a series of tasks that should be co-located on the same Nomad client. Any task within a group will be placed on the same client.
辅助工具的作用是经常在应用容器不了解的情况下增加和改进应用容器。 Sidecar容器安排在同一台主机上,这可以使用Nomad的group
节来实现。 group
节定义了一系列应位于同一Nomad客户端上的任务。 组中的任何任务都将放置在同一客户端上。
Example: SSL Proxy In this example we’re going to see how we can enable SSL for a legacy application. While we can modify the original application to add HTTPS handling, it’s much more convenient to just add an SSL proxy as a sidecar container. Here in this example, we’re deploying our application which Hashicorp’s Echo Server with an Nginx server as a sidecar proxy which:
示例:SSL代理在此示例中,我们将了解如何为旧版应用程序启用SSL。 虽然我们可以修改原始应用程序以添加HTTPS处理,但是将SSL代理添加为Sidecar容器要方便得多。 在此示例中,我们将部署我们的应用程序,即Hashicorp的Echo Server与Nginx服务器作为Sidecar代理,该应用程序:
- Intercepts all incoming traffic 拦截所有传入流量
- Terminates HTTPS 终止HTTPS
- Proxies the traffic to the application container 将流量代理到应用程序容器
To enable this we create a new task called ssl-proxy-sidecar
which mounts the SSL certificate and the SSL certificate key. It also proxies all traffic to NOMAD_ADDR_app_server_http
which is how Nomad makes the application container's HTTP port available as an environment variable. Here's a snippet of the Nginx config:
为实现此目的,我们创建了一个名为ssl-proxy-sidecar
的新任务,该任务将装入SSL证书和SSL证书密钥。 它还将所有流量代理到NOMAD_ADDR_app_server_http
,这是Nomad如何使应用程序容器的HTTP端口可用作环境变量。 这是Nginx配置的片段:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /secrets/certificate.crt;
ssl_certificate_key /secrets/certificate.key;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://{{ env "NOMAD_ADDR_app_server_http" }};
}
}
A working code example is available here.
这里提供了一个工作代码示例。
大使模式 (Ambassador Pattern)
The ambassador pattern uses an auxiliary container to act as a broker between the application container and the outside world.
大使模式使用辅助容器充当应用程序容器与外界之间的代理。
Example: Request Splitting or A/B Testing In many production environments while rolling out new updates it’s often beneficial to have a fraction of all requests to the newly updated service. A common testing method is A/B testing — also known as split testing — in which a (usually small) proportion of users is directed to the new version of an application while most users continue to use the current version.
示例:请求拆分或A / B测试在许多生产环境中,在推出新更新的同时,对新更新的服务的所有请求中的一小部分通常是有益的。 常见的测试方法是A / B测试(也称为拆分测试),其中,(通常很少)一部分用户被定向到应用程序的新版本,而大多数用户仍在使用当前版本。
In our example Nomad file we have service.nomad
which contains 2 tasks: service-experimental
and service-stable
for the respective experimental and stable containers. Both of our services are different versions of the echo server.
在我们的示例Nomad文件中,我们有service.nomad
,其中包含2个任务:分别用于实验容器和稳定容器的service-experimental
和service-stable
。 我们的两个服务都是回显服务器的不同版本。
In another Nomad file, app.nomad
we have our request-splitter
task which is an Nginx server acting as the request splitting ambassador for our main task which is app
. Here's a snippet of the Nginx config to act as request splitting ambassador:
在另一个Nomad文件app.nomad
我们有一个request-splitter
任务,它是一个Nginx服务器,充当我们主要任务app
的请求拆分大使。 这是Nginx配置的代码片段,用作请求拆分大使:
http {
upstream app_stable {
{{ range service "app-server-stable" }}
server {{.Address}}:{{.Port}} {{end}}
}
upstream app_experimental {
{{ range service "app-server-experimental" }}
server {{.Address}}:{{.Port}} {{end}}
}
split_clients "${remote_addr}" $appversion {
95% app_stable;
* app_experimental;
}
server {
listen 80;
location / {
proxy_set_header Host $host;
proxy_pass http://$appversion;
}
}
}
A code example is available on Github. In the code example, you’ll notice the application container is left blank but the idea would be that the application container would use the ambassador container to reach out to the external service instead of reaching out directly. I might implement a simple application and update it in the future.
Github上提供了一个代码示例。 在代码示例中,您会注意到应用程序容器保留为空白,但想法是应用程序容器将使用大使容器来访问外部服务,而不是直接访问。 我可能会实现一个简单的应用程序,并在将来对其进行更新。
适配器图案 (Adaptor Pattern)
The adaptor pattern is used to modify the interface of an existing application container to some other interface without modifying the application container. This is widely used in software engineering (Gang of Four) patterns for classes and objects but here we’ll be using it in the context of containers.
适配器模式用于将现有应用程序容器的接口修改为某些其他接口,而无需修改应用程序容器。 这在类和对象的软件工程模式(四人制)中被广泛使用,但是在这里我们将在容器的上下文中使用它。
Example: Monitoring with Prometheus Prometheus is an industry-standard monitoring system and time series database. In this example, we’ll see how we use the adaptor pattern to add telemetry to our existing application container without modifying the application. Prometheus expects applications to expose a metrics endpoint which servers the metrics in a given exposition format. In our previous examples we’ve deployed Nginx as our auxiliary container however here we’ll treat Nginx as our application container. We’ll be using the Nginx exporter container as our adapter to convert Nginx metrics.
示例:使用Prometheus进行监视 Prometheus是行业标准的监视系统和时间序列数据库。 在此示例中,我们将看到如何使用适配器模式将遥测添加到现有应用程序容器中,而无需修改应用程序。 Prometheus期望应用程序公开一个指标终结点,该终结点以给定的展示格式存储指标。 在前面的示例中,我们将Nginx部署为辅助容器,但是在这里,我们将Nginx视为应用程序容器。 我们将使用Nginx导出器容器作为我们的适配器来转换Nginx指标。
We define the following task for the Nginx exporter to act as our adaptor for Prometheus. Now in Prometheus config, we can point it to scrape the adaptor container which returns metrics in a format Prometheus understands.
我们为Nginx导出器定义以下任务,以充当Prometheus的适配器。 现在在Prometheus配置中,我们可以将其指向刮取适配器容器,该容器以Prometheus理解的格式返回度量。
task "adaptor-nginx-exporter" {
driver = "docker"
config {
image = "nginx/nginx-prometheus-exporter:0.8.0"
args = [
"--nginx.scrape-uri", "http://${NOMAD_ADDR_service_nginx_http}/status"
]
port_map {
http = 9113
}
}
resources{
network {
mbits = 10
port "http" {}
}
}
}
资源资源 (Resources)
Originally published at https://iyer.ai on July 14, 2020.
最初于 2020年7月14日 在 https://iyer.ai 上 发布 。
翻译自: https://medium.com/swlh/container-patterns-for-micro-services-with-nomad-7c60e9a13e57
nomad 服务编排