k8s基本原理

分享的內容包括

  • k8s demo部署示例
  • k8s基本架構和原理
  • k8s資源對象
  • k8s網絡模型
  • 總結

k8s就像圖中的貨船,管理各類集裝箱(容器)前端

裝滿集裝箱的船

一. k8s demo部署示例

說明

  • 先經過一個hello world程序直觀感覺一下k8s
  • 程序部署在宿主機,容器和k8s三種環境,對比他們的差別
  • 代碼大體是這個樣子
    @RestController
    public class K8sDemoController {
    
        @GetMapping("/hello")
        public String hello(){
            return "hello k8s demo.";
        }
    }
    複製代碼

1. 宿主機上如何運行

  1. mvn編譯代碼打成jar包
  2. 執行java -jar k8s-demo.jar &
  3. 瀏覽器中輸入 http://10.1.69.101:8080/hello 地址訪問服務

2. Docker容器上如何運行

  1. mvn編譯代碼打成jar包
  2. 將jar包打成docker鏡像
  3. 執行docker run --name k8s-demo -d -p 8080:8080 k8s-demo:0.0.1-SNAPSHOT
  4. 瀏覽器中輸入 http://10.1.69.101:8080/hello 地址訪問服務

3. 在k8s中如何運行

這一步大體感覺一下yaml的樣子,不須要關心腳本的細節,後面介紹資源時會細說。只須要有個大致的印象,部署一個k8s服務的基本流程。java

  1. mvn編譯代碼打成jar包
  2. 將jar包打成docker鏡像
  3. 構建一個運行服務的yaml文件
  4. 執行kubectl apply -f k8s-demo.yaml
  5. 瀏覽器中輸入 www.k8s-demo.com/hello 地址訪問服務
  • yaml文件內容
# 文件名爲k8s-demo.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: k8s-demo
 namespace: spring-test
spec:
 replicas: 3
 template:
 metadata:
 labels:
 app: k8s-demo
 spec:
 containers:
 - name: k8s-demo
 image: k8s-demo:0.0.1-SNAPSHOT
 ports:
 - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
 name: k8s-demo
 namespace: spring-test
spec:
 type: NodePort
 selector:
 app: k8s-demo
 ports:
 - protocol: TCP
 port: 8888
 targetPort: 8080
 nodePort: 30003

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: k8s-demo
 namespace: spring-test
spec:
 rules:
 - host: www.k8s-demo.com
 http:
 paths:
 - path: /hello
 backend:
 serviceName: k8s-demo
 servicePort: 8888
複製代碼

4. 總結三種部署方式

爲了減小部署複雜度,代碼並無使用redis,只是實例圖增長了redisnode

5. 流程愈來愈複雜,爲何不直接部署在宿主機?

5.1 容器比宿主機優點在哪?

  • 可移植性:容器提供了運行應用程序的基本包裝,能夠在任何支持容器的雲上部署
  • 高效率:啓動一個容器只需一個鏡像,且啓動時間很是短
  • 隔離性:宿主機上每每安裝不少服務,且各自依賴不同。而一個容器只跑一個服務
  • 版本控制:方便追溯不一樣版本差別,方便快速回滾,只需替換鏡像版本,無需宿主機上一套複雜的流程
  • 低成本:小巧輕便,不須要像宿主機或虛擬機同樣佔用不少資源

5.2 k8s的出現又解決了容器的什麼問題?

  • 自動編排調度:大量容器劇增後,如何管理、如何調度的問題
  • 分佈式解決方案:節點可水平擴展,容器可方便擴縮容
  • 自愈能力:故障自動發現,並進行自我修復

咱們說容器實現了單個應用程序的基本包裝實現可移植。上圖中,宿主機部署的方式若是加上一個nginx作反向代理,就和k8s中ingress的部署方式是同樣的。也就是k8s實現了整套分佈式應用的可移植linux

二. 基本架構和原理

k8s架構圖

1. Master節點的組件

apiServer

  • 提供資源操做的惟一入口,提供api註冊、發現、認證、訪問控制等功能

etcd

  • 一個key-value數據庫
  • 保存整個機器的狀態

controller-manager

  • 負責維護機器狀態,好比:自動擴容、故障檢查、滾動更新
  • 實現集羣自動化的關鍵組件

scheduler

  • 負責資源調度
  • 將未分配節點的pod調度到合適的節點上

2. Node節點的組件

kubelet

  • 負責容器生命週期管理,好比:建立、刪除
  • 同時負責Volume,網絡的管理

kube-proxy

  • 負責爲Service提供負載均衡、服務發現

Container Runtime

  • 容器運行環境
  • 默認是Docker,同時還支持其餘容器引擎

三. 資源對象

概述

  • k8s中大部分概念,如Node,Pod,Service均可以看作一種資源對象
  • 資源的描述:yaml文件或json文件
  • 資源的操做:對象能夠經過kubectl(或者api)執行增、刪、改、查
  • 資源的存儲:信息在etcd中持久化

k8s經過對比資源的「實際狀態」和etcd中的「指望狀態」,實現自動化控制nginx

1. Pod

  • Pod是k8s中最重要最基本的資源
  • pod是在容器以外又封裝的一層概念
  • pod是容器調度的基本單元(不是docker容器)
  • 每一個pod包含一個特殊的根容器:Pause容器,和一個或多個業務容器
  • 每一個pod有惟一的ip,pod內的容器可經過localhost通信

爲何要新增pod這個概念?redis

  1. 一組容器做爲一個單元,很難判斷總體狀態,以及對總體進行管控。新增業務無關的pause容器,用於管控總體
  2. 簡化了關聯容器通訊和共享的問題

2. Deployment

  • 實現Pod自動編排:建立、刪除、擴容、縮容
  • 經過replicas控制pod數量,template控制要建立的pod的模板
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: k8s-demo
 namespace: spring-test
spec:
 replicas: 3
 template:
 metadata:
 labels:
 app: k8s-demo
 spec:
 containers:
 - name: k8s-demo
 image: k8s-demo:0.0.1-SNAPSHOT
 ports:
 - containerPort: 8080
複製代碼

3. Service

  • pod異常時,可能會被調度到另外一臺機器,致使pod的ip改變,使用ip訪問服務不可靠

3.1概述

  • k8s裏最核心的資源之一,相似微服務架構中的「微服務」
  • 前端應用經過入口地址訪問服務,服務經過label對接到後端的pod,即便pod的ip變了
  • kube-proxy負責把service請求轉發到後端,並作負載均衡
  • service整個生命週期內,ClusterIp不會變,對外提供的服務地址也就不會變
apiVersion: v1
kind: Service
metadata:
 name: k8s-demo
 namespace: spring-test
spec:
 type: NodePort
 selector:
 app: k8s-demo
 ports:
 - protocol: TCP
 port: 8888
 targetPort: 8080
 nodePort: 30003
複製代碼

4. Ingress

service提供了ip:port的訪問方式,即工做在tcp/ip層,而http服務須要將不一樣的url對應到不一樣的後端服務,service是沒法實現這一功能的。spring

  • Ingress提供http層的負載分發功能
  • Ingress能夠實現不一樣的請求,分發到不一樣的後端服務
  • Ingress定義後,須要結合Ingress Controller,才能造成完整的功能
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: k8s-demo
 namespace: spring-test
spec:
 rules:
 - host: www.k8s-demo.com
 http:
 paths:
 - path: /hello
 backend:
 serviceName: k8s-demo
 servicePort: 8888
複製代碼

4.1 Ingress Controller定義

  • 可使用公有云提供的Ingress Controller
  • 也可使用google提供的Ingress Controller,以pod形式運行,功能以下:
    • 監聽apiserver,獲取ingress的定義
    • 基於ingress定義,生成nginx的配置文件的內容
    • 執行nginx -s reload,從新加載配置

4.2 Ingress定義

  • 建立類型爲Ingress的yaml文件
  • 配置spec.rules,指定hostname中url和service的對應關係

四. k8s網絡模型

前面hello world程序中,對於如何訪問到服務,有必要了解一下k8s的網絡模型,在這以前先介紹docker的網絡模型docker

1. Docker網絡模型

docker網絡模型數據庫

  • docker第一次啓動時,會建立虛擬網橋docker0
  • 爲docker0分配一個子網
  • docker建立每一個容器時,會建立veth設備對,一端關聯到網橋上,另外一端使用linux的網絡命名空間技術鏈接到容器內,並給容器內eth0設備分配一個ip地址

2. Docker網絡的侷限性

  • Docker網絡模型沒有考慮到多主機互聯的網絡解決方案,崇尚簡單爲美
  • 同一機器內的容器之間能夠直接通信,可是不一樣機器之間的容器沒法通信
  • 爲了跨節點通信,必須在主機的地址上分配端口,經過端口路由或代理到容器
  • 分配和管理容器特別困難,特別是水平擴展時

3. k8s網絡模型概述

3.1 k8s網絡模型的原則:

  • 每一個pod都擁有惟一個獨立的ip地址,稱IP-Per-Pod模型
  • 全部pod都在一個可連通的網絡環境中
  • 不論是否在同一個node,均可以經過ip直接通信
  • pod被看做一臺獨立的物理機或虛擬機

目前原生docker和kubernetes還不能打通多節點容器與容器的通信,要支持該模型,必須依靠第三方網絡插件實現,好比:flanneljson

3.2 設計這個原則的緣由:

  • 用戶不須要額外考慮如何創建pod之間的鏈接
  • 用戶不須要考慮將容器端口映射到主機端口的問題
  • 能夠兼容過去跑在宿主機和KVM的應用

3.3 IP-Per-Pod與Docker端口映射的區別

  • docker端口映射到宿主機會引入端口管理的複雜性
  • docker最終被訪問的ip和端口,與提供的不一致,引發配置的複雜性

4. k8s網絡模型詳解

k8s網絡實現

4.1 容器與容器的通信

  • 同一個容器的pod直接共享同一個linux協議棧
  • 就像在同一臺機器上,可經過localhost訪問
  • 可類比一個物理機上不一樣應用程序的狀況

4.2 pod與pod的通信

同一Node內的pod之間通信
  • 同一Node內的pod都是經過veth鏈接在同一個docker0網橋上,地址段相同,因此能夠直接通信
不一樣Node的pod之間通信
  • docker0網段與宿主機不在同一個網段,因此不一樣pod之間的pod不能直接通信
  • 不一樣node之間通信只能經過宿主機物理網卡
  • 前面說過k8s網絡模型須要不一樣的pod之間能通信,因此ip不能重複,這就要求k8s部署時要規劃好docker0的網段
  • 同時,要記錄每一個pod的ip地址掛在哪一個具體的node上
  • 爲了達到這個目的,有不少開源軟件加強了docker和k8s的網絡

4. 開源網絡組件Flannel

4.1 實現的功能

  • 協助k8s給每一個Node上的docker容器分配互不衝突的ip地址
  • 能在這些ip地址之間創建覆蓋網絡(Overlay Network),將數據傳遞到目標容器

4.2 底層原理

  • Flannel建立名爲flannel0的網橋
  • flannel0網橋一端鏈接docker0網橋,另外一端鏈接flanneld進程
  • flanneld進程一端鏈接etcd,利用etcd管理分配的ip地址資源,同時監控pod地址,創建pod節點路由表
  • flanneld進程一端鏈接docker0和物理網絡,配合路由表,完成數據包投遞,完成pod之間通信

4.3 缺點

  • 引入多個網絡組件,帶來網絡時延和損耗
  • 默認使用udp做爲底層傳輸協議,具備不可靠性

五. 總結

  • 本文先經過一個demo,部署在不一樣的環境中,直觀感覺瞭如何使用k8s。這個過程咱們須要思考k8s誕生解決了什麼問題?核心的提供了一個平臺,主要負責容器的自動調度和編排
  • 對k8s有直觀感覺後,介紹了下k8s的基本架構。各個組件是如何交互的,在使用k8s過程當中不斷回想架構圖,能加深對k8s的瞭解
  • 掌握了基本架構後,想要將服務部署到k8s中,須要對經常使用的資源對象有必定了解,所以接着介紹了主要的資源對象。k8s中其餘的資源對象可類比學習
  • 當你把一個服務部署到k8s以後,如何作驗證呢,如何暴露你的服務呢?須要對k8s的網絡模型有必定了解,才能真正掌握它暴露服務的方式。所以最後部分着重介紹了k8s的網絡模型

參考

  • 《kubernetes權威指南》
相關文章
相關標籤/搜索