⑴ 伺服器搭建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會為您恢復更改,利用日益增長的部署解決方案的生態系統。
⑵ 什麼是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架構下常見的開放服務指紋如下:
注:前六個重點關注: 一旦被控制可以直接獲取相應容器、相應節點、集群許可權的服務
了解各個組件被攻擊時所造成的影響
組件分工圖:
假如用戶想在集群裡面新建一個容器集合單元, 流程如下:
攻擊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 設置如下:
後通過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
⑶ 雲計算時代操作系統Kubernetes之PV,PVC存儲體系
我們前邊的關於存儲卷的討論,都是在講如何將網路存儲設備掛載到我們的應用程序POD中,而在實際項目上,我們必須對集群所提供存儲技術和類型有深入的理解,才能順利完成將支持類型的volume掛載到容器中,供應用程序來持久化數據。
舉個例子,如果你使用的是託管的阿里巴巴ACK集群,需要使用OSS存儲類型,那麼你就必須定義對應的Persistent Volume,當我們將應用遷移到自己數據中心後,就需要定義數據中心Kubernetes環境支持的Persistent Volume對象,因此這種直接定義PV的方式,靈活性太差了。為了能在其他雲平台上使用PV,我們就必須修改YAML文件,以適配新的環境。
我們一直強調Kubernetes標准化了應用程序的部署,特別是在多個雲平台之間的跨雲部署場景,每次都修改PV才能完成部署很明顯有悖於我們介紹的Kubernetes理念。幸運的是,Kubernetes已經考慮了這個問題,並且提供了一種更加便利的機制來給POD增加存儲資源。而我們通常把這種機制叫做PV/PVC體系。
理想情況下對於開發人員而言,部署應用程序到Kubernetes集群就不應該關心具體的存儲技術和細節,就如同Kubernetes將工作節點進行抽象類型,開發人員面對的只有POD,而基礎設施相關的部分應該讓專業人士來處理,比如集群的運維人員和專業的devops團隊。
正因為如此,我們在部署應用到Kuberntes集群的時候,我們很少直接設置具體存儲的細節,而是通過一種間接的方式來使用PV提供的存儲能力,如下圖所示,這就把POD和底層具體的存儲系統進行了解耦,POD的定義中不用在包含和具體基礎設施相關的配置信息:
很多公司內部都會自己搭建NFS文件存儲伺服器,我們來舉個例子,假設在POD中我們要使用NFS文件服務來共享數據,那麼在volume的定義中就需要包含NFS文件伺服器的IP地址和要掛載的目錄路徑,如下圖所示:
註:網路文件系統(NFS)是文件系統之上的一個網路抽象,允許遠程客戶端以和本地文件系統類似的方式來通過網路進行數據訪問。NFS允許在多個用戶之間共享公共文件系統,並提供數據集中的優勢,來最小化所需的存儲空間。
這樣做的結果是,我們將POD和具體的集群存儲細節進行了耦合,從而降低了靈活性。如果我們要將如上這個POD部署到另外一個集群中,那麼我們就需要修改NFS文件伺服器的IP地址,修改YAML文件可能會產生錯誤,因此這種方式本質上說明POD跨Kubernetes集群部署的靈活性不足。如下圖所示:
由於這個原因,我們需要將環境相關的配置信息抽取到另外一個叫PV的對象中,來解耦POD和具體存儲信息,提升POD的兼容性。Kubernetes平台用PersistentVolume對象來代表集群中可以用來存儲數據的volume,如下圖所示,PersistentVolume對象將底層存儲機制的詳細信息從POD的YAML文件中解耦:
由於POD中不再包含基礎設施相關的配置信息,兼容性得到了極大的提升。當然這些配置信息還是需要的,只是被轉移到PV對象上而已。本上上來看,這其實並不是什麼新技術。但是計算機從發展之初,通過增加一層來解決問題的方法,可以說是屢試不爽,我們應該在自己的架構設計中,多多考慮這樣的思想,當然需要考慮復雜性和合理性,並不是說中間層越多越好。
筆者在上篇文章中介紹過使用阿里雲OSS存儲卷類型的例子,如果你還有印象的話,應該記得我們的配置文件中使用persistentVolumeClaim對象來定義數據卷,如下圖所示。在Kubernetes平台中,通常POD間接的通過PVC映射到PV對象,這就讓PV從POD的生命周期中進一步解耦。
如上圖所示,PersistentVolumeClaim對象表示用戶對存儲資源的需求,由於用戶在使用存儲資源的時候,並不清楚集群中有哪些類型的Volume,因此Kubernetes就引入了這個PVC對象,來簡化使用PV的復雜度。這樣的話我們只需要在定義POD的時候,使用PVC對象即可,而在PVC對象的定義中,我們需要聲明存儲的需求,比如存儲空間大小,訪問模式等。
當POD運行完成退出的時候,會刪除PVC,底層的PV會被釋放,釋放後的PV就可以被其他的PVC使用。接下來我們通過一個實際的例子看看如何定義PCV和PV存儲模式。
比如我們現在已經在集群中創建了一個PV對象,指向NFS文件存儲伺服器;有一個PVC對象綁定到PV對象,這樣我們就可以直接在POD的YAML中,數據卷定義部分直接指定PVC對象,不用設置詳細的NFS文件伺服器IP地址等。
如下圖所示,當POD被調度到具體的工作節點時,Kubernetes負責通過PVC引用到PV對象,然後使用PV對象中配置的NFS文件伺服器的信息將對應的目錄掛載到容器中。
如上圖所示,POD在創建的時候,會通過PVC引用的PV對象來定位到存儲資源的具體信息,並將指定的目錄掛載到容器實例上。表面看,通過三個對象來掛載存儲資源很明顯比一個要復雜,但是你有沒有深入思考過Kubernetes為什麼要如此設計?
其實這里最大的好處就是「解耦」,或者叫消除依賴。通過增加PV和PVC這兩個對象,基礎設施相關的信息和應用的部署YAML解耦了,讓專業的人,集群管理員來負責PV的創建,開發人員的時間就可以放在更具價值的開發上,如果要部署,只需要使用PCV來聲明自己的需求就可以了。如下圖所示,我們來看看集群管理員開發人員是如何配合在一起,各司其職,成功將應用部署到Kubernetes集群上:
如上圖所示,開發人員不用再面對具體底層的存儲資源配置細節,集群管理員統一負責配置和管理所有的存儲資源,並且在Kubernetes平台上通過創建PV對象來提供給應用程序使用。當開發人員在部署應用的時候,通過創建PVC來聲明具體要使用的資源需求,比如直接指定PV對象的名稱,或者指定請求的存儲空間大小和訪問模式,Kubernetes基於這些信息完成綁定。
接下來我們就可以在POD中定義volume的時候使用PCV,當POD被創建的時候,POD中運行的容器實例就可以將存儲設備attach到工作節點,並將指定的目錄掛載到容器的文件目錄樹中。大家需要特別注意的是,在PVC/PV模式下,開發人員不需要了解底層具體的存儲設備信息,這部分工作屬於專業人士集群管理員,開發人員只需要通過PVC來聲明應用的存儲資源需求。
進一步講,如果我們的集群是託管實例,那麼管理員甚至都不需要自己手動來進行PV的創建和管理,我們可以通過雲平台提供的自動化volume提供機制,在有需要的時候,自動創建PersistentVolume和PersistentVolumeClaim對象,提供給應用程序使用。
通過上邊的內容,相信讀者對PVC/PV有全面的了解了,接下來我們來通過實際的例子來驗證一下。由於筆者使用的Kubernetes環境支持的存儲資源非常有限,但是又需要通過具體的例子來說明這些對象如何使用,筆者決定暫緩這部分內容到後續專門介紹如何在阿里雲ACK上使用PV/PCV。
好了,今天的內容就這么多了,我們下篇文章會介紹雲原生模式中一個非常重要的概念,如何讓應用無狀態,或者說如何管理應用程序的配置信息,敬請期待!
⑷ 從雲計算到雲原生:從概念到落地
雲計算最近幾年已經火得不行, 雲原生 (Cloud Native)這個概念又來了,如果上雲不「原生」,那就等於白上雲。究竟什麼是雲原生?雲原生有何優勢?怎麼從「不原生」一步一步做到雲原生?本文將給出切實可行的雲原生落地指南。
我們先從雲計算說起 。在雲計算普及之前,一個應用想要發布到互聯網,就需要企業自己先買幾台伺服器,找一個IDC機房,租幾個機架,把伺服器放進去。接下來就是裝Linux系統,部署應用。我們就假定用Java寫了Web應用,怎麼部署上去呢?先配置Tomcat伺服器,在把編譯好的war包上傳到伺服器,有用FTP的,安全意識高一點的會選SCP,然後配置Nginx、MySQL這些服務,最後一通調試,把應用跑起來,就算齊活。
這種物理機配合自搭網路環境、自搭Linux、自配環境的方式,有很多缺點,但最主要的問題有這么幾個:
解決方案是上雲 。上雲不能解決所有問題,但部分解決了前兩個問題:
但是如果僅僅滿足上雲,把物理機換成虛擬機,把物理網換成虛擬專用網(VPC),是遠遠不夠的。這些是計算資源和網路資源層面的簡化。應用方面,如果延續舊的一套開發、測試、部署流程,做不到快速迭代。
要做到快速迭代,敏捷開發,就需要DevOps,即開發運維由一個團隊負責,開發階段,就要把部署、運維的工作考慮進去,而不是發布一個war包或者jar包後扔給運維不管了。
重開發、輕部署,直接後果就是缺少自動化發布流程。想要把部署規范化,就需要整體考慮一系列問題。
還是以Java應用為例,如果是手動部署,那麼就上傳war包到伺服器,覆蓋原有的版本,重啟Tomcat,再測試。如果發現有嚴重問題要回滾怎麼辦?把老版本再傳一遍,然後重啟Tomcat。
手動部署,每次部署都是一次生死考驗,所以最好不要安排在半夜,以免手抖敲錯了命令,本來中斷10分鍾的服務,變成了災備恢復,中斷3天。
稍微靠譜一點的是寫腳本部署,但各家寫出來的腳本都有各家特色,不通用,不易維護,所以更好的方式是用成熟的部署方案,比如Ansible,把腳本標准化,比如做成藍綠發布,把伺服器分組,比如A、B兩組,先把流量切到B組,升級A組伺服器,有問題就回滾,沒問題了,再把流量切到A組,升級B組伺服器,最後,恢復正常流量,整個部署完成。
但是回滾這個事情,遠沒有那麼簡單。做過開發的同學都知道,升級新版本,一般要加配置,改配置,如果回滾到舊版本,忘了把配置改回去,那舊版本可能也不能正常工作。
上雲,除了物理變虛擬,簡化運維外,最重要的特點——彈性計算,一定要充分利用。
理論指導實踐,實踐完善理論。如果我們分析大多數基於互聯網的應用,可以看到,一個應用,通常用到的資源如下:
上雲後,雲服務商通常都提供託管的資料庫,以及大規模存儲系統(S3),可解決存儲資源問題。通過雲服務商提供的負載均衡(Load Balancer),也無需自行部署Nginx等網關,免去了運維的問題。各種標準的業務組件如Redis、Kafka等,均可直接租用雲服務商提供的資源。
我們重點討論計算資源,也就是雲上的虛擬機資源。對於應用來說,可以設計成有狀態和無狀態兩種。一個應用在一台虛擬機內跑著,如果有本地文件的修改,它就是有狀態的。有狀態的應用既不利於擴展,也不利於部署。反過來,如果一個應用在運行期數據總是存在資料庫或者緩存集群,本地文件無任何修改,它就是無狀態的。
無狀態的應用對應的虛擬機實際上就是不變的計算資源。這里的「不變」非常重要,它是指,一台虛擬機通過一個固定的鏡像(預先內置好必要的支持環境,如JRE等)啟動後,部署一個應用(對應一個war包或者jar包),該虛擬機狀態就不再變化了,直接運行到銷毀。
有的同學會問:如果給這台虛擬機重新部署一個新的應用版本,它的狀態不就發生了變化?
確實如此。為了確保虛擬機的不變性,一旦啟動後部署了某個版本,就不允許再重新部署。這樣一來,對虛擬機這種計算資源來說,就具有了不變性。不變性意味著某個虛擬機上的應用版本是確定的,與之打包的配置文件是確定的,不存在今天是版本1,明天變成版本2,後天回滾到版本1的情況。
計算資源不變,能確保啟動一台虛擬機,對應發布的應用版本和配置是確定的且不變的,對於運維、排錯非常重要。
那麼如何在保持計算資源不變的前提下發布新版本?
我們以AWS的CodeDeploy服務為例,假設一組正在運行的某應用v1集群包含3台虛擬機:
現在,我們要把應用從v1升級到v2,絕不能直接把現有的3台虛擬機的應用直接升級,而是由CodeDeploy服務啟動3台新的一模一樣的虛擬機,只是部署的應用是v2。現在,一共有6台虛擬機,其中3台運行v1版本,另外3台運行v2版本,但此刻負載均衡控制的網路流量仍然導向v1集群,用戶感受不到任何變化:
v2集群部署成功後,做一些自動化冒煙測試和內網測試,如果有問題,直接銷毀,相當於本次部署失敗,但無需回滾。如果沒有問題,通過負載均衡把流量從v1集群切到v2,用戶可無感知地直接訪問v2版本:
穩定一段時間(例如15分鍾)後,銷毀v1集群。至此,整個升級完成。
上述的藍綠部署就是CodeDeploy的一種標准部署流程。CodeDeploy也支持灰度發布,適用於更大規模的應用。
把計算資源不可變應用到部署上,實際上是充分利用了彈性計算這個優勢,短時間創建和銷毀虛擬機,只有上雲才能做到,並且針對雲計算,把部署流程變得更加簡單可靠,每天發幾個版本甚至幾十、幾百個版本都變得可能,DevOps能落地,有點「雲原生」的味道了。
說到AWS的CodeDeploy,最早我使用AWS時,對於它的計費採用Reserved Instance預付模型感到很不理解,租用一台虛擬機,按國內阿里雲、騰訊雲包年包月預付享折扣不是更直觀嗎?如果僅僅把上雲變成租用虛擬機,那就完全喪失了彈性計算的優勢,相當於租用了一台虛擬機在裡面自己折騰。AWS的Reserved Instance計費並不綁定某一台虛擬機,而是一種規格的虛擬機。
我們還是舉例說明,如果我們有1台2v4G規格的虛擬機,並購買了1年的Reserved Instance,那麼,我隨時可以銷毀這台虛擬機,並重新創建一台同樣規格的新的虛擬機,Reserved Instance計費會自動匹配到新的虛擬機上,這樣才能實現計算資源不變,頻繁實施藍綠部署,真正把部署變成一種雲服務。最近阿里雲終於推出了節省計劃的付費模式,有點真正的雲計算的付費味道了,但是騰訊雲、華為雲還停留在包年包月和按量付費這兩種原始租賃模型。
講了這么多自動化部署,實際上一個指導思想就是如何充分利用雲的彈性計算資源。從充分利用雲的彈性資源為出發點,設計一整套開發、部署、測試的流程,就是雲原生。彈性資源利用得越充分,雲原生的「濃度」就越高,就越容易實施小步快跑的快速迭代。
那麼虛擬機是不是彈性最好的計算資源呢?從應用的角度看,顯然容器是一種比虛擬機更具彈性,更加抽象,也更容易部署的計算資源。
容器和虛擬機相比,它實際上是一種資源隔離的進程,運行在容器中的應用比獨佔一個虛擬機消耗的資源更少,啟動速度更快。此外,容器的鏡像包含了完整的運行時環境,部署的時候,無需考慮任何額外的組件,比其他任何部署方式都簡單。使用容器,開發部署流程就變成了開發,生成鏡像,推送至Docker Hub或雲服務商提供的Registry,直接啟動容器,整個過程大大簡化。
使用容器比使用CodeDeploy部署還要更加簡單,因為CodeDeploy需要在虛擬機鏡像中預置Agent,由於沒有統一的發布標准,還需要配置CodeDeploy,告訴它去哪拉取最新版本,這又涉及到一系列許可權配置。而容器作為標準的部署方案,連發布系統都以Registry對各個鏡像版本進行了有效管理,所以部署非常簡單。
容器作為一種彈性計算資源,也應遵循計算不變性,即不要給容器掛載可變的存儲卷。一組不變的容器集群才能更容易地升級。容器的運行方式本身就遵循了不變性原則,因為通過一個鏡像啟動一個容器,在運行過程中,是不可能換一個鏡像的。容器本身也強烈不建議應用寫入數據到文件系統,因為重啟後這些修改將全部丟失。
容器的啟動和銷毀非常容易,不過,容器的管理卻並不簡單。容器的管理涉及到創建、調度、彈性擴容、負載均衡、故障檢測等等,Kubernetes作為事實上的容器編排標准平台,已經成為各個雲服務商的標配。
如果要直接使用K8s,在雲環境中首先要有一組虛擬機資源作為底層資源,然後搭建K8s環境,定義好容器編排並啟動容器。雲服務商幾乎都提供託管的K8s服務,但直接管理K8s仍然需要非常熟悉K8s的工程師。
還有一種更簡單的使用容器的方式,即完全將底層虛擬機和K8s託管給雲服務商,企業客戶只需關心如何部署容器,底層的K8s和虛擬機對企業不可見或者無需關心。AWS的Elastic Container和阿里雲的彈性容器均為此類服務。對於中小規模的應用來說,計算資源直接使用容器,再配合雲服務商提供的負載均衡,託管的資料庫、消息系統、日誌系統等組件服務,應該是目前最「雲原生」的一種方案。
最後,我們總結一下雲原生的特點:
所謂雲原生,就是在上雲的過程中,充分發揮雲平台的彈性計算、彈性存儲的優勢,盡量把應用設計成適合雲計算的架構,把部署設計成簡單易用的流程,這樣才能實現業務快速上線,快速迭代。
雲原生是一個大方向,在上雲的過程中,逐步改造應用架構和部署流程,從手動往自動轉,逐步增加計算資源的彈性,就能把雲原生一步步落地。
⑸ kubernetes 提供什麼功能
Kubernetes,是開源容器應用自動化部署技術,也就是大家經常說的k8s。
Kubernetes(k8s)是自動化容器操作的開源平台,這些操作包括部署,調度和節點集群間擴展。如果你曾經用過Docker容器技術部署容器,那麼可以將Docker看成Kubernetes內部使用的低級別組件。Kubernetes不僅僅支持Docker,還支持Rocket,這是另一種容器技術。
使用Kubernetes可以:
自動化容器的部署和復制
隨時擴展或收縮容器規模
將容器組織成組,並且提供容器間的負載均衡
很容易地升級應用程序容器的新版本
提供容器彈性,如果容器失效就替換它,等等...
它有這些特點:
可移植:支持公有雲,私有雲,混合雲,多重雲 multi-cloud
可擴展:模塊化,插件化,可掛載,可組合
自動化:自動部署,自動重啟,自動復制,自動伸縮/擴展
如果還有想要了解的可以到官網或是相關教程視頻中看看,比如B站這個視頻教程:
⑹ 好雨雲幫為什麼採用K8s,而不用Docker Swarm
用過就知道了K8s比Docker Swarm還是要強一些些的……k8s api簡直不要太好用……
⑺ K8S安裝和創建集群終極教程(單master多worker)
本文會以 最簡單 、 最直接 、 最完整 的方式記錄kubernetes(下面統稱K8S)單master多工作節點(worker nodes)的集群步驟
首先要簡單了解一下本文的3個核心概念:
內存建議至少4G
問:如何查看主機名?
答:執行命令hostname
問:如何修改主機名?
答:永久生效的做法:執行命令vi /etc/hostname,把第一行去掉(不能注釋掉,要去掉),然後重新寫上自定義的主機名(注意命名規范),保存並重啟後生效;
臨時生效的做法:執行以下命令
問:如何查看MAC地址?
答:執行命令ip link,然後看你的第一網卡
問:如何查看proct_uuid?
答:執行命令sudo cat /sys/class/dmi/id/proct_uuid
注意:30000-32767這個埠范圍是我們創建服務的埠必須要設置的一個范圍(如果設置范圍以外的會有限制提示並創建失敗),這是K8S規定的。
另外,如果你要直接關閉防火牆可以執行
⑥必須禁用Swap
Swap total大於0,說明Swap分區是開啟的
問:如何關閉Swap?
答:編輯文件/etc/fstab,在swap行前面加上#號注釋, 保存並重啟伺服器
再次查看分區狀態,已生效
常見的容器引擎(Container runtime,簡稱runtime):
本文使用的容器引擎是Docker
安裝完成後查看版本:
當出現可能跟Docker引擎相關的奇怪異常時可以嘗試把Docker卸載干凈並重新安裝,但一定要注意鏡像、容器、卷或配置文件這些是否需要備份。
下面記錄卸載Docker引擎的步驟:
①卸載 Docker Engine、CLI 和 Containerd 包:
②主機上的映像、容器、卷或自定義配置文件不會自動刪除。刪除所有鏡像、容器和卷:
③配置文件如果有不合法的字元時會導致啟動失敗,我們需要將其刪除然後重建
此時Docker引擎已卸載干凈
官網用的是谷歌的yum源,因為國內是連不上的,所以這里替換成阿里提供的yum源
①安裝
從安裝信息中可以看到版本號是1.22
Installing:
kubeadm x86_64 1.22.4-0 kubernetes 9.3 M
kubectl x86_64 1.22.4-0 kubernetes 9.7 M
kubelet x86_64 1.22.4-0 kubernetes 20 M
②啟動
這就是一個驅動程序,注意cgroup和cgroupfs不要混淆了
引用官方的一段話
「由於 kubeadm 把 kubelet 視為一個系統服務來管理,所以對基於 kubeadm 的安裝, 我們推薦使用 systemd 驅動,不推薦 cgroupfs 驅動。」
kubeadm默認是使用systemd 驅動,而我們的Docker默認驅動是cgroupfs(docker info可以查看),所以需要將Docker的驅動改成systemd
①編輯Docker配置文件
②重啟Docker服務
再次docker info查看驅動信息已變成了systemd
工作節點(worker nodes)的最小配置就到這里了
①鏡像源參數說明
默認情況下, kubeadm 會從 k8s.gcr.io 倉庫拉取鏡像,國內是拉不了的。官方文檔明確表示允許你使用其他的 imageRepository 來代替 k8s.gcr.io。
--image-repository 你的鏡像倉庫地址
接下來我找了一些國內的鏡像源,並簡單做了下分析
綜合上述統計,我選擇阿里雲的鏡像源
②ip地址范圍參數說明
--pod-network-cidr =192.168.0.0/16
注意:如果192.168.0.0/16已經在您的網路中使用,您必須選擇一個不同的pod網路CIDR,在上面的命令中替換192.168.0.0/16。
集群初始化命令:
因為我用的是演示機器,所以這里把完整的執行信息都貼出來方便查閱,平時工作中一定要注意保護好敏感的信息(我的ip地址范圍是自定義的便於下面的功能演示,另外初次init需要下載鏡像文件,一般需要等幾分鍾)
如上所示,集群初始化成功,此時一定要注意看上面執行結果最後的那部分操作提示,我已用標明了初始化成功後還需要執行的3個步驟
注意:如果init成功後發現參數需要調整,可以執行kubeadm reset,它的作用是盡最大努力恢復kubeadm init 或者 kubeadm join所做的更改。
To start using your cluster, you need to run the following as a regular user:
翻譯:開始使用集群前,如果你是普通用戶(非root),你需要執行以下的命令:
Alternatively, if you are the root user, you can run:
翻譯:或者,如果你使用的是root,你可以執行以下命令:
(注意:export只是臨時生效,意味著每次登錄你都需要執行一次)
網路配置配的就是Pod的網路,我的網路插件選用calico
cidr就是ip地址范圍,如果您使用 pod CIDR 192.168.0.0/16,請跳到下一步。
但本文中使用的pod CIDR是192.100.0.0/16,所以我需要取消對清單中的 CALICO_IPV4POOL_CIDR 變數的注釋,並將其設置為與我選擇的 pod CIDR 相同的值。(注意一定要注意好格式,注意對齊)
可根據需求自定義清單,一般不需要的就直接跳過這步
在所有的工作節點上執行join命令(復制之前初始化成功後返回的加入集群命令到所有的工作節點執行即可)
master上查看所有節點的狀態
到這里集群已經創建完成
最後我再安裝K8S的可視化界面kubernetes-dashboard,方便我們日常使用
①下載yaml文件
②修改yaml文件,新增type和nodePort,使服務能夠被外部訪問
③安裝並查看運行情況
④新建用戶
文件創建完成後保存並apply
⑤獲取Token,用於界面登錄
⑥登錄dashboard
192.168.189.128是我的master伺服器ip,另外要注意必須使用https,並且不能使用ie內核模式
復制⑤生成的token到輸入框,點擊登錄
dashboard安裝配置完成
問:如何在查看資源情況?
答:在master上執行以下命令可查看資源情況(-o wide是顯示更詳細的信息),
①查看所有節點
②查看所有命名空間
③查看命名空間下的pod
④查看所有命名空間的pod
⑤實時查看查看命名空間下的pod運行情況
問:kubeadm join 出現異常[ERROR Port-10250]: Port 10250 is in use,如何解決?
答:這是因為你之前join失敗過了,需要先執行kubeadm reset再重新join
問:虛擬機上測試時網卡突然消失如何解決(題外問題記錄)?
答:
①確認丟失的網卡信息,ens開頭(可選步驟)
ifconfig -a
②執行以下命令解決
問:如何查看K8S版本?
答:kubectl version
問:join命令忘記或者過期了怎麼辦?
答:
生成永不過期的
生成時效24小時的
問:Pod不斷重啟並且無其它報錯信息時怎麼辦?
答:這種情況通常是因為你的集群中只有master,沒有worker節點,master的創建默認是有污點的,即不允許調度新的Pod,如果你需要(當然這並不推薦),就需要刪除 master 上的污點。刪除污點可以執行以下命令,
它應該返回以下內容。
⑻ 雲和k8s哪個更有前途
k8s
k8s是一個開源的容器集群管理系統,可以實現容器集群的自動化部署、自動擴縮容、維護等功能。
原因是k8s是容器管理編排引擎,一般配合docker容器使用。容器化的優勢是快速部署、輕量化、彈性擴容和可移植。docker相對於虛擬化KVM,優勢是啟動快、資源佔用小,通過namespace和cgroup實現資源調配和隔離,缺點是隔離性不好,依賴宿主機內核。
k8s可以更快的更新新版本,打包應用,更新的時候可以做到不用中斷服務,伺服器故障不用停機,從開發環境到測試環境到生產環境的遷移極其方便,一個配置文件搞定,一次生成image,到處運行。