国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 操作系統(tǒng) > 正文

如何利用fleet單元文件為CoreOS集群創(chuàng)建高靈活性服務(wù)

2024-06-28 16:02:33
字體:
供稿:網(wǎng)友

提供:ZStack云計算

系列教程

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

內(nèi)容簡介

CoreOS能夠利用一系列工具以集群化與Docker容器化方式簡化服務(wù)管理工作。其中etcd負(fù)責(zé)將各獨立節(jié)點聯(lián)系起來并提供全局?jǐn)?shù)據(jù)平臺,而大部分實際服務(wù)管理任務(wù)則由fleet守護(hù)進(jìn)程實現(xiàn)。

在上一篇教程中,我們了解了如何利用fleetctl命令操縱服務(wù)及集群成員。在今天的教程中,我們將了解如何利用單元文件定義服務(wù)。

在接下來的內(nèi)容中,我們將探討如何構(gòu)建fleet單元文件,外加在生產(chǎn)環(huán)境下提升服務(wù)健壯性的可行方法。

先決條件

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

在之前的系列教程如何利用DigitalOcean創(chuàng)建一套CoreOS集群當(dāng)中,我們已經(jīng)完成了集群創(chuàng)建工作。

此集群配置包含三個節(jié)點。它們能夠利用專有網(wǎng)絡(luò)接口實現(xiàn)彼此通信。這三臺節(jié)點亦擁有公共接口以運行公共服務(wù)。各節(jié)點名稱分別為:

coreos-1coreos-2coreos-3

雖然本教程中的大部分內(nèi)容在于介紹單元文件的創(chuàng)建,但上述設(shè)備也將在后文說明特定指令的調(diào)度作用時被用到。

這里還建議大家參閱如何使用fleetctl一文。只有具備了fleetctl的相關(guān)知識,大家才能提交并在集群當(dāng)中使用這些單元文件。

滿足上述要求后,我們這就開始今天的學(xué)習(xí)之旅。

單元文件的區(qū)段與類型

由于fleet服務(wù)管理機(jī)制在很大程度上依靠本地系統(tǒng)的systemd init系統(tǒng),因此systemd單元文件自然被用于定義各項服務(wù)。

除了服務(wù)類型之外,還有其它多種單元類型定義,且通常被作為systemd單元文件中的一個子集。每種類型都會通過一段文件后綴進(jìn)行類型定義,例如example.service:

service: 這是最常見的單元文件類型。其用于定義能夠運行在集群中某臺設(shè)備上的服務(wù)或者應(yīng)用程序。socket: 定義關(guān)于嵌套或者嵌套類文件。其中包括網(wǎng)絡(luò)嵌套、ipC嵌套以及FIFO緩沖。當(dāng)流量指向該文件時,它們負(fù)責(zé)調(diào)用服務(wù)以實現(xiàn)啟動。device: 定義與udev設(shè)備樹中可用設(shè)備相關(guān)的信息。Systemd會根據(jù)需求在各設(shè)備上根據(jù)udev規(guī)則創(chuàng)建device單元。其常被用于進(jìn)行問題排序,從而在實際啟動之前確保設(shè)備切實可用。mount: 定義與設(shè)備安裝點相關(guān)的信息。其名稱位于所引用安裝點之后,且以破折號替代斜杠。automount: 定義掛載點。其與mount單元采用同樣的命名方式,且必須配合相關(guān)的mount單元。其用于描述按需與并發(fā)安裝。timer: 定義一個與其它單元關(guān)聯(lián)的計時器。當(dāng)此文件中設(shè)定的時間點被觸發(fā)時,該相關(guān)單元即開始啟動。path: 定義一條路徑,其可被監(jiān)控以進(jìn)行基于路徑的激活操作。我們可以利用它在特定路徑發(fā)生變更時啟動其它單元。

盡管大家可以隨意選擇上述選項,但service單元仍是最為常用的條目。在本教程中,我們將單純探討service單元的配置。

單元文件為簡單的文本文件,且結(jié)尾為“.”加上以上后綴之一。文件內(nèi)容由多處區(qū)段組成。在fleet當(dāng)中,大部分單元文件將采用以下基本格式:

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

區(qū)段標(biāo)題及單元文件中的其它內(nèi)容皆區(qū)分大小寫。其中[Unit]用于定義單元的常規(guī)信息。以上與各單元類型相關(guān)的選項皆可添加在這里。

[Service]區(qū)段用于設(shè)定指向各服務(wù)單元的指令。大多數(shù)(但并非全部)單元類型都與unit-type-specific區(qū)段信息相關(guān)聯(lián)。大家可以參閱常見systemd單元文件man頁面以了解更多與不同單元類型相關(guān)的細(xì)節(jié)。

[X-Fleet]區(qū)段用于設(shè)定該單元的調(diào)度要求以供fleet使用。利用此區(qū)段,大家可以要求某特定條件為御前 以在主機(jī)上實現(xiàn)單元調(diào)度。

構(gòu)建主服務(wù)

在這一區(qū)段中,首先對在CoreOS上運行服務(wù)中使用過的單元文件進(jìn)行調(diào)整。該文件名為apache.1.service,且內(nèi)容如下:

[Unit]Description=Apache web server service# RequirementsRequires=etcd.serviceRequires=docker.serviceRequires=apache-discovery.1.service# Dependency orderingAfter=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 variablesEnvironmentFile=/etc/environment# Pre-start and Start## Directives with "=-" are allowed to fail without consequenceExecStartPre=-/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# StopExecStop=/usr/bin/docker stop apache[X-Fleet]# Don't schedule on the same machine as other Apache instancesX-Conflicts=apache.*.service

我們首先從[Unit]區(qū)段入手。在這里,我們的基本思路是描述該單元并添加關(guān)聯(lián)性信息。首先設(shè)定相關(guān)要求。在本示例中,我們將使用部分硬性約束條件。如果我們希望fleet嘗試啟動額外服務(wù),但又不會因故障而導(dǎo)致流程中斷,則可使用Wants指令。

之后,我們需要明確列出要求的先后順序。這一點非常重要,因為某些要求需要以特定服務(wù)正在運行為前提。另外,我們也可以在這里自動利用etcd聲明我們將要構(gòu)建的服務(wù)。

在[Service]區(qū)段中,我們關(guān)閉服務(wù)啟動超時機(jī)制。由于服務(wù)首次在主機(jī)上運行時,容器需要自Docker注冊表中提取信息,而這往往會造成啟動超時。其默認(rèn)時長為90秒,一般來說應(yīng)該是足夠的,但較為復(fù)雜的容器可能需要更長的啟動時間。

而后將killmode設(shè)置為none。這是因為正常的關(guān)閉模式(control-group)有時候會導(dǎo)致容器移除命令失效(特別是Docker的–rmoption)。這有可能在下一次重啟時帶來問題。

我們可以在此環(huán)境文件中找到COREOS_PUBLIC_IPV4以及COREOS_PRIVATE_IPV4環(huán)境變量(如果創(chuàng)建過程中啟用了專有網(wǎng)絡(luò)機(jī)制)。我們可以利用其特定主機(jī)信息輕松配置Docker容器。

ExecStartPre各行用于清空此前尚未運行的部分以實現(xiàn)執(zhí)行環(huán)境清理。我們可以在前兩行中使用=-以確保出現(xiàn)問題時,systemd會忽略錯誤并繼續(xù)執(zhí)行后續(xù)命令。這一點非常重要,因為我們的預(yù)啟動操作基本上清除了任何先前正在運行的服務(wù)。如果找不到已經(jīng)在運行的服務(wù),則操作自然會失敗——但由于其僅僅屬于清理流程,因此我們不希望其影響到服務(wù)的正常執(zhí)行。最后的pre-start用于確保容器始終運行最新版本。

這條啟動命令會引導(dǎo)Docker容器并將其與主機(jī)設(shè)備的公共IPv4接口相綁定。其使用此環(huán)境文件中的信息并輕松實現(xiàn)接口與端口交換。這一流程采用前臺運行方式,這是因為該容器會在運行中進(jìn)程結(jié)束后退出。而stop命令則嘗試對容器進(jìn)行正常關(guān)閉。

[X-Fleet]區(qū)段包含一條簡單狀態(tài),用于強(qiáng)制fleet在尚未運行其它Apache服務(wù)的主機(jī)上調(diào)度該服務(wù)。這是一種簡單的服務(wù)高可用性實現(xiàn)方式,即強(qiáng)制要求服務(wù)啟動在不同設(shè)備上。

構(gòu)建主服務(wù)的幾項要點

在以上示例中,我們已經(jīng)進(jìn)行了一些比較基礎(chǔ)的配置。不過還有其它一些需要關(guān)注的重點。

下面來看構(gòu)建主服務(wù)中需要注意的幾點:

對關(guān)聯(lián)性與排序邏輯進(jìn)行區(qū)分:利用Requires=或者Wants=指令進(jìn)行關(guān)聯(lián)性排布,具體取決于如果不填寫此關(guān)聯(lián)性,該單元是否會失敗。排序區(qū)分則可使用After=以及Before=行實現(xiàn),這樣我們就能輕松判斷要求是否出現(xiàn)變更。將關(guān)聯(lián)性列表與排序區(qū)分開來能幫助我們調(diào)試關(guān)聯(lián)性問題。利用獨立進(jìn)程處理服務(wù)注冊:我們的服務(wù)應(yīng)當(dāng)利用etcd進(jìn)行注冊以發(fā)揮服務(wù)發(fā)現(xiàn)機(jī)制的使用,并借此實現(xiàn)動態(tài)配置功能。不過,我們應(yīng)當(dāng)使用單獨的“sidekick”容器以保持邏輯獨立性。這樣從外部視角來看,其才能提供更為明確的服務(wù)運行狀態(tài)報告,并供其它組件加以參考。關(guān)注服務(wù)超時可能性:考慮調(diào)整TimeoutStartSec指令以允許更長的啟動時間。將其設(shè)置為“0”則會禁用啟動超時機(jī)制。我們建議這樣設(shè)定,因為Docker往往需要從注冊表中提取鏡像(在首次運行或者發(fā)現(xiàn)更新時),這可能顯著增加服務(wù)的初始化時長。如果服務(wù)未能徹底停止,請調(diào)整KillMode:如果我們的服務(wù)或者容器似乎無法徹底停止,請考慮使用KillMode選項。將其設(shè)置為“none”有時候能夠解決容器停止后未被移除的問題。特別是在對容器進(jìn)行命名時,由于Docker會因為存在重名容器而出現(xiàn)錯誤。查閱KillMode說明文檔以獲取更多信息。在啟動前清理運行環(huán)境:與上一條相關(guān),請確保在每次啟動前清除環(huán)境中的全部既有Docker容器。這些清理命令行需要使用=-標(biāo)記以保證不需要清理時仍能執(zhí)行下一步操作。雖然我們一般都會使用docker stop對容器進(jìn)行正常停止,但也可以使用docker kill以確保其被徹底清除。引入并使用特定主機(jī)信息以實現(xiàn)服務(wù)可移植性:如果大家需要將服務(wù)綁定至特定網(wǎng)絡(luò)接口,請引入/etc/environment文件以訪問COREOS_PUBLIC_IPV4以及COREOS_PRIVATE_IPV4。如果我們需要查看當(dāng)前運行中服務(wù)所在設(shè)備的主機(jī)名稱,則可使用%H系統(tǒng)標(biāo)記。要了解更多可用標(biāo)記信息,請參閱systemd標(biāo)記說明文檔。在[X-Fleet]區(qū)段中,只能使用%n、%N、%i與%p。

構(gòu)建sidekick聲明服務(wù)

現(xiàn)在我們已經(jīng)掌握了如何構(gòu)建主服務(wù),接下來需要了解傳統(tǒng)的“sidekick”服務(wù)。這些sidekick服務(wù)與主服務(wù)相關(guān)聯(lián),且可通過etcd作為注冊服務(wù)的外部點。

這個被引用于主單元文件中的文件名為apache-discovery.1.service,內(nèi)容如下:

[Unit]Description=Apache web server etcd registration# RequirementsRequires=etcd.serviceRequires=apache.1.service# Dependency ordering and bindingAfter=etcd.serviceAfter=apache.1.serviceBindsTo=apache.1.service[Service]# Get CoreOS environmental variablesEnvironmentFile=/etc/environment# Start## Test whether service is accessible and then register useful informationExecStart=/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'# StopExecStop=/usr/bin/etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}[X-Fleet]# Schedule on the same machine as the associated Apache serviceX-ConditionMachineOf=apache.1.service

Sidekick服務(wù)的實現(xiàn)方式與主服務(wù)基本一致。我們首先描述該單元的作用,而后為其提供關(guān)聯(lián)性信息與排序邏輯。

這里要用到的新命令為BindsTo=。此命令會使該單元逐步執(zhí)行啟動、停止以及重啟操作。基本上,這意味著我們能夠在兩個單元被載入至fleet當(dāng)中后,通過操縱主單元同時管理這兩個單元。這是一種單向機(jī)制,所以對sidekick單元進(jìn)行控制不會影響到主單元。

在[Service]區(qū)段中,我們再次查找/etc/environment文件中的變量。此時ExecStart=指令基本上屬于一條簡短的bash腳本。它會嘗試?yán)靡呀?jīng)聲明的接口與端口接入主服務(wù)。

如果連接成功,那么etcdctl命令會在etcd內(nèi)的/services/apache中利用主機(jī)設(shè)備的公共IP地址設(shè)定一個鍵。該鍵的值為JSON對象,其中包含與該服務(wù)相關(guān)的信息。此鍵的過期時長為30秒,因此如果該單元意外停止,則對應(yīng)服務(wù)信息亦不會駐留在etcd中。如果連接失敗,那么該鍵會被立即移除——這是因為該服務(wù)無法被驗證為可用。

此循環(huán)中包含一條20秒的sleep命令。這意味著每20秒(早于etcd的30秒鍵超時設(shè)定),此單元就會重新檢查其主單元是否可用并重置該鍵。這基本上相當(dāng)于對鍵上的TTL進(jìn)行刷新,使其在接下來30秒中繼續(xù)生效。

在這種情況下,stop命令只用于手動移除該鍵。意味著該服務(wù)注冊將在主單元的stop命令由于BindsTo=指令而被鏡像至此單元時被移除。

在[X-Fleet]區(qū)段中,我們需要確保此單元與主單元啟動在同一臺服務(wù)器上。盡管這套方案不允許該單元向遠(yuǎn)程設(shè)備報告服務(wù)可用性,但在本示例中,最重要的是確保BindsTo=指令正常起效。

構(gòu)建sidekick服務(wù)的幾項要點

在構(gòu)建sidekick單元時,我們應(yīng)當(dāng)認(rèn)真考慮以下幾項要求:

檢查主單元的實際可用性:檢查主單元運行狀態(tài)非常重要。不要僅靠sidekick能夠正常初始化就認(rèn)為主單元可用。雖然實際可用性取決于主單元的設(shè)計與功能,但檢查機(jī)制越強(qiáng)大,注冊狀態(tài)的可靠性就越高。這樣的檢查工作應(yīng)該擁有廣泛的涵蓋面,從檢查/health端點到嘗試?yán)每蛻舳私尤霐?shù)據(jù)庫。定期對注冊邏輯進(jìn)行重新檢查:檢查服務(wù)可用性當(dāng)然很重要,但定期進(jìn)行復(fù)查同樣重要。我們可以借此發(fā)現(xiàn)意料之外的服務(wù)故障,特別是在容器中的某些結(jié)果仍在繼續(xù)運行時。在不同周期間進(jìn)行暫停,并借此對主單元上的其它負(fù)載進(jìn)行快速審查。使用TTL標(biāo)記通過etcd對故障進(jìn)行自動注銷:sidekick單元中的意外故障可能導(dǎo)致etcd內(nèi)信息與實際信息間發(fā)生沖突。為了避免這種沖突,我們應(yīng)當(dāng)允許鍵超時。利用以上循環(huán)間隔機(jī)制,我們可以在各鍵超時前對其進(jìn)行刷新,從而確保其永遠(yuǎn)不會在sidekick正常運行時過期。這種休眠間隔應(yīng)被設(shè)定為略短于超時間隔,從而確保功能正常起效。利用etcd注冊可用信息,而非單純確認(rèn):在對sidekick進(jìn)行首次迭代時,我們往往只關(guān)注單元啟動時是否確切注冊至etcd。然而其中也包含有大量可資其它服務(wù)利用的信息。雖然我們目前并不需要這些信息,但其可能會在構(gòu)建其它組件時發(fā)揮作用。Etcd服務(wù)屬于一項全局性鍵-值存儲機(jī)制,因此別忘記利用它提供鍵信息。以JSON對象方式存儲細(xì)節(jié)是傳遞多條信息的好辦法。

掌握了以上幾條要點,我們就能構(gòu)建強(qiáng)大的注冊單元,同時確保etcd擁有正常的信息可以使用。

與fleet相關(guān)的思考

雖然fleet單元文件與其它常見systemd單元文件并沒有太大區(qū)別,但其中仍存在著一些值得關(guān)注的特性與陷阱。

其中最大的區(qū)別就是[X-Fleet]的存在,其可用于指引fleet制定調(diào)度決策。具體可用選項包括:

X-ConditionMachineID: 其可用于指定某臺設(shè)備以進(jìn)行單元加載。其提供的值為完整的設(shè)備ID。此值可由集群內(nèi)單一成員通過檢查/etc/machine-id文件進(jìn)行檢索,或者通過fleetctl的list-machines -l命令查看。其必須使用完整的ID字符串。如果大家是在特定設(shè)備上運行一套數(shù)據(jù)庫及其數(shù)據(jù)目錄,那么這一要求就非常必要了。當(dāng)然,在非必要情況下不推薦大家使用它,因為其會嚴(yán)重影響到單元的靈活性。X-ConditionMachineOf: 用于將當(dāng)前單元調(diào)度至加載有其它特定單元的設(shè)備之上。其可用于調(diào)度sidekick單元或者將多個單元聯(lián)系在一起。X-Conflicts: 與上一條相反,其限定當(dāng)前單元文件不可被調(diào)度至特定設(shè)備上。我們可以利用它輕松實現(xiàn)高可用性配置,即在不同設(shè)備上運行同一服務(wù)的多個版本。X-ConditionMachineMetadata:用于根據(jù)當(dāng)前可用設(shè)備的元數(shù)據(jù)指定調(diào)度要求。在fleetctl list-machines輸出結(jié)果中的“METADATA”列當(dāng)中,大家可以看到每臺主機(jī)所設(shè)定的元數(shù)據(jù)。要設(shè)置元數(shù)據(jù),可在服務(wù)器實例初始化時將其添加至cloud-config文件中。Global: 這是一條特殊的指令,會利用一條boolean參數(shù)標(biāo)記目標(biāo)單元是否應(yīng)被調(diào)度至集群內(nèi)的全部設(shè)備上。我們應(yīng)當(dāng)僅使用此指令處理元數(shù)據(jù)狀態(tài)。

這些額外指令允許管理員更加靈活且有效地定義服務(wù)在可用設(shè)備上的運行方式。我們需要對其進(jìn)行預(yù)先評估,而后方可在fleetctl加載階段中將其傳遞至特定設(shè)備的systemd實例中。

這就帶來了fleet中需要注意的另一項要點。事實上,fleetctl工具并不會對單元文件內(nèi)[X-Fleet]區(qū)段之外的關(guān)聯(lián)性要求進(jìn)行評估。這意味著fleet中的各單元可能在協(xié)作時引發(fā)某些有趣的問題。

具體來講,當(dāng)fleetctl工具采取必要步驟以將目標(biāo)單元操作至所需狀態(tài)時,其不會考慮到該單元的關(guān)聯(lián)性需求。

因此,如果我們分別提交了主與sidekick單元,但尚未在fleet中完成加載,那么輸入fleetctl start main.service將加載并嘗試啟動main.serivce單元。然而,由于sidekick.service單元尚未被加載,而fleetctl又不會在加載與啟動過程中評估關(guān)聯(lián)性,因此main.service單元會發(fā)生錯誤。這是因為一旦設(shè)備上的systemd實例開始處理main.service單元,將無法在關(guān)聯(lián)性評估階段找到sidekick.service。

為了避免這種情況,我們可以同時手動啟動這些服務(wù),而非領(lǐng)先BindsTo=指令將sidekick引入運行狀態(tài):

fleetctl start main.service sidekick.service

另一種方式則是確保sidekick單元一定會在主單元運行時進(jìn)行加載。其載入過程由設(shè)備選擇,而該單元文件則被提交至本地systemd實例當(dāng)中。這樣能夠確保關(guān)聯(lián)性得到滿意,而BindsTo=指令也能夠正常執(zhí)行以啟動該輔助單元:

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

因此當(dāng)fleetctl命令報錯時,大家可以從以上幾個角度進(jìn)行排查。

實例與模板

在使用fleet時,其最為強(qiáng)大的概念之一就是單元模板。單元模板依賴于systemd下一種名為“實例”的特性。它們屬于實例化的單元,通過處理模板單元文件被創(chuàng)建在運行時當(dāng)中。模板文件在很大程度上類似于常規(guī)單元文件,只是其中存在幾處小小的修改。如果得到正確利用,其將發(fā)揮巨大作用。

模板文件可通過在文件名中使用@來標(biāo)記。大多數(shù)常規(guī)服務(wù)的文件名格式為unit.service,而模板文件的名稱格式則為unit@.service。

當(dāng)某單元利用模板進(jìn)行實例化時,其實例標(biāo)記符將位于@與.service后綴之間。此標(biāo)記符可由管理員任意指定:

unit@instance_id.service

此基礎(chǔ)單元名稱可通過%p標(biāo)記符在單元文件之內(nèi)進(jìn)行訪問。同樣的,給定實例標(biāo)記符則可通過%i進(jìn)行訪問。

主單元文件即模板

這意味著我們無需像之前那樣一步步創(chuàng)建apache.1.service主單元文件,而可以直接創(chuàng)建一套名為apache@.service的模板:

[Unit]Description=Apache web server service on port %i# RequirementsRequires=etcd.serviceRequires=docker.serviceRequires=apache-discovery@%i.service# Dependency orderingAfter=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 variablesEnvironmentFile=/etc/environment# Pre-start and Start## Directives with "=-" are allowed to fail without consequenceExecStartPre=-/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# StopExecStop=/usr/bin/docker stop apache.%i[X-Fleet]# Don't schedule on the same machine as other Apache instancesX-Conflicts=apache@*.service

如大家所見,我們將apache-discovery.1.service關(guān)聯(lián)性修改為apache-discovery@%i.service。這意味著如果我們擁有此單元文件的一個名為apache@8888.service的實例,那么其將需要一個名為apache-discovery@8888.service的sidekick單元。其中的%i已經(jīng)被替換為實例標(biāo)記符。在這種情況下,我們使用該標(biāo)記符代表與當(dāng)前所運行服務(wù)相關(guān)的動態(tài)信息,特別是Apache服務(wù)器的可用端口編號。

為了實現(xiàn)這一目標(biāo),我們可以變更docker的運行參數(shù),從而將該容器的端口聲明至主機(jī)上的某個端口。在該靜態(tài)單元文件中,我們使用的參數(shù)為COREOSPUBLICIPV4:80:80,其負(fù)責(zé)將該容器的端口80映射至主機(jī)端口80的公共IPv4接口。在此模板文件中,我們可以將其替換成{COREOS_PUBLIC_IPV4}:%i:80,因為我們會利用實例標(biāo)記符來告知所使用的具體端口。總而言之,使用實例標(biāo)記符能夠在模板文件中實現(xiàn)更理想的靈活性。

Docker名稱本身也進(jìn)行了修改,這樣它也會使用基于實例ID的惟一容器名稱。請注意,Docker容器無法使用@標(biāo)記,因此我們必須在單元文件中選擇其它名稱。為此,我們修改了全部在Docker容器上運行的指令。

在[X-Fleet]區(qū)段中,我們還修改了調(diào)度信息以識別這些實例化單元,而非我們之前使用的靜態(tài)單元。

Sidekick單元即模板

我們也可以利用同樣的方法將sidekick單元轉(zhuǎn)化為模板。

我們的新sidekick單元將被命名為apache-discovery@.service,如下所示:

[Unit]Description=Apache web server on port %i etcd registration# RequirementsRequires=etcd.serviceRequires=apache@%i.service# Dependency ordering and bindingAfter=etcd.serviceAfter=apache@%i.serviceBindsTo=apache@%i.service[Service]# Get CoreOS environmental variablesEnvironmentFile=/etc/environment# Start## Test whether service is accessible and then register useful informationExecStart=/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'# StopExecStop=/usr/bin/etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}[X-Fleet]# Schedule on the same machine as the associated Apache serviceX-ConditionMachineOf=apache@%i.service

我們也用同樣的方式對sidekick單元中的內(nèi)容進(jìn)行了調(diào)整,從而構(gòu)建這套實例化版本并保證其與正確的實例化主單元相匹配。

在curl命令中,當(dāng)我們檢查服務(wù)的實際可用性時,我們會利用實例ID替換靜態(tài)端口80,從而保證其接入正確的位置。這一點非常重要,因為我們已經(jīng)在Docker命令中對主單元的端口聲明映射做出了變更。

我們還修改了“port”部分以登錄至etcd,旨在保證其使用同樣的實例ID。變更之后,被設(shè)定在etcd中的JSON數(shù)據(jù)將完全動態(tài)。其會提取主機(jī)名稱、IP地址以及服務(wù)運行所在的端口。

最后,我們再次變更[X-Fleet]區(qū)段。我們需要確保此流程與主單元實例運行在同一臺設(shè)備上。

利用模板進(jìn)行單元實例化

要利用模板文件進(jìn)行單元實例化,我們擁有幾種不同選項。

其中fleet與systemd都能夠處理符號鏈接,這意味著我們可以創(chuàng)建包含完整實例ID且指向模板文件的鏈接,具體如下:

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

這將創(chuàng)建兩條鏈接,分別名為apache@8888.service與apache-discovery@8888.service。二者皆擁有fleet與systemd運行單元所必需的信息。不過,它們會指向回對應(yīng)模板,因此我們需要再做點調(diào)整。

在此之后,我們可以利用以下fleetctl命令實現(xiàn)服務(wù)的提交、加載或者啟動:

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

如果我們不希望利用符號鏈接定義自己的實例,則可使用另一種fleetctl內(nèi)的模板提交方式:

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

只需要將實例標(biāo)記符分配給運行時,我們就能在fleetctl中以模板為基礎(chǔ)實現(xiàn)單元實例化。例如,大家可以使用以下命令:

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

這就消除了對符號鏈接的需求。部分管理員傾向于使用鏈接機(jī)制,因為這能保證實例文件隨時可用。其同時允許我們將目錄傳遞至fleetctl,從而一次性啟動全部組件。

例如,在我們的工作目錄中,大家可以為模板文件建立一個名為templates的子目錄,并為實例化鏈接版本建立名為instances的子目錄。大家甚至可以為非模板單元建立static子目錄。具體命令如下:

mkdir templates instances static

而后將靜態(tài)文件移動到static子目錄下,而模板文件則移動對templates子目錄下:

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

在這里,大家可以創(chuàng)建自己需要的實例鏈接了。假設(shè)我們的服務(wù)運行在端口5555、6666與7777上:

cd instancesln -s ../templates/apache@.service apache@5555.serviceln -s ../templates/apache@.service apache@6666.serviceln -s ../templates/apache@.service apache@7777.serviceln -s ../templates/apache-discovery@.service apache-discovery@5555.serviceln -s ../templates/apache-discovery@.service apache-discovery@6666.serviceln -s ../templates/apache-discovery@.service apache-discovery@7777.service

而后利用以下命令即可一次性啟動全部實例:

cd ..fleetctl start instances/*

非常簡單,也非常快捷。

總結(jié)

到這里,大家應(yīng)該已經(jīng)掌握了fleet單元文件的構(gòu)建方法了。利用單元文件帶來的動態(tài)特性,我們能夠確保自己的服務(wù)始終得到均勻分布、擁有正確的關(guān)聯(lián)性并利用etcd注冊使用信息。

在下一篇文章中,我們將探討如何配置自己的容器,從而使用通過etcd注冊的信息。如此一來,我們就能夠建立對實際部署環(huán)境的認(rèn)識,并將請求傳遞至后端中的合適容器當(dāng)中。

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

翻譯:diradw


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 班玛县| 泰兴市| 洛隆县| 托克托县| 日喀则市| 靖江市| 河间市| 华阴市| 伊春市| 久治县| 贡山| 陇西县| 舒兰市| 合阳县| 孝义市| 邯郸市| 罗甸县| 永吉县| 襄樊市| 梧州市| 海门市| 盐源县| 新野县| 台南县| 东阿县| 乌恰县| 海安县| 泰来县| 潜江市| 乌鲁木齐市| 景泰县| 石河子市| 巴楚县| 肥乡县| 塔城市| 进贤县| 石首市| 宣城市| 长春市| 阿瓦提县| 肥乡县|