導航:首頁 > 源碼編譯 > k8s源碼搭建

k8s源碼搭建

發布時間:2022-09-21 17:47:21

① 搭建k8s有哪些方式

② Kubernetes如何入門

一、初級
1.了解Kubernetes 基礎架構與核心組件功能
2.了解Docker基本概念和用法
3.理解Docker與Kubernetes的基本關系
4.能夠安裝、部署與配置 Kubernetes 集群
5.熟練使用 kubectl 命令操作各種 Kubernetes 資源對象,了解基本概念和使用方法
6.能夠在 Kubernetes 上部署、運行、管理工作負載並了解其調度演算法
7.能夠使用 Service、Ingress 等訪問工作負載
8.深入理解Pod相關的配置及使用
9.了解Kubernetes生態相關工具及其作用
二、中級
1.理解Kubernetes的資源管理,資源分配、優先順序、QoS等
2.能夠使用 Flannel、Calico、Macvlan 等常用 CNI 插件配置集群網路
3.能夠排查 Kubernetes 集群系統組件、網路、日誌、監控告警與存儲的故障
4.能夠使用 EFK 搭建容器日誌系統
5.能夠使用 Prometheus、AlertManager 等搭建容器監控告警系統
6.能夠配置應用使用持久性存儲並了解 Ceph、NFS、GlusterFS 等常見存儲工作原理
7.應用生命周期管理
8.理解Kubernetes容器調度的基本流程和使用方法
9.Kubernetes集群日常維護
10.理解並使用Kubernetes的用戶認證及授權體系(RBAC)
11.理解彈性伸縮(HPA)的基本原理
三、高級
1.理解Kubernets核心組件的工作原理,並能夠進行問題定位及提供解決方案
2.掌握Kubernetes的admission 控制器,audit,鏡像gc,Pod驅趕行為等相關工作原理
3.可以擴展和定製Kubernetes調度器
4.能夠用 Operator/CRD 對 Kubernetes 作定製化開發
5.理解 Kubernetes 多可用區/多集群管理模式
6.靈活掌握Kubernetes的擴展機制,可以按需定製,包括CNI、CSI、Ingress、自定義控制器等擴展定製
7.可以解決日誌、監控等核心組件的問題定位以及進行性能調優
四、專家
1.能夠對 Kubernetes 集群、操作系統、鏡像、應用做安全加固
2.能夠排查 linux 內核、Docker 容器運行時故障
3.能夠基於 Kubernetes、Jenkins等工具構建雲原生DevOps方案
4.理解Kubernetes生態主要工具的作用及優缺點,可以在不同場景下靈活運用相關工具並確定最佳實施方案
5.具備對大規模集群支持的相關經驗,包括架構設計、性能調優等穩定性保障
6.理解Kubernetes社區運作模式,能夠為社區提供PR
7.理解Kubernetes各組件源代碼,並能排查、分析相關問題
作為國內領先的全棧雲原生技術服務提供商,時速雲特別推出了Kubernetes培訓課程,對於剛接觸Kubernetes技術、企業計劃使用容器及Kubernetes集群、以及計劃考取CKA證書的人群會是一個不錯的選擇。

③ 如何 kubernetes源碼 編譯

我是怎麼閱讀kubernetes源代碼的 每拖進去一個viewconteoller,就新建一對viewcontroller的子對象.比如你想做一個登錄界面,拖一個viecomtroller到storyboard裡面,然後在你的項目裡面添加一個loginInterfac緝長光短叱的癸痊含花e(

④ 伺服器搭建k8s內存需要多大

你好!2gb或者4gb都行
1.什麼是k8s?
k8s是一個docker容器管理工具
它是一個全新的基於容器技術的分布式架構領先方案,是開源的容器集群管理系統。
在docker的基礎上,為容器化的應用提供部署運行,資源調度,服務發現和動態伸縮等一系列完整功能
2.----k8s的優勢:
a,容器編排
b,輕量級
c,開源
d,彈性伸縮
e,負載均衡
二:k8s的核心功能
1.自愈: 重新啟動失敗的容器,在節點不可用時,替換和重新調度節點上的容器,對用戶定義的健康檢查不響應的容器會被中止,並且在容器准備好服務之前不會把其向客戶端廣播。
彈性伸縮: 通過監控容器的cpu的負載值,如果這個平均高於80%,增加容器的數量,如果這個平均低於10%,減少容器的數量
服務的自動發現和負載均衡: 不需要修改您的應用程序來使用不熟悉的服務發現機制,Kubernetes 為容器提供了自己的 IP 地址和一組容器的單個 DNS 名稱,並可以在它們之間進行負載均衡。
滾動升級和一鍵回滾: Kubernetes 逐漸部署對應用程序或其配置的更改,同時監視應用程序運行狀況,以確保它不會同時終止所有實例。 如果出現問題,Kubernetes會為您恢復更改,利用日益增長的部署解決方案的生態系統。

⑤ kubernetes源碼是java

Kubernetes(簡稱k8s)是Google在2014年6月開源的一個容器集群管理系統,使用Go語言開發,用於管理雲平台中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單並且高效,Kubernetes提供了資源調度、部署管理、服務發現、擴容縮容、監控,維護等一整套功能。,努力成為跨主機集群的自動部署、擴展以及運行應用程序容器的平台。 它支持一系列容器工具, 包括Docker等。

所以注意:K8s學習有一個前提條件,需要先掌握docker,如果你沒有docker基礎的話,那還不能學習 K8s k8s它底層的部署容器的那麼容器本來就是docker。

還可以通過B站上這個視頻教程了解更多:

⑥ 什麼是K8S



k8s是什麼?

Kubernetes 是一個可移植的,可擴展的開源容器編排平台,用於管理容器化的工作負載和服務,方便了聲明式配置和自動化。它擁有一個龐大且快速增長的生態系統。Kubernetes 的服務,支持和工具廣泛可用。

為什麼現在流行使用容器?

早期: 在物理伺服器上面部署應用程序存在資源分配問題,因為其不能在物理伺服器中的應用程序定義資源邊界,導致應用程序資源利用不足而無法擴展.

後來: 為了解決該問題,引入了虛擬化技術, 虛擬化技術是指允許你在單個物理伺服器的 CPU 上運行多個虛擬機,可以讓多個應用程序在虛擬機之間進行隔離,具有一定的安全性, 每一個虛擬機就是一台完整的計算機, 在虛擬化硬體之上運行所有組件.

現在: 多數在物理伺服器上面部署應用程序都是采kubectl用容器的方式,容器類似於虛擬機,它們都具有自己的文件系統、CPU、內存、進程空間等, 且由於它們與基礎架構分離,因此可以跨雲和 OS 發行版本進行移植。基於此特點被企業大范圍使用.

為什麼需要使用k8s容器?

若出現這樣一個環境: 在生產環境中如果一個容器發生故障,則我們需要手動去啟動另外一個容器,這樣的操作是對我們的管理員來說是不太方便的, 若一個容器出現故障,另一個容器可以自動啟動容器接管故障的容器,這樣是最好的.

k8s就可以實現該效果,Kubernetes 提供了一個可彈性運行分布式系統的框架。 Kubernetes 會滿足你的擴展要求、故障轉移、部署模式等。

k8s功能: 服務發現和負載均衡, 存儲編排, 自動部署和回滾, 自動完成裝箱計算, 自我修復, 密鑰與配置管理

名詞解釋

secret

Secret有三種類型:

k8s的組成

k8s是由組件,API,對象等組成.

包含所有相互關聯組件的 Kubernetes 集群圖如下:

組件


API

Kubernetes 控制面 的核心是 API 伺服器。 API 伺服器負責提供 HTTP API,以供用戶、集群中的不同部分和集群外部組件相互通信。

對象

Kubernetes對象是Kubernetes系統中的持久實體。Kubernetes使用這些實體來表示集群的狀態.

具體來說,他們可以描述:

Kubernetes 架構

Kubernetes 架構由節點,控制面到節點通信, 控制器, 雲控制器管理器組成.

master 流程圖


節點

節點可以是一個虛擬機或者物理機器,取決於所在的集群配置。 每個節點包含運行 Pods 所需的服務, 這些 Pods 由 控制面 負責管理.

節點上的組件包括 kubelet、 容器運行時以及 kube-proxy。

節點狀態

可以使用 kubectl 來查看節點狀態和其他細節信息:

kubectl describe node <�節點名稱>

一個節點包含以下信息:

控制面到節點通信

控制器

在 Kubernetes 中,控制器通過監控集群 的公共狀態,並致力於將當前狀態轉變為期望的狀態。

舉個例子: 當前室內溫度為20度, 我們通過調節遙控器,使其溫度上升至24度, 這20度到24度的變化即為讓其從當前狀態接近期望狀態。

控制器模式分為直接控制和通過API伺服器來控制.

雲控制器管理器

雲控制器管理器是指嵌入特定雲的控制邏輯的 控制平面組件。 雲控制器管理器允許您鏈接聚合到雲提供商的應用編程介面中, 並分離出相互作用的組件與您的集群交互的組件。

雲控制器管理器中的控制器包括:

Kubernetes 安全性

雲原生安全

雲原生安全4個C: 雲(Cloud)、集群(Cluster)、容器(Container)和代碼(Code)

雲原生安全模型的每一層都是基於下一個最外層,代碼層受益於強大的基礎安全層(雲、集群、容器)。我們無法通過在代碼層解決安全問題來為基礎層中糟糕的安全標准提供保護。

基礎設施安全

Kubetnetes 基礎架構關注領域

建議

通過網路訪問 API 服務(控制平面)

所有對 Kubernetes 控制平面的訪問不允許在 Internet 上公開,同時應由網路訪問控制列表控制,該列表包含管理集群所需的 IP 地址集。

通過網路訪問 Node(節點)

節點應配置為 僅能 從控制平面上通過指定埠來接受(通過網路訪問控制列表)連接,以及接受 NodePort 和 LoadBalancer 類型的 Kubernetes 服務連接。如果可能的話,這些節點不應完全暴露在公共互聯網上。

Kubernetes 雲訪問提供商的 API

每個雲提供商都需要向 Kubernetes 控制平面和節點授予不同的許可權集。為集群提供雲提供商訪問許可權時,最好遵循對需要管理的資源的最小特權原則。Kops 文檔提供有關 IAM 策略和角色的信息。

訪問 etcd

對 etcd(Kubernetes 的數據存儲)的訪問應僅限於控制平面。根據配置情況,你應該嘗試通過 TLS 來使用 etcd。更多信息可以在 etcd 文檔中找到。

etcd 加密

在所有可能的情況下,最好對所有驅動器進行靜態數據加密,但是由於 etcd 擁有整個集群的狀態(包括機密信息),因此其磁碟更應該進行靜態數據加密。

集群組件安全

容器安全

代碼安全

Kubernetes架構常見問題

Kubernetes ATTACK 矩陣

信息泄露

雲賬號AK泄露

API憑證(即阿里雲AccessKey)是用戶訪問內部資源最重要的身份憑證。用戶調用API時的通信加密和身份認證會使用API憑證.

API憑證是雲上用戶調用雲服務API、訪問雲上資源的唯一身份憑證。

API憑證相當於登錄密碼,用於程序方式調用雲服務API.

k8s configfile泄露

kubeconfig文件所在的位置:

$HOME/.kube/config

Kubeconfig文件包含有關Kubernetes集群的詳細信息,包括它們的位置和憑據。

雲廠商會給用戶提供該文件,以便於用戶可以通過kubectl對集群進行管理. 如果攻擊者能夠訪問到此文件(如辦公網員工機器入侵、泄露到Github的代碼等),就可以直接通過API Server接管K8s集群,帶來風險隱患。

Master節點SSH登錄泄露

常見的容器集群管理方式是通過登錄Master節點或運維跳板機,然後再通過kubectl命令工具來控制k8s。

雲伺服器提供了通過ssh登陸的形式進行登陸master節點.

若Master節點SSH連接地址泄露,攻擊者可對ssh登陸進行爆破,從而登陸上ssh,控制集群.

容器組件未鑒權服務

Kubernetes架構下常見的開放服務指紋如下:

注:前六個重點關注: 一旦被控制可以直接獲取相應容器、相應節點、集群許可權的服務

了解各個組件被攻擊時所造成的影響

組件分工圖:

假如用戶想在集群裡面新建一個容器集合單元, 流程如下:

  1. 用戶與 kubectl進行交互,提出需求(例: kubectl create -f pod.yaml)
  2. kubectl 會讀取 ~/.kube/config 配置,並與 apiserver 進行交互,協議:http/https
  3. apiserver 會協同 ETCD, kube-controller-manager, scheler 等組件准備下發新建容器的配置給到節點,協議:http/https
  4. apiserver 與 kubelet 進行交互,告知其容器創建的需求,協議:http/https;
  5. kubelet 與Docker等容器引擎進行交互,創建容器,協議:http/unix socket.
  6. 容器已然在集群節點上創建成功

攻擊apiserver

apiserver介紹:
在Kubernetes中,對於未鑒權對apiserver, 能訪問到 apiserver 一般情況下就能獲取了集群的許可權.

在攻擊者眼中Kubernetes APIServer

默認情況下apiserver都有鑒權:

未鑒權配置如下:

對於這類的未鑒權的設置來說,訪問到 apiserver 一般情況下就獲取了集群的許可權:

如何通過apiserver來進行滲透,可參考:https://Kubernetes.io/docs/reference/generated/kubectl/kubectl-commands

攻擊kubelet

每一個Node節點都有一個kubelet(每個節點上運行的代理)服務,kubelet監聽了10250,10248,10255等埠。

10250埠,是kubelet與apiserver進行通信對主要埠, 通過該埠,kubelet可以知道當前應該處理的任務.該埠在最新版Kubernetes是有鑒權的, 但在開啟了接受匿名請求的情況下,不帶鑒權信息的請求也可以使用10250提供的能力, 在Kubernetes早期,很多挖礦木馬基於該埠進行傳播.

在配置文件中,若進行如下配置,則可能存在未授權訪問漏洞.

/var/bin/kubulet/config/yaml

若10250埠存在未授權訪問漏洞,我們可以直接訪問/pods進行查看

根據在pods中獲取的信息,我們可以在容器中執行命令

curl -Gks https://host:10250/exec/{namespace}/{podname}/{containername} -d 'input=1' -d 'output=1' -d 'tty=1' -d 'command=whoami'

上述命令得到websocket地址,連接websocket得到命令結果:

使用wscat工具連接websocket

wscat -c 「https://X.X.X.X:10250/{websocket}」 --no-check

即可得到我們執行命令的結果.

獲取token

/var/run/secrets/kubernetes.io/serviceaccount

然後即可訪問kube-api server,獲取集群許可權

curl -ks -H "Authorization: Bearer ttps://master:6443/api/v1/namespaces/{namespace}/secrets

"

攻擊kubelet總體步驟如下:

攻擊dashboard

dashboard登陸鏈接如下:

http://xxx.xxx.xxx.xxx:xxxx/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login

dashboard界面如下:

dashboard是Kubernetes官方推出的控制Kubernetes的圖形化界面.在Kubernetes配置不當導致dashboard未授權訪問漏洞的情況下,通過dashboard我們可以控制整個集群。

默認情況下, dashboard是需要進行鑒權操作的,當用戶開啟了enable-skip-login時可以在登錄界面點擊Skip跳過登錄進入dashboard.

通過skip登陸的dashboard默認是沒有操作集群的許可權,因為Kubernetes使用RBAC(Role-based access control)機制進行身份認證和許可權管理,不同的serviceaccount擁有不同的集群許可權。

但有些開發者為了方便或者在測試環境中會為Kubernetes-dashboard綁定cluster-admin這個ClusterRole(cluster-admin擁有管理集群的最高許可權).

為Kubernetes-dashboard綁定cluster-admin 設置如下:

  1. 新建dashboard-admin.yaml內容
  2. apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: kubernetes-dashboardroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-adminsubjects : kind: ServiceAccount name: kubernetes-dashboard namespace: kubernetes-dashboard
  3. kubectl create -f dashboard-admin.yaml

後通過skip登陸dashboard便有了管理集群的許可權.

創建Pod控制node節點,該pod主要是將宿主機根目錄掛載到容器tmp目錄下。

新建一個Pod如下:

通過該容器的tmp目錄管理node節點的文件

攻擊etcd

Kubernetes默認使用了etcd v3來存儲數據, 若能na
etcd對內暴露2379埠,本地127.0.0.1可免認證訪問. 其他地址要帶—endpoint參數和cert進行認證。

未授權訪問流程:

攻擊docker remote api(Docker daemon公網暴露)

2375是docker遠程操控的默認埠,通過這個埠可以直接對遠程的docker 守護進程進行操作。Docker 守護進程默認監聽2375埠且未鑒權.

當機器以方式啟動daemon時,可以在外部機器對該機器的docker daemon進行直接操作:

docker daemon -H=0.0.0.0:2375

之後依次執行systemctl daemon-reload、systemctl restart docker

外部主機使用 即可操作暴露2375埠的主機.

-H

因此當你有訪問到目標Docker API 的網路能力或主機能力的時候,你就擁有了控制當前伺服器的能力。我們可以利用Docker API在遠程主機上創建一個特權容器,並且掛載主機根目錄到容器.

檢測目標是否存在docker api未授權訪問漏洞的方式也很簡單,訪問http://[host]:[port]/info路徑是否含有ContainersRunning、DockerRootDir等關鍵字。

攻擊kubectl proxy

二次開發所產生的問題

管理Kubernetes無論是使用 kubectl 或 Kubernetes dashboard 的UI功能,其實都是間接在和 APIServer 做交互.

如果有需求對k8s進行二次開發的話,大部分的開發功能請求了 APIServer 的 Rest API 從而使功能實現的。

例如:

類似於這樣去調用apiserver, 攻擊者若修改namespace、pod和容器名, 那麼即可造成越權.

推薦工具

Kube-Hunter掃描漏洞

kube-hunter是一款用於尋找Kubernetes集群中的安全漏洞掃描器

下載地址: https://github.com/aquasecurity/kube-hunter

CDK(強推)

CDK是一款為容器環境定製的滲透測試工具,在已攻陷的容器內部提供零依賴的常用命令及PoC/EXP。集成Docker/K8s場景特有的 逃逸、橫向移動、持久化利用方式,插件化管理。

下載地址: https://github.com/cdk-team/CDK/wiki/CDK-Home-CN

參考鏈接

https://developer.aliyun.com/article/765449?groupCode=aliyunsecurity
https://xz.aliyun.com/t/4276#toc-2
https://www.secrss.com/articles/29544
https://kubernetes.io/zh/docs/concepts/workloads/pods/#what-is-a-pod
https://www.huweihuang.com/kubernetes-notes/concepts/architecture/kubernetes-architecture.html
https://www.kubernetes.org.cn/service-account
https://www.aquasec.com/cloud-native-academy/cloud-native-applications/cloud-native-infrastructure/
https://www.cdxy.me/?p=827

⑦ 企業級k8s集群部署

二進制包

註:推薦用二進制包部署Kubernetes集群,雖手動部署麻煩,但可以學習很多工作原理利於後期維護。

環境

可以使用VMware虛擬機,宿主機必須8G內存以上

• 伺服器可以訪問外網,有從網上拉取鏡像的需求

單Master伺服器規劃:( 註:部署時候根據具體環境進行IP地址調整即可 )



這里使用3台組建集群,可容忍1台機器故障,當然,你也可以使用5台組建集群

etcd1: 192.168.3.110 etcd2: 192.168.3.112 etcd3: 192.168.3.113

cfssl是一個開源的證書管理工具,使用json文件生成證書,相比openssl更方便使用。

找任意一台伺服器操作,這里用Master節點。

創建工作目錄:

自簽CA:

生成證書:

會生成ca.pem和ca-key.pem文件。

創建證書申請文件:

註:上述文件hosts欄位中IP為所有etcd節點的集群內部通信IP,一個都不能少!為了方便後期擴容可以多寫幾個預留的IP。

生成證書:

會生成etcd.pem和etcd-key.pem文件。

https://github.com/etcd-io/etcd/releases/download/v3.5.1/ etcd-v3.5.1-linux-amd64.tar.gz

以下在節點1上操作,然後將文件拷貝到其他集群機器

把剛才生成的證書拷貝到配置文件中的路徑:

注意修改節點2和節點3分別etcd.conf配置,按照下面提示的修改

啟動各節點的etcd服務

如果輸出上面信息,就說明集群部署成功。

如果有問題看日誌:/var/log/message

docker二進制下載地址:

https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz

註:使用yum安裝也行

集群所有機器都安裝docker

生成證書:

會生成ca.pem和ca-key.pem文件。

創建證書申請文件:

生成證書:

會生成k8s.pem和k8s-key.pem文件。

下載地址參考:

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#downloads-for-v12013

Wget https://dl.k8s.io/v1.20.13/kubernetes-server-linux-amd64.tar.gz


把剛才生成的證書拷貝到配置文件中的路徑:

TLS Bootstrapping 機制,對work-node加入進行自簽證書用


創建上述配置文件中token文件:

token 可以自行生產,網路下怎麼生產

kube-apiserver服務


生成kube-controller-manager證書:

生成kubeconfig文件(以下是shell命令,直接在終端執行):

生成kube-scheler證書:

生成kubeconfig文件:


生成kubeconfig文件:

通過kubectl工具查看當前集群組件狀態:


在所有worker node創建工作目錄:

從master節點拷貝:

註:由於網路插件還沒有部署,節點會沒有準備就緒 NotReady

二進制包下載地址:https://github.com/containernetworking/plugins/releases



確保kubelet啟用CNI:




在Master執行:



應用場景:例如kubectl logs

在Master節點將Worker Node涉及文件拷貝到新節點192.168.3.112/113

註:這幾個文件是證書申請審批後自動生成的,每個Node不同,必須刪除

Node2(192.168.3.113 )節點同上。記得修改主機名!


訪問地址:https://NodeIP:30001

創建service account並綁定默認cluster-admin管理員集群角色:

使用輸出的token登錄Dashboard。

CoreDNS用於集群內部Service名稱解析。

DNS解析測試:

這樣 單Master集群就搭建完成了



⑧ 計算機網路-k8s網路

K8S網路模型設計:扁平的可連通的網路

K8S的網路是一個極其復雜的網路,如果想要用兩個簡單的詞來描述K8S網路,那麼我覺得扁平和可連通是K8S網路最大的特點(不懂隔離性)。

何為連通呢?

二層網路的連通:如果能夠直接通過MAC幀直接通信的網路便是二層連通的網路,LAN就是這種網路

比如無限WIFI網路,比如乙太網

三層網路的連通:如果能夠通過IP報直接通信的網路便是三層連通的網路,便是三層連通

三層網路的連通分為兩個部分,第一個部分是三層網路中的每一個LAN都是二層連通的,其次需要存在能夠連通的路由來保證;這里可以簡單回顧下三層網路通信的流程

通過路由表確定目標ip是否在鏈路上

如果在鏈路上,通過arp協議獲取對應主機的mac地址,發送mac幀到鏈路上;

如果不在同一個鏈路上,通過本地路由表發送mac幀給下一跳,然後下一跳解析mac幀,分析ip報,繼續路由直到最終跳到目標網路再次通過mac幀發送到目標主機或者到達ttl消失。

假如其中任何一個步驟不滿足或者出問題,三層網路就無法連通

何為扁平呢?

就是希望可以在pod內直接通過IP進行互相通信而不需要在pod內部使用vpn之類的東西來連接其他pod(基礎架構化),具體的可以看下k8s對網路的設計與要求。

k8s在設計其網路時,就希望網路對運行在其中的pod是透明的,因此提出了以下的一些要求與原則

k8s組網要求

所有的Pods之間可以在不使用 NAT網路地址轉換 的情況下相互通信

所有的Nodes之間可以在不使用NAT網路地址轉換的情況下相互通信

每個Pod自己看到的自己的ip和其他Pod看到的一致

k8s網路模型設計原則

每個Pod都擁有一個獨立的 IP地址,而且 假定所有 Pod 都在一個可以直接連通的、扁平的網路空間中 。

不管它們是否運行在同 一 個 Node (宿主機)中,都要求它們可以直接通過對方的 IP 進行訪問。

設計這個原則的原因 是,用戶不需要額外考慮如何建立 Pod 之間的連接,也不需要考慮將容器埠映射到主機埠等問題。

而要想深入了解K8S的網路,就不得不去了解Linux操作系統中的網路以及計算機網路協議棧和一些網路技術

其中關於計算機網路協議棧道部分上次分享已經分享過了,所以本次的主題更多是Linux操作系統的網路以及一些網路技術

Linux操作系統中的網路

首先,我們來看下基本的linux網路,如下圖所示

一個APP生成socket數據,然後經過網路協議棧包裝IP報文,然後封裝成MAC幀,在經過網路協議棧的過程中,會存在netfilters對數據進行一定的處理,同時也會存在路由的過程,

如果在同一個物理鏈路內,將直接通過ARP協議獲取目標IP地址的MAC地址最終發送出去;

如果不在同一個物理鏈路則通過路由表確定下一跳的MAC地址,封裝成MAC幀發送到目標地址。

在這個過程中,會根據路由表選擇對應的埠,如果是lo埠,則會將幀原封不動的返回計算機網路協議棧,然後回到監聽對應埠的SOCKET里。

如果是乙太網埠則走乙太網埠,如果是藍牙或者無線網埠同理。

iptables與netfilters

iptables是一個用戶空間的應用程序,通過該程序可以修改一些配置文件,這些文件定義了防火牆的一些行為,netfilters是操作系統內核的一部分,netfilters里有5個回調鉤子會觸發iptables里的規則;iptables只是Linux防火牆的管理工具而已,位於/sbin/iptables。真正實現防火牆功能的是

netfilter,它是Linux內核中實現包過濾的內部結構。

這里不具體講述其實現的原理,僅僅列出netfilters的一些功能:

1)filter表——三個鏈:INPUT、FORWARD、OUTPUT

作用:過濾數據包 內核模塊:iptables_filter.

2)Nat表——三個鏈:PREROUTING、POSTROUTING、OUTPUT

作用:用於網路地址轉換(IP、埠) 內核模塊:iptable_nat

3)Mangle表——五個鏈:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD

作用:修改數據包的服務類型、TTL、並且可以配置路由實現QOS內核模塊:iptable_mangle(別看這個表這么麻煩,咱們設置策略時幾乎都不會用到它)

4)Raw表——兩個鏈:OUTPUT、PREROUTING

作用:決定數據包是否被狀態跟蹤機制處理 內核模塊:iptable_raw

虛擬網路設備 tap/tun

TUN 和 TAP 設備是 Linux 內核虛擬網路設備,純軟體實現。TUN(TUNnel)設備模擬網路層設備,處理三層報文如 IP

報文。TAP 設備模擬鏈路層設備,處理二層報文,比如乙太網幀。TUN 用於路由,而 TAP 用於創建網橋。OS 向連接到 TUN/TAP

設備的用戶空間程序發送報文;用戶空間程序可像往物理口發送報文那樣向 TUN/TAP 口發送報文,在這種情況下,TUN/TAP

設備發送(或注入)報文到 OS 協議棧,就像報文是從物理口收到一樣。

虛擬網路設備 veth-pairs

虛擬乙太網電纜。使用雙向有名管道實現。常用於不同 namespace 之間的通信,即 namespace 數據穿越或容器數據穿越。

虛擬網路設備 bridge

bridge是linux自帶的虛擬交換機(網橋),其可以連接多個乙太網設備,擁有智能處理MAC幀的能力,流向交換機的MAC幀將智能的被傳輸到相應的二層鏈路

網路命名空間

在 Linux 中,網路名字空間可以被認為是隔離的擁有單獨網路棧(網卡、路由轉發表、iptables)的環境。網路名字空間經常用來隔離網路設備和服務,只有擁有同樣網路名字空間的設備,才能看到彼此。

從邏輯上說,網路命名空間是網路棧的副本,有自己的網路設備、路由選擇表、鄰接表、Netfilter表、網路套接字、網路procfs條目、網路sysfs條目和其他網路資源。

從系統的角度來看,當通過clone()系統調用創建新進程時,傳遞標志CLONE_NEWNET將在新進程中創建一個全新的網路命名空間。

從用戶的角度來看,我們只需使用工具ip(package is iproute2)來創建一個新的持久網路命名空間。

從系統實現來說,就是原本一個數據結構是static公共的,後來變成進程私有的,在PCB里存在一個命名空間的結構,命名空間里有著網路命名空間,網路命名空間擁有著所有跟網路相關的配置數據

默認空的網路命名空間可能只有一個未啟動的lo回環網卡。

兩個網路命名空間可以通過乙太網攬直接連著兩個網路命名空間的網卡,也可以通過乙太網網橋連接。

通過乙太網網橋或者乙太網攬連接的兩個網路命名空間只能說是在二層連通的,如果希望在三層連通,還需要給每個網路命名空間配置相應的路由表規則以及分配IP地址。

如何使用虛擬網路設備聯通網路命名空間

SingleHost容器網路

none模式

本質上就是創建一個網路命名空間,裡面沒有路由表,也沒有通過veths-pair連接任何鏈路,外部無法訪問這個容器,容器也無法訪問外部

host模式

本質上就是使用宿主機的默認網路命名空間

container模式

本質上就是將當前容器部署在另一個容器所在的網路命名空間,這樣發給本地的報文最終通過回環網卡回到了本機,這是同一個網路命名空間可以互通的原因

bridge模式

橋接模式就是在這些網路命名空間通過veth-pairs連接到同一個虛擬交換機上(二層連通),同時在對應的命名空間配置對應的路由表規則,但是從圖片中可以看到交換機另一端連的上網路協議棧。

也就是那些MAC幀都會被宿主機接收,但是宿主機接收並不一定會處理,比如並沒有開啟ip轉發功能(工作於路由器模式還是主機模式),那麼不是本地ip的報文都會被丟棄;或者說netfilters拒絕處理

這些奇怪的報文。

理論上,這些容器發送給其他容器的mac報文是會被虛擬交換機智能轉發到對應的容器的,這是同一主機不同容器互相連通的原因

假如宿主機配備了相應的路由規則和防火牆規則,那麼容器的報文說能夠通過路由最終轉發出去的,這也是容器訪問互聯網的原理

但是這種模式是沒法運用在多主機的情況下,因為宿主機不知道其他宿主機里的虛擬網路的路由,當相關ip報到達宿主機時,這些ip報將會被宿主機交給默認路由(下一跳:路由器)

最終路由器會把相關的ip報丟失或者到達ttl最終丟失

MultiHost容器網路

路由方案

回顧docker的單機網路模型,我們發現多主機不能通行的原因就在於你只能給當前主機配置路由規則和防火牆規則,而其他主機並不知道這些ip在你的虛擬網路中,假如能夠將這些路由信息同步到其他

宿主機,那麼網路便會打通。比較直接的想法就是給每台宿主機配置路由規則。而路由規則要求下一跳必須在當前網路,所以假如宿主機是二層互聯的,那麼通過給這些宿主機同步這些路由規則便能夠

實現一個扁平的連通的網路。

其中布置在每一台宿主機可以通過k8s的daemonSet實現,而這種數據的管理可以交給etcd來實現。

這類方案便是基於路由,基於這個方案的實現有基於靜態路由的flannel的host-gateway,以及基於動態路由的calico(使用邊際路由協議以及一堆深奧的名詞的實現)。

下面來看看Flannel的host-gateway原理(每一台宿主機都相當於本機容器網路的路由器):

通過路由方案構建的網路,宿主機也能訪問這些虛擬網路里的Pod

詢問基德大佬得知國際化sit環境的k8s網路介面實現就是Flannel的Host-gateway,而我們的辦公網路和集群網路之間的路由是搭建好的,所以我們應該可以直接通過podId訪問pod里的服務

下面是sit環境的兩個服務

跟蹤路由發現符合猜想

其中10.1.9.56和10.1.1.24就是宿主機的ip,這些宿主機在一個LAN里,這些宿主機相當於虛擬網路中的路由器;

猜測我們辦公網和qunhe集群在一個VLAN里(二層可達)

隧道方案

隧道方案比較典型的就是UDP和XVLAN,兩者都是使用Overlay網路(覆蓋網路,所謂的大二層技術);其實用隧道技術最多的是VPN應用

其中UDP是XVLAN的替代品(早期Linux沒有支持XVLAN協議,通過tun/tap技術將流量引到用戶空間然後解包生成包再發,因為發生在用戶空間而且多次導致性能較差,所以一般不推薦,除非你的linux版本比較低沒法用xvlan)

下面就簡單介紹下XVLAN技術的大概原理,下圖是XVLAN的報文格式,可以發現就是在高層協議的報文里塞了二層報文

其中XVLAN頭里有一個關鍵的欄位,VNID這是個24位的欄位,每個虛擬的網路主機都有一個自身的VNID作為標識,理論上支持2的24次方個虛擬網路。

在docker的橋接網路里,是使用docker0網橋,在Flannel的xvlan方案里則是使用cni0作為網橋(和docker0沒啥區別),主要的不同是cni網橋後面連接的是flannel.1這個網路設備,應該是一個虛擬網卡

這個網卡將原始報文包裝成XVLAN報文(linux高版本支持xvlan報文)

這時需要的信息有 源nodeId,目標nodeId,源vnid,源macId,目標macId,源podId,目標podId

其中目標nodeId,目標macId這兩個信息是不存在的;因此需要有個方式根據目標podId獲取目標nodeId以及目標macId

因此需要記錄如何根據目標podId獲取目標macId以及目標nodeId即可

這些數據是可以託管在某個地方的,Flannel就是將這些信息記錄在etcd上

在每個node上的flannel.1網路設備通過etcd來通過對方的podId獲取nodeId和macId

這樣最終報文就變成了一個源ip是源nodeIp,目標ip是目標nodeIp的IP報文了(兩台宿主機三層可達)

原本經過虛擬網橋是直接連接網路協議棧,但在xvlan模式下,則改為連接一個flannel1,在flannel1中將對原始報文封裝成overlay報文轉發

udp模式類似,只是udp轉發報文說通過tap連通到用戶空間,用戶空間對報文進行處理然後發送(因為多次內核態用戶態切換且數據問題,性能較差,僅在不支持xvlan的低版本linux中使用)

當然xvlan是一個技術,上面只是簡單介紹最簡單的形式

參考:

開發內功修煉之網路篇: https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MjM5Njg5NDgwNA==&action=getalbum&album_id=1532487451997454337&scene=173&from_msgid=2247485270&from_itemidx=1&count=3&nolastread=1#wechat_redirect

K8S知識圖譜: https://zhaohuabing.com/post/2020-02-22-k8s-mindmap/

VXLAN協議原理簡介: https://cizixs.com/2017/09/25/vxlan-protocol-introction/

⑨ 在k8s中部署redis cluster實戰

  項目需要在k8s上搭建一個redis cluster集群,網上找到的教程例如:
   github原版帶配置文件
   在原版基礎上補充詳細使用步驟但是無配置文件版
   手把手教你一步一步創建的一篇博客
  redis運行在容器中時必須選擇一種外部存儲方案,用來保存redis的持久化文件,否則容器銷毀重建後無法讀取到redis的持久化文件(隨著容器一同銷毀了);並且還要保證容器重建後還能讀取到之前對應的持久化文件。上面的教程使用的是nfs存儲,但是受於條件限制本文只能使用宿主機的本地目錄來做存儲,與上面的教程有一些不一樣的地方。
  本文的目的是講一下使用local pv來作為存儲創建redis cluster集群的步驟,以及說明過程中需要注意的問題。

  Kubernetes支持幾十種類型的後端存儲卷,其中本地存儲卷有3種,分別是emptyDir、hostPath、local volume,尤其是local與hostPath這兩種存儲卷類型看起來都是一個意思。這里講一下區別。

emptyDir

hostPath

local volume

pv的回收策略有三種:Retain、Recycle、Delete,可以在腳本中指定:

也可以在pv創建成功後使用命令修改:

假設有一個pv叫test-pv,綁定的pvc角坐test-pvc,test-pv使用的local pv

會刪除test-pv在對應存儲空間上的數據。NFS目前不支持 Delete,支持Delete的存儲空間有AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等(網上看的,沒測試過)。

  前面已經說過,redis有數據持久化需求,並且同一個pod重啟後需要讀取原來對應的持久化數據,這一點在不使用k8s時很容易實現(只使用docker不使用k8s時也很容易),啟動redis cluster每個節點時指定其持久化目錄就行了,但是k8s的Deployment的調度對於我們這個需求來說就顯得很隨機,你無法指定deployment的每個pod使用哪個存儲,並且重啟後仍然使用那個存儲。
  Deployment不行,Statefulset可以。官方對Statefulset的優點介紹是:

  看完還是比較迷糊,我們可以簡單的理解為原地更新,更新後還是原來那個pod,只更新了需要更新的內容(一般是修改自己寫的程序,與容器無關)。
  Statefulset和local pv結合,redis cluster的每個pod掛掉後在k8s的調度下重啟時都會使用之前自己的持久化文件和節點信息。

  創建StorageClass的目的是deployment中根據StorageClass來自動為每個pod選擇一個pv,否則手動為每個pod指定pv又回到了老路上。

  創建6個pv,因為redis cluster最低是三主三從的配置,所以最少需要6個pod。後面的pv2~pv5我就不貼出來了。

  Headless service是StatefulSet實現穩定網路標識的基礎,需要提前創建。

  每個Pod都會得到集群內的一個DNS域名,格式為 (service name).$(namespace).svc.cluster.local。可以在pod中ping一下這些域名,是可以解析為pod的ip並ping通的。

  這個service是可以自由發揮的,使用port-forward、NodePort還是ingress你自己選擇,我這里只是一個內網訪問統一入口。

  至此,redis cluster的六個節點都已經創建成功。下面需要創建集群(此時就是6個單節點的redis,並不是一個集群)。

  我們之前都是通過外部安裝redis-trib創建的集群,但是根據 這篇文章 redis 5.0之後已經內置了redis-trib工具,感興趣的可以嘗試。
  專門啟動一個Ubuntu/CentOS的容器,可以在該容器中安裝Redis-tribe,進而初始化Redis集群,執行:
kubectl run -i --tty centos --image=centos --restart=Never /bin/bash
成功後,我們可以進入centos容器中,執行如下命令安裝基本的軟體環境:

然後執行如下命令創建集群:

根據提示一步一步完成。

  否則報錯例如 MOVED 1545 10.244.3.239:6379","data":false
  如本文的情況,redis cluster的每個節點都是一個跑在k8s裡面的pod,這些pod並不能被外部直接訪問,而是通過ingress等方法對外暴露一個訪問介面,即只有一個統一的ip:port給外部訪問。經由k8s的調度,對這個統一介面的訪問會被發送到redis集群的某個節點。這時候對redis的用戶來說,看起來這就像是一個單節點的redis。但是, 此時無論是直接使用命令行工具redis-cli,還是某種語言的sdk,還是需要按照集群來配置redis的連接信息,才能正確連接 ,例如

  這里-c就代表這是訪問集群,又或者springboot的redis配置文件

閱讀全文

與k8s源碼搭建相關的資料

熱點內容
雞料與雞糞的演算法 瀏覽:833
phpif變數為空值 瀏覽:59
iot編譯器異常 瀏覽:600
代理伺服器被禁用怎麼上網 瀏覽:411
隱私加密怎麼設置密碼 瀏覽:940
馬丁靴補色解壓 瀏覽:565
在設置app上怎麼找到個人熱點 瀏覽:754
按照檔案號生成文件夾 瀏覽:1000
程序員轉方向 瀏覽:111
lol敏捷加密 瀏覽:882
傳統公司眼中的加密貨幣 瀏覽:430
電腦圖標又出現文件夾怎麼去掉 瀏覽:964
排序演算法c和a 瀏覽:418
手機拍照上傳android 瀏覽:343
linux壓縮率 瀏覽:614
電腦瀏覽器加密埠 瀏覽:536
單片機線性電源 瀏覽:268
韓國雲伺服器評測 瀏覽:740
python輸出hello 瀏覽:594
如何在最左側添加文件夾 瀏覽:500