如何利用fleet单元文件为CoreOS集群创建高灵活性服务

开题报告该怎么写 考研即将来临,而一般很多大学都会选择在考研结束之后开始安排选题和开题报考(考研之前一般都不谈,老师也很人性化的,不愿意耽误你的复习) 但无论怎么推迟,我们最终都需要去面对并完成这些任务。 现在我就要教大家该如何写一个完整的开题报告! 准备模板。不同的学校有不同的格式,一般情况你的导师会给你们一个学校的标准格式,这个不用太费心。有了模板我们就可以按照模板的“线索”一步一步填充完成即可! 一般大致格式可谓: 研究背景/论文的目的、背景和意义 我们需要写明选择该题目的... 阅读详情

提供:ZStack云计算

系列教程

本教程为CoreOS上手指南系列九篇中的第六篇。

内容简介

CoreOS能够利用一系列工具以集群化与Docker容器化方式简化服务管理工作。其中etcd负责将各独立节点联系起来并提供全局数据平台,而大部分实际服务管理任务则由fleet守护进程实现。

在上一篇教程中,我们了解了如何利用fleetctl命令操纵服务及集群成员。在今天的教程中,我们将了解如何利用单元文件定义服务。

在接下来的内容中,我们将探讨如何构建fleet单元文件,外加在生产环境下提升服务健壮性的可行方法。

先决条件

要完成本篇教程,大家首先需要拥有一套可用CoreOS集群。

在之前的系列教程如何利用DigitalOcean创建一套CoreOS集群当中,我们已经完成了集群创建工作。

此集群配置包含三个节点。它们能够利用专有网络接口实现彼此通信。这三台节点亦拥有公共接口以运行公共服务。各节点名称分别为:

  • coreos-1
  • coreos-2
  • coreos-3

虽然本教程中的大部分内容在于介绍单元文件的创建,但上述设备也将在后文说明特定指令的调度作用时被用到。

这里还建议大家参阅如何使用fleetctl一文。只有具备了fleetctl的相关知识,大家才能提交并在集群当中使用这些单元文件。

满足上述要求后,我们这就开始今天的学习之旅。

单元文件的区段与类型

由于fleet服务管理机制在很大程度上依靠本地系统的systemd init系统,因此systemd单元文件自然被用于定义各项服务。

除了服务类型之外,还有其它多种单元类型定义,且通常被作为systemd单元文件中的一个子集。每种类型都会通过一段文件后缀进行类型定义,例如example.service:

  • service: 这是最常见的单元文件类型。其用于定义能够运行在集群中某台设备上的服务或者应用程序。
  • socket: 定义关于嵌套或者嵌套类文件。其中包括网络嵌套、IPC嵌套以及FIFO缓冲。当流量指向该文件时,它们负责调用服务以实现启动。
  • device: 定义与udev设备树中可用设备相关的信息。Systemd会根据需求在各设备上根据udev规则创建device单元。其常被用于进行问题排序,从而在实际启动之前确保设备切实可用。
  • mount: 定义与设备安装点相关的信息。其名称位于所引用安装点之后,且以破折号替代斜杠。
  • automount: 定义挂载点。其与mount单元采用同样的命名方式,且必须配合相关的mount单元。其用于描述按需与并发安装。
  • timer: 定义一个与其它单元关联的计时器。当此文件中设定的时间点被触发时,该相关单元即开始启动。
  • path: 定义一条路径,其可被监控以进行基于路径的激活操作。我们可以利用它在特定路径发生变更时启动其它单元。

尽管大家可以随意选择上述选项,但service单元仍是最为常用的条目。在本教程中,我们将单纯探讨service单元的配置。

单元文件为简单的文本文件,且结尾为“.”加上以上后缀之一。文件内容由多处区段组成。在fleet当中,大部分单元文件将采用以下基本格式:

[Unit]generic_unit_directive_1generic_unit_directive_2[Service]service_specific_directive_1service_specific_directive_2service_specific_directive_3[X-Fleet]fleet_specific_directive

区段标题及单元文件中的其它内容皆区分大小写。其中[Unit]用于定义单元的常规信息。以上与各单元类型相关的选项皆可添加在这里。

[Service]区段用于设定指向各服务单元的指令。大多数(但并非全部)单元类型都与unit-type-specific区段信息相关联。大家可以参阅常见systemd单元文件man页面以了解更多与不同单元类型相关的细节。

[X-Fleet]区段用于设定该单元的调度要求以供fleet使用。利用此区段,大家可以要求某特定条件为御前
以在主机上实现单元调度。

构建主服务

在这一区段中,首先对在CoreOS上运行服务中使用过的单元文件进行调整。该文件名为apache.1.service,且内容如下:

[Unit]Description=Apache web server service

# Requirements
Requires=etcd.serviceRequires=docker.serviceRequires=apache-discovery.1.service

# Dependency ordering
After=etcd.serviceAfter=docker.serviceBefore=apache-discovery.1.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 apacheExecStartPre=-/usr/bin/docker rm apacheExecStartPre=/usr/bin/docker pull username/apacheExecStart=/usr/bin/docker run --name apache -p ${COREOS_PUBLIC_IPV4}:80:80 \username/apache /usr/sbin/apache2ctl -D FOREGROUND

# Stop
ExecStop=/usr/bin/docker stop apache[X-Fleet]
# Don't schedule on the same machine as other Apache instances
X-Conflicts=apache.*.service

我们首先从[Unit]区段入手。在这里,我们的基本思路是描述该单元并添加关联性信息。首先设定相关要求。在本示例中,我们将使用部分硬性约束条件。如果我们希望fleet尝试启动额外服务,但又不会因故障而导致流程中断,则可使用Wants指令。

之后,我们需要明确列出要求的先后顺序。这一点非常重要,因为某些要求需要以特定服务正在运行为前提。另外,我们也可以在这里自动利用etcd声明我们将要构建的服务。

在[Service]区段中,我们关闭服务启动超时机制。由于服务首次在主机上运行时,容器需要自Docker注册表中提取信息,而这往往会造成启动超时。其默认时长为90秒,一般来说应该是足够的,但较为复杂的容器可能需要更长的启动时间。

而后将killmode设置为none。这是因为正常的关闭模式(control-group)有时候会导致容器移除命令失效(特别是Docker的–rmoption)。这有可能在下一次重启时带来问题。

我们可以在此环境文件中找到COREOS_PUBLIC_IPV4以及COREOS_PRIVATE_IPV4环境变量(如果创建过程中启用了专有网络机制)。我们可以利用其特定主机信息轻松配置Docker容器。

ExecStartPre各行用于清空此前尚未运行的部分以实现执行环境清理。我们可以在前两行中使用=-以确保出现问题时,systemd会忽略错误并继续执行后续命令。这一点非常重要,因为我们的预启动操作基本上清除了任何先前正在运行的服务。如果找不到已经在运行的服务,则操作自然会失败——但由于其仅仅属于清理流程,因此我们不希望其影响到服务的正常执行。最后的pre-start用于确保容器始终运行最新版本。

这条启动命令会引导Docker容器并将其与主机设备的公共IPv4接口相绑定。其使用此环境文件中的信息并轻松实现接口与端口交换。这一流程采用前台运行方式,这是因为该容器会在运行中进程结束后退出。而stop命令则尝试对容器进行正常关闭。

[X-Fleet]区段包含一条简单状态,用于强制fleet在尚未运行其它Apache服务的主机上调度该服务。这是一种简单的服务高可用性实现方式,即强制要求服务启动在不同设备上。

构建主服务的几项要点

在以上示例中,我们已经进行了一些比较基础的配置。不过还有其它一些需要关注的重点。

下面来看构建主服务中需要注意的几点:

  • 对关联性与排序逻辑进行区分:利用Requires=或者Wants=指令进行关联性排布,具体取决于如果不填写此关联性,该单元是否会失败。排序区分则可使用After=以及Before=行实现,这样我们就能轻松判断要求是否出现变更。将关联性列表与排序区分开来能帮助我们调试关联性问题。
  • 利用独立进程处理服务注册:我们的服务应当利用etcd进行注册以发挥服务发现机制的使用,并借此实现动态配置功能。不过,我们应当使用单独的“sidekick”容器以保持逻辑独立性。这样从外部视角来看,其才能提供更为明确的服务运行状态报告,并供其它组件加以参考。
  • 关注服务超时可能性:考虑调整TimeoutStartSec指令以允许更长的启动时间。将其设置为“0”则会禁用启动超时机制。我们建议这样设定,因为Docker往往需要从注册表中提取镜像(在首次运行或者发现更新时),这可能显著增加服务的初始化时长。
  • 如果服务未能彻底停止,请调整KillMode:如果我们的服务或者容器似乎无法彻底停止,请考虑使用KillMode选项。将其设置为“none”有时候能够解决容器停止后未被移除的问题。特别是在对容器进行命名时,由于Docker会因为存在重名容器而出现错误。查阅KillMode说明文档以获取更多信息。
  • 在启动前清理运行环境:与上一条相关,请确保在每次启动前清除环境中的全部既有Docker容器。这些清理命令行需要使用=-标记以保证不需要清理时仍能执行下一步操作。虽然我们一般都会使用docker stop对容器进行正常停止,但也可以使用docker kill以确保其被彻底清除。
  • 引入并使用特定主机信息以实现服务可移植性:如果大家需要将服务绑定至特定网络接口,请引入/etc/environment文件以访问COREOS_PUBLIC_IPV4以及COREOS_PRIVATE_IPV4。如果我们需要查看当前运行中服务所在设备的主机名称,则可使用%H系统标记。要了解更多可用标记信息,请参阅systemd标记说明文档。在[X-Fleet]区段中,只能使用%n、%N、%i与%p。

构建sidekick声明服务

现在我们已经掌握了如何构建主服务,接下来需要了解传统的“sidekick”服务。这些sidekick服务与主服务相关联,且可通过etcd作为注册服务的外部点。

这个被引用于主单元文件中的文件名为apache-discovery.1.service,内容如下:

[Unit]Description=Apache web server etcd registration

# Requirements
Requires=etcd.serviceRequires=apache.1.service

# Dependency ordering and binding
After=etcd.serviceAfter=apache.1.serviceBindsTo=apache.1.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_PUBLIC_IPV4}:80; \
if [ $? -eq 0 ]; then \
  etcdctl set /services/apache/${COREOS_PUBLIC_IPV4} \'{"host": "%H", "ipv4_addr": ${COREOS_PUBLIC_IPV4}, "port": 80}\' --ttl 30; \
else \
  etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}; \
fi; \
sleep 20; \
done'

# Stop
ExecStop=/usr/bin/etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}[X-Fleet]
# Schedule on the same machine as the associated Apache service
X-ConditionMachineOf=apache.1.service

Sidekick服务的实现方式与主服务基本一致。我们首先描述该单元的作用,而后为其提供关联性信息与排序逻辑。

这里要用到的新命令为BindsTo=。此命令会使该单元逐步执行启动、停止以及重启操作。基本上,这意味着我们能够在两个单元被载入至fleet当中后,通过操纵主单元同时管理这两个单元。这是一种单向机制,所以对sidekick单元进行控制不会影响到主单元。

在[Service]区段中,我们再次查找/etc/environment文件中的变量。此时ExecStart=指令基本上属于一条简短的bash脚本。它会尝试利用已经声明的接口与端口接入主服务。

如果连接成功,那么etcdctl命令会在etcd内的/services/apache中利用主机设备的公共IP地址设定一个键。该键的值为JSON对象,其中包含与该服务相关的信息。此键的过期时长为30秒,因此如果该单元意外停止,则对应服务信息亦不会驻留在etcd中。如果连接失败,那么该键会被立即移除——这是因为该服务无法被验证为可用。

此循环中包含一条20秒的sleep命令。这意味着每20秒(早于etcd的30秒键超时设定),此单元就会重新检查其主单元是否可用并重置该键。这基本上相当于对键上的TTL进行刷新,使其在接下来30秒中继续生效。

在这种情况下,stop命令只用于手动移除该键。意味着该服务注册将在主单元的stop命令由于BindsTo=指令而被镜像至此单元时被移除。

在[X-Fleet]区段中,我们需要确保此单元与主单元启动在同一台服务器上。尽管这套方案不允许该单元向远程设备报告服务可用性,但在本示例中,最重要的是确保BindsTo=指令正常起效。

构建sidekick服务的几项要点

在构建sidekick单元时,我们应当认真考虑以下几项要求:

  • 检查主单元的实际可用性:检查主单元运行状态非常重要。不要仅靠sidekick能够正常初始化就认为主单元可用。虽然实际可用性取决于主单元的设计与功能,但检查机制越强大,注册状态的可靠性就越高。这样的检查工作应该拥有广泛的涵盖面,从检查/health端点到尝试利用客户端接入数据库。
  • 定期对注册逻辑进行重新检查:检查服务可用性当然很重要,但定期进行复查同样重要。我们可以借此发现意料之外的服务故障,特别是在容器中的某些结果仍在继续运行时。在不同周期间进行暂停,并借此对主单元上的其它负载进行快速审查。
  • 使用TTL标记通过etcd对故障进行自动注销:sidekick单元中的意外故障可能导致etcd内信息与实际信息间发生冲突。为了避免这种冲突,我们应当允许键超时。利用以上循环间隔机制,我们可以在各键超时前对其进行刷新,从而确保其永远不会在sidekick正常运行时过期。这种休眠间隔应被设定为略短于超时间隔,从而确保功能正常起效。
  • 利用etcd注册可用信息,而非单纯确认:在对sidekick进行首次迭代时,我们往往只关注单元启动时是否确切注册至etcd。然而其中也包含有大量可资其它服务利用的信息。虽然我们目前并不需要这些信息,但其可能会在构建其它组件时发挥作用。Etcd服务属于一项全局性键-值存储机制,因此别忘记利用它提供键信息。以JSON对象方式存储细节是传递多条信息的好办法。

掌握了以上几条要点,我们就能构建强大的注册单元,同时确保etcd拥有正常的信息可以使用。

与fleet相关的思考

虽然fleet单元文件与其它常见systemd单元文件并没有太大区别,但其中仍存在着一些值得关注的特性与陷阱。

其中最大的区别就是[X-Fleet]的存在,其可用于指引fleet制定调度决策。具体可用选项包括:

  • X-ConditionMachineID: 其可用于指定某台设备以进行单元加载。其提供的值为完整的设备ID。此值可由集群内单一成员通过检查/etc/machine-id文件进行检索,或者通过fleetctl的list-machines -l命令查看。其必须使用完整的ID字符串。如果大家是在特定设备上运行一套数据库及其数据目录,那么这一要求就非常必要了。当然,在非必要情况下不推荐大家使用它,因为其会严重影响到单元的灵活性。
  • X-ConditionMachineOf: 用于将当前单元调度至加载有其它特定单元的设备之上。其可用于调度sidekick单元或者将多个单元联系在一起。
  • X-Conflicts: 与上一条相反,其限定当前单元文件不可被调度至特定设备上。我们可以利用它轻松实现高可用性配置,即在不同设备上运行同一服务的多个版本。
  • X-ConditionMachineMetadata:用于根据当前可用设备的元数据指定调度要求。在fleetctl list-machines输出结果中的“METADATA”列当中,大家可以看到每台主机所设定的元数据。要设置元数据,可在服务器实例初始化时将其添加至cloud-config文件中。
  • Global: 这是一条特殊的指令,会利用一条boolean参数标记目标单元是否应被调度至集群内的全部设备上。我们应当仅使用此指令处理元数据状态。

这些额外指令允许管理员更加灵活且有效地定义服务在可用设备上的运行方式。我们需要对其进行预先评估,而后方可在fleetctl加载阶段中将其传递至特定设备的systemd实例中。

这就带来了fleet中需要注意的另一项要点。事实上,fleetctl工具并不会对单元文件内[X-Fleet]区段之外的关联性要求进行评估。这意味着fleet中的各单元可能在协作时引发某些有趣的问题。

具体来讲,当fleetctl工具采取必要步骤以将目标单元操作至所需状态时,其不会考虑到该单元的关联性需求。

因此,如果我们分别提交了主与sidekick单元,但尚未在fleet中完成加载,那么输入fleetctl start main.service将加载并尝试启动main.serivce单元。然而,由于sidekick.service单元尚未被加载,而fleetctl又不会在加载与启动过程中评估关联性,因此main.service单元会发生错误。这是因为一旦设备上的systemd实例开始处理main.service单元,将无法在关联性评估阶段找到sidekick.service。

为了避免这种情况,我们可以同时手动启动这些服务,而非领先BindsTo=指令将sidekick引入运行状态:

fleetctl start main.service sidekick.service

另一种方式则是确保sidekick单元一定会在主单元运行时进行加载。其载入过程由设备选择,而该单元文件则被提交至本地systemd实例当中。这样能够确保关联性得到满意,而BindsTo=指令也能够正常执行以启动该辅助单元:

fleetctl load main.service sidekick.service
fleetctl start main.service

因此当fleetctl命令报错时,大家可以从以上几个角度进行排查。

实例与模板

在使用fleet时,其最为强大的概念之一就是单元模板。单元模板依赖于systemd下一种名为“实例”的特性。它们属于实例化的单元,通过处理模板单元文件被创建在运行时当中。模板文件在很大程度上类似于常规单元文件,只是其中存在几处小小的修改。如果得到正确利用,其将发挥巨大作用。

模板文件可通过在文件名中使用@来标记。大多数常规服务的文件名格式为unit.service,而模板文件的名称格式则为unit@.service。

当某单元利用模板进行实例化时,其实例标记符将位于@与.service后缀之间。此标记符可由管理员任意指定:

unit@instance_id.service

此基础单元名称可通过%p标记符在单元文件之内进行访问。同样的,给定实例标记符则可通过%i进行访问。

主单元文件即模板

这意味着我们无需像之前那样一步步创建apache.1.service主单元文件,而可以直接创建一套名为apache@.service的模板:

[Unit]Description=Apache web server service on port %i

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

# Dependency ordering
After=etcd.serviceAfter=docker.serviceBefore=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.%iExecStartPre=-/usr/bin/docker rm apache.%iExecStartPre=/usr/bin/docker pull username/apacheExecStart=/usr/bin/docker run --name apache.%i -p ${COREOS_PUBLIC_IPV4}:%i:80 \username/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
X-Conflicts=apache@*.service

如大家所见,我们将apache-discovery.1.service关联性修改为apache-discovery@%i.service。这意味着如果我们拥有此单元文件的一个名为apache@8888.service的实例,那么其将需要一个名为apache-discovery@8888.service的sidekick单元。其中的%i已经被替换为实例标记符。在这种情况下,我们使用该标记符代表与当前所运行服务相关的动态信息,特别是Apache服务器的可用端口编号。

为了实现这一目标,我们可以变更docker的运行参数,从而将该容器的端口声明至主机上的某个端口。在该静态单元文件中,我们使用的参数为 COREOSPUBLICIPV4:80:80,其负责将该容器的端口80映射至主机端口80的公共IPv4接口。在此模板文件中,我们可以将其替换成 {COREOS_PUBLIC_IPV4}:%i:80,因为我们会利用实例标记符来告知所使用的具体端口。总而言之,使用实例标记符能够在模板文件中实现更理想的灵活性。

Docker名称本身也进行了修改,这样它也会使用基于实例ID的惟一容器名称。请注意,Docker容器无法使用@标记,因此我们必须在单元文件中选择其它名称。为此,我们修改了全部在Docker容器上运行的指令。

在[X-Fleet]区段中,我们还修改了调度信息以识别这些实例化单元,而非我们之前使用的静态单元。

Sidekick单元即模板

我们也可以利用同样的方法将sidekick单元转化为模板。

我们的新sidekick单元将被命名为apache-discovery@.service,如下所示:

[Unit]Description=Apache web server on port %i etcd registration

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

# Dependency ordering and binding
After=etcd.serviceAfter=apache@%i.serviceBindsTo=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_PUBLIC_IPV4}:%i; \
if [ $? -eq 0 ]; then \
  etcdctl set /services/apache/${COREOS_PUBLIC_IPV4} \'{"host": "%H", "ipv4_addr": ${COREOS_PUBLIC_IPV4}, "port": %i}\' --ttl 30; \
else \
  etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}; \
fi; \
sleep 20; \
done'

# Stop
ExecStop=/usr/bin/etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}[X-Fleet]
# Schedule on the same machine as the associated Apache service
X-ConditionMachineOf=apache@%i.service

我们也用同样的方式对sidekick单元中的内容进行了调整,从而构建这套实例化版本并保证其与正确的实例化主单元相匹配。

在curl命令中,当我们检查服务的实际可用性时,我们会利用实例ID替换静态端口80,从而保证其接入正确的位置。这一点非常重要,因为我们已经在Docker命令中对主单元的端口声明映射做出了变更。

我们还修改了“port”部分以登录至etcd,旨在保证其使用同样的实例ID。变更之后,被设定在etcd中的JSON数据将完全动态。其会提取主机名称、IP地址以及服务运行所在的端口。

最后,我们再次变更[X-Fleet]区段。我们需要确保此流程与主单元实例运行在同一台设备上。

利用模板进行单元实例化

要利用模板文件进行单元实例化,我们拥有几种不同选项。

其中fleet与systemd都能够处理符号链接,这意味着我们可以创建包含完整实例ID且指向模板文件的链接,具体如下:

ln -s apache@.service apache@8888.service
ln -s apache-discovery@.service apache-discovery@8888.service

这将创建两条链接,分别名为apache@8888.service与apache-discovery@8888.service。二者皆拥有fleet与systemd运行单元所必需的信息。不过,它们会指向回对应模板,因此我们需要再做点调整。

在此之后,我们可以利用以下fleetctl命令实现服务的提交、加载或者启动:

fleetctl start apache@8888.service apache-discovery@8888.service

如果我们不希望利用符号链接定义自己的实例,则可使用另一种fleetctl内的模板提交方式:

fleetctl submit apache@.service apache-discovery@.service

只需要将实例标记符分配给运行时,我们就能在fleetctl中以模板为基础实现单元实例化。例如,大家可以使用以下命令:

fleetctl start apache@8888.service apache-discovery@8888.service

这就消除了对符号链接的需求。部分管理员倾向于使用链接机制,因为这能保证实例文件随时可用。其同时允许我们将目录传递至fleetctl,从而一次性启动全部组件。

例如,在我们的工作目录中,大家可以为模板文件建立一个名为templates的子目录,并为实例化链接版本建立名为instances的子目录。大家甚至可以为非模板单元建立static子目录。具体命令如下:

mkdir templates instances static

而后将静态文件移动到static子目录下,而模板文件则移动对templates子目录下:

mv apache.1.service apache-discovery.1.service static
mv apache@.service apache-discovery@.service templates

在这里,大家可以创建自己需要的实例链接了。假设我们的服务运行在端口5555、6666与7777上:

cd instances
ln -s ../templates/apache@.service apache@5555.service
ln -s ../templates/apache@.service apache@6666.service
ln -s ../templates/apache@.service apache@7777.service
ln -s ../templates/apache-discovery@.service apache-discovery@5555.service
ln -s ../templates/apache-discovery@.service apache-discovery@6666.service
ln -s ../templates/apache-discovery@.service apache-discovery@7777.service

而后利用以下命令即可一次性启动全部实例:

cd ..
fleetctl start instances/*

非常简单,也非常快捷。

总结

到这里,大家应该已经掌握了fleet单元文件的构建方法了。利用单元文件带来的动态特性,我们能够确保自己的服务始终得到均匀分布、拥有正确的关联性并利用etcd注册使用信息。

在下一篇文章中,我们将探讨如何配置自己的容器,从而使用通过etcd注册的信息。如此一来,我们就能够建立对实际部署环境的认识,并将请求传递至后端中的合适容器当中。

本文来源自DigitalOcean Community。英文原文:How to Create Flexible Services for a CoreOS Cluster with Fleet Unit Files By Justin Ellingwood

翻译:diradw

《基于Yolo算法的火灾检测系统设计与实现》开题报告 在消防安全领域,火灾对生命财产安全构成严重威胁。传统的火灾检测手段存在诸多不足,如误报率高、检测范围有限、响应速度慢等。基于 Yolo 算法的火灾检测系统能够利用深度学习技术,实现对火灾的高效、精准检测,具有重要的现实意义。         从社会安全角度看,该系统可以广泛应用于各类公共场所、工业厂房和居民住宅,实时监测火灾隐患,及时发出警报,为人员疏散和消防救援争取宝贵时间,有效降低火灾造成的人员伤亡和财产损失,保障社会公共安全。 阅读详情

相关推荐

Dynamics 365从入门到精通:一站式掌握微软智能商业应用平台

很多新手学Dynamics 365时,容易陷入“死记功能”的误区,其实这款平台的核心价值不是“功能多全”,而是“能适配企业业务流程,通过生态集成提升效率”。先从具体业务场景入手,理解每个功能的实际价值;再通过生态集成拓展系统能力;最后通过开发实现定制化,满足企业的特殊需求。按照这个思路,新手不用害怕复杂,一步步落地实战,3个月就能从“入门”到“能独立负责项目”。如果在学习过程中遇到具体问题(比如部署报错、数据迁移失败),欢迎在评论区留言,我会结合实战经验帮你解答!

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1045

Systemd使用总结

systemd是一系列工具的集合,提供了一个系统和服务管理器,运行为 PID 1 并负责启动其它程序。其作用也远远不仅是启动操作系统,它还接管了后台服务、结束、状态查询、以及日志归档、设备管理、电源管理、定时任务等许多职责,并支持通过特定事件和特定端口触发的on-demand任务。unit表示不同类型的systemd对象,通过配置文件进行标识和配置;文件中主要包含了系统服务、监听socket、保存的系统快照以及其它与init相关的信息。

超人的专栏 5031

ubuntu安装XXX包时出现(= 20.0.8-0ubuntu1~18.04.1) but it is not going to be installed

安装mujoco_py时,最后一步尝试 import mujoco_py 时出现报错 esashim.c:1:10: fatal error: GL/osmesa.h: No such file or directory 1 | #include <GL/osmesa.h> | ^~~~~~~~~~~~~ compilation terminated. 在https://github.com/openai/mujoco-py#ubuntu-ins

dealexce的博客 1794

Keepalived 解决使用systemctl 无法关闭

Keepalived 解决使用systemctl 无法关闭 修改keepalived.service 文件 vim /usr/lib/systemd/system/keepalived.service 修改KillMode=control-group KillMode值释义: process kill 主进程 control-group 杀死进程组,不设置时默认值 指定PIDFile=keepalived.pid 的生成路径,需要注意文件存放目录是否有写入权限 $MAINPID 为该文件记

weixin_43740223的博客 2154

【硬件相关】IB网与以太网核心技术解析及高性能网络部署指南

本文深入解析了IB网与以太网的核心技术差异,包括协议栈、流量控制机制及硬件架构,并提供了高性能网络部署的实战指南。通过对比测试和调优案例,展示了IB网在低延迟和高负载下的优势,以及混合组网中的创新应用,助力超算集群和高效网络部署。

weixin_29311017的博客 102

北京联通IPTV组播实战:OpenWRT软路由配置全解析

本文详细解析了在北京联通IPTV环境下,利用OpenWRT软路由和udpxy工具实现组播转单播的实战配置。内容涵盖网络接口设置、防火墙规则、udpxy安装配置、直播源M3U文件处理以及全平台播放指南,帮助用户无需机顶盒即可在家庭局域网内任何设备上流畅观看电视直播。

weixin_29313547的博客 1416

手把手教你编写 Linux 系统的 systemd 服务脚本

是一个系统和服务管理器,也是 Linux 操作系统中最常用的初始化系统之一。它的设计目标是提供更快、更有效、更可靠的系统启动过程,并提供强大的管理和监控服务的能力。本文首先介绍 systemd 服务脚本的基本情况,并通过一个简单的示例带领读者学习如何编写 systemd 服务脚本,实现 Linux 服务的自启动、启动、停止和重启管理。

程序员「阿基米东」的编程之旅 4983

ESP-CSI:使用ESP32进行CSI(信道状态信息)采集

使用esp32进行csi(信道状态信息)采集和处理

capsize的博客 8285

systemd

systemd是Linux下的一种init软件,由Lennart Poettering带头开发,并在LGPL 2.1及其后续版本许可证下开源发布。其开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到降低Shell的系统开销的效果,最终代替现在常用的System V与BSD风格init程序。    传统的System V是串行启动,即在

a624731186的专栏 3886

Docker小白也能搞定!5分钟用calibre-web搭建私人Kindle书库(附静读天下配置)

本文为零基础用户提供了一份详尽的指南,介绍如何利用Docker容器技术,在5分钟内快速部署Calibre-Web服务,从而搭建一个完全私有的个人Kindle书库。教程涵盖了从Docker安装、Calibre-Web一键部署、书籍元数据管理到移动端配置的全流程,并重点讲解了如何与安卓端知名阅读应用“静读天下”联动,实现跨设备无缝访问,打造媲美在线书城的个性化阅读体验。

weixin_29216957的博客 543

基于MATLAB的Hough变换指针式仪表识别

综上所述,本文介绍了如何使用MATLAB中的Hough变换算法来实现指针式仪表的自动识别和读数。通过图像预处理、Hough变换和直线提取,我们可以准确地检测指针的位置,并进一步进行仪表读数。本文将介绍如何使用MATLAB中的Hough变换算法来实现指针式仪表的自动识别和读数。在指针式仪表识别中,我们可以利用Hough变换来检测仪表盘上的指针。以上是基于MATLAB的Hough变换指针式仪表识别的详细步骤和源代码示例。根据指针在仪表盘上的位置,我们可以进行角度计算或使用其他技术来获取准确的读数。

techDM的博客 466

使用systemd管理springboot程序

使用systemd管理springboot程序

liuyij3430448的博客 1760

lvgl 9虚拟键盘控件 (lv_keyboard) 使用指南

是 LittlevGL 提供的一个虚拟键盘控件,适用于在图形界面中输入文本。与按钮矩阵类似,虚拟键盘预定义了多个键位布局,支持多种模式和自定义键位映射,能够满足各种文本输入需求。通过与文本区域 (Text Area) 的结合,键盘能够自动将输入的字符传送到指定区域。控件是 LittlevGL 提供的强大虚拟键盘解决方案,适用于任何需要文本输入的界面。通过预定义的键盘模式、自定义键位映射和文本区域自动填充功能,可以大大提升用户输入体验。无论是在嵌入式系统的用户界面中,还是在其他需要虚拟键盘的应用中,

m0_62599305的博客 2187

coreos_CoreOS简介

coreos 如果您正在阅读此博客,那么您将大致了解什么是容器以及为什么要使用它们。 Docker使容器的实验变得容易,并且正逐渐使其在生产环境中的部署和管理变得更加容易。 但是,Docker提供的(免费)仍然存在很多空白,并且其他人已经加紧弥补了这些空白。 CoreOS就是这样一种选择。 它不仅是容器管理系统,而且是旨在运行容器的整个(基于Linux)操作系统。 CoreOS的组件 ...

danpu0978的博客 548

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

CoreOS简介

如果您正在阅读此博客,那么您将大致了解什么是容器以及为什么要使用它们。 Docker使容器的实验变得容易,并且正逐渐使其在生产环境中的部署和管理变得更加容易。 但是,在Docker提供的产品(免费)上仍然存在很多空白,并且其他人已经加紧弥补了这些空白。 CoreOS就是这样一种选择。 它不仅是容器管理系统,而且是旨在运行容器的整个(基于Linux)操作系统。 CoreOS的组件 Co...

danpu0978的博客 1646

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

探索高效集群管理:Fleet-UI 开源项目推荐

探索高效集群管理:Fleet-UI 开源项目推荐 在现代软件开发中,高效的集群管理是确保系统稳定性和可扩展性的关键。今天,我们将介绍一个强大的开源项目——Fleet-UI,它为CoreOS的fleet工具提供了一个基于Web的用户界面,极大地简化了集群管理的复杂性。 项目介绍 Fleet-UI 是一个基于Web的界面,用于管理CoreOS的fleet集群。通过Fleet-UI,用户可以轻松地查看和...

gitblog_01143的博客 652

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

CoreOS项目

CoreOS项目   CoreOS的设计目的是为你提供想谷歌一样的大型互联网公司一样的基础设施管理能力来动态扩展和管理的计算能力.   CoreOS的安装文件和运行以来非常小,它提供了精简的Linux系统.它使用Linux容器在更高的抽象层来管理你的服务,而不是通过常规的YUM和APT来安装包.   COreOS集合可以运行在任何平台:Vagrant,A

见证大牛成长之路的专栏 4597

Paz vs 传统PaaS:为什么选择这款开源容器编排平台?终极指南

在当今快速发展的云原生时代,容器编排平台已成为现代应用部署的核心基础设施。Paz作为一款开源、自托管的**容器编排平台**,为开发者提供了与传统PaaS完全不同的部署体验。这款基于Docker、CoreOS、Etcd和Fleet构建的**开源PaaS解决方案**,让企业能够拥有自己的私有PaaS环境,同时享受开源带来的灵活性和控制权。 ## 🚀 Paz是什么?重新定义私有PaaS Paz是一

gitblog_07966的博客 844

Coreos操作系统

linux大规模服务器部署---前言1.一个最小的操作系统(A Minimal Operating System)coreos被设计成一个现代的,最小的基础来构建平台,消耗内存比平常系统少40%;了解更多using coreos2.自动更新(Painless Updating)利用active/passive dual-partition 计划更新操作系统,作为single ...

weixin_34177064的博客 189

CoreOS 入门

本文讲的是CoreOS 入门【编者的话】本文是一篇 CoreOS 入门文章。分别介绍了 CoreOS 的三个主要组件——配置和服务发现、应用程序管理和调度以及应用程序,对一些概念进行了解释,并初步介绍了一些 CoreOS 的高阶组件供读者探索。如果你正在阅读这篇博客,那么你大概知道容器是什么以及为何要使用它们。 Docker 通过容器使得实验更加容易,在...

weixin_34344677的博客 244

VGG为什么仍是CNN理解的必经路标

卷积神经网络(CNN)作为计算机视觉的基石,其核心原理在于通过局部感受野与层级抽象实现特征学习。VGG模型以统一的3×3小卷积核堆叠、规整的特征图降维节奏和可解释的深度结构,将CNN的工程逻辑具象化为一套可验证、可复现、可调试的设计范式。它不依赖复杂正则化,却因结构洁癖天然抑制过拟合;不强调参数效率,却为迁移学习、嵌入式部署与教学调试提供了稳定基座。在ResNet、ViT等新架构盛行的今天,VGG所承载的‘小核渐进抽象’‘空间-通道双螺旋演化’‘特征图即调试界面’等思想,持续影响着模型设计、特征可视化与工业

weixin_33766805的博客 410

Linux:Centos自定义systemctl服务启动脚本

目录 Centos自定义systemctl服务启动脚本 一、创建tomcat.service文件 二、测试 知识补充 KILL常见信号解释 为Tomcat配置pid文件路径 systemctl服务详解 Centos自定义systemctl服务启动脚本 一、创建tomcat.service文件 # cd/usr/lib/systemd/system # vim tomcat.service 文件内容: [Unit] Description=Tomcat After=...

樱之魔 1281

linux systemd service 服务文件简介

定义启动类型。可设置的值如下:simple(默认值):ExecStart字段启动的进程为主进程;forking:ExecStart字段以fork()方式启动,父进程退出后,子进程将成为主进程;oneshot:类似于simple,但只执行一次,Systemd 会等它执行完,才启动其他服务;dbus:类似于simple,但会等待 D-Bus 信号后启动;;notify:类似于simple,启动结束后会发出通知信号,然后 Systemd 再启动其他服务;

whatday的专栏 3455

ubuntu设置自启

ubuntu设置自启

weixin_43213237的博客 246

Linux Systemd 停止服务时杀死子进程的机制及 KillMode 参数详解

这种方法既保持了 systemd 的管理能力,又允许工作进程有独立的生命周期。:主进程退出后,子进程变成僵尸或继续运行但systemd认为服务已停止。

学亮编程手记 653

Linux systemd 系统服务管理

是一个系统和服务管理器,也是 Linux 操作系统中最常用的初始化系统之一。它的设计目标是提供更快、更有效、更可靠的系统启动过程,并提供强大的管理和监控服务的能力。本文首先介绍 systemd 服务脚本的基本情况,并通过一个简单的示例带领读者学习如何编写 systemd 服务脚本,实现 Linux 服务的自启动、启动、停止和重启管理。

yiyu20180729的博客 1758
上一篇: 如何使用Etcdctl与Etcd——CoreOS的分布式键-值存储
下一篇: 如何利用Confd与Etcd对CoreOS中的服务进行动态重新配置
普通网友
博客等级 码龄10年 769粉丝 269原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值