介绍
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服务模板单元文件
现在,你有一个容器可用,您可以创建一个模板单元文件,以便
fleet
和
systemd
可以正确地管理服务。 在我们开始之前,让我们设置一个目录结构,以便我们可以保持组织:
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
的位置
etcd
到
range
块。 然后,我们可以使用表示插入值的“{{”和“}}”中的单个点在当前迭代中获取键的值。 我们在范围循环中使用它来填充服务器池。 最后,我们结束与循环
{{ 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实例中配置的页面:
现在,如果你在你的日志再看看,你应该能够看到信息,表示其后端服务器实际上是通过了要求:
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
生成其初始配置。我们还在后台设置它以连续检查更改。这与基于模板的动态配置生成相结合,使我们能够始终获得我们的后端服务器的最新图片。