東莞建站網(wǎng)站模板站長(zhǎng)查詢工具
GCP(Google Cloud Platform)是Google云,為其內(nèi)部(Google search、Gmail、YouTube等)和外部客戶提供IaaS、PaaS以及Serverless computing等云服務(wù)的平臺(tái)。
本文將帶領(lǐng)你走進(jìn)GCP,并深入體驗(yàn)其產(chǎn)品功能,感受Google云的產(chǎn)品設(shè)計(jì)理念以及相關(guān)架構(gòu)思想。從而可以淬其精華,為我所用。本文的主要內(nèi)容如下:
1. 注冊(cè)Free Trial賬號(hào)
云的產(chǎn)品體系非常龐大,注冊(cè)一個(gè)GCP的Free Trial賬號(hào)非常有必要。有了賬號(hào),我們可以解鎖大部分GCP功能。注冊(cè)不難,前往cloud.google.com按照要求注冊(cè)就可以。
但有一點(diǎn)需要注意,在注冊(cè)過程中,需要進(jìn)行信用卡預(yù)授權(quán)(Authorize)300美元,這個(gè)錢試用期之后會(huì)退給你。試用期限是3個(gè)月,所以這3個(gè)月中所有的資源消耗都是免費(fèi)的,當(dāng)然這些資源也是有限的,不過用來(lái)運(yùn)行一些demo和跑一些tutorial還是足夠用了。
2.在GKE部署hello-app
2.1 根據(jù)tutorial完成hello-app的部署
這是一個(gè)Learn Tutorial,如下圖所示,即它會(huì)用頁(yè)面引導(dǎo)的方式,手把手教你怎么在GKE里面部署一個(gè)web應(yīng)用。
2.2 體驗(yàn)autoscale
按照上面的tutorial部署完web-app之后,你會(huì)發(fā)現(xiàn)初始時(shí)這個(gè)deployment的replicas是3,但是過一段時(shí)間就會(huì)變成1。這是因?yàn)閍utoscale這個(gè)插件在搞鬼,當(dāng)它檢測(cè)到3個(gè)pods的CPU使用率都小于80%的時(shí)候,它就會(huì)將pods的數(shù)量從3縮容到1。
這里直接修改AutoScaler配置可能會(huì)報(bào)不能有兩個(gè)AutoScaler錯(cuò)誤,這時(shí)可以先Delete再Save就可以了。
你也可以使用kubectl get hpa來(lái)查看autoscaler情況,對(duì)于我們這個(gè)案例來(lái)說(shuō),將顯示如下內(nèi)容,其中minipods是2正是我們上面在console上設(shè)置的值。NAME?????????????????REFERENCE??????????????TARGETS???MINPODS???MAXPODS???REPLICAS???AGE
hello-app-hpa-ryrw???Deployment/hello-app???0%/80%????2?????????5?????????2??????????4h41m
其中hpa是CRD對(duì)象HorizontalPodAutoscaler,更多關(guān)于autoscale的內(nèi)容可以參看autoscale文檔。
2.3 更新hello-app
在這個(gè)tutorial里面,這個(gè)hello-app的代碼是從github上clone下來(lái)的,在cloud shell中的路徑是kubernetes-engine-samples/hello-app,這是一個(gè)非常簡(jiǎn)單的go http server,按照tutorial我們是打了一個(gè)hello-app v1的鏡像,然后我們?cè)趗s-west4這個(gè)Region創(chuàng)建了一個(gè)Artifact Repository,并把hello-app v1鏡像push到這個(gè)Repository了。
現(xiàn)在,我們可以增加一個(gè)計(jì)數(shù)功能,打一個(gè)v2版本的新image,然后對(duì)workload進(jìn)行滾動(dòng)更新,其具體步驟如下:
修改kubernetes-engine-samples/hello-app/main.go代碼:
var?count?intfunc?hello(w?http.ResponseWriter,?r?*http.Request)?{log.Printf("Serving?request:?%s",?r.URL.Path)host,?_?:=?os.Hostname()count++fmt.Fprintf(w,?"Visited?count:?%d\n",?count)fmt.Fprintf(w,?"Version:?2.0.0\n")fmt.Fprintf(w,?"Hostname:?%s\n",?host)
}
可以在本地通過go run main.go啟動(dòng)服務(wù),然后運(yùn)行命令curl localhost:8080測(cè)試一下改動(dòng)是否ok
測(cè)試沒有問題,通過下面命令重新打v2版本的docker鏡像
docker?build?-t?${REGION}-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2?.#?或者替換變量
docker?build?-t?us-west4-docker.pkg.dev/my-second-project-398309/hello-repo/hello-app:v2?.
注意:其中REGION和PROJECT_ID這兩個(gè)環(huán)境變量是在2.1的過程中設(shè)置過的,可以通過echo ${PROJECT_ID}驗(yàn)證一下,因?yàn)槿绻鹀loud shell重新連接的話,環(huán)境變量會(huì)丟失,需要重新設(shè)置。
將新的image上傳到我們項(xiàng)目的repository
docker?push?${REGION}-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2#?或者替換變量
docker?push?us-west4-docker.pkg.dev/my-second-project-398309/hello-repo/hello-app:v2
5. 進(jìn)行滾動(dòng)更新(Rolling update)
在kubenetes的環(huán)境里,我們一般會(huì)通過修改yaml文件,將里面的container使用的image修改成我們上面上傳的v2版本,然后kubectl apply一下,控制面會(huì)幫助我們完成更新。因?yàn)槲覀冞@個(gè)tutorial是基于GUI console的,所以我們也可以在界面上完成更新操作。具體就是點(diǎn)擊Actions里面的Rolling update,然后將Container Image換成我們的v2版本,點(diǎn)擊update就可以完成更新任務(wù)。
完成這些動(dòng)作之后,通過訪問hello-app-service暴露的公網(wǎng)endpoint,訪問一下,如果返回頁(yè)面上有統(tǒng)計(jì)訪問計(jì)數(shù)功能,說(shuō)明我們的更新是完成了。
3. 體驗(yàn)Terraform
3.1 基礎(chǔ)概念
Terraform是一個(gè)IT基礎(chǔ)架構(gòu)自動(dòng)化編排工具,可以用代碼來(lái)管理維護(hù)IT資源。它編寫了描述云資源拓?fù)涞呐渲梦募械幕A(chǔ)結(jié)構(gòu),例如虛擬機(jī)、存儲(chǔ)賬戶和網(wǎng)絡(luò)接口。也就是我們通常說(shuō)的IAC(Infrastructure As Code)。
其中Provider和Resource這兩個(gè)最重要的概念,我們要理解。
Provider:Terraform是一個(gè)框架,它可以支撐所有的云廠商,不同的云廠商是不同的Provider。
Resource:Resource是infrastructure的各類組件,可以是物理組件比如服務(wù)器,也可以是邏輯組件比如安全組等。在描述Resource block的時(shí)候,有兩個(gè)String字段,它們分別表示Resource type和Resource name。比如:
resource?"google_compute_network"?"vpc_network"?{name?=?"terraform-network"
}
The resource type is google_compute_network and the name is vpc_network. The prefix of the type maps to the name of the provider. In the example configuration, Terraform manages the google_compute_network resource with the google provider. Together, the resource type and resource name form a unique ID for the resource. For example, the ID for your network is google_compute_network.vpc_network。
如果想要更近一步了解provider和resource的概念,可以查看hashicorp的官方文檔。如果需要查看GCP的terraform Resource定義可以查看GCP的Terraform文檔。同樣,華為云也有自己的Terraform指南。
接下來(lái),讓我們根據(jù)Terraform Tutorial一起體驗(yàn)一下其強(qiáng)大的IaC功能。
3.2 使用Terraform創(chuàng)建VPC
根據(jù)tutorial,我們要新建一個(gè)main.tf文件,首先創(chuàng)建VPC網(wǎng)絡(luò)。具體內(nèi)容參考tutorial
3.3 使用Terraform創(chuàng)建虛機(jī)
然后是創(chuàng)建Compute Engine虛擬機(jī)資源,具體內(nèi)容參考tutorial
此時(shí)我們的main.tf內(nèi)容如下:
#?Create?VPC?network?and?subnet
resource?"google_compute_network"?"vpc_network"?{name????????????????????=?"my-custom-mode-network"auto_create_subnetworks?=?falsemtu?????????????????????=?1460
}resource?"google_compute_subnetwork"?"default"?{name??????????=?"my-custom-subnet"ip_cidr_range?=?"10.0.1.0/24"region????????=?"us-west1"network???????=?google_compute_network.vpc_network.id
}
3.4 執(zhí)行Terraform
執(zhí)行一般需要3步:
第一步是使用terraform init來(lái)添加必要的插件并構(gòu)建.terraform目錄。
第二步使用terraform plan來(lái)驗(yàn)證main.tf的語(yǔ)法是否正確,顯示將要?jiǎng)?chuàng)建的資源。
第三步是使用terraform apply來(lái)實(shí)施資源的創(chuàng)建。
注意:因?yàn)槲覀兪褂玫氖莊ree trial賬號(hào),能創(chuàng)建的資源非常有限,可能會(huì)出現(xiàn)配額不足的情況。此時(shí),我們可以通過Quota配額管理,來(lái)查看配額使用情況。如果是配額原因的話,可以釋放資源再嘗試。
3.5 用Terraform創(chuàng)建一個(gè)可部署Web應(yīng)用的環(huán)境
接下來(lái),我們會(huì)創(chuàng)建一個(gè)web應(yīng)用,將其部署到虛擬機(jī)。這需要我們做以下準(zhǔn)備:
添加自定義SSH防火墻規(guī)則,可以讓我們遠(yuǎn)程SSH到虛擬機(jī)。對(duì)于華為云來(lái)說(shuō),就是安全組(Security Group)
#?在原來(lái)main.tf的基礎(chǔ)上,追加以下內(nèi)容,在執(zhí)行terraform apply的時(shí)候,
#?已創(chuàng)建的資源會(huì)被ignore,只會(huì)創(chuàng)建新添加的resource#?add?ssh?firewall?rule
resource?"google_compute_firewall"?"ssh"?{name?=?"allow-ssh"allow?{ports????=?["22"]protocol?=?"tcp"}direction?????=?"INGRESS"network???????=?google_compute_network.vpc_network.idpriority??????=?1000source_ranges?=?["0.0.0.0/0"]target_tags???=?["ssh"]
}
使用ssh登錄到flask-vm的虛擬機(jī)
構(gòu)建Flask應(yīng)用
創(chuàng)建app.py文件
寫一個(gè)簡(jiǎn)單hello world http server
from?flask?import?Flask app?=?Flask(__name__)@app.route('/') def?hello_cloud():return?'Hello?Terraform!'app.run(host='0.0.0.0')
運(yùn)行python3 app.py。Flask默認(rèn)為通過localhost:5000暴露服務(wù)
在虛擬機(jī)上開放5000端口
為了執(zhí)行上面的配置,我們需要在原來(lái)main.tf的基礎(chǔ)上追加以下內(nèi)容,然后執(zhí)行terraform apply。
#?expose?5000?port?
resource?"google_compute_firewall"?"flask"?{name????=?"flask-app-firewall"network?=?google_compute_network.vpc_network.idallow?{protocol?=?"tcp"ports????=?["5000"]}source_ranges?=?["0.0.0.0/0"]
}#?A?variable?for?extracting?the?external?IP?address?of?the?VM
output?"Web-server-URL"?{value?=?join("",["http://",google_compute_instance.default.network_interface.0.access_config.0.nat_ip,":5000"])
}
然后我們部署一個(gè)簡(jiǎn)單的Python Flask應(yīng)用來(lái)驗(yàn)證我們的web server是否OK,至此我們整個(gè)實(shí)驗(yàn)也就完成了。
4. 實(shí)現(xiàn)GitOps形式的CICD
4.1 基本概念
Cloud build是GCP的提供的serverless CI/CD平臺(tái),可以在上面完成代碼托管、構(gòu)建、artifiact registry,測(cè)試和部署等ops工作。
術(shù)語(yǔ) GitOps 一詞由 Weaveworks 首先提出,如果說(shuō)DevOps是一種理念的話,那么GitOps則是對(duì)DevOps理念的落地實(shí)踐,主要是通過IaC(Infrastructure as Code)的方式將基礎(chǔ)實(shí)施創(chuàng)建,CI/CD等運(yùn)維動(dòng)作“代碼化”(比如Cloud build的配置,Terraform的配置,kubenetes的配置等),然后用Git對(duì)這些配置腳本進(jìn)行管理。
因此,實(shí)現(xiàn)GitOps的前提條件就是我們的infrastructure要可以聲明式管理(Be declaratively managed)。
4.2 實(shí)現(xiàn)概述
本實(shí)驗(yàn)的參考Tutorial,本教程使用兩個(gè) Git 代碼庫(kù):
app 代碼庫(kù):包含應(yīng)用本身的源代碼
env 代碼庫(kù):包含 Kubernetes 部署的清單
我們將 app 代碼庫(kù)和 env 代碼庫(kù)分開,是因?yàn)樗鼈兙哂胁煌纳芷诤陀猛尽pp 代碼庫(kù)的主要用戶是真人,此代碼庫(kù)專用于特定應(yīng)用。env 代碼庫(kù)的主要用戶是自動(dòng)化系統(tǒng)(例如 Cloud Build),并且此代碼庫(kù)可能由多個(gè)應(yīng)用共享。env 代碼庫(kù)可以有多個(gè)分支,每個(gè)分支映射到特定環(huán)境。
這里為了演示,我們只有一個(gè)環(huán)境,真實(shí)場(chǎng)景可以有多個(gè)環(huán)境。
4.3 用Cloud Build實(shí)現(xiàn)GitOps CI
所謂的CI,Continuous integration refers to the build and unit testing stages of the software release process. Every revision that is committed triggers an automated build and test.
在GCP里面,是通過觸發(fā)器(Trigger)來(lái)感知GIT里面提交代碼的變化,然后在這個(gè)trigger上配置Cloud Build流水線配置文件:
steps:
#?This?step?runs?the?unit?tests?on?the?app
-?name:?'python:3.7-slim'id:?Testentrypoint:?/bin/shargs:-?-c-?'pip?install?flask?&&?python?test_app.py?-v'#?This?step?builds?the?container?image.
-?name:?'gcr.io/cloud-builders/docker'id:?Buildargs:-?'build'-?'-t'-?'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild:$SHORT_SHA'-?'.'#?This?step?pushes?the?image?to?Artifact?Registry
#?The?PROJECT_ID?and?SHORT_SHA?variables?are?automatically
#?replaced?by?Cloud?Build.
-?name:?'gcr.io/cloud-builders/docker'id:?Pushargs:-?'push'-?'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild:$SHORT_SHA'
上面的腳本,實(shí)際上就是一個(gè)典型的CI流程,即測(cè)試、打鏡像包、上傳鏡像。
4.4 用Cloud Build實(shí)現(xiàn)GitOps CD
所謂的CD(Continuous Delivery),簡(jiǎn)單來(lái)說(shuō)就是在CI的基礎(chǔ)上多出了deployment部署的動(dòng)作,在tutorial中這個(gè)動(dòng)作也是通過git代碼倉(cāng)庫(kù)觸發(fā)的。
為達(dá)此目的,我們需要新建一個(gè)代碼倉(cāng),同樣我們需要給這個(gè)代碼倉(cāng)配置一個(gè)觸發(fā)器,這個(gè)觸發(fā)器的作用就是在接收到新的鏡像變化時(shí),將其部署到GKE集群。然而這個(gè)觸發(fā)動(dòng)作,需要我們?cè)谥癈I cloudbuild.yaml后面追加以下內(nèi)容,其主要職責(zé)就是將新的鏡像寫入CD的配置文件,并push到CD的配置代碼倉(cāng),從而觸發(fā)CD執(zhí)行。
#?This?step?clones?the?hello-cloudbuild-env?repository
-?name:?'gcr.io/cloud-builders/gcloud'id:?Clone?env?repositoryentrypoint:?/bin/shargs:-?'-c'-?|gcloud?source?repos?clone?hello-cloudbuild-env?&&?\cd?hello-cloudbuild-env?&&?\git?checkout?candidate?&&?\git?config?user.email?$(gcloud?auth?list?--filter=status:ACTIVE?--format='value(account)')#?This?step?generates?the?new?manifest
-?name:?'gcr.io/cloud-builders/gcloud'id:?Generate?manifestentrypoint:?/bin/shargs:-?'-c'-?|sed?"s/GOOGLE_CLOUD_PROJECT/${PROJECT_ID}/g"?kubernetes.yaml.tpl?|?\sed?"s/COMMIT_SHA/${SHORT_SHA}/g"?>?hello-cloudbuild-env/kubernetes.yaml#?This?step?pushes?the?manifest?back?to?hello-cloudbuild-env
-?name:?'gcr.io/cloud-builders/gcloud'id:?Push?manifestentrypoint:?/bin/shargs:-?'-c'-?|set?-x?&&?\cd?hello-cloudbuild-env?&&?\git?add?kubernetes.yaml?&&?\git?commit?-m?"Deploying?image?us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild:${SHORT_SHA}Built?from?commit?${COMMIT_SHA}?of?repository?hello-cloudbuild-appAuthor:?$(git?log?--format='%an?<%ae>'?-n?1?HEAD)"?&&?\git?push?origin?candidate
此時(shí)我們已經(jīng)將kubernetes.yaml寫入hello-cloudbuild-env的candidate分支。為了執(zhí)行部署動(dòng)作,我們需要新建另一個(gè)觸發(fā)器(Trigger),這里我們將其命名為cloudbuild-delivery.yaml,其內(nèi)容如下:
#?[START?cloudbuild-delivery]
steps:
#?This?step?deploys?the?new?version?of?our?container?image
#?in?the?hello-cloudbuild?Kubernetes?Engine?cluster.
-?name:?'gcr.io/cloud-builders/kubectl'id:?Deployargs:-?'apply'-?'-f'-?'kubernetes.yaml'env:-?'CLOUDSDK_COMPUTE_REGION=us-central1'-?'CLOUDSDK_CONTAINER_CLUSTER=hello-cloudbuild'#?This?step?copies?the?applied?manifest?to?the?production?branch
#?The?COMMIT_SHA?variable?is?automatically
#?replaced?by?Cloud?Build.
-?name:?'gcr.io/cloud-builders/git'id:?Copy?to?production?branchentrypoint:?/bin/shargs:-?'-c'-?|set?-x?&&?\#?Configure?Git?to?create?commits?with?Cloud?Build's?service?accountgit?config?user.email?$(gcloud?auth?list?--filter=status:ACTIVE?--format='value(account)')?&&?\#?Switch?to?the?production?branch?and?copy?the?kubernetes.yaml?file?from?the?candidate?branchgit?fetch?origin?production?&&?git?checkout?production?&&?\git?checkout?$COMMIT_SHA?kubernetes.yaml?&&?\#?Commit?the?kubernetes.yaml?file?with?a?descriptive?commit?messagegit?commit?-m?"Manifest?from?commit?$COMMIT_SHA$(git?log?--format=%B?-n?1?$COMMIT_SHA)"?&&?\#?Push?the?changes?back?to?Cloud?Source?Repositorygit?push?origin?production
#?[END?cloudbuild-delivery]
這樣,當(dāng)hello-cloudbuild-env這個(gè)代碼倉(cāng)接收到代碼提交,就會(huì)觸發(fā)部署動(dòng)作,把最新的docker鏡像部署到auto-pilot集群,并且可以通過service訪問。一切正常的話,最后會(huì)把最新部署腳本寫入production分支。
4.5 結(jié)果驗(yàn)證
修改代碼
sed -i 's/Hello Cloud Build/Hello huawei/g' app.pysed -i 's/Hello Cloud Build/Hello huawei/g' test_app.pysed -i 's/Hello huawei/Hello Cloud Build/g' app.pysed -i 's/Hello huawei/Hello Cloud Build/g' test_app.py
提交變更,或者M(jìn)R
git add?app.py?test_app.py
git commit -m “Hello Cloud Build”
git push查看CICD
https://console.cloud.google.com/cloud-build/builds查看容器部署 kubectl get pods
查看service:http://34.172.165.210/
5?GKE Autopilot
可以根據(jù)創(chuàng)建Autopilot集群指南來(lái)創(chuàng)建Autopilot集群。
可以根據(jù)部署無(wú)狀態(tài)負(fù)載指南來(lái)部署一個(gè)無(wú)狀態(tài)應(yīng)用。
我們還是選用2.1中創(chuàng)建的Docker鏡像來(lái)部署,我們可以在Cloud Shell中創(chuàng)建一個(gè)deployment.yaml,其內(nèi)如如下:
apiVersion: apps/v1kind: Deploymentmetadata:name: my-appspec:replicas: 3selector:matchLabels:run: my-apptemplate:metadata:labels:run: my-appspec:containers:- name: hello-appimage: us-west1-docker.pkg.dev/polynomial-text-398202/hello-repo/hello-app:v1
然后使用kubectl apply -f deployment.ymal進(jìn)行部署,然后用kubectl get pods查看部署情況:
NAME READY STATUS RESTARTS AGE
my-app-7fcfbd5c8d-55jcf 1/1 Running 0 61m
my-app-7fcfbd5c8d-lrxcn 1/1 Running 0 61m
my-app-7fcfbd5c8d-wfzzz 1/1 Running 0 61m