提供:ZStack云計(jì)算
本教程為CoreOS上手指南系列九篇中的第三篇。
CoreOS為我們提供了一套跨越多服務(wù)器環(huán)境的Docker容器管理平臺(tái),而其中的fleet服務(wù)則能夠顯著簡(jiǎn)化整套集群的管理難度。
Fleet允許用戶將Docker容器作為服務(wù)對(duì)整體集群進(jìn)行管理。它既作為接口存在,同時(shí)亦作為各集群成員中systemd init系統(tǒng)的抽象層。用戶可以設(shè)定約束條件,從而對(duì)服務(wù)的運(yùn)行方式加以限定。通過(guò)這種方式,管理員能夠要求特定應(yīng)用程序運(yùn)行在同一或者不同主機(jī)之上,并以此實(shí)現(xiàn)基礎(chǔ)設(shè)施調(diào)整。
在今天的教程中,我們將了解fleet并學(xué)習(xí)利用fleetctl工具控制該守護(hù)進(jìn)程。
要完成本篇教程,大家首先需要擁有一套可用CoreOS集群。
在之前的系列教程如何利用DigitalOcean創(chuàng)建一套CoreOS集群當(dāng)中,我們已經(jīng)完成了集群創(chuàng)建工作。
此集群配置包含三個(gè)節(jié)點(diǎn)。它們能夠利用專有網(wǎng)絡(luò)接口實(shí)現(xiàn)彼此通信。這三臺(tái)節(jié)點(diǎn)亦擁有公共接口以運(yùn)行公共服務(wù)。各節(jié)點(diǎn)名稱分別為:
coreos-1coreos-2coreos-3在集群準(zhǔn)備就緒后,下面繼續(xù)這場(chǎng)fleet之旅。
在探討fleetctl工具之前,我們應(yīng)當(dāng)首先聊聊服務(wù)單元文件。
單元文件由systemd init系統(tǒng)用于描述每項(xiàng)可用服務(wù),定義對(duì)其進(jìn)行管理的必要命令并設(shè)定服務(wù)啟動(dòng)時(shí)確保系統(tǒng)處于正常狀態(tài)的各關(guān)聯(lián)性信息。其中fleet守護(hù)進(jìn)程構(gòu)建在systemd基礎(chǔ)之上,從而立足于集群層面進(jìn)行服務(wù)管理。有鑒于此,它使用的systemd單元文件與標(biāo)準(zhǔn)版本略有不同。
為了進(jìn)一步了解fleet單元文件,請(qǐng)參閱深度解析一文。在今天的教程內(nèi),我們只會(huì)對(duì)這些文件的格式進(jìn)行概述。我們還會(huì)提供一個(gè)示例單元文件以幫助大家了解fleetctl。
大多數(shù)單元文件都包含以下幾個(gè)基礎(chǔ)區(qū)段:
Unit: 此區(qū)段用于提供與該單元相關(guān)的普通信息,且與單元的“type”無(wú)關(guān)。其中包括元數(shù)據(jù)信息及關(guān)聯(lián)性信息。其在fleet中主要用于提供描述并指定該單元如何與其它其它服務(wù)單元對(duì)接。Unit Type Section: fleet守護(hù)進(jìn)程能夠容納多種不同單元類型,包括: ServiceSocketDeviceMountAutomountTimerPath如果該類型已經(jīng)擁有特定選項(xiàng),則允許其中包含一個(gè)與類型相關(guān)的區(qū)段。Service區(qū)段類型最為常見(jiàn),其用于定義特定類型的屬性。對(duì)于Service單元而言,這些屬性通常包括定義命令的啟動(dòng)與停止,或者以前置及后置方式啟動(dòng)或停止命令。
X-Fleet: 此區(qū)段用于提供特定fleet配置選項(xiàng)。具體來(lái)講,這意味著大家可以指定某項(xiàng)服務(wù)必須或者絕不可以特定方式進(jìn)行調(diào)度,具體條件包括設(shè)備ID、當(dāng)前正在運(yùn)行的服務(wù)以及元數(shù)據(jù)信息等等。單元文件的一般格式如下:
[Unit]Generic_option_1Generic_option_2[Service]Service_specific_option_1Service_specific_option_2[X-Fleet]Fleet_option_1Fleet_option_2要開(kāi)始本篇教程,我們需要首先獲取單元文件。大家可通過(guò)CoreOS快速上手頁(yè)面中獲取。在任一CoreOS設(shè)備中輸入:
vim hello.service而后,輸入我們的示例服務(wù)文件:
[Unit]Description=My ServiceAfter=docker.service[Service]TimeoutStartSec=0ExecStartPRe=-/usr/bin/docker kill helloExecStartPre=-/usr/bin/docker rm helloExecStartPre=/usr/bin/docker pull busyboxExecStart=/usr/bin/docker run --name hello busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"ExecStop=/usr/bin/docker stop hello下面來(lái)看其具體作用。
在[Unit]區(qū)段設(shè)定一條描述,意味著我們告知systemd此服務(wù)只能在docker.service單元啟動(dòng)之后開(kāi)始運(yùn)行。這是因?yàn)槲覀兊膯卧枰浜螪ocker才能正常起效。
而在[Service]區(qū)段,我們禁用啟動(dòng)超時(shí),而后設(shè)置一系列操作以完成服務(wù)啟動(dòng)前需要首先運(yùn)行的組件。其中ExecStartPre會(huì)在主ExecStart操作之前執(zhí)行。如果其由=-調(diào)用,則表明無(wú)論其是否成功啟動(dòng)皆不會(huì)對(duì)服務(wù)本身造成影響。這一點(diǎn)非常重要,因?yàn)槲覀兊念A(yù)啟動(dòng)操作基本上清除了任何先前正在運(yùn)行的服務(wù)。如果找不到已經(jīng)在運(yùn)行的服務(wù),則操作自然會(huì)失敗——但由于其僅僅屬于清理流程,因此我們不希望其影響到服務(wù)的正常執(zhí)行。
最后的pre-start區(qū)段負(fù)責(zé)提取運(yùn)行命令所需要的基礎(chǔ)busybox鏡像。由于這項(xiàng)操作具有 必要性,因此我們不可使用=-語(yǔ)法。接下來(lái),我們利用該鏡像啟動(dòng)一套容器,并以初始循環(huán)每秒輸出一次“Hello World”。其停止操作則會(huì)直接關(guān)閉此容器。
如果大家希望了解更多與fleet文件開(kāi)發(fā)相關(guān)的知識(shí),請(qǐng)查閱我們的fleet單元文件指南。
先來(lái)介紹fleetctl工具。作為一款集群管理工具,fleetctl將成為我們管理設(shè)備集群的主要接口。其中大部分語(yǔ)法都直接照搬自systemctl——systemd的管理工具。
作為第一步,我們利用以下命令獲取一份集群成員清單:
fleetctl list-machinesMACHINE IP METADATA14ffe4c3... 10.132.249.212 -1af37f7c... 10.132.249.206 -9e389e93... 10.132.248.177 -如大家所見(jiàn),每臺(tái)可用設(shè)備都被羅列了出來(lái)。其中每個(gè)成員在啟動(dòng)時(shí)都使用cloud-config文件對(duì)自身進(jìn)行引導(dǎo),生成一個(gè)惟一設(shè)備ID并借此區(qū)分各個(gè)節(jié)點(diǎn)。這部分信息被寫入至/etc/machine-id文件當(dāng)中。
在默認(rèn)情況下,fleet會(huì)使用設(shè)備的公共IPv4地址實(shí)現(xiàn)不同成員間的通信。不過(guò)在我們的cloud-config文件當(dāng)中,也可以要求fleet使用專有接口進(jìn)行通信。以上輸出結(jié)果正是這些IP地址。
其中“METADATA”一列目前還是空白,我們可以在cloud-config文件內(nèi)的元數(shù)據(jù)屬性中為其添加任意鍵-值對(duì)。如下所示:
#cloud-config. . .coreos:fleet:public-ip: $private_ipv4metadata: region=europe,public_ip=$public_ipv4如果大家在cloud-config文件中這樣設(shè)置以引導(dǎo)全部設(shè)備,則輸出結(jié)果應(yīng)如下所示:
MACHINE IP METADATA14ffe4c3... 10.132.249.212 public_ip=104.131.36.200,region=europe1af37f7c... 10.132.249.206 public_ip=104.131.15.192,region=europe9e389e93... 10.132.248.177 public_ip=104.131.15.192,region=europe這部分額外數(shù)據(jù)可在管理工作當(dāng)中用于快速?gòu)墓?jié)點(diǎn)中提取信息,但其同時(shí)亦可在服務(wù)定義中用于指向特定主機(jī)。
為了接入集群中的特定設(shè)備,大家可以使用fleetctl ssh命令。如此一來(lái),我們就能夠根據(jù)設(shè)備ID或者與給定單元名稱相對(duì)應(yīng)的設(shè)備識(shí)別所接入的設(shè)備身份。
舉例來(lái)說(shuō),如果大家擁有一個(gè)名為nginx.service的運(yùn)行中單元,則可通過(guò)以下命令直接接入運(yùn)行該服務(wù)的對(duì)應(yīng)主機(jī):
fleetctl ssh nginx運(yùn)行后,我們會(huì)直接進(jìn)入對(duì)應(yīng)主機(jī)中的shell會(huì)話。大家也可以在遠(yuǎn)程主機(jī)上運(yùn)行單一命令,具體方式與運(yùn)行普通ssh可執(zhí)行文件一樣。舉例來(lái)說(shuō),要從/etc/environment文件(基于cloud-config參數(shù)以及可用網(wǎng)絡(luò)接口)當(dāng)中獲取CoreOS設(shè)定的COREOS_PRIVATE_IPV4與COREOS_PUBLIC_IPV4兩條變量,大家可以使用以下命令:
fleetctl ssh nginx cat /etc/environmentCOREOS_PRIVATE_IPV4=10.132.249.212COREOS_PUBLIC_IPV4=104.131.29.80在其它可用于fleetctl的命令中,大部分與服務(wù)管理相關(guān)。
啟動(dòng)一項(xiàng)服務(wù)需要涉及多個(gè)步驟。該服務(wù)文件必須被載入至fleet當(dāng)中,從而保證其感知到目標(biāo)單元。接下來(lái),其需要被調(diào)度至集群中的特定設(shè)備之上,最后才能完成啟動(dòng)。每個(gè)步驟都需要使用fleetctl命令,而這些命令分別負(fù)責(zé)執(zhí)行各個(gè)階段的對(duì)應(yīng)操作。
大家只可以使用submit命令將我們的單元文件提交至fleet。通過(guò)這種方式,fleet會(huì)將該文件內(nèi)容讀取至內(nèi)存,以備后續(xù)操作使用。
fleetctl submit hello.service我們的hello.service文件現(xiàn)在已經(jīng)為fleet所感知。要查看已經(jīng)提交完成的單元文件,大家可以使用以下命令:
fleetctl list-unit-filesUNIT HASH DSTATE STATE TMACHINEhello.service 0d1c468 inactive inactive -如大家所見(jiàn),該單元文件顯示如上,但尚未被調(diào)度至任何主機(jī)或者實(shí)際啟動(dòng)。
要查看fleet已經(jīng)識(shí)別出的單元文件內(nèi)容,大家可以使用以下命令:
fleetctl cat hello.service[Unit]Description=My ServiceAfter=docker.service[Service]TimeoutStartSec=0ExecStartPre=-/usr/bin/docker kill helloExecStartPre=-/usr/bin/docker rm helloExecStartPre=/usr/bin/docker pull busyboxExecStart=/usr/bin/docker run --name hello busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"ExecStop=/usr/bin/docker stop hello這樣大家就能查看fleet所感知的當(dāng)前文件內(nèi)容了。
注意:submit命令是冪等的,就是說(shuō)在進(jìn)行重復(fù)提交時(shí),fleet將不會(huì)更新內(nèi)存內(nèi)單元文件。如果大家需要更新自己的單元文件,則必須將其徹底移除,而后重新提交。我們將在后面具體進(jìn)行討論。
在單元提交完成后,下一步是將其調(diào)度至某臺(tái)設(shè)備。在單元調(diào)度過(guò)程中,fleet引擎會(huì)檢查該單元以保證其運(yùn)行在最合適的集群節(jié)點(diǎn)之上。具體結(jié)果取決于該單元中[X-Fleet]區(qū)段的約束條件以及集群中各臺(tái)設(shè)備的當(dāng)前負(fù)載量。當(dāng)該單元被調(diào)度完成后,其將被傳遞至特定設(shè)備并加入至本地systemd實(shí)例當(dāng)中。
使用load命令以加載并調(diào)度該單元:
fleetctl load hello.serviceUnit hello.service loaded on 14ffe4c3.../10.132.249.212如果大家之前還沒(méi)有以手動(dòng)方式載入單元,則此流程會(huì)在當(dāng)前目錄中搜索合適的文件名稱并進(jìn)行自動(dòng)加載。
現(xiàn)在,如果我們檢查自己的單元文件,就會(huì)發(fā)現(xiàn)其已經(jīng)被加載完畢。我們甚至能夠查看其被調(diào)度至哪臺(tái)設(shè)備上:
fleetctl list-unit-filesUNIT HASH DSTATE STATE TMACHINEhello.service 0d1c468 loaded loaded 14ffe4c3.../10.132.249.212這也是我們第一次使用list-units命令。該命令用于顯示任意運(yùn)行中或者已調(diào)度的單元及其狀態(tài):
fleetctl list-unitsUNIT MACHINE ACTIVE SUBhello.service 14ffe4c3.../10.132.249.212 inactive dead要啟動(dòng)一個(gè)單元,大家可以使用start命令。其會(huì)根據(jù)單元文件內(nèi)的start命令定義在特定設(shè)備上啟動(dòng)該單元:
fleetctl start hello.serviceUnit hello.service launched on 14ffe4c3.../10.132.249.212再次檢查list-unit-files:
fleetctl list-unit-filesUNIT HASH DSTATE STATE TMACHINEhello.service 0d1c468 launched launched 14ffe4c3.../10.132.249.212在以上輸出結(jié)果中,我們可以看到該服務(wù)已經(jīng)啟動(dòng)完成。其中DSTATE列所示為“理想狀態(tài)”,而STATE則指示實(shí)際狀態(tài)。如果二者相符,則意味著操作已經(jīng)成功。
下面再次查看list-units:
fleetctl list-unitsUNIT MACHINE ACTIVE SUBhello.service 14ffe4c3.../10.132.249.212 active running在這里我們可以看到與systemd狀態(tài)相關(guān)的信息。其直接收集自本地守護(hù)進(jìn)程,因此能夠幫助我們更好地掌握本地系統(tǒng)獲取到的服務(wù)狀態(tài)。其中ACTIVE列為該單元的一般性狀態(tài),而SUB則為更為較低層級(jí)的狀態(tài)。
以上各條命令都擁有一條與之對(duì)應(yīng)的反義命令。
舉例來(lái)說(shuō),我們可以使用stop命令停止一項(xiàng)運(yùn)行中的服務(wù)。在執(zhí)行后,本地設(shè)備的systemd實(shí)例將執(zhí)行單元定義中的停止指令:
fleetctl stop hello.serviceUnit hello.service loaded on 14ffe4c3.../10.132.249.212如大家所見(jiàn),該服務(wù)已經(jīng)恢復(fù)至已載入狀態(tài)。這意味著其仍被加載至設(shè)備的systemd當(dāng)中,但已經(jīng)不再繼續(xù)運(yùn)行。我們可以通過(guò)以下命令進(jìn)行確認(rèn):
fleetctl list-unit-filesUNIT HASH DSTATE STATE TMACHINEhello.service 0d1c468 loaded loaded 14ffe4c3.../10.132.249.212要移除該設(shè)備systemd中的單元,且同時(shí)保證其在fleet中的可用性,我們可以對(duì)該單元進(jìn)行unload。如果該單元目前正處于活動(dòng)狀態(tài),則會(huì)在被卸載前首先停止:
fleetctl unload hello.service如果檢查該狀態(tài),可以看到其現(xiàn)在已被標(biāo)記為非活動(dòng)狀態(tài)。另外目標(biāo)設(shè)備一項(xiàng)亦被留空:
fleetctl list-unit-filesUNIT HASH DSTATE STATE TMACHINEhello.service 0d1c468 inactive inactive -如果我們需要將該單元從fleet中完全移除,則可使用destroy命令。其會(huì)停止并卸載該單元,而后將其從fleet中移除:
fleetctl destroy hello.service如果我們修改某個(gè)單元文件,則必須摧毀fleet中的現(xiàn)有單元,而后再重新提交/啟動(dòng)。
大家應(yīng)該已經(jīng)了解到幾種獲取單元狀態(tài)信息的方式了。
舉例來(lái)說(shuō),list-units會(huì)列出全部當(dāng)前被調(diào)度至某設(shè)備上的單元:
fleetctl list-unitsUNIT MACHINE ACTIVE SUBhello.service 14ffe4c3.../10.132.249.212 active running而list-unit-files則提供一套包含_全部_fleet已知單元的清單。其還會(huì)提供理想與實(shí)際狀態(tài)信息:
fleetctl list-unit-filesUNIT HASH DSTATE STATE TMACHINEhello.service 0d1c468 launched launched 14ffe4c3.../10.132.249.212要獲取更為具體的已啟動(dòng)單元信息,我們還可以使用其它幾條命令。其中status命令會(huì)將返回目標(biāo)主機(jī)上運(yùn)行中單元的systemctl狀態(tài):
fleetctl status hello.service● hello.service - My ServiceLoaded: loaded (/run/fleet/units/hello.service; linked-runtime)Active: active (running) since Mon 2014-09-08 21:51:22 UTC; 3min 57s agoProcess: 7630 ExecStartPre=/usr/bin/docker pull busybox (code=exited, status=0/SUCCESS)Process: 7618 ExecStartPre=/usr/bin/docker rm hello (code=exited, status=0/SUCCESS)Process: 7609 ExecStartPre=/usr/bin/docker kill hello (code=exited, status=0/SUCCESS)Main PID: 7638 (docker)CGroup: /system.slice/hello.service └─7638 /usr/bin/docker run --name hello busybox /bin/sh -c while true; do echo Hello World; sleep 1; doneSep 08 21:55:11 coreos-3 docker[7638]: Hello WorldSep 08 21:55:12 coreos-3 docker[7638]: Hello WorldSep 08 21:55:13 coreos-3 docker[7638]: Hello WorldSep 08 21:55:14 coreos-3 docker[7638]: Hello WorldSep 08 21:55:15 coreos-3 docker[7638]: Hello WorldSep 08 21:55:16 coreos-3 docker[7638]: Hello WorldSep 08 21:55:17 coreos-3 docker[7638]: Hello WorldSep 08 21:55:18 coreos-3 docker[7638]: Hello WorldSep 08 21:55:19 coreos-3 docker[7638]: Hello WorldSep 08 21:55:20 coreos-3 docker[7638]: Hello World如大家所見(jiàn),我們最終證明示例單元的輸出結(jié)果正在正常顯示。
同樣的,如果大家請(qǐng)?jiān)谙嚓P(guān)設(shè)備上查看該服務(wù)的journal條目,則可使用journal命令:
fleetctl journal hello.service-- Logs begin at Mon 2014-09-08 14:22:14 UTC, end at Mon 2014-09-08 21:55:47 UTC. --Sep 08 21:55:38 coreos-3 docker[7638]: Hello WorldSep 08 21:55:39 coreos-3 docker[7638]: Hello WorldSep 08 21:55:40 coreos-3 docker[7638]: Hello WorldSep 08 21:55:41 coreos-3 docker[7638]: Hello WorldSep 08 21:55:42 coreos-3 docker[7638]: Hello WorldSep 08 21:55:43 coreos-3 docker[7638]: Hello WorldSep 08 21:55:44 coreos-3 docker[7638]: Hello WorldSep 08 21:55:45 coreos-3 docker[7638]: Hello WorldSep 08 21:55:46 coreos-3 docker[7638]: Hello WorldSep 08 21:55:47 coreos-3 docker[7638]: Hello World在默認(rèn)情況下,其會(huì)顯示最后十行。大家也可以通過(guò)添加–行參數(shù)對(duì)此進(jìn)行調(diào)整:
fleetctl journal --lines 20 hello.service大家也可以使用-f參數(shù),其代表“follow”。通過(guò)添加-f參數(shù)的命令,系統(tǒng)會(huì)不斷發(fā)回最新日志條目:
fleetctl journal -f hello.service通過(guò)學(xué)習(xí)如何使用fleet與fleetctl,大家可以輕松控制自己的CoreOS集群。我們的服務(wù)與容器亦可非常順暢地在不同設(shè)備之間往來(lái)遷移。
在下一篇教程中,我們將更為深入地探討how to create fleet unit files如何創(chuàng)建fleet單元文件。通過(guò)這種方式,大家能夠創(chuàng)建出可充分發(fā)揮CoreOS架構(gòu)優(yōu)勢(shì)的、靈活且強(qiáng)大的服務(wù)。
本文來(lái)源自DigitalOcean Community。英文原文:How To Use Fleet and Fleetctl to Manage your CoreOS Cluster By Justin Ellingwood
翻譯:diradw
新聞熱點(diǎn)
疑難解答
圖片精選