我們討論了最近的微服務(wù)趨勢,以及伴隨微服務(wù)架構(gòu)可能出現(xiàn)的一些復(fù)雜問題。在接下來的幾周內(nèi),我們將深入探討這個問題。我們將探討不同設(shè)計選擇中固有的權(quán)衡,以及可以采取哪些措施來緩解這些問題。
然而,在深入之前,我認為花一點時間來了解當(dāng)今微服務(wù)中的最新技術(shù)狀態(tài)是有意義的。我們首先回顧一下領(lǐng)先的容器管理和服務(wù)編排框架Kubernetes。 如今,Kubernetes和微服務(wù)幾乎是同義詞,所以最好徹底了解它們是如何組合在一起的。
Kubernetes
與微服務(wù)本身非常相似,容器近年來已成為現(xiàn)代可擴展架構(gòu)中不可或缺的一部分。與微服務(wù)一樣,容器已經(jīng)流行起來,因為它們?yōu)殚_發(fā)過程提供了真正的好處:它們可靠,易于擴展,并提供了一個很好的抽象,隔離了Web服務(wù)的核心組件。
特別是,一種容器化技術(shù)已遠遠超過其他技術(shù)。 這是正確的,我們的微服務(wù)之旅的下一站是看看Kubernetes和Docker,它是現(xiàn)代微服務(wù)設(shè)施的主力。簡單地說,Kubernetes是現(xiàn)代基于容器的DevOps和微服務(wù)以及容器攜手并進的黃金標(biāo)準(zhǔn)。

隨著容器化技術(shù)的興起,有幾種競爭技術(shù)可用于管理大型Docker部署和基于容器的服務(wù)。你可能還記得其中一些退役的解決方案:Docker Swarm,Apache Mesos,OpenStack Magnum等。然而,現(xiàn)在Kubernetes已經(jīng)淘汰了競爭對手。它是唯一的AWS,Azure,Google Cloud原生自帶,同時RedHat和Pivotal等許多私有云供應(yīng)商也提供的容器化解決方案。
Kubernetes能夠如此迅速地獲得如此多的優(yōu)勢,根因在于它能夠?qū)⑴渲门c編排分開。這種復(fù)雜程度應(yīng)該不足為奇,因為Kubernetes來自谷歌的內(nèi)部項目Borg,它是谷歌在分布式系統(tǒng)上的數(shù)十年經(jīng)驗總結(jié)。使用Kubernetes,你可以指定服務(wù)的外觀,實例數(shù),冗余類型,服務(wù)所在位置。然后,該工具自動計算從現(xiàn)狀到創(chuàng)建該服務(wù)需要進行哪些更改??梢园阉胂蟪蒘QL,你沒有指定數(shù)據(jù)庫如何添加或轉(zhuǎn)換每個行。你可以指定數(shù)據(jù)的外觀,數(shù)據(jù)庫會指出如何實現(xiàn)數(shù)據(jù)。 Kubernetes也是一樣的。
Kubernetes特點
Kubernetes提供的是將容器視為服務(wù)定義的能力。Kubernetes可以處理純?nèi)萜?。即使你想在不進入微服務(wù)領(lǐng)域的情況下只部署容器,Kubernetes在管理和部署方面也能為你提供很多幫助。你在群集中的服務(wù)器上安裝Kubernetes軟件,Kubernetes主進程將自動部署你的軟件。
除了基本的容器外,Kubernetes還可以使用它所稱的Pod。 Pod是由一個或多個服務(wù)組成的單獨定義。 Pod可以包含從單獨運行的單個服務(wù)器到完整的多容器服務(wù),例如數(shù)據(jù)庫容器與鍵值存儲和一個包含在一起的http服務(wù)器相結(jié)合。 Pod是Kubernetes的基本構(gòu)建塊。
最后一個元素是服務(wù)。在Kubernetes中,服務(wù)就像是將Pod組合到應(yīng)用程序中的配方。雖然Pod是具有生命周期的具體部署,但服務(wù)更抽象。它描述了一個單獨的組件,如后端或數(shù)據(jù)庫。
結(jié)合所有這些能力的是Kubernetes命令行工具kubectl。雖然Kubernetes提供的抽象很棒,但命令行工具非常強大,允許你使用kubectl命令描述對架構(gòu)的復(fù)雜更改??偠灾?,kubectl CLI工具包含近50種不同的命令,用于處理在修改基于容器的微服務(wù)部署過程中出現(xiàn)的所有情況(你總會出現(xiàn)出錯的時候)。
動手實踐一番
雖然高層次描述很有幫助,但實際上沒有什么比實際部署Kubernetes服務(wù)能更好的理解它的了。我們在這里沒有做任何高深的東西,只是展示如何部署一個簡單的“Hello World”服務(wù),但它應(yīng)該是有益的。
我們在Go中編寫了一個簡單的服務(wù)器,用“Hello World”響應(yīng)http請求。代碼非常簡單:
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func handler(w http.ResponseWriter, r *http.Request) {
log.Print("Hello world received a request.")
version := os.Getenv("VERSION")
if version == "" {
version = "v1"
}
log.Println(version)
fmt.Fprintf(w, "Hello world %s\n",version)
}
func main() {
log.Print("Hello world sample started.")
http.HandleFunc("/api/hello", handler)
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
運行它的第一步是將其構(gòu)建到Docker容器中。為此,我們從基礎(chǔ)Go Docker鏡像開始構(gòu)建以下Dockerfile。
# Use the official Golang image to create a build artifact.
# https://hub.docker.com/_/golang
FROM golang as builder
# Copy local code to the container image.
WORKDIR /go/src/github.com/haseebh/hello-world
COPY . .
RUN go build -o helloworld-v1 main/helloworld-v1.go
# Use a Docker multi-stage build to create a lean production image.
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM alpine
COPY --from=builder /go/src/github.com/haseebh/hello-world-v1 /helloworld-v1
ENV PORT 8080
# Run the web service on container startup.
CMD ["/helloworld-v1"]
現(xiàn)在我們只需要構(gòu)建它。 選擇一個鏡像tag,然后運行以下兩個Docker命令來構(gòu)建和保存鏡像:
# Build the container on your local machine
docker build -t <image-tag> .
# Push the container to docker registry
docker push <image-tag>
在我們部署之前還有一步。雖然我們已經(jīng)定義了將進入我們的Pod的內(nèi)容,但我們還沒有定義我們的服務(wù)。讓我們做一個簡單的服務(wù)定義,稱為Hello Service。我們將它保存在hello-service.yml服務(wù)定義文件中。
apiVersion: v1
kind: Service
metadata:
name: helloworld-v1
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: helloworld-v1
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
labels:
app: helloworld-v1
spec:
replicas: 1
selector:
matchLabels:
app: helloworld-v1
template:
metadata:
labels:
app: helloworld-v1
spec:
containers:
- name: helloworld-kubernetes
# replace <image-tag> with your actual image
image: <image-tag>
ports:
- containerPort: 8080
現(xiàn)在我們已經(jīng)擁有了所需的一切。我們的鏡像已經(jīng)構(gòu)建,我們已經(jīng)根據(jù)它定義了一項服務(wù)?,F(xiàn)在我們終于可以使用Kubernetes來部署它了。我們將使用kubectl命令行工具將其部署在我們的集群上:
kubectl apply -f helloworld-go-v1.yaml
要獲取服務(wù)負載均衡器IP,請運行以下命令:
kubectl get svc helloworld-v1 -o wide
記下外部IP。
現(xiàn)在,當(dāng)我們訪問負載均衡器地址時,我們可以看到已部署的服務(wù)。它并不多,但“Hello World”向我們展示了這一切都奏效了!
關(guān)鍵組件
構(gòu)建此服務(wù)使我們能夠演示大多數(shù)主要的Kubernetes組件。首先,我們布置了Dockerfile來為服務(wù)創(chuàng)建代碼。要在Kubernetes中實際創(chuàng)建服務(wù),我們需要使用YAML來定義它。我們的定義采用我們定義的鏡像并提供一些關(guān)鍵信息:應(yīng)該部署的位置,版本以及其他配置信息。
之后,我們在Pod上部署了該服務(wù)。在Kubernetes模型中,Pod與容器密切相關(guān)。許多部署(如我們的部署)使用單個Pod進行服務(wù)。嚴格來說,Kubernetes不管理容器,它管理。有時這些容器與Pod有一對一的關(guān)系,有時候有多個容器關(guān)聯(lián)到一個Pod。
最后,我們看到了編排的原則。在定義了我們希望如何部署API之后,我們只是將配置文件推送到Kubernetes并完成其余工作。使用kubectl,我們能夠指定我們想要的架構(gòu),Kubernetes負責(zé)其余的工作。當(dāng)我們稍后查看更復(fù)雜的示例時,通過多個版本和復(fù)雜的部署,我們將更清楚地看到這個簡單想法的強大功能。
深入了解
部署簡單的服務(wù)只是一個開始。Kubernetes原生支持微服務(wù),它能用很好的方式來部署基本的,甚至更復(fù)雜的微服務(wù)架構(gòu),而不會有太多的麻煩。但要真正利用微服務(wù)的可擴展性,你還需要知道更多。
在下一篇文章中,我們將介紹Istio。通過微服務(wù)方法,我們能夠?qū)我坏膽?yīng)用程序分解為多種服務(wù)。
最后在打一波廣告:
如果你也想在IT行業(yè)拿高薪,可以參加我們的訓(xùn)練營課程,選擇最適合自己的課程學(xué)習(xí),技術(shù)大牛親授,8個月后,進入名企拿高薪。我們的課程內(nèi)容有:Java工程化、高性能及分布式、高性能、深入淺出。高架構(gòu)。性能調(diào)優(yōu)、Spring,MyBatis,Netty源碼分析和大數(shù)據(jù)等多個知識點。如果你想拿高薪的,想學(xué)習(xí)的,想就業(yè)前景好的,想跟別人競爭能取得優(yōu)勢的,想進阿里面試但擔(dān)心面試不過的,你都可以來。以下截圖屬于一小部分。

以上內(nèi)容免費領(lǐng)取傳送門:https://shimo.im/docs/BYMjlkYOqM08diLI
