最詳細的 K8S 學習筆記總結(2021最新版)

雖然 Docker 已經很強大了,可是在實際使用上仍是有諸多不便,好比集羣管理、資源調度、文件管理等等。那麼在這樣一個百花齊放的容器時代涌現出了不少解決方案,好比 Mesos、Swarm、Kubernetes 等等,其中谷歌開源的 Kubernetes 是做爲老大哥的存在。html

image.png

kubernetes 已經成爲容器編排領域的王者,它是基於容器的集羣編排引擎,具有擴展集羣、滾動升級回滾、彈性伸縮、自動治癒、服務發現等多種特性能力。node

kubernetes 介紹

image.png

Kubernetes 解決的核心問題

  • 服務發現和負載均衡
    • Kubernetes 可使用 DNS 名稱或本身的 IP 地址公開容器,若是到容器的流量很大,Kubernetes 能夠負載均衡並分配網絡流量,從而使部署穩定。
  • 存儲編排
    • Kubernetes 容許您自動掛載您選擇的存儲系統,例如本地存儲、公共雲提供商等。
  • 自動部署和回滾
    • 您可使用 Kubernetes 描述已部署容器的所需狀態,它能夠以受控的速率將實際狀態更改成所需狀態。例如,您能夠自動化 Kubernetes 來爲您的部署建立新容器,刪除現有容器並將它們的全部資源用於新容器。
  • 自動二進制打包
    • Kubernetes 容許您指定每一個容器所需 CPU 和內存(RAM)。當容器指定了資源請求時,Kubernetes 能夠作出更好的決策來管理容器的資源。
  • 自我修復
    • Kubernetes 從新啓動失敗的容器、替換容器、殺死不響應用戶定義的運行情況檢查的容器,而且在準備好服務以前不將其通告給客戶端。
  • 密鑰與配置管理
    • Kubernetes 容許您存儲和管理敏感信息,例如密碼、OAuth 令牌和 ssh 密鑰。您能夠在不重建容器鏡像的狀況下部署和更新密鑰和應用程序配置,也無需在堆棧配置中暴露密鑰。

Kubernetes 的出現不只主宰了容器編排的市場,更改變了過去的運維方式,不只將開發與運維之間邊界變得更加模糊,並且讓 DevOps 這一角色變得更加清晰,每個軟件工程師均可以經過 Kubernetes 來定義服務之間的拓撲關係、線上的節點個數、資源使用量而且可以快速實現水平擴容、藍綠部署等在過去複雜的運維操做。mysql

知識圖譜

主要介紹學習一些什麼知識linux

image.png

軟件架構

傳統的客戶端服務端架構nginx

image.png

  • 架構說明

Kubernetes 遵循很是傳統的客戶端/服務端的架構模式,客戶端能夠經過 RESTful 接口或者直接使用 kubectl 與 Kubernetes 集羣進行通訊,這二者在實際上並無太多的區別,後者也只是對 Kubernetes 提供的 RESTful API 進行封裝並提供出來。每個 Kubernetes 集羣都是由一組 Master 節點和一系列的 Worker 節點組成,其中 Master 節點主要負責存儲集羣的狀態併爲 Kubernetes 對象分配和調度資源。git

image.png

image.png

  • 主節點服務 - Master 架構

做爲管理集羣狀態的 Master 節點,它主要負責接收客戶端的請求,安排容器的執行而且運行控制循環,將集羣的狀態向目標狀態進行遷移。Master 節點內部由下面三個組件構成:web

API Server: 負責處理來自用戶的請求,其主要做用就是對外提供 RESTful 的接口,包括用於查看集羣狀態的讀請求以及改變集羣狀態的寫請求,也是惟一一個與 etcd 集羣通訊的組件。面試

etcd: 是兼具一致性和高可用性的鍵值數據庫,能夠做爲保存 Kubernetes 全部集羣數據的後臺數據庫。redis

Scheduler: 主節點上的組件,該組件監視那些新建立的未指定運行節點的 Pod,並選擇節點讓 Pod 在上面運行。調度決策考慮的因素包括單個 Pod 和 Pod 集合的資源需求、硬件/軟件/策略約束、親和性和反親和性規範、數據位置、工做負載間的干擾和最後時限。算法

controller-manager: 在主節點上運行控制器的組件,從邏輯上講,每一個控制器都是一個單獨的進程,可是爲了下降複雜性,它們都被編譯到同一個可執行文件,並在一個進程中運行。這些控制器包括:節點控制器(負責在節點出現故障時進行通知和響應)、副本控制器(負責爲系統中的每一個副本控制器對象維護正確數量的 Pod)、端點控制器(填充端點 Endpoints 對象,即加入 Service 與 Pod))、服務賬戶和令牌控制器(爲新的命名空間建立默認賬戶和 API 訪問令牌)。

image.png

  • 工做節點 - Node 架構

其餘的 Worker 節點實現就相對比較簡單了,它主要由 kubelet 和 kube-proxy 兩部分組成。

kubelet: 是工做節點執行操做的 agent,負責具體的容器生命週期管理,根據從數據庫中獲取的信息來管理容器,並上報 pod 運行狀態等。

kube-proxy: 是一個簡單的網絡訪問代理,同時也是一個 Load Balancer。它負責將訪問到某個服務的請求具體分配給工做節點上同一類標籤的 Pod。kube-proxy 實質就是經過操做防火牆規則(iptables或者ipvs)來實現 Pod 的映射。

Container Runtime: 容器運行環境是負責運行容器的軟件,Kubernetes 支持多個容器運行環境: Docker、 containerd、cri-o、 rktlet 以及任何實現 Kubernetes CRI(容器運行環境接口)。

image.png

image.png

組件說明

主要介紹關於 K8s 的一些基本概念

image.png

主要由如下幾個核心組件組成:

  • apiserver
    • 全部服務訪問的惟一入口,提供認證、受權、訪問控制、API 註冊和發現等機制
  • controller manager
    • 負責維護集羣的狀態,好比副本指望數量、故障檢測、自動擴展、滾動更新等
  • scheduler
    • 負責資源的調度,按照預約的調度策略將 Pod 調度到相應的機器上
  • etcd
    • 鍵值對數據庫,保存了整個集羣的狀態
  • kubelet
    • 負責維護容器的生命週期,同時也負責 Volume 和網絡的管理
  • kube-proxy
    • 負責爲 Service 提供 cluster 內部的服務發現和負載均衡
  • Container runtime
    • 負責鏡像管理以及 Pod 和容器的真正運行

除了核心組件,還有一些推薦的插件:

  • CoreDNS
    • 能夠爲集羣中的 SVC 建立一個域名 IP 的對應關係解析的 DNS 服務
  • Dashboard
    • 給 K8s 集羣提供了一個 B/S 架構的訪問入口
  • Ingress Controller
    • 官方只可以實現四層的網絡代理,而 Ingress 能夠實現七層的代理
  • Prometheus
    • 給 K8s 集羣提供資源監控的能力
  • Federation
    • 提供一個能夠跨集羣中心多 K8s 的統一管理功能,提供跨可用區的集羣

以上內容參考連接: www.escapelife.site/posts/2c421…

安裝

安裝v1.16.0版本,居然成功了。記錄在此,避免後來者踩坑。

本篇文章,安裝大步驟以下:

  • 安裝docker-ce 18.09.9(全部機器)
  • 設置k8s環境前置條件(全部機器)
  • 安裝k8s v1.16.0 master管理節點
  • 安裝k8s v1.16.0 node工做節點
  • 安裝flannel(master)

詳細安裝步驟參考:CentOS 搭建 K8S,一次性成功,收藏了! 集羣安裝教程請參考:全網最新、最詳細基於V1.20版本,無坑部署最小化 K8S 集羣教程

Pod 實現原理

Pod 就是最小而且最簡單的 Kubernetes 對象

image.png

Pod、Service、Volume 和 Namespace 是 Kubernetes 集羣中四大基本對象,它們可以表示系統中部署的應用、工做負載、網絡和磁盤資源,共同定義了集羣的狀態。Kubernetes 中不少其餘的資源其實只對這些基本的對象進行了組合。

  • Pod -> 集羣中的基本單元
  • Service -> 解決如何訪問 Pod 裏面服務的問題
  • Volume -> 集羣中的存儲卷
  • Namespace -> 命名空間爲集羣提供虛擬的隔離做用

詳細介紹請參考:Kubernetes 之 Pod 實現原理

Harbor 倉庫

Kuternetes 企業級 Docker 私有倉庫 Harbor 工具。 Harbor 的每一個組件都是以 Docker 容器的形式構建的,使用 Docker Compose 來對它進行部署。用於部署 Harbor 的 Docker Compose 模板位於 /Deployer/docker-compose.yml 中,其由 5 個容器組成,這幾個容器經過 Docker link 的形式鏈接在一塊兒,在容器之間經過容器名字互相訪問。對終端用戶而言,只須要暴露 Proxy(即Nginx) 的服務端口便可。

  • Proxy
    • 由Nginx服務器構成的反向代理
  • Registry
    • 由Docker官方的開源官方的開源Registry鏡像構成的容器實例
  • UI
    • 即架構中的core services服務,構成此容器的代碼是Harbor項目的主體
  • MySQL
    • 由官方MySQL鏡像構成的數據庫容器
  • Log
    • 運行着rsyslogd的容器,經過log-driver的形式收集其餘容器的日誌

詳細介紹與搭建步驟請參考:企業級環境中基於 Harbor 搭建

YAML 語法

YAML 是一種很是簡潔/強大/專門用來寫配置文件的語言!

YAML 全稱是 」YAML Ain’t a Markup Language」 的遞歸縮寫,該語言的設計參考了 JSON / XML 和 SDL 等語言,強調以數據爲中心,簡潔易讀,編寫簡單。

image.png

YAML 語法特性

學過編程的人理解起來應該很是容易

image.png

語法特色
  • 大小寫敏感
  • 經過縮進表示層級關係
  • 禁止使用tab縮進,只能使用空格鍵
  • 縮進的空格數目不重要,只要相同層級左對齊
  • 使用#表示註釋

推薦給你們一篇文章:Kubernetes 之 YAML 語法,這篇文章介紹的很是詳細,有不少例子說明。

資源清單

K8S 中全部的內容都抽象爲了資源,資源實例化以後就叫作對象。

在 Kubernetes 系統中,Kubernetes 對象是持久化的實體,Kubernetes 使用這些實體去表示整個集羣的狀態。特別地,它們描述了以下信息:

  • 哪些容器化應用在運行,以及在哪一個 Node 上
  • 能夠被應用使用的資源
  • 關於應用運行時表現的策略,好比重啓策略、升級策略,以及容錯策略

Kubernetes 對象是 「目標性記錄」 —— 一旦建立對象,Kubernetes 系統將持續工做以確保對象存在。經過建立對象,本質上是在告知 Kubernetes 系統,所須要的集羣工做負載看起來是什麼樣子的,這就是 Kubernetes 集羣的指望狀態。

image.png

Kubernetes 之資源清單詳細介紹看這裏

資源控制器

Kubernetes 資源控制器配置文件的編寫是學習 K8S 的重中之重!

資源配額控制器確保了指定的資源對象始終不會超過配置的資源,可以有效的下降整個系統宕機的機率,加強系統的魯棒性,對整個集羣的穩定性有很是重要的做用。

image.png

Kubernetes 資源控制器使用指南手冊

服務發現

Kubernetes 中爲了實現服務實例間的負載均衡和不一樣服務間的服務發現,創造了 Service 對象,同時又爲從集羣外部訪問集羣建立了 Ingress 對象。

image.png

Kubernetes 之服務發現

Ingress 服務

咱們都知道傳統的 SVC 只支持四層上面的代碼,而對於七層上的代碼而無能爲力。好比:咱們使用 K8S 集羣對外提供 HTTPS 的服務,爲了方便和便捷,咱們須要在對外的 Nginx 服務上面配置 SSL 加密,可是將請求發送給後端服務的時候,進行證書卸載的操做,後續都是用 HTTP 的協議進行處理。而面對此問題,K8S 中給出了使用 Ingress (K8S在1.11版本中推出了)來進行處理。

image.png

更多詳細內容請參閱:Kubernetes 之 Ingress 服務,介紹關於 Ingress 服務的安裝方式,配置關於 Ingress 服務的 HTTP 代理訪問,介紹 Ingress 服務的 BasicAuth 認證方式,介紹 Ingress 的進行規則重寫的方式。

數據存儲

在以前的文章中,咱們已經知道了不少 K8S 中的組件了,包括資源控制器等。在資源控制器中,咱們說到了 StatefulSet 這個控制器組件,其專門爲了有狀態服務而生的,而對應的存儲要存放到哪裏呢?

image.png

介紹 K8S 中常見的存儲機制可讓咱們所使用的:Kubernetes 之數據存儲

集羣調度

有這樣一個需求,就是集羣中多臺服務的配置是不一致的。這就致使資源分配並非均勻的,好比咱們須要有些服務節點用來運行計算密集型的服務,而有些服務節點來運行須要大量內存的服務。而在 k8s 中固然也配置了相關服務來處理上述的問題,那就是 Scheduler。

Scheduler 是 kubernetes 的調度器,主要的任務是把定義的 Pod 分配到集羣的節點上。聽起來很是簡單,但有不少要考慮的問題:

  • 公平
    • 如何保證每一個節點都能被分配資源
  • 資源高效利用
    • 集羣全部資源最大化被使用
  • 效率
    • 調度的性能要好,可以儘快地對大批量的 Pod 完成調度工做
  • 靈活
    • 容許用戶根據本身的需求控制調度的邏輯

Scheduler 是做爲單獨的程序運行的,啓動以後會一直堅挺 API Server,獲取 PodSpec.NodeName 爲空的 Pod,對每一個 Pod 都會建立一個 binding,代表該 Pod 應該放到哪一個節點上。

image.png

詳細的介紹請參考:Kubernetes 之集羣調度

kubectl 使用指南

kubectl 是 Kubernetes 自帶的客戶端,能夠用它來直接操做 Kubernetes 集羣。

平常在使用 Kubernetes 的過程當中,kubectl 工具多是最經常使用的工具了,因此當咱們花費大量的時間去研究和學習 Kuernetes 的時候,那麼咱們就很是有必要去了解下如何高效的使用它了。

從用戶角度來講,kubectl 就是控制 Kubernetes 的駕駛艙,它容許你執行全部可能的 Kubernetes 操做;從技術角度來看,kubectl 就是 Kubernetes API 的一個客戶端而已。

image.png

Kubernetes API 是一個 HTTP REST API 服務,該 API 服務纔是 Kubernetes 的真正用到的用戶接口,因此 Kubernetes 經過該 API 進行實際的控制。這也就意味着每一個 Kubernetes 的操做都會經過 API 端點暴露出去,固然也就能夠經過對這些 API 端口進行 HTTP 請求來執行相應的操做。因此,kubectl 最主要的工做就是執行 Kubernetes API 的 HTTP 請求。

工具使用參數

get       #顯示一個或多個資源
describe  #顯示資源詳情
create    #從文件或標準輸入建立資源
update   #從文件或標準輸入更新資源
delete   #經過文件名、標準輸入、資源名或者 label 刪除資源
log       #輸出 pod 中一個容器的日誌
rolling-update  #對指定的 RC 執行滾動升級
exec  #在容器內部執行命令
port-forward #將本地端口轉發到 Pod
proxy   #爲 Kubernetes API server 啓動代理服務器
run     #在集羣中使用指定鏡像啓動容器
expose   #將 SVC 或 pod 暴露爲新的 kubernetes service
label     #更新資源的 label
config   #修改 kubernetes 配置文件
cluster-info #顯示集羣信息
api-versions #以」組/版本」的格式輸出服務端支持的 API 版本
version       #輸出服務端和客戶端的版本信息
help         #顯示各個命令的幫助信息
ingress-nginx  #管理 ingress 服務的插件(官方安裝和使用方式)
複製代碼

使用相關配置

# Kubectl自動補全
$ source <(kubectl completion zsh)
$ source <(kubectl completion bash)

# 顯示合併後的 kubeconfig 配置
$ kubectl config view

# 獲取pod和svc的文檔
$ kubectl explain pods,svc
複製代碼

建立資源對象

分步驟建立
# yaml
kubectl create -f xxx-rc.yaml
kubectl create -f xxx-service.yaml

# json
kubectl create -f ./pod.json
cat pod.json | kubectl create -f -

# yaml2json
kubectl create -f docker-registry.yaml --edit -o json
複製代碼
一次性建立
kubectl create -f xxx-service.yaml -f xxx-rc.yaml
複製代碼
根據目錄下全部的 yaml 文件定義內容進行建立
kubectl create -f <目錄>
複製代碼
使用 url 來建立資源
kubectl create -f https://git.io/vPieo
複製代碼

查看資源對象

查看全部 Node 或 Namespace 對象
kubectl get nodes
kubectl get namespace
複製代碼
查看全部 Pod 對象
# 查看子命令幫助信息
kubectl get --help

# 列出默認namespace中的全部pod
kubectl get pods

# 列出指定namespace中的全部pod
kubectl get pods --namespace=test

# 列出全部namespace中的全部pod
kubectl get pods --all-namespaces

# 列出全部pod並顯示詳細信息
kubectl get pods -o wide
kubectl get replicationcontroller web
kubectl get -k dir/
kubectl get -f pod.yaml -o json
kubectl get rc/web service/frontend pods/web-pod-13je7
kubectl get pods/app-prod-78998bf7c6-ttp9g --namespace=test -o wide
kubectl get -o template pod/web-pod-13je7 --template={{.status.phase}}

# 列出該namespace中的全部pod包括未初始化的
kubectl get pods,rc,services --include-uninitialized
複製代碼
查看全部 RC 對象
kubectl get rc
複製代碼
查看全部 Deployment 對象
# 查看所有deployment
kubectl get deployment

# 列出指定deployment
kubectl get deployment my-app
複製代碼
查看全部 Service 對象
kubectl get svc
kubectl get service
複製代碼
查看不一樣 Namespace 下的 Pod 對象
kubectl get pods -n default
kubectl get pods --all-namespace
複製代碼

查看資源描述

顯示 Pod 詳細信息
kubectl describe pods/nginx
kubectl describe pods my-pod
kubectl describe -f pod.json
複製代碼
查看 Node 詳細信息
kubectl describe nodes c1
複製代碼
查看 RC 關聯的 Pod 信息
kubectl describe pods <rc-name>
複製代碼

更新修補資源

滾動更新
# 滾動更新 pod frontend-v1
kubectl rolling-update frontend-v1 -f frontend-v2.json

# 更新資源名稱並更新鏡像
kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2

# 更新 frontend pod 中的鏡像
kubectl rolling-update frontend --image=image:v2

# 退出已存在的進行中的滾動更新
kubectl rolling-update frontend-v1 frontend-v2 --rollback

# 強制替換; 刪除後從新建立資源; 服務會中斷
kubectl replace --force -f ./pod.json

# 添加標籤
kubectl label pods my-pod new-label=awesome

# 添加註解
kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq
複製代碼
修補資源
# 部分更新節點
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'

# 更新容器鏡像;spec.containers[*].name 是必須的,由於這是合併的關鍵字
kubectl patch pod valid-pod -p \
    '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'
複製代碼
Scale 資源
# Scale a replicaset named 'foo' to 3
kubectl scale --replicas=3 rs/foo

# Scale a resource specified in "foo.yaml" to 3
kubectl scale --replicas=3 -f foo.yaml

# If the deployment named mysql's current size is 2, scale mysql to 3
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql

# Scale multiple replication controllers
kubectl scale --replicas=5 rc/foo rc/bar rc/baz
複製代碼

刪除資源對象

基於 xxx.yaml 文件刪除 Pod 對象
# yaml文件名字按照你建立時的文件一致
kubectl delete -f xxx.yaml
複製代碼
刪除包括某個 label 的 pod 對象
kubectl delete pods -l name=<label-name>
複製代碼
刪除包括某個 label 的 service 對象
kubectl delete services -l name=<label-name>
複製代碼
刪除包括某個 label 的 pod 和 service 對象
kubectl delete pods,services -l name=<label-name>
複製代碼
刪除全部 pod/services 對象
kubectl delete pods --all
kubectl delete service --all
kubectl delete deployment --all
複製代碼

編輯資源文件

在編輯器中編輯任何 API 資源

# 編輯名爲docker-registry的service
kubectl edit svc/docker-registry
複製代碼

直接執行命令

在寄主機上,不進入容器直接執行命令

執行 pod 的 date 命令,默認使用 pod 的第一個容器執行
kubectl exec mypod -- date
kubectl exec mypod --namespace=test -- date
複製代碼
指定 pod 中某個容器執行 date 命令
kubectl exec mypod -c ruby-container -- date
複製代碼
進入某個容器
kubectl exec mypod -c ruby-container -it -- bash
複製代碼

查看容器日誌

直接查看日誌
# 不實時刷新kubectl logs mypod
kubectl logs mypod --namespace=test
複製代碼
查看日誌實時刷新
kubectl logs -f mypod -c ruby-container
複製代碼

管理工具

Kubernetes正在不斷加快在雲原生環境的應用,但如何以統1、安全的方式對運行於任何地方的Kubernetes集羣進行管理面臨着挑戰,而有效的管理工具可以大大下降管理的難度。

K9s

k9s是基於終端的資源儀表板。它只有一個命令行界面。不管在Kubernetes儀表板Web UI上作什麼,均可以在終端使用K9s儀表板工具進行相同的操做。k9s持續關注Kubernetes集羣,並提供命令以使用集羣上定義的資源。

image.png

詳細介紹:Kubernetes 集羣管理工具 K9S

推薦:輕鬆管理 Kubernetes 集羣的7個工具

生產環境最佳實踐

使用Kubernetes的一些策略,在安全性、監控、網絡、治理、存儲、容器生命週期管理和平臺選擇方面應用最佳實踐。下面讓咱們來看看Kubernetes的一些生產最佳實踐。在生產中運行Kubernetes並不容易; 有如下幾個方面須要注意。

是否使用存活探針和就緒探針進行健康檢查?

管理大型分佈式系統可能會很複雜,特別是當出現問題時,咱們沒法及時獲得通知。爲了確保應用實例正常工做,設置Kubernetes健康檢查相當重要。

經過建立自定義運行健康檢查,能夠有效避免分佈式系統中殭屍服務運行,具體能夠根據環境和須要對其進行調整。

就緒探針的目的是讓Kubernetes知道該應用是否已經準備好爲流量服務。Kubernetes將始終確保準備就緒探針經過以後開始分配服務,將流量發送到Pod。

Liveness-存活探針

你怎麼知道你的應用程序是活的仍是死的?存活探針可讓你作到這一點。若是你的應用死了,Kubernetes會移除舊的Pod並用新Pod替換它。

Resource Management-資源管理

爲單個容器指定資源請求和限制是一個很好的實踐。另外一個好的實踐是將Kubernetes環境劃分爲不一樣團隊、部門、應用程序和客戶機的獨立名稱空間。

Kubernetes資源使用狀況

Kubernetes資源使用指的是容器/pod在生產中所使用的資源數量。

所以,密切關注pods的資源使用狀況是很是重要的。一個明顯的緣由是成本,由於越高的資源利用證實越少的資源浪費。

Resource utilization資源利用率

Ops團隊一般但願優化和最大化pods消耗的資源百分比。資源使用狀況是Kubernetes環境實際優化程度的指標之一。

您能夠認爲優化後的Kubernetes環境中運行的容器的平均CPU等資源利用率是最優的。

啓用RBAC

RBAC表明基於角色的訪問控制。它是一種用於限制系統/網絡上的用戶和應用程序的訪問和准入的方法。!

image.png

他們從Kubernetes 1.8版本引入了RBAC。使用rbac.authorization.k8s RBAC用於建立受權策略。

在Kubernetes中,RBAC用於受權,使用RBAC,您將可以授予用戶、賬戶、添加/刪除權限、設置規則等權限。所以,它基本上爲Kubernetes集羣添加了額外的安全層。RBAC限制誰能夠訪問您的生產環境和集羣。

集羣置備和負載均衡

生產級Kubernetes基礎設施一般須要考慮某些關鍵方面,例如高可用性、多主機、多etcd Kubernetes集羣等。此類集羣的配置一般涉及到Terraform或Ansible等工具。

image.png

一旦集羣都設置好了,而且爲運行應用程序建立了pods,這些pods就配備了負載平衡器;這些負載均衡器將流量路由到服務。開源的Kubernetes項目並非默認的負載平衡器;所以,它須要與NGINX Ingress controller與HAProxy或ELB等工具集成,或任何其餘工具,擴大Kubernetes的Ingress插件,以提供負載均衡能力。

給Kubernetes對象添加標籤

標籤就像附加到對象上的鍵/值對,好比pods。標籤是用來標識對象的屬性的,這些屬性對用戶來講是重要的和有意義的。

在生產中使用Kubernetes時,不能忽視的一個重要問題是標籤;標籤容許批量查詢和操做Kubernetes對象。標籤的特殊之處在於,它們還能夠用於識別Kubernetes對象並將其組織成組。這樣作的最佳用例之一是根據pod所屬的應用程序對它們進行分組。在這裏,團隊能夠構建並擁有任意數量的標籤約定。

配置網絡策略

使用Kubernetes時,設置網絡策略相當重要。網絡策略只不過是一個對象,它使你可以明確地聲明和決定哪些流量是容許的,哪些是不容許的。這樣,Kubernetes將可以阻止全部其餘不想要的和不符合規則的流量。在咱們的集羣中定義和限制網絡流量是強烈推薦的基本且必要的安全措施之一。

Kubernetes中的每一個網絡策略都定義了一個如上所述的受權鏈接列表。不管什麼時候建立任何網絡策略,它所引用的全部pod都有資格創建或接受列出的鏈接。簡單地說,網絡策略基本上就是受權和容許鏈接的白名單——一個鏈接,不管它是到仍是從pod,只有在應用於pod的至少一個網絡策略容許的狀況下才被容許。

集羣監控和日誌記錄

在使用Kubernetes時,監控部署是相當重要的。確保配置、性能和流量保持安全更是重要。若是不進行日誌記錄和監控,就不可能診斷出發生的問題。爲了確保合規性,監視和日誌記錄變得很是重要。在進行監視時,有必要在體系結構的每一層上設置日誌記錄功能。生成的日誌將幫助咱們啓用安全工具、審計功能和分析性能。

從無狀態應用程序開始

運行無狀態應用要比運行有狀態應用簡單得多,但隨着Kubernetes運營商的不斷增加,這種想法正在改變。對於剛接觸Kubernetes的團隊來講,建議首先使用無狀態應用程序。

建議使用無狀態後端,這樣開發團隊就能夠確保不存在長時間運行的鏈接,從而增長了擴展的難度。使用無狀態,開發人員還能夠更有效地、零停機部署應用程序。人們廣泛認爲,無狀態應用程序能夠方便地根據業務須要進行遷移和擴展。

邊啓動自動擴縮容

Kubernetes有三種用於部署的自動伸縮功能:水平pod自動伸縮(HPA)、垂直pod自動伸縮(VPA)和集羣自動伸縮。

水平pod autoscaler根據感知到的CPU利用率自動擴展deployment、replicationcontroller, replicaset, statefulset的數量。

Vertical pod autoscaling爲CPU和內存請求和限制推薦合適的值,它能夠自動更新這些值。

Cluster Autoscaler擴展和縮小工做節點池的大小。它根據當前的利用率調整Kubernetes集羣的大小。

控制鏡像拉取來源

控制在集羣中運行全部容器的鏡像源。若是您容許您的Pod從公共資源中拉取鏡像,您就不知道其中真正運行的是什麼。

若是從受信任的註冊表中提取它們,則能夠在註冊表上應用策略以提取安全和通過認證的鏡像。

持續學習

不斷評估應用程序的狀態和設置,以學習和改進。例如,回顧容器的歷史內存使用狀況能夠得出這樣的結論:咱們能夠分配更少的內存,在長期內節省成本。

保護重要服務

使用Pod優先級,您能夠決定設置不一樣服務運行的重要性。例如,爲了更好的穩定性,你須要確保RabbitMQ pod比你的應用pod更重要。或者你的入口控制器pods比數據處理pods更重要,以保持服務對用戶可用。

零停機時間

經過在HA中運行全部服務,支持集羣和服務的零停機升級。這也將保證您的客戶得到更高的可用性。

使用pod反親和性來確保在不一樣的節點上調度一個pod的多個副本,從而經過計劃中的和計劃外的集羣節點停機來確保服務可用性。

使用pod Disruptions策略,不惜一切代價確保您有最低的Pod副本數量!

計劃失敗

硬件最終會失敗,軟件最終會運行。--(邁克爾·哈頓)

結論

衆所周知,Kubernetes實際上已經成爲DevOps領域的編排平臺標準。Kubernetes從可用性、可伸縮性、安全性、彈性、資源管理和監控的角度來應對生產環境產生的風暴。因爲許多公司都在生產中使用Kubernetes,所以必須遵循上面提到的最佳實踐,以順利和可靠地擴展應用程序。

內容來源:my.oschina.net/u/1787735/b…

介紹5 款頂級 Kubernetes 日誌監控工具

對於新安裝的 Kubernetes,常常出現的一個問題是 Service 沒有正常工做。若是您已經運行了 Deployment 並建立了一個 Service,可是當您嘗試訪問它時沒有獲得響應,但願這份文檔(全網最詳細的 K8s Service 不能訪問排查流程)能幫助您找出問題所在。

Kubernetes 常見問題總結

如何刪除不一致狀態下的 rc,deployment,service

在某些狀況下,常常發現 kubectl 進程掛起現象,而後在 get 時候發現刪了一半,而另外的刪除不了

[root@k8s-master ~]# kubectl get -f fluentd-elasticsearch/
NAME DESIRED CURRENT READY AGE
rc/elasticsearch-logging-v1 0 2 2 15h

NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deploy/kibana-logging 0 1 1 1 15h
Error from server (NotFound): services "elasticsearch-logging" not found
Error from server (NotFound): daemonsets.extensions "fluentd-es-v1.22" not found
Error from server (NotFound): services "kibana-logging" not found
複製代碼

刪除這些 deployment,service 或者 rc 命令以下:

kubectl delete deployment kibana-logging -n kube-system --cascade=false

kubectl delete deployment kibana-logging -n kube-system  --ignore-not-found

delete rc elasticsearch-logging-v1 -n kube-system --force now --grace-period=0
複製代碼

刪除不了後如何重置 etcd

rm -rf /var/lib/etcd/*
複製代碼

刪除後從新 reboot master 結點。

reset etcd 後須要從新設置網絡

etcdctl mk /atomic.io/network/config '{ "Network": "192.168.0.0/16" }'
複製代碼

啓動 apiserver 失敗

每次啓動都是報以下問題:

start request repeated too quickly for kube-apiserver.service
複製代碼

但其實不是啓動頻率問題,須要查看, /var/log/messages,在個人狀況中是由於開啓 ServiceAccount 後找不到 ca.crt 等文件,致使啓動出錯。

May 21 07:56:41 k8s-master kube-apiserver: Flag --port has been deprecated, see --insecure-port instead.
May 21 07:56:41 k8s-master kube-apiserver: F0521 07:56:41.692480 4299 universal_validation.go:104] Validate server run options failed: unable to load client CA file: open /var/run/kubernetes/ca.crt: no such file or directory
May 21 07:56:41 k8s-master systemd: kube-apiserver.service: main process exited, code=exited, status=255/n/a
May 21 07:56:41 k8s-master systemd: Failed to start Kubernetes API Server.
May 21 07:56:41 k8s-master systemd: Unit kube-apiserver.service entered failed state.
May 21 07:56:41 k8s-master systemd: kube-apiserver.service failed.
May 21 07:56:41 k8s-master systemd: kube-apiserver.service holdoff time over, scheduling restart.
May 21 07:56:41 k8s-master systemd: start request repeated too quickly for kube-apiserver.service
May 21 07:56:41 k8s-master systemd: Failed to start Kubernetes API Server.
複製代碼

在部署 fluentd 等日誌組件的時候,不少問題都是由於須要開啓 ServiceAccount 選項須要配置安全致使,因此說到底仍是須要配置好 ServiceAccount.

出現 Permission denied 狀況

在配置 fluentd 時候出現cannot create /var/log/fluentd.log: Permission denied 錯誤,這是由於沒有關掉 SElinux 安全致使。

能夠在 /etc/selinux/config 中將 SELINUX=enforcing 設置成 disabled,而後 reboot

基於 ServiceAccount 的配置

首先生成各類須要的 keys,k8s-master 需替換成 master 的主機名.

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=k8s-master" -days 10000 -out ca.crt
openssl genrsa -out server.key 2048

echo subjectAltName=IP:10.254.0.1 > extfile.cnf

#ip由下述命令決定

#kubectl get services --all-namespaces |grep 'default'|grep 'kubernetes'|grep '443'|awk '{print $3}'

openssl req -new -key server.key -subj "/CN=k8s-master" -out server.csr

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile extfile.cnf -out server.crt -days 10000
複製代碼

若是修改 /etc/kubernetes/apiserver 的配置文件參數的話,經過 systemctl start kube-apiserver 啓動失敗,出錯信息爲:

Validate server run options failed: unable to load client CA file: open /root/keys/ca.crt: permission denied
複製代碼

但能夠經過命令行啓動 API Server

/usr/bin/kube-apiserver --logtostderr=true --v=0 --etcd-servers=http://k8s-master:2379 --address=0.0.0.0 --port=8080 --kubelet-port=10250 --allow-privileged=true --service-cluster-ip-range=10.254.0.0/16 --admission-control=ServiceAccount --insecure-bind-address=0.0.0.0 --client-ca-file=/root/keys/ca.crt --tls-cert-file=/root/keys/server.crt --tls-private-key-file=/root/keys/server.key --basic-auth-file=/root/keys/basic_auth.csv --secure-port=443 &>> /var/log/kubernetes/kube-apiserver.log &
複製代碼

命令行啓動 Controller-manager

/usr/bin/kube-controller-manager --logtostderr=true --v=0 --master=http://k8s-master:8080 --root-ca-file=/root/keys/ca.crt --service-account-private-key-file=/root/keys/server.key & >>/var/log/kubernetes/kube-controller-manage.log
複製代碼

ETCD 啓動不起來-問題<1>

etcd是kubernetes 集羣的zookeeper進程,幾乎全部的service都依賴於etcd的啓動,好比flanneld,apiserver,docker.....在啓動etcd是報錯日誌以下:

May 24 13:39:09 k8s-master systemd: Stopped Flanneld overlay address etcd agent.
May 24 13:39:28 k8s-master systemd: Starting Etcd Server...
May 24 13:39:28 k8s-master etcd: recognized and used environment variable ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379,http://etcd:4001
May 24 13:39:28 k8s-master etcd: recognized environment variable ETCD_NAME, but unused: shadowed by corresponding flag
May 24 13:39:28 k8s-master etcd: recognized environment variable ETCD_DATA_DIR, but unused: shadowed by corresponding flag
May 24 13:39:28 k8s-master etcd: recognized environment variable ETCD_LISTEN_CLIENT_URLS, but unused: shadowed by corresponding flag
May 24 13:39:28 k8s-master etcd: etcd Version: 3.1.3
May 24 13:39:28 k8s-master etcd: Git SHA: 21fdcc6
May 24 13:39:28 k8s-master etcd: Go Version: go1.7.4
May 24 13:39:28 k8s-master etcd: Go OS/Arch: linux/amd64
May 24 13:39:28 k8s-master etcd: setting maximum number of CPUs to 1, total number of available CPUs is 1
May 24 13:39:28 k8s-master etcd: the server is already initialized as member before, starting as etcd member...
May 24 13:39:28 k8s-master etcd: listening for peers on http://localhost:2380
May 24 13:39:28 k8s-master etcd: listening for client requests on 0.0.0.0:2379
May 24 13:39:28 k8s-master etcd: listening for client requests on 0.0.0.0:4001
May 24 13:39:28 k8s-master etcd: recovered store from snapshot at index 140014
May 24 13:39:28 k8s-master etcd: name = master
May 24 13:39:28 k8s-master etcd: data dir = /var/lib/etcd/default.etcd
May 24 13:39:28 k8s-master etcd: member dir = /var/lib/etcd/default.etcd/member
May 24 13:39:28 k8s-master etcd: heartbeat = 100ms
May 24 13:39:28 k8s-master etcd: election = 1000ms
May 24 13:39:28 k8s-master etcd: snapshot count = 10000
May 24 13:39:28 k8s-master etcd: advertise client URLs = http://etcd:2379,http://etcd:4001
May 24 13:39:28 k8s-master etcd: ignored file 0000000000000001-0000000000012700.wal.broken in wal
May 24 13:39:29 k8s-master etcd: restarting member 8e9e05c52164694d in cluster cdf818194e3a8c32 at commit index 148905
May 24 13:39:29 k8s-master etcd: 8e9e05c52164694d became follower at term 12
May 24 13:39:29 k8s-master etcd: newRaft 8e9e05c52164694d [peers: [8e9e05c52164694d], term: 12, commit: 148905, applied: 140014, lastindex: 148905, lastterm: 12]
May 24 13:39:29 k8s-master etcd: enabled capabilities for version 3.1
May 24 13:39:29 k8s-master etcd: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32 from store
May 24 13:39:29 k8s-master etcd: set the cluster version to 3.1 from store
May 24 13:39:29 k8s-master etcd: starting server... [version: 3.1.3, cluster version: 3.1]
May 24 13:39:29 k8s-master etcd: raft save state and entries error: open /var/lib/etcd/default.etcd/member/wal/0.tmp: is a directory
May 24 13:39:29 k8s-master systemd: etcd.service: main process exited, code=exited, status=1/FAILURE
May 24 13:39:29 k8s-master systemd: Failed to start Etcd Server.
May 24 13:39:29 k8s-master systemd: Unit etcd.service entered failed state.
May 24 13:39:29 k8s-master systemd: etcd.service failed.
May 24 13:39:29 k8s-master systemd: etcd.service holdoff time over, scheduling restart.
複製代碼

核心語句:

raft save state and entries error: open /var/lib/etcd/default.etcd/member/wal/0.tmp: is a directory
複製代碼

進入相關目錄,刪除 0.tmp,而後就能夠啓動啦!

ETCD啓動不起來-超時問題<2>

問題背景:當前部署了 3 個 etcd 節點,忽然有一天 3 臺集羣所有停電宕機了。從新啓動以後發現 K8S 集羣是能夠正常使用的,可是檢查了一遍組件以後,發現有一個節點的 etcd 啓動不了。

通過一遍探查,發現時間不許確,經過如下命令 ntpdate ntp.aliyun.com 從新將時間調整正確,從新啓動 etcd,發現仍是起不來,報錯以下:

Mar 05 14:27:15 k8s-node2 etcd[3248]: etcd Version: 3.3.13
Mar 05 14:27:15 k8s-node2 etcd[3248]: Git SHA: 98d3084
Mar 05 14:27:15 k8s-node2 etcd[3248]: Go Version: go1.10.8
Mar 05 14:27:15 k8s-node2 etcd[3248]: Go OS/Arch: linux/amd64
Mar 05 14:27:15 k8s-node2 etcd[3248]: setting maximum number of CPUs to 4, total number of available CPUs is 4
Mar 05 14:27:15 k8s-node2 etcd[3248]: the server is already initialized as member before, starting as etcd member
...
Mar 05 14:27:15 k8s-node2 etcd[3248]: peerTLS: cert = /opt/etcd/ssl/server.pem, key = /opt/etcd/ssl/server-key.pe
m, ca = , trusted-ca = /opt/etcd/ssl/ca.pem, client-cert-auth = false, crl-file =
Mar 05 14:27:15 k8s-node2 etcd[3248]: listening for peers on https://192.168.25.226:2380
Mar 05 14:27:15 k8s-node2 etcd[3248]: The scheme of client url http://127.0.0.1:2379 is HTTP while peer key/cert
files are presented. Ignored key/cert files.
Mar 05 14:27:15 k8s-node2 etcd[3248]: listening for client requests on 127.0.0.1:2379
Mar 05 14:27:15 k8s-node2 etcd[3248]: listening for client requests on 192.168.25.226:2379
Mar 05 14:27:15 k8s-node2 etcd[3248]: member 9c166b8b7cb6ecb8 has already been bootstrapped
Mar 05 14:27:15 k8s-node2 systemd[1]: etcd.service: main process exited, code=exited, status=1/FAILURE
Mar 05 14:27:15 k8s-node2 systemd[1]: Failed to start Etcd Server.
Mar 05 14:27:15 k8s-node2 systemd[1]: Unit etcd.service entered failed state.
Mar 05 14:27:15 k8s-node2 systemd[1]: etcd.service failed.
Mar 05 14:27:15 k8s-node2 systemd[1]: etcd.service failed.
Mar 05 14:27:15 k8s-node2 systemd[1]: etcd.service holdoff time over, scheduling restart.
Mar 05 14:27:15 k8s-node2 systemd[1]: Starting Etcd Server...
Mar 05 14:27:15 k8s-node2 etcd[3258]: recognized environment variable ETCD_NAME, but unused: shadowed by correspo
nding flag
Mar 05 14:27:15 k8s-node2 etcd[3258]: recognized environment variable ETCD_DATA_DIR, but unused: shadowed by corr
esponding flag
Mar 05 14:27:15 k8s-node2 etcd[3258]: recognized environment variable ETCD_LISTEN_PEER_URLS, but unused: shadowed
 by corresponding flag
Mar 05 14:27:15 k8s-node2 etcd[3258]: recognized environment variable ETCD_LISTEN_CLIENT_URLS, but unused: shadow
ed by corresponding flag
Mar 05 14:27:15 k8s-node2 etcd[3258]: recognized environment variable ETCD_INITIAL_ADVERTISE_PEER_URLS, but unuse
d: shadowed by corresponding flag
Mar 05 14:27:15 k8s-node2 etcd[3258]: recognized environment variable ETCD_ADVERTISE_CLIENT_URLS, but unused: sha
dowed by corresponding flag
Mar 05 14:27:15 k8s-node2 etcd[3258]: recognized environment variable ETCD_INITIAL_CLUSTER, but unused: shadowed
by corresponding flag
Mar 05 14:27:15 k8s-node2 etcd[3258]: recognized environment variable ETCD_INITIAL_CLUSTER_TOKEN, but unused: sha
dowed by corresponding flag
Mar 05 14:27:15 k8s-node2 etcd[3258]: recognized environment variable ETCD_INITIAL_CLUSTER_STATE, but unused: sha
dowed by corresponding flag
複製代碼

解決方法:

檢查日誌發現並無特別明顯的錯誤,根據經驗來說,etcd 節點壞掉一個其實對集羣沒有大的影響,這時集羣已經能夠正常使用了,可是這個壞掉的 etcd 節點並無啓動,解決方法以下:

進入 etcd 的數據存儲目錄進行備份 備份原有數據:

cd /var/lib/etcd/default.etcd/member/
cp *  /data/bak/
複製代碼

刪除這個目錄下的全部數據文件

rm -rf /var/lib/etcd/default.etcd/member/*
複製代碼

中止另外兩臺 etcd 節點,由於 etcd 節點啓動時須要全部節點一塊兒啓動,啓動成功後便可使用。

#master 節點
systemctl stop etcd
systemctl restart etcd

#node1 節點
systemctl stop etcd
systemctl restart etcd

#node2 節點
systemctl stop etcd
systemctl restart etcd
複製代碼

CentOS下配置主機互信

在每臺服務器須要創建主機互信的用戶名執行如下命令生成公鑰/密鑰,默認回車便可

ssh-keygen -t rsa
複製代碼

能夠看到生成個公鑰的文件。

互傳公鑰,第一次須要輸入密碼,以後就OK了。

ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.199.132 (-p 2222)
複製代碼

-p 端口 默認端口不加-p,若是更改過端口,就得加上-p. 能夠看到是在.ssh/下生成了個 authorized_keys的文件,記錄了能登錄這臺服務器的其餘服務器的公鑰。

測試看是否能登錄:

ssh 192.168.199.132 (-p 2222)
複製代碼

CentOS 主機名的修改

hostnamectl set-hostname k8s-master1
複製代碼

Virtualbox 實現 CentOS 複製和粘貼功能

若是不安裝或者不輸出,能夠將 update 修改爲 install 再運行。

yum install update
yum update kernel
yum update kernel-devel
yum install kernel-headers
yum install gcc
yum install gcc make
複製代碼

運行完後

sh VBoxLinuxAdditions.run
複製代碼

刪除Pod一直處於Terminating狀態

能夠經過下面命令強制刪除

kubectl delete pod NAME --grace-period=0 --force
複製代碼

刪除namespace一直處於Terminating狀態

能夠經過如下腳本強制刪除

[root@k8s-master1 k8s]# cat delete-ns.sh
#!/bin/bash
set -e

useage(){
    echo "useage:"
    echo " delns.sh NAMESPACE"
}

if [ $# -lt 1 ];then
    useage
    exit
fi

NAMESPACE=$1
JSONFILE=${NAMESPACE}.json
kubectl get ns "${NAMESPACE}" -o json > "${JSONFILE}"
vi "${JSONFILE}"
curl -k -H "Content-Type: application/json" -X PUT --data-binary @"${JSONFLE}" \
    http://127.0.0.1:8001/api/v1/namespaces/"${NAMESPACE}"/finalize
複製代碼

容器包含有效的 CPU/內存 requests 且沒有指定 limits 可能會出現什麼問題?

下面咱們建立一個對應的容器,該容器只有 requests 設定,可是沒有 limits 設定,

- name: busybox-cnt02
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello from cnt02; sleep 10;done"]
    resources:
      requests:
        memory: "100Mi"
        cpu: "100m"
複製代碼

這個容器建立出來會有什麼問題呢?

其實對於正常的環境來講沒有什麼問題,可是對於資源型 pod 來講,若是有的容器沒有設定 limit 限制,資源會被其餘的 pod 搶佔走,可能會形成容器應用失敗的狀況。能夠經過 limitrange 策略來去匹配,讓 pod 自動設定,前提是要提早配置好limitrange 規則。

來源:www.cnblogs.com/passzhang

Kubernetes 上對應用程序進行故障排除的 6 個技巧 推薦給你們,平常排錯必備。分享一份阿里雲內部超全K8s實戰手冊,免費下載!

面試題

一個目標:容器操做;兩地三中心;四層服務發現;五種 Pod 共享資源;六個 CNI 經常使用插件;七層負載均衡;八種隔離維度;九個網絡模型原則;十類 IP 地址;百級產品線;千級物理機;萬級容器;相如無億,k8s 有億:億級日服務人次。

一個目標:容器操做

Kubernetes(k8s)是自動化容器操做的開源平臺。這些容器操做包括:部署、調度和節點集羣間擴展。

具體功能:
  • 自動化容器部署和複製。

  • 實時彈性收縮容器規模。

  • 容器編排成組,並提供容器間的負載均衡。

  • 調度:容器在哪一個機器上運行。

組成:
  • kubectl:客戶端命令行工具,做爲整個系統的操做入口。

  • kube-apiserver:以 REST API 服務形式提供接口,做爲整個系統的控制入口。

  • kube-controller-manager:執行整個系統的後臺任務,包括節點狀態情況、Pod 個數、Pods 和Service 的關聯等。

  • kube-scheduler:負責節點資源管理,接收來自 kube-apiserver 建立 Pods 任務,並分配到某個節點。

  • etcd:負責節點間的服務發現和配置共享。

  • kube-proxy:運行在每一個計算節點上,負責 Pod 網絡代理。定時從 etcd 獲取到 service 信息來作相應的策略。

  • kubelet:運行在每一個計算節點上,做爲 agent,接收分配該節點的 Pods 任務及管理容器,週期性獲取容器狀態,反饋給 kube-apiserver。

  • DNS:一個可選的 DNS 服務,用於爲每一個 Service 對象建立 DNS 記錄,這樣全部的 Pod 就能夠經過 DNS 訪問服務了。

下面是 k8s 的架構拓撲圖:

圖片

兩地三中心


兩地三中心包括本地生產中心、本地災備中心、異地災備中心。

圖片

兩地三中心要解決的一個重要問題就是數據一致性問題。

k8s 使用 etcd 組件做爲一個高可用、強一致性的服務發現存儲倉庫。用於配置共享和服務發現。

它做爲一個受到 Zookeeper 和 doozer 啓發而催生的項目。除了擁有他們的全部功能以外,還擁有如下 4 個特色:

  • 簡單:基於 HTTP+JSON 的 API 讓你用 curl 命令就能夠輕鬆使用。

  • 安全:可選 SSL 客戶認證機制。

  • 快速:每一個實例每秒支持一千次寫操做。

  • 可信:使用 Raft 算法充分實現了分佈式。

四層服務發現

先一張圖解釋一下網絡七層協議:

圖片

k8s 提供了兩種方式進行服務發現:

  • 環境變量:當建立一個 Pod 的時候,kubelet 會在該 Pod 中注入集羣內全部 Service 的相關環境變量。須要注意的是,要想一個 Pod 中注入某個 Service 的環境變量,則必須 Service 要先比該 Pod 建立。這一點,幾乎使得這種方式進行服務發現不可用。 好比,一個 ServiceName 爲 redis-master 的 Service,對應的 ClusterIP:Port 爲 10.0.0.11:6379,則對應的環境變量爲:

image.png

  • DNS:能夠經過 cluster add-on 的方式輕鬆的建立 KubeDNS 來對集羣內的 Service 進行服務發現。

以上兩種方式,一個是基於 TCP,DNS 基於 UDP,它們都是創建在四層協議之上。

五種 Pod 共享資源

Pod 是 k8s 最基本的操做單元,包含一個或多個緊密相關的容器。

一個 Pod 能夠被一個容器化的環境看做應用層的「邏輯宿主機」;一個 Pod 中的多個容器應用一般是緊密耦合的,Pod 在 Node 上被建立、啓動或者銷燬;每一個 Pod 裏運行着一個特殊的被稱之爲 Volume 掛載卷,所以他們之間通訊和數據交換更爲高效。在設計時咱們能夠充分利用這一特性將一組密切相關的服務進程放入同一個 Pod 中。

圖片

同一個 Pod 裏的容器之間僅需經過 localhost 就能互相通訊。

一個 Pod 中的應用容器共享五種資源:

  • PID 命名空間:Pod 中的不一樣應用程序能夠看到其餘應用程序的進程 ID。

  • 網絡命名空間:Pod 中的多個容器可以訪問同一個IP和端口範圍。

  • IPC 命名空間:Pod 中的多個容器可以使用 SystemV IPC 或 POSIX 消息隊列進行通訊。

  • UTS 命名空間:Pod 中的多個容器共享一個主機名。

  • Volumes(共享存儲卷):Pod 中的各個容器能夠訪問在 Pod 級別定義的 Volumes。

Pod 的生命週期經過 Replication Controller 來管理;經過模板進行定義,而後分配到一個 Node 上運行,在 Pod 所包含容器運行結束後,Pod 結束。

Kubernetes 爲 Pod 設計了一套獨特的網絡配置,包括爲每一個 Pod 分配一個IP地址,使用 Pod 名做爲容器間通訊的主機名等。

六個 CNI 經常使用插件

CNI(Container Network Interface)容器網絡接口是 Linux 容器網絡配置的一組標準和庫,用戶須要根據這些標準和庫來開發本身的容器網絡插件。CNI 只專一解決容器網絡鏈接和容器銷燬時的資源釋放,提供一套框架。因此 CNI 能夠支持大量不一樣的網絡模式,而且容易實現。

下面用一張圖表示六個 CNI 經常使用插件:

image.png

七層負載均衡

提負載均衡就不得不先提服務器之間的通訊。

IDC(Internet Data Center)也可稱數據中心、機房,用來放置服務器。IDC 網絡是服務器間通訊的橋樑。

image.png 上圖裏畫了不少網絡設備,它們都是幹啥用的呢?

路由器、交換機、MGW/NAT 都是網絡設備,按照性能、內外網劃分不一樣的角色。

  • 內網接入交換機:也稱爲 TOR(top of rack),是服務器接入網絡的設備。每臺內網接入交換機下聯 40-48 臺服務器,使用一個掩碼爲 /24 的網段做爲服務器內網網段。
  • 內網核心交換機:負責 IDC 內各內網接入交換機的流量轉發及跨 IDC 流量轉發。
  • MGW/NAT:MGW 即 LVS 用來作負載均衡,NAT 用於內網設備訪問外網時作地址轉換。
  • 外網核心路由器:經過靜態互聯運營商或 BGP 互聯美團統一外網平臺。

先說說各層負載均衡:

  • 二層負載均衡:基於 MAC 地址的二層負載均衡。
  • 三層負載均衡:基於 IP 地址的負載均衡。
  • 四層負載均衡:基於 IP+端口 的負載均衡。
  • 七層負載均衡:基於 URL 等應用層信息的負載均衡。

這裏用一張圖來講說四層和七層負載均衡的區別:

image.png

上面四層服務發現講的主要是 k8s 原生的 kube-proxy 方式。k8s 關於服務的暴露主要是經過 NodePort 方式,經過綁定 minion 主機的某個端口,而後進行 Pod 的請求轉發和負載均衡,但這種方式有下面的缺陷:

  • Service 可能有不少個,若是每一個都綁定一個 Node 主機端口的話,主機須要開放外圍的端口進行服務調用,管理混亂。

  • 沒法應用不少公司要求的防火牆規則。

理想的方式是經過一個外部的負載均衡器,綁定固定的端口,好比 80;而後根據域名或者服務名向後面的 Service IP 轉發。

Nginx 很好的解決了這個需求,但問題是若是有的新的服務加入,如何去修改而且加載這些 Nginx 配置

Kubernetes 給出的方案就是 Ingress。這是一個基於七層的方案。

八種隔離維度

image.png

k8s 集羣調度這邊須要對上面從上到下、從粗粒度到細粒度的隔離作相應的調度策略。

九個網絡模型原則

k8s 網絡模型要符合四個基礎原則、三個網絡要求原則、一個架構原則、一個 IP 原則。

每一個 Pod 都擁有一個獨立的 IP 地址,並且假定全部 Pod 都在一個能夠直接連通的、扁平的網絡空間中,無論是否運行在同一 Node 上均可以經過 Pod 的 IP 來訪問。

k8s 中的 Pod 的 IP 是最小粒度 IP。同一個 Pod 內全部的容器共享一個網絡堆棧,該模型稱爲 IP-per-Pod 模型。

  • Pod 由 docker0 實際分配的 IP。

  • Pod 內部看到的 IP 地址和端口與外部保持一致。

  • 同一個 Pod 內的不一樣容器共享網絡,能夠經過localhost來訪問對方的端口,相似同一個虛擬機內不一樣的進程。

IP-per-Pod 模型從端口分配、域名解析、服務發現、負載均衡、應用配置等角度看,Pod 能夠看作是一臺獨立的虛擬機或物理機。

  • 全部容器均可以不用 NAT 的方式同別的容器通訊。

  • 全部節點均可以在不一樣 NAT 方式下同全部容器通訊,反之亦然。

  • 容器的地址和別人看到的地址是同一個地址。

要符合下面的架構:

圖片

由上圖架構引伸出來 IP 概念從集羣外部到集羣內部:

十類IP地址

你們都知道 IP 地址分爲 ABCDE 類,另外還有五類特殊用途的 IP。

第一類

A 類:1.0.0.0-1226.255.255.255,默認子網掩碼/8,即255.0.0.0。
B 類:128.0.0.0-191.255.255.255,默認子網掩碼/16,即255.255.0.0。
C 類:192.0.0.0-223.255.255.255,默認子網掩碼/24,即255.255.255.0。
D 類:224.0.0.0-239.255.255.255,通常用於組播。
E 類:240.0.0.0-255.255.255.255(其中255.255.255.255爲全網廣播地址)。E 類地址通常用於研究用途。
複製代碼

第二類

0.0.0.0
嚴格來講,0.0.0.0 已經不是一個真正意義上的 IP 地址了。它表示的是這樣一個集合:全部不清楚的主機和目的網絡。這裏的不清楚是指在本機的路由表裏沒有特定條目指明如何到達。做爲缺省路由。
127.0.0.1 本機地址。
複製代碼

第三類

224.0.0.1 組播地址。
若是你的主機開啓了IRDP(internet路由發現,使用組播功能),那麼你的主機路由表中應該有這樣一條路由。
複製代碼

第四類

169.254.x.x
使用了 DHCP 功能自動獲取了 IP 的主機,DHCP 服務器發生故障,或響應時間太長而超出了一個系統規定的時間,系統會爲你分配這樣一個 IP,表明網絡不能正常運行。
複製代碼

第五類

10.xxx、172.16.x.x~172.31.x.x、192.168.x.x 私有地址。
大量用於企業內部。保留這樣的地址是爲了不亦或是哪一個接入公網時引發地址混亂。
複製代碼

連接:blog.csdn.net/huakai_sun/article/details/82378856

採用 jenkins pipeline 實現自動構建並部署至 k8s
10個小技巧提升 Kubernetes 容器效率
Kubernetes 常見運維技巧總結
相關文章
相關標籤/搜索