如何使用 Pulumi 管理 DigitalOcean 和 Kubernetes 基礎(chǔ)設(shè)施
Pulumi(https://www.pulumi.com) 是一個支持多語言和混合云開發(fā)平臺,使用通用編程語言編寫的代碼來創(chuàng)建、部署和管理基礎(chǔ)設(shè)施的工具。Pulumi 采用了基礎(chǔ)設(shè)施即代碼以及不可變基礎(chǔ)設(shè)施的概念,并可讓您從您最喜歡的語言(而不是 YAML 或 DSL)中獲得自動化和可重復性優(yōu)勢。
除應(yīng)用程序配置外,它還支持自動化所有 DigitalOcean 的托管服務(wù),例如 Droplet、托管數(shù)據(jù)庫、DNS 記錄和 Kubernetes 集群。通過易于使用的命令行工具進行部署,該工具還集成了各種流行的 CI/CD 系統(tǒng)。
Pulumi 支持多種語言,在本教程中,我們將使用 TypeScript 來進行說明,此外我們將配置一個 DigitalOcean Kubernetes 集群,一個負載均衡的 Kubernetes 應(yīng)用程序和一個 DigitalOcean DNS 域。
先決條件
要學習本教程,您需要:
用于部署資源的 DigitalOcean 帳戶,如果您還沒有,請在此處注冊(https://cloud.digitalocean.com/registrations/new) 。 用于執(zhí)行自動部署的 DigitalOcean API Token,在此處生成個人訪問令牌(https://www.digitalocean.com/docs/api/create-personal-access-token/)。 因為要創(chuàng)建和使用 Kubernetes 集群,所以您需要安裝 kubectl。您將在 TypeScript 中編寫基礎(chǔ)架構(gòu)代碼,因此您需要安裝 Node.js 8或更高版本。 您將使用 Pulumi 部署基礎(chǔ)架構(gòu),因此您需要安裝開源 Pulumi SDK(https://www.pulumi.com/docs/reference/install/) 。 將域名配置為使用 DigitalOceanNameservers(可選)。
第1步 - 創(chuàng)建新項目
第一步是創(chuàng)建一個存儲 Pulumi 項目的目錄。除了描述項目及其 NPM 依賴項的元數(shù)據(jù)文件之外,此目錄還將包含基礎(chǔ)架構(gòu)定義的源代碼。
首先,創(chuàng)建一個目錄,然進入新創(chuàng)建的目錄:
$?mkdir?do-k8s
$?cd?do-k8s
后面我們都在這個新創(chuàng)建的do-k8s目錄下運行命令。接下來,創(chuàng)建一個新的 Pulumi 項目,有不同的方法可以實現(xiàn)這一點,但最簡單的方法是使用pulumi new命令和pulumi new項目模板。此命令將首先提示您登錄 Pulumi,以便保存項目和部署狀態(tài),然后在當前目錄中創(chuàng)建一個簡單的 TypeScript 項目:
$?pulumi?new?typescript?-y
在這里,您已將-y選項傳遞給new命令,該命令告訴它接受默認項目選項。例如,項目名稱取自當前目錄的名稱,因此將是do-k8s。如果您想為項目名稱使用不同的選項,只需忽略-y 。
運行該命令后,使用ls列出目錄的內(nèi)容:
$?ls
Pulumi.yaml???????index.ts??????????node_modules
package-lock.json?package.json??????tsconfig.json
您要編輯的主要文件是index.ts ,我們也完全可以使用 Node.js 模塊中您認為合適的方式來組織項目。
第2步 - 添加依賴項
下一步是在 DigitalOcean 和 Kubernetes 包上安裝和添加依賴項。首先,使用 NPM 安裝它們:
$?npm?install?@pulumi/digitalocean?@pulumi/kubernetes
這將下載 Pulumi 插件,并將它們保存為依賴項。接下來,使用您喜歡的編輯器打開index.ts文件,這里我們使用 nano:
nano?index.ts
用以下內(nèi)容替換index.ts的內(nèi)容:
import?*?as?digitalocean?from?"@pulumi/digitalocean";
import?*?as?kubernetes?from?"@pulumi/kubernetes";
添加內(nèi)容后保存并關(guān)閉文件。
注意:我們將使用這些包中可用內(nèi)容的子集。有關(guān)資源、屬性和相關(guān) API 的完整文檔,請參閱
@pulumi/digitalocean(https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/digitalocean/) 和@pulumi/kubernetes(https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/kubernetes/) 軟件包的相關(guān) API 文檔。
接下來,將配置您的 DigitalOcean 令牌,以便 Pulumi 可以在您的帳戶中配置資源:
$?pulumi?config?set?digitalocean:token?YOUR_TOKEN_HERE?--secret
注意 --secret 標志,它使用 Pulumi 的加密服務(wù)來加密你的令牌,確保它存儲在密文中。如果您愿意,可以使用 DIGITALOCEAN_TOKEN 環(huán)境變量,但每次更新程序時都需要記住設(shè)置它,而使用配置會自動存儲并將其用于您的項目。
第3步 - 配置 Kubernetes 集群
現(xiàn)在已準備好創(chuàng)建 DigitalOcean Kubernetes 集群。重新打開index.ts文件開始:
$?nano?index.ts
在index.ts文件的末尾添加這些行:
…
const?cluster?=?new?digitalocean.KubernetesCluster("do-cluster",?{
????region:?digitalocean.Regions.SFO2,
????version:?"latest",
????nodePool:?{
????????name:?"default",
????????size:?digitalocean.DropletSlugs.DropletS2VPCU2GB,
????????nodeCount:?3,
????},
});
export?const?kubeconfig?=?cluster.kubeConfigs[0].rawConfig;
這個新代碼會分配了一個 digitalocean.KubernetesCluster 實例,并在其上設(shè)置了許多屬性,包括使用區(qū)域 slug、最新支持的 Kubernetes 版本、Droplet 大小,以及三個 Droplet 實例數(shù)量。
有關(guān)可在群集上配置的完整屬性列表,請參閱 KubernetesCluster API 文檔**(https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/digitalocean/#KubernetesCluster) 。
該代碼段中的最后一行導出生成的 Kubernetes 集群的kubeconfig文件,導出的變量將打印到控制臺,以方便其他工具訪問。
現(xiàn)在已經(jīng)準備好部署群集了,執(zhí)行如下命令即可:
$?pulumi?up
此命令獲取程序生成用于創(chuàng)建所述基礎(chǔ)架構(gòu)的計劃,并執(zhí)行一系列步驟來部署這些變更。這適用于初始創(chuàng)建基礎(chǔ)架構(gòu),此外還可以在進行后續(xù)更新時對您的基礎(chǔ)架構(gòu)進行區(qū)分和更新。在這種情況下,輸出將如下所示:
Previewing?update?(dev):
?????Type?????????????????????????????????????Name????????Plan
?+???pulumi:pulumi:Stack??????????????????????do-k8s-dev??create
?+???└─?digitalocean:index:KubernetesCluster??do-cluster??create
Resources:
????+?2?to?create
Do?you?want?to?perform?this?update?
??yes
>?no
??details
這表示繼續(xù)更新將創(chuàng)建一個名為 do-cluster 的 Kubernetes 集群,yes/no/details 提示允許我們在實際進行任何更改之前確認這是期望的結(jié)果。如果選擇 details,將顯示資源及其屬性的完整列表,選擇 yes 開始部署:
Updating?(dev):
?????Type?????????????????????????????????????Name????????Status
?+???pulumi:pulumi:Stack??????????????????????do-k8s-dev??created
?+???└─?digitalocean:index:KubernetesCluster??do-cluster??created
Outputs:
????kubeconfig:?"…"
Resources:
????+?2?created
Duration:?6m5s
Permalink:?https://app.pulumi.com/…/do-k8s/dev/updates/1
創(chuàng)建群集需要幾分鐘,隨后它將啟動并運行,并且完整的 kubeconfig 將打印到控制臺。將 kubeconfig 保存到文件:
$?pulumi?stack?output?kubeconfig?>?kubeconfig.yml
然后使用它與 kubectl 工具即可執(zhí)行任何 Kubernetes 命令:
$?KUBECONFIG=./kubeconfig.yml?kubectl?get?nodes
NAME???????????STATUS????ROLES?????AGE???????VERSION
default-o4sj???Ready?????????4m5s??????v1.14.2
default-o4so???Ready?????????4m3s??????v1.14.2
default-o4sx???Ready?????????3m37s?????v1.14.2
現(xiàn)在我們就設(shè)置了基礎(chǔ)設(shè)施即代碼,并具有可重復的方式來啟動和配置新的 DigitalOcean Kubernetes 集群。在下一步中,您將在此基礎(chǔ)上構(gòu)建在代碼中定義的 Kubernetes 集群,并學習如何以類似方式部署和管理它們。
第4步 - 將應(yīng)用程序部署到群集
接下來,您將使用礎(chǔ)設(shè)施即代碼來描述 Kubernetes 應(yīng)用程序的配置,這將包括三個部分:
一個 Provider對象,它告訴 Pulumi 將 Kubernetes 資源部署到 DigitalOcean 集群,而不是kubectl配置使用的默認值。Kubernetes Deployment,是部署 Docker 容鏡像的標準 Kubernetes 方法,可以部署任意數(shù)量的 Pod 副本。Kubernetes Service,這是告訴 Kubernetes 跨目標 Pod 集合進行負載均衡訪問的標準方法。
這是一個相當標準的參考架構(gòu)用于在 Kubernetes 中啟動和運行負載均衡服務(wù),要部署所有這三個,請再次打開index.ts文件:
$?nano?index.ts
文件打開后,將此代碼附加到文件末尾:
…
const?provider?=?new?kubernetes.Provider("do-k8s",?{?kubeconfig?})
const?appLabels?=?{?"app":?"app-nginx"?};
const?app?=?new?kubernetes.apps.v1.Deployment("do-app-dep",?{
????spec:?{
????????selector:?{?matchLabels:?appLabels?},
????????replicas:?5,
????????template:?{
????????????metadata:?{?labels:?appLabels?},
????????????spec:?{
????????????????containers:?[{
????????????????????name:?"nginx",
????????????????????image:?"nginx",
????????????????}],
????????????},
????????},
????},
},?{?provider?});
const?appService?=?new?kubernetes.core.v1.Service("do-app-svc",?{
????spec:?{
????????type:?"LoadBalancer",
????????selector:?app.spec.template.metadata.labels,
????????ports:?[{?port:?80?}],
????},
},?{?provider?});
export?const?ingressIp?=?appService.status.loadBalancer.ingress[0].ip;
此代碼與標準 Kubernetes 配置類似,對象及其屬性的行為是等效的,除了它與您的其他基礎(chǔ)架構(gòu)聲明一起使用 TypeScript 編寫。
進行更改后保存并關(guān)閉文件,就像之前一樣,運行 pulumi up 進行預覽,然后部署更改:
$?pulumi?up
選擇yes繼續(xù)后,CLI 將打印出詳細的狀態(tài)更新,包括有關(guān) Pod 可用性,IP 地址分配等的診斷信息,這將有助于您了解部署可能需要時間來完成或卡住的原因。
完整輸出將如下所示:
Updating?(dev):
?????Type????????????????????????????Name????????Status
?????pulumi:pulumi:Stack?????????????do-k8s-dev
?+???├─?pulumi:providers:kubernetes??do-k8s??????created
?+???├─?kubernetes:apps:Deployment???do-app-dep??created
?+???└─?kubernetes:core:Service??????do-app-svc??created
Outputs:
??+?ingressIp?:?"157.230.199.202"
Resources:
????+?3?created
????2?unchanged
Duration:?2m52s
Permalink:?https://app.pulumi.com/…/do-k8s/dev/updates/2
完成后,查看部署的 Pod 正在運行:
$?KUBECONFIG=./kubeconfig.yml?kubectl?get?pods
NAME???????????????????????????????????READY?????STATUS????RESTARTS???AGE
do-app-dep-vyf8k78z-758486ff68-5z8hk???1/1???????Running???0??????????1m
do-app-dep-vyf8k78z-758486ff68-8982s???1/1???????Running???0??????????1m
do-app-dep-vyf8k78z-758486ff68-94k7b???1/1???????Running???0??????????1m
do-app-dep-vyf8k78z-758486ff68-cqm4c???1/1???????Running???0??????????1m
do-app-dep-vyf8k78z-758486ff68-lx2d7???1/1???????Running???0??????????1m
與程序?qū)С鋈杭?kubeconfig 文件的方式kubeconfig ,此程序還會導出 Kubernetes 服務(wù)生成的負載均衡器的 IP 地址,可以使用curl端點來查看:
$?curl?$(pulumi?stack?output?ingressIp)
Welcome?to?nginx!
Welcome?to?nginx!
If?you?see?this?page,?the?nginx?web?server?is?successfully?installed?and
working.?Further?configuration?is?required.
For?online?documentation?and?support?please?refer?to
nginx.org.
Commercial?support?is?available?at
nginx.com.
Thank?you?for?using?nginx.
這里可以輕松編輯和重新部署應(yīng)用程序基礎(chǔ)設(shè)施,例如,嘗試更改 replicas: 5 為 replicas: 7 ,然后重新運行pulumi up :
$?pulumi?up
請注意,它只顯示已更改的內(nèi)容:
Previewing?update?(dev):
?????Type???????????????????????????Name????????Plan???????Info
?????pulumi:pulumi:Stack????????????do-k8s-dev
?~???└─?kubernetes:apps:Deployment??do-app-dep??update?????[diff:?~spec]
Resources:
????~?1?to?update
????4?unchanged
Do?you?want?to?perform?this?update??details
??pulumi:pulumi:Stack:?(same)
????[urn=urn:pulumi:dev::do-k8s::pulumi:pulumi:Stack::do-k8s-dev]
????~?kubernetes:apps/v1:Deployment:?(update)
????????[id=default/do-app-dep-vyf8k78z]
????????[urn=urn:pulumi:dev::do-k8s::kubernetes:apps/v1:Deployment::do-app-dep]
????????[provider=urn:pulumi:dev::do-k8s::pulumi:providers:kubernetes::do-k8s::80f36105-337f-451f-a191-5835823df9be]
??????~?spec:?{
??????????~?replicas:?5?=>?7
????????}
現(xiàn)在,您擁有一個功能齊全的 Kubernetes 集群和一個正常運行的應(yīng)用程序。啟動并運行應(yīng)用程序后,您可能需要配置要與應(yīng)用程序一起使用的自定義域名。下一步將指導您使用 Pulumi 配置 DNS。
第5步 - 創(chuàng)建 DNS 域(可選)
雖然 Kubernetes 集群和應(yīng)用程序已啟動并運行,但應(yīng)用程序的地址取決于集群自動分配 IP 地址。在調(diào)整和重新部署內(nèi)容時,此地址可能會發(fā)生變化。在此步驟中,您將看到如何將自定義 DNS 名稱分配給負載均衡器 IP 地址,以便即使您隨后更改基礎(chǔ)架構(gòu)也能保持穩(wěn)定。
注意:要完成此步驟,請確保使用 DigitalOcean 的 DNSNameservers:
ns1.digitalocean.com、ns2.digitalocean.com和ns3.digitalocean.com。
要配置 DNS,請打開index.ts文件并將以下代碼添加到文件末尾:
…
const?domain?=?new?digitalocean.Domain("do-domain",?{
????name:?"your_domain",
????ipAddress:?ingressIp,
});
此代碼創(chuàng)建一個帶有 A 記錄的新 DNS 條目,該記錄引用您的 Kubernetes 服務(wù)的 IP 地址。將此代碼段中的your_domain替換為您選擇的域名。通常需要其他子域(如www)指向 Web 應(yīng)用程序,使用 DigitalOcean DNS 記錄很容易實現(xiàn)。
…
const?cnameRecord?=?new?digitalocean.DnsRecord("do-domain-cname",?{
????domain:?domain.name,
????type:?"CNAME",
????name:?"www",
????value:?"@",
});
進行這些更改后保存并關(guān)閉文件。最后,運行 pulumi up 以部署 DNS 更改以指向現(xiàn)有應(yīng)用程序和集群:
Updating?(dev):
?????Type?????????????????????????????Name?????????????Status
?????pulumi:pulumi:Stack??????????????do-k8s-dev
?+???├─?digitalocean:index:Domain?????do-domain????????created
?+???└─?digitalocean:index:DnsRecord??do-domain-cname??created
Resources:
????+?2?created
????5?unchanged
Duration:?6s
Permalink:?https://app.pulumi.com/…/do-k8s/dev/updates/3
當 DNS 更改后,您將能夠在自定義域中訪問您的內(nèi)容:
$?curl?www.your_domain.com
您將收到類似于以下內(nèi)容的輸出:
Welcome?to?nginx!
Welcome?to?nginx!
If?you?see?this?page,?the?nginx?web?server?is?successfully?installed?and
working.?Further?configuration?is?required.
For?online?documentation?and?support?please?refer?to
nginx.org.
Commercial?support?is?available?at
nginx.com.
Thank?you?for?using?nginx.
有了這個,您就已經(jīng)成功建立了一個新的 DigitalOcean Kubernetes 集群,為其部署了一個負載均衡的 Kubernetes 應(yīng)用程序,并使用 DigitalOcean DNS 為該應(yīng)用程序的負載均衡器提供了一個穩(wěn)定的域名,所有這些都在60行代碼和一個pulumi up命令中完成的。
如果您不再需要這些資源,下一步將指導您刪除資源。
第6步 - 刪除資源(可選)
在結(jié)束本教程之前,您可能希望銷毀上面創(chuàng)建的所有資源,這將確保您不會因未使用的資源而被收取費用。如果您希望保持應(yīng)用程序正常運行,請?zhí)^此步驟。
運行以下命令以銷毀資源,不過需要小心使用它,因為它無法撤消!
$?pulumi?destroy
與up命令一樣, destroy在執(zhí)行操作之前會顯示預覽和提示:
Previewing?destroy?(dev):
?????Type?????????????????????????????????????Name?????????????Plan
?-???pulumi:pulumi:Stack??????????????????????do-k8s-dev???????delete
?-???├─?digitalocean:index:DnsRecord??????????do-domain-cname??delete
?-???├─?digitalocean:index:Domain?????????????do-domain????????delete
?-???├─?kubernetes:core:Service???????????????do-app-svc???????delete
?-???├─?kubernetes:apps:Deployment????????????do-app-dep???????delete
?-???├─?pulumi:providers:kubernetes???????????do-k8s???????????delete
?-???└─?digitalocean:index:KubernetesCluster??do-cluster???????delete
Resources:
????-?7?to?delete
Do?you?want?to?perform?this?destroy?
??yes
>?no
??details
選擇 yes 觀察刪除的信息:
Destroying?(dev):
?????Type?????????????????????????????????????Name?????????????Status
?-???pulumi:pulumi:Stack??????????????????????do-k8s-dev???????deleted
?-???├─?digitalocean:index:DnsRecord??????????do-domain-cname??deleted
?-???├─?digitalocean:index:Domain?????????????do-domain????????deleted
?-???├─?kubernetes:core:Service???????????????do-app-svc???????deleted
?-???├─?kubernetes:apps:Deployment????????????do-app-dep???????deleted
?-???├─?pulumi:providers:kubernetes???????????do-k8s???????????deleted
?-???└─?digitalocean:index:KubernetesCluster??do-cluster???????deleted
Resources:
????-?7?deleted
Duration:?7s
Permalink:?https://app.pulumi.com/…/do-k8s/dev/updates/4
可以看到上面的資源都被刪除了,DNS 條目消失了、Kubernetes 集群以及在其中運行的應(yīng)用程序都被刪除了。Permalink 仍然可用,因此您仍然可以返回并查看此的完整更新歷史記錄。如果 destroy 是一個錯誤的操作,這可以幫助您恢復,因為該服務(wù)保留所有資源的完整狀態(tài)歷史記錄。
如果您想要完整地銷毀項目,請刪除:
$?pulumi?stack?rm
您將收到如下所示的信息,要求您通過鍵入的名稱來確認刪除:
This?will?permanently?remove?the?'dev'?stack!
Please?confirm?that?this?is?what?you'd?like?to?do?by?typing?("dev"):
與刪除云基礎(chǔ)架構(gòu)資源的 destroy 命令不同,rm 命令會從 Pulumi 的權(quán)限中完全刪除的完整歷史記錄。
總結(jié)
在本教程中,除了使用 Kubernetes 應(yīng)用程序配置外,還部署了 DigitalOcean 基礎(chǔ)架構(gòu)的資源:Kubernetes 集群和具有 A、CNAME 記錄的 DNS 域。使用熟悉的編程語言 TypeScript 編寫的基礎(chǔ)設(shè)施代碼完成了這項工作,該編程語言可以與現(xiàn)有的編輯器、工具和庫一起使用,并利用現(xiàn)有的社區(qū)和軟件包。您已使用單個命令行工作流完成所有這些工作,以執(zhí)行跨應(yīng)用程序和基礎(chǔ)設(shè)施的部署。
更多有用的信息可以訪問如下幾個文檔:
探索 Pulumi 支持的全套 DigitalOcean 資源(https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/digitalocean/) 探索 Pulumi 對 Kubernetes 應(yīng)用程序的支持](https://www.pulumi.com/docs/reference/clouds/kubernetes/) 使用 CI/CD 和 Git 工作流集成自動部署(https://www.pulumi.com/docs/reference/cd/)
有關(guān)如何在您自己的項目中使用 Pulumi 將基礎(chǔ)設(shè)施作為代碼的詳細信息,請查看 Pulumi 文檔(https://www.pulumi.com/docs)、教程(https://www.pulumi.com/docs/reference/tutorials)或入門指南(https://www.pulumi.com/docs/quickstart)。
原文鏈接:https://www.digitalocean.com/community/tutorials/how-to-manage-digitalocean-and-kubernetes-infrastructure-with-pulumi
K8S進階訓練營,點擊下方圖片了解詳情

