如何使用Confd和ETCD动态重新配置服务在CoreOS

介绍

CoreOS允许您在一组机器上轻松运行Docker容器中的服务。 这样做一般程序包括启动服务的一个或多个实例,然后注册每个实例 etcd ,CoreOS的分布式key-value存储。 通过利用这种模式,相关服务可以获得关于基础设施的状态的有价值的信息,并且使用这些知识来通知他们自己的行为。这使得有可能对服务动态地配置自身每当显著 etcd值的变化。 在本指南中,我们将讨论一个叫做工具 confd ,这是专门制作的观赏分布式键值存储更改。它从Docker容器中运行,用于触发配置修改和服务重新加载。

先决条件和目标

为了完成本指南,您应该对CoreOS及其组件有基本的了解。在以前的指南中,我们设置了一个CoreOS集群,并熟悉了用于管理集群的一些工具。 以下是在开始阅读本文之前应该阅读的指南。我们将修改这些指南中描述的一些服务的行为,因此虽然了解材料很重要,但在使用本指南时应该重新开始: 此外,为了更熟悉我们将使用的一些管理工具,您需要阅读以下指南: “如何创建灵活的服务”指南对于本指南尤其重要,因为模板化的主要+ sidekick服务将作为我们将在本指南中设置的前端服务的基础。如前所述,虽然上面的指南讨论了Apache和sidekick服务的创建,但是本指南还有一些配置更改,使得从头开始更容易。我们将在本指南中创建这些服务的修改版本。 在本教程中,我们将重点介绍使用Nginx创建一个新的应用程序容器。这将作为对我们可以从我们的模板文件生成的各种Apache实例的反向代理。 nginx的容器将被配置 confd观看服务注册,我们的搭档服务负责。 我们将从我们通过这个系列使用的相同的三个机器集群开始。
  • coreos-1
  • coreos-2
  • coreos-3
当您阅读完上述指南并让您的三个机器群集可用后,继续。

配置后端Apache服务

我们将开始设置我们的后端Apache服务。这将主要反映上一个指南的最后一部分,但我们将通过整个过程在这里,由于一些细微的差异。 登录到您的一台CoreOS机器以开始:
ssh -A core@ip_address

Apache容器设置

我们将从创建基本的Apache容器开始。这实际上与上一个指南相同,因此如果您的Docker Hub帐户中已有该映像,则不必再次执行此操作。我们将这个容器放在Ubuntu 14.04容器镜像之外。 我们可以通过键入下拉基本映像并启动容器实例:
docker run -i -t ubuntu:14.04 /bin/bash
你将会进入一个 bash一旦容器启动会话。 从这里,我们就会更新本地 apt包指数和安装 apache2
apt-get update
apt-get install apache2 -y
我们还将设置默认页面:
echo "<h1>Running from Docker on CoreOS</h1>" > /var/www/html/index.html
我们现在可以退出容器,因为它处于我们需要的状态:
exit
通过键入以下内容登录或创建您的帐户:
docker login
您必须为您的Docker Hub帐户提供您的用户名,密码和电子邮件地址。 接下来,获取刚刚离开的实例的容器ID:
docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
1db0c9a40c0d        ubuntu:14.04        "/bin/bash"         2 minutes ago       Exited (0) 4 seconds ago                       jolly_pare
上面突出显示的字段是容器ID。复制您在自己的计算机上看到的输出。 现在,使用该容器ID,您的Docker Hub用户名和图像的名称进行提交。我们将在这里使用“apache”:
docker commit 1db0c9a40c0d user_name/apache
将您的新映像推送到Docker Hub:
docker push user_name/apache
现在可以在您的服务文件中使用此映像。

创建Apache服务模板单元文件

现在,你有一个容器可用,您可以创建一个模板单元文件,以便 fleetsystemd可以正确地管理服务。 在我们开始之前,让我们设置一个目录结构,以便我们可以保持组织:
cd ~
mkdir static templates instances
现在,我们可以使我们在模板文件 templates目录:
vim templates/apache@.service
将以下信息粘贴到文件中。您可以按照上一指南获取有关每个我们正在使用的选项的详细信息 创建灵活的船队单元文件
[Unit]
Description=Apache web server service on port %i

# Requirements
Requires=etcd.service
Requires=docker.service
Requires=apache-discovery@%i.service

# Dependency ordering
After=etcd.service
After=docker.service
Before=apache-discovery@%i.service

[Service]
# Let processes take awhile to start up (for first run Docker containers)
TimeoutStartSec=0

# Change killmode from "control-group" to "none" to let Docker remove
# work correctly.
KillMode=none

# Get CoreOS environmental variables
EnvironmentFile=/etc/environment

# Pre-start and Start
## Directives with "=-" are allowed to fail without consequence
ExecStartPre=-/usr/bin/docker kill apache.%i
ExecStartPre=-/usr/bin/docker rm apache.%i
ExecStartPre=/usr/bin/docker pull user_name/apache
ExecStart=/usr/bin/docker run --name apache.%i -p ${COREOS_PRIVATE_IPV4}:%i:80 \
user_name/apache /usr/sbin/apache2ctl -D FOREGROUND

# Stop
ExecStop=/usr/bin/docker stop apache.%i

[X-Fleet]
# Don't schedule on the same machine as other Apache instances
Conflicts=apache@*.service
我们在这里做的一个修改是使用私人接口,而不是公共接口。由于所有我们的Apache实例将 通过 Nginx的反向代理,而不是从开放的网络连接处理传递流量,这是一个好主意。记住,如果你使用DigitalOcean上的私有接口,你启动的服务器必须在创建时选择了“private networking”标志。 此外,请记住改变 user_name引用您的Docker Hub的用户名,以便正确地拉下泊坞文件。

创建Sidekick模板单元文件

现在,我们将对sidekick服务执行相同操作。这一点,我们将稍微修改,以预期以后我们将需要的信息。 在编辑器中打开模板文件:
vim templates/apache-discovery@.service
我们将在此文件中使用以下信息:
[Unit]
Description=Apache web server on port %i etcd registration

# Requirements
Requires=etcd.service
Requires=apache@%i.service

# Dependency ordering and binding
After=etcd.service
After=apache@%i.service
BindsTo=apache@%i.service

[Service]

# Get CoreOS environmental variables
EnvironmentFile=/etc/environment

# Start
## Test whether service is accessible and then register useful information
ExecStart=/bin/bash -c '\
  while true; do \
    curl -f ${COREOS_PRIVATE_IPV4}:%i; \
    if [ $? -eq 0 ]; then \
      etcdctl set /services/apache/${COREOS_PRIVATE_IPV4} \'${COREOS_PRIVATE_IPV4}:%i\' --ttl 30; \
    else \
      etcdctl rm /services/apache/${COREOS_PRIVATE_IPV4}; \
    fi; \
    sleep 20; \
  done'

# Stop
ExecStop=/usr/bin/etcdctl rm /services/apache/${COREOS_PRIVATE_IPV4}

[X-Fleet]
# Schedule on the same machine as the associated Apache service
MachineOf=apache@%i.service
上述配置在几个方面与上一个指南中的不同。我们已经调整了设置的值 etcdctl set命令。我们不是传递JSON对象,而是设置一个简单的IP地址+端口组合。这样,我们可以直接读取此值,以找到获取此服务所需的连接信息。 我们还调整了信息以指定私有接口,就像我们在其他文件中做的那样。如果您没有此选项可供选择,请将此选项设为公开。

实例化您的服务

现在,让我们创建这些服务的两个实例。 首先,让我们创建符号链接。移动到 ~/instances创建目录和链接来定义,他们将上运行的端口。我们想要在端口7777上运行一个服务,而在端口8888上运行另一个服务:
cd ~/instances
ln -s ../templates/apache@.service apache@7777.service
ln -s ../templates/apache@.service apache@8888.service
ln -s ../templates/apache-discovery@.service apache-discovery@7777.service
ln -s ../templates/apache-discovery@.service apache-discovery@8888.service
现在,我们可以通过将启动这些服务的 ~/instances目录 fleet
fleetctl start ~/instances/*
在您的实例启动(这可能需要几分钟),你应该能够看到 etcd你插袋的条目:
etcdctl ls --recursive /
/coreos.com
/coreos.com/updateengine
/coreos.com/updateengine/rebootlock
/coreos.com/updateengine/rebootlock/semaphore
/services
/services/apache
/services/apache/10.132.249.206
/services/apache/10.132.249.212
如果您要求这些条目中的一个的值,您可以看到您获得一个IP地址和端口号:
etcdctl get /services/apache/10.132.249.206
10.132.249.206:8888
您可以使用 curl检索页面,并确保其功能正常。如果您将服务配置为使用专用网络,则此操作只能在您的计算机上工作:
curl 10.132.249.206:8888
<h1>Running from Docker on CoreOS</h1>
我们现在已经设置了后端基础设施。我们下一步是要熟悉 confd这样我们就可以观看 /services/apache的位置 etcd更改,每次重新配置Nginx的。

创建Nginx容器

我们将从我们用于Apache服务的相同的Ubuntu 14.04基础启动Nginx容器。

安装软件

键入以下命令来启动新容器:
docker run -i -t ubuntu:14.04 /bin/bash
更新本地 apt包缓存并安装Nginx的。 我们还需要安装 curl由于基本图像不包括这一点,我们需要它来得到稳定的 confd从GitHub包瞬间:
apt-get update
apt-get install nginx curl -y
现在,我们可以去 发布页面confd在GitHub上在我们的浏览器。 我们需要找到到最新稳定版本的链接。 在写这篇文章的时候,那是 v0.5.0 ,但这可能会有所改变。右键单击Linux版本工具的链接,然后选择“复制链接地址”或任何类似选项。 现在,回到你的Docker容器中,使用复制的URL下载应用程序。我们将在被把这个 /usr/local/bin目录。 我们需要选择 confd作为输出文件:
cd /usr/local/bin
curl -L https://github.com/kelseyhightower/confd/releases/download/v0.5.0/confd-0.5.0<^>-linux-amd64 -o confd
现在,使文件可执行,以便我们可以在我们的容器中使用它:
chmod +x confd
我们还应该利用这个机会来创建配置结构 confd的期望。 这将是中 /etc目录:
mkdir -p /etc/confd/{conf.d,templates}

创建Confd配置文件以读取Etcd值

现在,我们已经安装了我们的应用,我们应该开始配置 confd 。我们将从创建配置文件或模板资源文件开始。 在配置文件中 confd用于设置服务检查某些 etcd值和检测到变化时发起行动。 这些使用 TOML文件格式,它很容易使用和非常直观。 我们称为配置目录中中创建的文件开始 nginx.toml
vi /etc/confd/conf.d/nginx.toml
我们将在这里建立我们的配置文件。添加以下信息:
[template]

# The name of the template that will be used to render the application's configuration file
# Confd will look in `/etc/conf.d/templates` for these files by default
src = "nginx.tmpl"

# The location to place the rendered configuration file
dest = "/etc/nginx/sites-enabled/app.conf"

# The etcd keys or directory to watch.  This is where the information to fill in
# the template will come from.
keys = [ "/services/apache" ]

# File ownership and mode information
owner = "root"
mode = "0644"

# These are the commands that will be used to check whether the rendered config is
# valid and to reload the actual service once the new config is in place
check_cmd = "/usr/sbin/nginx -t"
reload_cmd = "/usr/sbin/service nginx reload"
上面的文件有一些注释解释一些基本的想法,但我们可以去看下面的选项:
指示 需要? 类型 描述
src 将用于呈现信息的模板的名称。如果这是位于之外/etc/confd/templates ,则应该使用完整路径。
dest 应放置所呈现的配置文件的文件位置。
字符串数组 etcd该模板需要钥匙正确呈现。如果模板设置为处理子键,这可以是目录。
所有者 没有 将被赋予所呈现的配置文件所有权的用户名。
没有 将给予呈现的配置文件的组所有权的组。
模式 没有 应为已渲染的文件设置的八进制权限模式。
check_cmd 没有 应用于检查呈现的配置文件的语法的命令。
reload_cmd 没有 应用于重新加载应用程序配置的命令。
字首 没有 中的一部分etcd在按键之前出现层次keys指令。 这可以用来使.toml文件更灵活。
我们创建的文件告诉我们如何我们一些重要的事情 confd实例都将发挥作用。 我们的Nginx容器将使用存储在模板 /etc/confd/templates/nginx.conf.tmpl来呈现将被放置在一个配置文件 /etc/nginx/sites-enabled/app.conf 。 该文件将被赋予的权限设置 0644和所有权将给予root用户。 该 confd应用程序将在更改 /services/apache节点。 当的变化被看出, confd将查询该节点下的新的信息。然后它将为Nginx渲染一个新的配置。它将检查配置文件的语法错误,并在文件就位后重新加载Nginx服务。 我们现在已经创建了我们的模板资源文件。我们应该在实际的模板文件,将用于渲染我们的Nginx配置文件。

创建Confd模板文件

对于我们的模板文件中,我们将使用来自一个例子 confd项目的 GitHub的文件让我们开始。 创建我们在上面的配置文件中引用的文件。把这个文件在我们的 templates目录:
vi /etc/confd/templates/nginx.tmpl
在这个文件中,我们基本上只是重新创建一个标准的Nginx反向代理配置文件。不过,我们会使用一些 Go 模板语法来代替一些该信息 confd从拉 etcd 。 首先,我们使用“上游”服务器配置块。此部分用于定义Nginx可以向其发送请求的服务器池。格式一般如下:
upstream pool_name {
    server server_1_IP:port_num;
    server server_2_IP:port_num;
    server server_3_IP:port_num;
}
这使我们可以通过请求到 pool_name和Nginx的将选择定义的服务器之一到手的请求。 我们后面的模板文件的想法是解析 etcd我们的Apache Web服务器的IP地址和端口号。 因此,不是静态定义我们的上游服务器,我们应该在文件呈现时动态填充此信息。 我们可以通过这样做 Go 模板的动态内容。 为此,我们将使用它作为我们的块:
upstream apache_pool {
{{ range getvs "/services/apache/*" }}
    server {{ . }};
{{ end }}
}
让我们解释一下发生了什么。我们已经开了一个块定义一个名为服务器的上游池 apache_pool 。在里面,我们指定我们使用双括号开始一些Go语言代码。 这些括号内,我们指定 etcd终点在哪里,我们感兴趣的是保存的值。 我们使用的 range ,以使列表可迭代。 我们用它来传递所有从下面的检索项 /services/apache的位置 etcdrange块。 然后,我们可以使用表示插入值的“{{”和“}}”中的单个点在当前迭代中获取键的值。 我们在范围循环中使用它来填充服务器池。 最后,我们结束与循环 {{ end }}指令。 注意 :请记住后添加分号 server内环路指令。忘记这将导致非工作配置。 设置服务器池后,我们可以使用代理传递来指向所有连接到该池。这只是一个标准的服务器块作为反向代理。有一件事要注意的是 access_log ,它采用,我们将暂时创建一个自定义格式:
upstream apache_pool {
{{ range getvs "/services/apache/*" }}
    server {{ . }};
{{ end }}
}

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    access_log /var/log/nginx/access.log upstreamlog;

    location / {
        proxy_pass http://apache_pool;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
这将应用到所有连接响应端口80上并传递给服务器在泳池 apache_pool是通过观察所生成的 etcd条目。 当我们处理这个服务的这个方面,我们应该删除默认的Nginx配置文件,以便我们以后不会遇到冲突。我们将删除启用默认配置的符号链接:
rm /etc/nginx/sites-enabled/default
现在也是一个好时机来配置我们在模板文件中引用的日志格式。这必须在 http的配置,这是可以在主配置文件中的块。立即打开:
vi /etc/nginx/nginx.conf
我们将添加一个 log_format指令来定义我们要记录的信息。它将记录正在访问的客户端以及请求传递到的后端服务器。我们将记录这些程序需要的时间量的一些数据:
. . .
http {
    ##
    # Basic Settings
    ##
    log_format upstreamlog '[$time_local] $remote_addr passed to: $upstream_addr: $request Upstream Response Time: $upstream_response_time Request time: $request_time';

    sendfile on;
    . . .
保存并在完成后关闭文件。

创建脚本以运行Confd

我们需要创建一个脚本文件,将调用 confd与我们的模板资源文件,我们在适当的时候模板文件。 脚本必须做两件事情,我们的服务才能正常工作:
  • 它必须在容器启动时运行,以根据后端基础架构的当前状态设置初始Nginx设置。
  • 它必须继续观察改变etcd注册为Apache服务器,以便它可以基于现有的后端服务器上重新配置Nginx的。
我们将得到我们的脚本 马塞尔·德格拉夫的GitHub的页面 。 这是一个不错的,简单的脚本,不 正是我们需要的。我们只会对我们的场景做一些小的编辑。 让我们把这个剧本与我们的 confd可执行文件。 我们称这个 confd-watch
vi /usr/local/bin/confd-watch
我们将开始与传统 bash头,以确定我们所需要的解释。 然后,我们会设置一些 bash ,这样脚本如果有什么不顺心立即失败选项。它将返回最后一个命令的值失败或运行。
#!/bin/bash

set -eo pipefail
接下来,我们要设置一些变量。通过使用 bash参数替代,我们将设置默认值,但建立一定的灵活性,让调用脚本的时候我们覆盖硬编码值。这基本上只是独立地设置连接地址的每个组件,然后将它们组合在一起以获得所需的完整地址。 参数替换用此语法创建的: ${ var_name :- default_value } 这与使用的价值的财产 var_name如果给出不为空,否则默认为 default_value 。 我们默认为这些值 etcd默认的期望。这将允许我们的脚本运行良好,没有额外的信息,但我们可以在调用脚本时根据需要进行自定义:
#!/bin/bash

set -eo pipefail

export ETCD_PORT=${ETCD_PORT:-4001}
export HOST_IP=${HOST_IP:-172.17.42.1}
export ETCD=$HOST_IP:$ETCD_PORT
现在我们将使用 confd通过读取值呈现Nginx的配置文件的最初版本 etcd时可用此脚本调用。 我们将使用 until循环,不断尝试建立初始配置。 万一循环结构可能有必要 etcd不可马上或在Nginx的容器在后端服务器之前联机的事件。 这使得它能够轮询 etcd反复,直到它最终可以产生一个有效的初始配置。 实际 confd我们曾经调用执行,并随后命令退出。 这是我们可以等待5秒,直到下一次运行给我们的后端服务器一个机会注册。 我们连接到全 ETCD我们使用默认内置或参数传递变量,我们使用模板资源文件来定义什么,我们想要做的行为:
#!/bin/bash

set -eo pipefail

export ETCD_PORT=${ETCD_PORT:-4001}
export HOST_IP=${HOST_IP:-172.17.42.1}
export ETCD=$HOST_IP:$ETCD_PORT

echo "[nginx] booting container. ETCD: $ETCD"

# Try to make initial configuration every 5 seconds until successful
until confd -onetime -node $ETCD -config-file /etc/confd/conf.d/nginx.toml; do
    echo "[nginx] waiting for confd to create initial nginx configuration"
    sleep 5
done
在初始配置设置之后,我们脚本的下一个任务应该是建立一个持续轮询的机制。我们想确保检测到任何未来的更改,以便Nginx将被更新。 要做到这一点,我们可以调用 confd一次。 这一次,我们要设置一个连续的轮询间隔,并将进程放在后台,使其无限期运行。 我们将通过在同一个 etcd连接信息和相同的模板资源文件,因为我们的目标仍然是相同的。 把后 confd加工成的背景下,我们可以使用被做了配置文件安全启动Nginx的。因为这个脚本将被称为我们的Docker“run”命令,所以我们需要保持它在前台运行,这样容器在这一点上不会退出。我们可以通过拖尾日志,让我们访问我们记录的所有信息:
#!/bin/bash

set -eo pipefail

export ETCD_PORT=${ETCD_PORT:-4001}
export HOST_IP=${HOST_IP:-172.17.42.1}
export ETCD=$HOST_IP:$ETCD_PORT

echo "[nginx] booting container. ETCD: $ETCD."

# Try to make initial configuration every 5 seconds until successful
until confd -onetime -node $ETCD -config-file /etc/confd/conf.d/nginx.toml; do
    echo "[nginx] waiting for confd to create initial nginx configuration."
    sleep 5
done

# Put a continual polling `confd` process into the background to watch
# for changes every 10 seconds
confd -interval 10 -node $ETCD -config-file /etc/confd/conf.d/nginx.toml &
echo "[nginx] confd is now monitoring etcd for changes..."

# Start the Nginx service using the generated config
echo "[nginx] starting nginx service..."
service nginx start

# Follow the logs to allow the script to continue running
tail -f /var/log/nginx/*.log
完成此操作后,保存并关闭文件。 我们需要做的最后一件事是使脚本可执行:
chmod +x /usr/local/bin/confd-watch
现在退出容器以返回到主机系统:
exit

提交并推送容器

现在,我们可以提交容器并将其推送到Docker Hub,以便它可用于我们的机器下拉。 查找容器ID:
docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
de4f30617499        ubuntu:14.04        "/bin/bash"         22 hours ago        Exited (0) About a minute ago                       stupefied_albattani
突出显示的字符串是我们需要的容器ID。使用此ID提交容器以及您的Docker Hub用户名和您要用于此映像的名称。我们将在本指南中使用名称“nginx_lb”:
docker commit de4f30617499 user_name/nginx_lb
如有必要,请登录到Docker Hub帐户:
docker login
现在,您应该推送已提交的图片,以便其他主机可以根据需要将其拉下来:
docker push user_name/nginx_lb

构建Nginx静态单元文件

下一步是创建一个单元文件,启动我们刚刚创建的容器。这将让我们用 fleet来控制进程。 因为这不会是一个模板,我们将放入 ~/static ,我们在这个目录的开头创建的目录:
vim static/nginx_lb.service
我们将开始与标准的 [Unit]部分来描述服务,并定义的依赖关系和顺序:
[Unit]
Description=Nginx load balancer for web server backends

# Requirements
Requires=etcd.service
Requires=docker.service

# Dependency ordering
After=etcd.service
After=docker.service
接下来,我们需要定义 [Service]文件的部分。我们将超时设置为零,并将killmode重新调整为none,就像我们对Apache服务文件所做的那样。我们将再次拉入环境文件,以便我们可以访问此容器正在运行的主机的公有和私有IP地址。 然后我们将清理我们的环境,以确保此容器的任何先前版本被杀死和删除。我们下拉我们刚刚创建的容器,以确保我们总是有最新的版本。 最后,我们将启动容器。这包括启动容器,给它我们在删除引用的名字和kill命令,并通过它正在运行的映射端口80的主机的公网IP地址我们称之为 confd-watch ,我们写的脚本运行命令。
[Unit]
Description=Nginx load balancer for web server backends

# Requirements
Requires=etcd.service
Requires=docker.service

# Dependency ordering
After=etcd.service
After=docker.service

[Service]
# Let the process take awhile to start up (for first run Docker containers)
TimeoutStartSec=0

# Change killmode from "control-group" to "none" to let Docker remove
# work correctly.
KillMode=none

# Get CoreOS environmental variables
EnvironmentFile=/etc/environment

# Pre-start and Start
## Directives with "=-" are allowed to fail without consequence
ExecStartPre=-/usr/bin/docker kill nginx_lb
ExecStartPre=-/usr/bin/docker rm nginx_lb
ExecStartPre=/usr/bin/docker pull user_name/nginx_lb
ExecStart=/usr/bin/docker run --name nginx_lb -p ${COREOS_PUBLIC_IPV4}:80:80 \
user_name/nginx_lb /usr/local/bin/confd-watch
现在,所有我们需要理清的是停止命令和 fleet调度方向。我们希望此容器仅在未运行其他负载平衡实例或后端Apache服务器的主机上启动。这将允许我们的服务有效地传播负载:
[Unit]
Description=Nginx load balancer for web server backends

# Requirements
Requires=etcd.service
Requires=docker.service

# Dependency ordering
After=etcd.service
After=docker.service

[Service]
# Let the process take awhile to start up (for first run Docker containers)
TimeoutStartSec=0

# Change killmode from "control-group" to "none" to let Docker remove
# work correctly.
KillMode=none

# Get CoreOS environmental variables
EnvironmentFile=/etc/environment

# Pre-start and Start
## Directives with "=-" are allowed to fail without consequence
ExecStartPre=-/usr/bin/docker kill nginx_lb
ExecStartPre=-/usr/bin/docker rm nginx_lb
ExecStartPre=/usr/bin/docker pull user_name/nginx_lb
ExecStart=/usr/bin/docker run --name nginx_lb -p ${COREOS_PUBLIC_IPV4}:80:80 \
user_name/nginx_lb /usr/local/bin/confd-watch

# Stop
ExecStop=/usr/bin/docker stop nginx_lb

[X-Fleet]
Conflicts=nginx.service
Conflicts=apache@*.service
保存并在完成后关闭文件。

运行Nginx负载均衡器

您应该已经有两个Apache实例从本教程的早期运行。您可以通过键入:
fleetctl list-units
UNIT                MACHINE             ACTIVE  SUB
apache-discovery@7777.service   197a1662.../10.132.249.206  active  running
apache-discovery@8888.service   04856ec4.../10.132.249.212  active  running
apache@7777.service     197a1662.../10.132.249.206  active  running
apache@8888.service     04856ec4.../10.132.249.212  active  running
您也可以仔细检查,他们正在用正确注册自己 etcd通过键入:
etcdctl ls --recursive /services/apache
/services/apache/10.132.249.206
/services/apache/10.132.249.212
我们现在可以尝试启动我们的Nginx服务:
fleetctl start ~/static/nginx_lb.service
Unit nginx_lb.service launched on 96ec72cf.../10.132.248.177
根据图像下拉的时间长短,服务可能需要一分钟左右才能启动。它启动后,如果您检查与日志 fleetctl journal命令,你应该能够看到一些日志信息 confd 。它应该看起来像这样:
fleetctl journal nginx_lb.service
-- Logs begin at Mon 2014-09-15 14:54:05 UTC, end at Tue 2014-09-16 17:13:58 UTC. --
Sep 16 17:13:48 lala1 docker[15379]: 2014-09-16T17:13:48Z d7974a70e976 confd[14]: INFO Target config /etc/nginx/sites-enabled/app.conf out of sync
Sep 16 17:13:48 lala1 docker[15379]: 2014-09-16T17:13:48Z d7974a70e976 confd[14]: INFO Target config /etc/nginx/sites-enabled/app.conf has been updated
Sep 16 17:13:48 lala1 docker[15379]: [nginx] confd is monitoring etcd for changes...
Sep 16 17:13:48 lala1 docker[15379]: [nginx] starting nginx service...
Sep 16 17:13:48 lala1 docker[15379]: 2014-09-16T17:13:48Z d7974a70e976 confd[33]: INFO Target config /etc/nginx/sites-enabled/app.conf in sync
Sep 16 17:13:48 lala1 docker[15379]: ==> /var/log/nginx/access.log <==
Sep 16 17:13:48 lala1 docker[15379]: ==> /var/log/nginx/error.log <==
Sep 16 17:13:58 lala1 docker[15379]: 2014-09-16T17:13:58Z d7974a70e976 confd[33]: INFO /etc/nginx/sites-enabled/app.conf has md5sum a8517bfe0348e9215aa694f0b4b36c9b should be 33f42e3b7cc418f504237bea36c8a03e
Sep 16 17:13:58 lala1 docker[15379]: 2014-09-16T17:13:58Z d7974a70e976 confd[33]: INFO Target config /etc/nginx/sites-enabled/app.conf out of sync
Sep 16 17:13:58 lala1 docker[15379]: 2014-09-16T17:13:58Z d7974a70e976 confd[33]: INFO Target config /etc/nginx/sites-enabled/app.conf has been updated
正如你所看到的, confd看着 etcd其初始配置。 然后,它开始 nginx 。 之后,我们可以看到在线条 etcd条目已经重新评估和新的配置文件进行。 如果新生成的文件不匹配 md5sum代替文件,该文件被切换出,服务被重新装载。 这允许我们的负载均衡服务最终跟踪我们的Apache后端服务器。如果 confd似乎不断更新,这可能是因为你的Apache实例往往令人耳目一新的TTL。您可以增加sidekick模板中的睡眠和TTL值,以避免这种情况。 在行动中看到负载平衡器,可以索要 /etc/environments从运行Nginx的服务的主机文件。 它包含主机的公共IP地址。 如果你想使这个配置比较好,考虑运行与登记信息一搭档服务 etcd ,就像我们为Apache的实例:
fleetctl ssh nginx_lb cat /etc/environment
COREOS_PRIVATE_IPV4=10.132.248.177
COREOS_PUBLIC_IPV4=104.131.16.222
现在,如果我们在浏览器中访问公共IPv4地址,我们应该看到我们在Apache实例中配置的页面: Apache索引页 现在,如果你在你的日志再看看,你应该能够看到信息,表示其后端服务器实际上是通过了要求:
fleetctl journal nginx_lb
. . .
Sep 16 18:04:38 lala1 docker[18079]: 2014-09-16T18:04:38Z 51c74658196c confd[28]: INFO Target config /etc/nginx/sites-enabled/app.conf in sync
Sep 16 18:04:48 lala1 docker[18079]: 2014-09-16T18:04:48Z 51c74658196c confd[28]: INFO Target config /etc/nginx/sites-enabled/app.conf in sync
Sep 16 18:04:48 lala1 docker[18079]: [16/Sep/2014:18:04:48 +0000] 108.29.37.206 passed to: 10.132.249.212:8888: GET / HTTP/1.1 Upstream Response Time: 0.003 Request time: 0.003

结论

正如你所看到的,也可以设置您的服务来检查 etcd配置的详细信息。 像工具 confd可以使这个过程变得相对通过允许显著项连续轮询简单。 在本指南中的例子中,我们配置了Nginx的服务来使用 etcd生成其初始配置。我们还在后台设置它以连续检查更改。这与基于模板的动态配置生成相结合,使我们能够始终获得我们的后端服务器的最新图片。
赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏