Kubernetes 學習筆記(一):基礎概念

我的筆記,僅本人查閱使用。html

零、微服務

微服務架構專一於應用解耦合,經過將應用完全地組件化和服務化,每一個微服務只包含一個很是小的功能,好比權限管理、日誌收集等等。由這一組微服務組合起來,提供一個應用的完整功能。前端

這樣的好處是:node

  1. 開發更方便了。各微服務再也不須要關注其餘服務內的細節,直接調用 API 就行。
  2. 方便持續集成。升級只須要從新部署更新了的微服務,不須要更新整個應用。
  3. 方便拓展。遇到性能瓶頸時,只須要拓展瓶頸所在的微服務,不須要拓展整個應用。

固然,這也帶來了一些難點:nginx

  1. 業務型微服務,要儘可能無狀態化。由於只有無狀態微服務,才能夠方便地作拓展,而不會致使狀態不一致。
    • 注:而數據層服務,儘可能使用雲平臺提供的服務,而不是本身搭建。(這樣數據層的負載均衡,數據一致性,就均可以甩鍋了。)
  2. 成百上千個微服務,須要相互協做。這對運維提出了更高的要求。
  3. bug 追蹤更難了,出現 bug 可能很難定位到緣由。

因而,kubernetes 應運而生。曾經還有個比 k8s 簡單不少的 mesos 與它競爭,可是如今 k8s 已經一統天下了,mesos 將很快中止維護。。git

1、基礎概念

1. kubernetes 中的對象與資源

Kubernetes 包含若干抽象用來表示系統狀態,這些抽象被稱做 kubernetes 對象。github

而對象(Objects)的實例(Instances),被稱作資源(Resources)數據庫

對象被用於表示已部署的容器化應用和負載、與它們相關的網絡和磁盤資源以及有關集羣正在運行的其餘操做的信息。編程

基本的 kubernetes 對象包括:後端

1). Pod 容器組

Pod 是 k8s 管理的最小的可執行單元,它可包含多個容器,可是一般只有一個。api

Pod 封裝了應用程序的容器(組)、存儲資源、惟一的網絡 IP,以及一些容器運行的參數。

同一個 Pod 中的容器,就好像是跑在同一個虛擬機上的應用同樣,他們:

  1. 能夠經過 localhost 發現對方(即共享網絡)
  2. 也共享同一個 Service(也是共享網絡)
  3. 也能夠共享存儲資源

所以,若是一個多容器的應用須要如上三個特性之一,那這個應用以多容器Pod的形式來部署。好比 nginx 靜態文件服務器和 nginx_upload 文件上傳服務兩個容器,一個負責對外提供文件訪問,一個服務將文件上傳到 nginx 存儲空間中。他們顯然就須要共享同一個存儲資源。

2). Service 服務:用於爲 pod 提供穩定的網絡 ip

Service 是一種抽象方式,它將在一組Pod上運行的應用程序公開爲網絡服務。
若是一個客戶端須要使用一項特定的服務,它只須要使用該服務的名稱就能找到對應的服務提供者(Pod)。
客戶端不須要關心該服務後面的 Pod 有多少個,運行在哪些節點上,ip 是多少等等。

只要你在 kubernetes 爲這一組 Pod 定義了一個【服務】,kubernetes 就保證客戶端可以經過該服務找到對應的 Pod,不論這些 Pod 如今運行在哪些節點上。

從概念上說, Service 其實就是負載均衡,或者說反向代理。
傳統的負載均衡方式,就是用一臺 Nginx 服務器作反向代理。
可是這種方式下,雖而後端是負載均衡了,可是 Nginx 服務器卻只有一臺,它一出問題,系統就掛了。
kubernetes 的 Service 則不一樣,它在每一個節點(Node)上都部署了一個 Proxy,全部對集羣服務的訪問,都會被節點上的這個 Proxy 轉換成對服務(Service)後端容器組(Pod)的訪問。

爲了知足各種需求,kubernetes 提供了四種類型的 service:

  1. ClusterIP: (默認使用的類型)集羣內部 ip,僅用於集羣內部 Pods 的通訊。
  2. NodePort: 在每一個節點上暴露出一個靜態 ip。這樣能夠經過<節點ip>:<port>來訪問指定節點上的 Service
  3. LoadBalancer: 使用雲提供商(因此本地集羣用不了)的 Load Balancer 建立 Service,這會爲服務提供一個靜態的外網 ip。
  4. ExternalName: 將服務映射到一個域名上,如myapp.xxx.me(新出的功能)

要將一個 Pod 暴露出去,可使用 ClusterIP 以外的另外三種 Service Type。

此外,也可使用 Ingress,和 Service 不一樣的是,Ingress 提供了一個集中式的集羣網絡入口。
客戶從外網訪問 Ingress Controller,而後 Ingress Controller 根據 Ingress 規則,將請求轉發到對應的 Service 上。
集羣對外只暴露 Ingress Controller(以 NodePort 或 LoadBalancer 的方式),外部請求經過 Ingress Controller 轉發到內部對應的 Service 上。
這樣集羣就只有一個公網 IP,就是 Ingress Controller 的公網 IP,其餘全部服務都只能通在內網訪問。
Ingress 也能夠添加 TLS/SSL 協議,做爲一個 SSL/TLS Proxy.

3). Volume 數據卷:持久化數據,使數據與 Pod 分離

將動態數據映射到數據卷,這樣數據就與 Pod 分離了,Pod 的 crash/recreate 就不會形成數據的丟失。

Docker 提供的 Volume 功能比較有限,Kubernetes 提供的數據卷功能更豐富,數據卷具備明確的生命週期:與使用它的 Pod 一致。
數據卷存在於 Pod 中的任何容器以外,只要 Pod 一直存在,那 Volume 就不會被清理。Pod 的重啓也不會致使 Volume 中的數據丟失。

另外,kubernetes 有不少類型的數據卷,Pod 能夠同時掛載多個數據卷使用。

可是要注意的是,Pod 刪除後,大部分類型的 Volume 也會被清理掉。
所以 Volume 不是全部的類型的 Volume 都能用於持久化數據的!要建立一個有狀態的應用,咱們須要使用持久化數據卷(Persistent Volume)來映射數據。

4). Namespace 名字空間

名字空間使咱們可以在一個物理集羣上部署多個虛擬集羣,這樣的一個虛擬集羣,就被稱作一個名字空間。

另外,Kubernetes 包含大量的被稱做控制器(controllers) 的高級抽象。控制器基於基本對象構建並提供額外的功能和方便使用的特性。具體包括:

1). ReplicaSet 副本集

副本集的目的是爲了在任什麼時候候,都能有一組穩定的副本 Pods 可以正常運行。這一般都是爲了保證一組特定的 Pod 一直可用。

1). Deployment 部署控制器

Deployment 控制器爲 Pod 和 ReplicaSets. 提供聲明式的更新。
你爲一個 Pod 聲明一個你但願達到的狀態,而後 Deployment 控制器就會盡力使該 Pod 遷移到這個狀態去。(好比說你但願它正常運行)

3). StatefulSet 有狀態副本集

這個應該是最難的概念之一,有狀態副本集用於管理有狀態應用。StatefulSet 必須有本身的存儲標識,以保證數據能跨 Pod 地使用。

P.S. 據說 StatefulSet 用起來坑不少,因此存儲仍是儘可能買雲服務或者本身搭建存儲集羣吧。。

4). DaemonSet 守護進程集

守護進程集會保證每一個 Node 上有運行着屬於該集合的 Pod 的一個副本,而且它會自動管理這些 Pod 的增刪。當節點被添加或刪除時,DaemonSet 會自動處理 Pod 的增刪以確保每一個節點上都有該 Pod 的一個副本。

DaemonSet 常被用於運行每一個節點都須要的服務,如日誌收集(Fluentd/logstash)、存儲(ceph/glusterd)、節點監控(Promethus)等。

5). Job 任務

Job 就是一次性的任務,跑完就結束。Job 會確保這個任務正常地終止,不然 Job 會被從新啓動。

此外還有 CronJob,定時執行的 Job

2. kubernetes 控制面

2.1. 節點

kubernetes 是一個「集羣操做系統」,既然是集羣,天然是會包含多種多樣的節點。kubernetes 有兩種節點:

  1. 主節點(master):主節點是集羣的控制中心,它上面運行了以下幾個組件:
    1. kube-apiserver:集羣控制層的前端,咱們使用 kubectl 時就是一直在與它打交道。
    2. etcd:存放集羣數據的鍵值數據庫。(確保該數據有備份)
    3. kube-scheduler:調度器,負責把新建的 pod 選擇找個坑(node)「埋」好,它會考慮到各類因素。
    4. kube-controller-manager:控制器都由它運行。
    5. cloud-controller-manager:負責管理與下層的雲服務提供商交互的控制器。(實驗特性)
  2. 工做節點(Node):提供 kubernetes 運行環境,全部的 pods 都運行在工做節點上。它包含以下幾個組件:
    1. kubelet:在每一個節點上運行的代理,它確保容器在 pod 中運行。
    2. kube-proxy:它經過維護一組主機上的網絡規則和鏈接轉發,實現了 kubernetes 的網絡抽象。
    3. 容器運行時:Docker

2.2. 附加組件(Addons)

附加組件使用 kubernetes 的資源來實現一些特性。

  1. CoreDNS
  2. Kubernetes Dashboard(Web UI)
  3. Ingress Controller: 提供網關同樣的集羣入口。

2、基本使用

0. 安裝阿里版的 minikube: AliyunContainerService/minikube

學了些理論,到底仍是要實際使用過才能真正理解。這就須要一個可用的 kubernetes 集羣。

安裝一個 k8s 的入門學習環境,最好最簡單的選擇,官方的 minikube 是其中之一。

minikube 是一個官方推出的單節點 k8s 集羣,適用於本地學習/開發。

可是因爲某種你們都曉得的緣由,官方的 minikube 在國內是訪問不到的,因此建議你們安裝阿里版的 minikube: AliyunContainerService/minikube,阿里官方的教程就很詳細。

1. 在 kubernetes 上運行一個 nginx 應用

minikube 是一個 k8s 集羣,前面介紹過,k8s 集羣是經過一個 apiserver 提供對集羣的操控功能的。

要對一個 k8s 集羣進行操做,就須要去訪問這個 apiserver,官方提供了一個命令行工具:kubectl,這個工具將 restful api 包裝成了方便易用的命令行工具。

下面就來學習一下 kubectl 的基本使用。

P.S. 既然是 restful api,固然就能夠經過任何實現了 http 協議的工具訪問。kubernetes 官方提供了各類語言的客戶端包供使用:https://github.com/kubernetes-client

1.1 kubectl run

首先使用 kubectl run 在集羣上運行指定的鏡像。

kubectl run nginx --image=nginx:1.10.0

上面這條命令會從 nginx 鏡像建立一個容器(單容器的 Pod),而後再建立一個 Deployment 來管理這個 Pod.

1.2 查看 Pods

接下來就能夠經過 kubectl get pods 查看到 kubectl run 建立的 Pod 了。

kubectl get pods

1.3 從外部訪問集羣的 Pods

如今 nginx 已經跑起來了,可是咱們不知道它跑在集羣的哪一個節點上,並且咱們也沒爲它指定任何端口映射,咱們沒辦法訪問到它。

爲了訪問 nginx,咱們須要給它分配一個固定的地址,不論它跑在哪一個 k8s 節點上,咱們都應該能經過這個地址訪問到它。k8s 經過 service 提供了這個功能。

能夠經過 kubectl expose 命令,爲剛剛建立好的 Pod/Depolyment 建立一個 Service,這樣就能訪問到它了。

kubectl expose deployments nginx --port=80 --type LoadBalancer

若是是在阿里雲上跑這個命令,Service 會被分配到一個公網 ip。但 minikube 是本地單節點集羣,它的 LoadBalancer 只能分配一個局域網 ip。
並且不能直接經過 kubectl get service 看到局域網的 ip 地址。須要經過 minikube service <schema>:<service-name>:<port> 訪問該服務

參考

問題

相關文章
相關標籤/搜索