摘要:簡稱,是在年發布的一個開源項目。網絡要能夠通信,必須部署網絡,是其中一個可選方案。最常使用,可以管理多個副本,并確保按照期望的狀態運行,底層調用。用于每個最多只運行一個副本的場景。
Kubernetes 簡稱 k8s,是 google 在 2014 年發布的一個開源項目。
Kubernetes 解決了哪些問題?
真實的生產環境應用會包含多個容器,而這些容器還很可能會跨越多個服務器主機部署。Kubernetes 提供了為那些工作負載大規模部署容器的編排與管理能力。Kubernetes 編排讓你能夠構建多容器的應用服務,在集群上調度或伸縮這些容器,以及管理它們隨時間變化的健康狀態。
kubernetes 基礎
kubernetes 優化
kubernetes 實戰
Kubernetes 基礎概念很多,第一次接觸容易看暈,如果是新手,建議直接看實戰部分,先跑起來再說。
kubernetes 基礎k8s 中有幾個重要概念。
概念 | 介紹 |
---|---|
cluster | 一個 k8s 集群 |
master | 集群中的一臺機器,是集群的核心,負責整個集群的管理和控制 |
node | 集群中的一臺機器,是集群中的工作負載節點 |
pod | k8s 最小調度單位,每個 pod 包含一個或多個容器 |
label | 一個 key = value 鍵值對,可以附加到各種資源對象上,方便其他資源進行匹配 |
controller | k8s 通過 controller 來管理 pod |
service | 對外提供統一的服務,自動將請求分發到正確的 pod 處 |
namespace | 將 cluster 邏輯上劃分成多個虛擬 cluster,每個 cluster 就是一個 namespace |
Cluster 代表一個 k8s 集群,是計算、存儲和網絡資源的集合,k8s 利用這些資源運行各種基于容器的應用。
Master 節點Master 是 cluster 的大腦,運行著的服務包括 kube-apiserver、kube-scheduler、kube-controller-manager、etcd 和 pod 網絡。
kube-apiserver
apiserver 是 k8s cluster 的前端接口,提供 restful api。各種客戶端工具以及 k8s 其他組件可以通過它管理 cluster 中的各種資源。
kube-scheduler
負責決定將 pod 放在哪個 node 上運行,scheduler 在調度時會充分考慮 cluster 中各個節點的負載,以及應用對高可用、性能、數據親和性的需求。
kube-controller-manager
負責管理 cluster 各種資源,保證資源處理預期狀態。controller-manager 由多種 controller 組成,包括 replication controller,endpoint controller,namespace controller,serviceaccount controller 等。
不同的 controller 管理不同的資源,例如:replication controller 管理 deployment ,statefulset,damonset 的生命周期,namespace controller 資源管理 namespace 資源。
etcd(分布式 key-value 存儲庫)
負責保存 cluster 的配置信息和各種資源的狀態信息。當數據發生變化時,etcd 會快速地通知 k8s 相關組件。
pod 網絡
pod 要能夠通信,cluster 必須部署 pod 網絡,flannel 是其中一個可選方案。
Node 節點Node 節點 是 pod 運行的地方。node 節點上運行的 k8s 組件有 kubelet、kube-proxy 和 pod 網絡。
kubelet
kubelet 是 node 節點的代理,當 master 節點中 kube-scheduler 確定在某個 node 節點上運行 pod 后,會將 pod 的具體配置信息發送給該節點的 kubelet,kubelet 根據這些信息創建和運行容器,并向 master 節點報告運行狀態。
kube-proxy
每個 node 節點都會運行 kube-proxy 服務,它負責將訪問 service 的請求轉發到后端的容器。如果有多個副本,kube-proxy 會實現負載均衡。
pod 網絡
pod 要能夠相互通信,k8s cluster 必須部署 pod 網絡,flannel 是其中一個可選方案。
Pod每一個 pod 包含一個或多個 container,pod 中的容器作為一個整體被 master 調度到 node 節點上運行。
為什么 k8s 使用 pod 管理容器,而不是直接操作容器?
1、因為有些容器天生就是需要緊密的聯系,放在一個 pod 中表示一個完整的服務,k8s 同時會在每個 pod 中加入 pause 容器,來管理內部容器組的狀態。
2、Pod 中的所有容器共享 ip,共享 volume,方便進行容器之間通信和數據共享。
什么時候需要在 pod 中定義多個容器?
答:這些容器聯系非常緊密,而且需要直接共享資源,例如一個爬蟲程序,和一個 web server 程序。web server 強烈依賴爬蟲程序提供數據支持。
LabelLabel 是一個 key = value 的鍵值對,其中 key 和 value 都由用戶自己指定。
Label 的使用場景:
kube-controller
通過 label selecter 篩選出要監控的 pod 副本,使 pod 副本數量符合預期。
kube-proxy
通過 label selecter 選擇對應的 pod,自動建立每個 service 到對應 pod 的請求轉發路由表,從而實現 service 的智能負載均衡機制。
通過對 node 定義 label,在 pod 中使用 node selector 匹配,kube-scheduler 進程可以實現 pod 定向調度的特性。
總之,label 可以給對象創建多組標簽,label 和 label selecter 共同構建了 k8s 系統中核心的應用模型,使得被管理對象能夠被精細地分組管理,同時實現了整個集群的高可用性。
Controllerk8s 通常不會直接創建 pod,而是通過 controller 來管理 pod。controller 中定義了 pod 的部署特性,比如有幾個副本,在什么樣的 node 上運行等。為了滿足不同的業務場景,k8s 提供了多種類型的 controller。
Deployment
最常使用,可以管理 pod 多個副本,并確保 pod 按照期望的狀態運行,底層調用 ReplicaSet。
ReplicaSet
實現 pod 的多副本管理,通常使用 Deployment 就夠了。
DaemonSet
用于每個 node 最多只運行一個 pod 副本的場景。
使用場景
在集群的每個節點上運行存儲 Daemon,比如 glusterd 或 ceph。
在每個節點上運行日志搜集 Daemon,比如 flunentd 或 logstash。
在每個節點上運行監控,比如 Prometheus Node Exporter 或 collected。
StatefuleSet
能夠保證 pod 的每個副本在整個生命周期中名稱是不變的,而其他 controller 不提供這個功能。
Job
用于運行結束就刪除的應用,而其他 controller 中的 pod 通常是長期持續運行。
提示Job
使用 deployment controller 創建的用例,如果出現有 pod 掛掉的情況,會自動新建一個 pod,來維持配置中的 pod 數量。
容器按照持續運行時間可分為兩類:服務類容器和工作類容器。
服務類容器通常持續提供服務,需要一直運行,比如 http server。工作類容器則是一次性任務,比如批處理程序,完成后容器就退出。
Controller 中 deployment、replicaSet 和 daemonSet 類型都用于管理服務類容器,對于工作類容器,我們使用 job。
ServiceService 是可以訪問一組 pod 的策略,通常稱為微服務。具體訪問哪一組 pod 是通過 label 匹配出來的。service 為 pod 提供了負載均衡,原理是使用 iptables。
為什么要用 service ?
pod 是有生命周期的,它們可以被創建,也可以被銷毀,然而一旦被銷毀生命就永遠結束。而 pod 在一個 k8s 集群中可能經常性的創建,銷毀,每一次重建都會產生一個新的 ip 地址。
service 從邏輯上代表了一組 pod,具體是哪些 pod 是由 label 來挑選的。service 有自己的 ip,而且這個 ip 是不變的,客戶端只需要訪問 service 的 ip,k8s 則負責建立和維護 service 與 pod 的映射關系,無論 pod 如何變化,對客戶端不會有任何影響,因為 service 沒有變。
外網如何訪問 service?
ClusterIP:通過集群的內部 ip 暴露服務,選擇該值,服務只能夠在集群內部可以訪問,這也是默認的 ServiceType。
NodePort:通過每個 node 上的 ip 和端口(NodePort)暴露服務。NodePort 服務會路由到 ClusterIP 服務,這個 ClusterIP 服務會自動創建。通過請求 nodeip:nodeport,可以從集群的外部訪問一個 service 服務。
LoadBalancer:使用云提供商的負載局衡器,可以向外部暴露服務。外部的負載均衡器可以路由到 NodePort 服務和 ClusterIP 服務。
ExternalName:通過返回 CNAME 和它的值,可以將服務映射到 externalName 字段的內容(例如, foo.bar.example.com)。 沒有任何類型代理被創建,這只有 k8s 1.7 或更高版本的 kube-dns 才支持。
Namespace如果有多個用戶使用同一個 k8s cluster,如何將他們創建的 controller,pod 等資源分開呢?
答:使用 namespace。
如果將物理的 cluster 邏輯上劃分成多個虛擬 cluster,每個 cluster 就是一個 namespace,不同 namespace 里的資源是完全隔離的。
k8s 默認創建了兩個 namespace。
default 創建資源時如果不指定,將會放到這個 namespace 中。
kube-system 存放 k8s 自己創建的系統資源。
Kubernetes 優化健康檢查
數據管理
密碼管理
集群監控
健康檢查強大的自愈能力是 k8s 這類容器編排引擎的一個重要特性。自愈的默認實現方式是自動重啟發生故障的容器。除此之外,用戶還可以利用 liveness 和 readiness 探測機制設置更精細的健康檢查,進而實現如下需求:
零停機部署
避免部署無效的鏡像
更加安全的滾動升級
默認情況下,只有容器進程返回值非零,k8s 才會認為容器發生了故障,需要重啟。如果我們想更加細粒度的控制容器重啟,可以使用 liveness 和 readiness。
liveness 和 readiness 的原理是定期檢查 /tmp/healthy 文件是否存在,如果存在即認為程序沒有出故障,如果文件不存在,則會采取相應的措施來進行反饋。
liveness 采取的策略是重啟容器,而 readiness 采取的策略是將容器設置為不可用。
如果需要在特定情況下重啟容器,可以使用 liveness。
如果需要保證容器一直可以對外提供服務,可以使用 readiness。
我們可以將 liveness 和 readiness 配合使用,使用 liveness 判斷容器是否需要重啟,用 readiness 判斷容器是否已經準備好對外提供服務。
數據管理上文說道,pod 可能會被頻繁地銷毀和創建,當容器銷毀時,保存在容器內部文件系統中的數據都會被清除。為了持久化保存容器的數據,可以使用 k8s volume。
Volume 的生命周期獨立于容器,pod 中的容器可能被銷毀和重建,但 volume 會被保留。實質上 vloume 是一個目錄,當 volume 被 mount 到 pod,pod 中的所有容器都可以訪問到這個 volume。
Volume 支持多種類型。
emptyDir
數據存放在 pod 中,對 pod 中的容器來說,是持久的,只要 pod 還在數據就還在。
hostPath
數據存在主機上,主機在數據就在。
AWS Elastic Block Store
數據存在云服務器上。
Persistent Volume
自定義一塊外部存儲空間 Persistent Volume,然后在創建 pod 時使用 PersistentVolumeClaim(PVC)去申請空間,并進行存儲。
Volume 提供了對各種類型的存放方式,但容器在使用 volume 讀寫數據時,不需要關心數據到底是存放在本地節點的系統中還是云硬盤上。對容器來說,所有類型的 volume 都只是一個目錄。
密碼管理應用程序在啟動過程中可能需要一些敏感信息,比如訪問數據庫的用戶名和密碼。將這些信息直接保存在容器鏡像中顯然不妥,k8s 提供的解決方案是 secret。
secret 會以密文的方式存儲數據,避免直接在配置文件中保存敏感信息。secret 會以 volume 的形式被 mount 到 pod,容器可通過文件的方式使用 secret 中的敏感數據,此外容器也可以按環境變量的形式使用這些數據。
使用配置文件創建 mysecret.yaml:
apiVersion: v1 kind Secret metadata: name:mysecret data: username:admin password:123
保存配置文件后,然后執行kubectl apply -f mysecret.yaml進行創建。
在 pod 中使用創建好的 secret:
# mypod.yaml apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: yhlben/notepad volumeMounts: - name: foo mountPath: "etc/foo" readOnly: true volumes: - name: foo secret: secretName: mysecret
執行kubectl apply -f mypod.yaml 創建 pod,并使用 secret。創建完成后,secret 保存在容器內 /etc/foo/username ,/etc/foo/password 目錄下。
集群監控創建 k8s 集群并部署容器化應用只是第一步。一旦集群運行起來,我們需要確保集群一切都是正常的,這就需要對集群進行監控。
常用的可視化監控工具如下。
Weave Scope
Heapster
Prometheus Operator
具體的使用步驟就直接看文檔了,這里不詳細說明。
通過集群監控我們能夠及時發現集群出現的問題,但為了方便進一步排查問題,我們還需要進行進行日志記錄。
常用的日志管理工具如下。
Elasticsearch 負責存儲日志并提供查詢接口。
Fluentd 負責從 k8s 搜集日志并發送給 Elasticsearch。
Kibana 提供一個可視化頁面,用戶可以瀏覽和搜索日志。
Kubernetes 實戰我們來實戰部署一個 k8s 記事本項目,項目使用 yhlben/notepad 鏡像進行構建,該鏡像在部署后會在 8083 端口上提供一個 web 版記事本服務,查看演示。
為了避免安裝 k8s 出現的各種坑,這里使用 Play with Kubernetes進行演示。
首先在 Play with Kubernetes 上創建 3 臺服務器,node1 作為 master 節點,node2 和 node3 作為工作節點。接下來進行以下操作;
創建一個集群 cluster
加入 node 節點
初始化 cluster 網絡
創建 controller
創建 service
執行部署
創建一個集群 cluster在 node1 上運行 kubeadm init 即可創建一個集群。
kubeadm init --apiserver-advertise-address $(hostname -i)
執行完成后會生成 token,這樣其他節點就可以憑借這個 token 加入該集群。
加入 node 節點在 node2 和 node3 機器上,分別執行以下命令,加入到 node1 的集群。
kubeadm join 192.168.0.8:6443 --token nfs9d0.z7ibv3xokif1mnmv --discovery-token-ca-cert-hash sha256:6587f474ae1543b38954b0e560832ff5b7c67f79e1d464e7f59e33b0fefd6548
命令執行完畢后,即可看到 node2,node3 已經加入成功。
查看集群狀態在 node1 節點上,執行以下命令。
kubectl get node
可以看到,集群中存在 node1 ,node2,node3 這 3 個節點,但這 3 個節點的都是 NotReady 狀態,為什么?
答:因為沒有創建集群網絡。
創建集群網絡執行以下代碼創建集群網絡。
kubectl apply -n kube-system -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 |tr -d " ")"
執行命令后,稍等一下,然后查看 node 狀態,可以看到,集群中的 3 個節點都是 Ready 狀態了。
創建 Deployment我們通過配置文件來創建 deployment,新建 deployment.yaml 文件,內容如下:
# 配置文件格式的版本 apiVersion: apps/v1 # 創建的資源類型 kind: Deployment # 資源的元數據 metadata: name: notepad # 規格說明 spec: # 定義 pod 數量 replicas: 3 # 通過 label 找到對應的 pod selector: matchLabels: app: mytest # 定義 pod 的模板 template: # pod 的元數據 metadata: # 定義 pod 的 label labels: app: mytest # 描述 pod 的規格 spec: containers: - name: notepad image: yhlben/notepad ports: - containerPort: 8083
文件創建之后,執行命令:
kubectl apply -f ./deployment.yaml # deployment.apps/notepad created
查看部署的 pod。
可以看到,我們使用 deployment 類型的 controller 創建了 3 個 pod,分別運行在 node2 和 node3 機器上,如果有更多的機器,也會自動負載均衡,合理地分配到每個機器上。
創建 Service創建 service 和 deployment 類似,新建 service.yaml 文件,內容如下:
apiVersion: v1 kind: Service metadata: name: my-service spec: # 在節點上部署訪問 pod 的端口 type: NodePort ports: - port: 80 # service 代理的端口 targetPort: 8083 # node 節點上提供給集群外部的訪問端口 nodePort: 30036 # 匹配 pod selector: app: mytest
文件創建之后,執行命令:
kubectl apply -f ./service.yaml # service/my-service created查看創建結果
使用 kubectl get deployment 和 kubectl get service 查看創建結果。
可以看到,deployment 和 service 均創建成功,并且已知 service 暴露的 ip 地址為:10.106.74.65,端口號為 80,由于設置了 targetPort,service 在接收到請求時,會自動轉發到 pod 對應的 8083 端口上。
訪問部署結果部署成功后,我們可以通過兩種方式進行訪問:
集群內:通過 service 的 clusterIp + port 端口進行訪問。
集群外:通過任意一個 node 節點 + nodePort 端口進行訪問。
# 集群內訪問 curl 10.106.74.65 # 集群外訪問 # 192.168.0.12 是 node2 節點的ip # 192.168.0.11 是 node3 節點的ip curl 192.168.0.12:30036 curl 192.168.0.11:30036
集群內訪問。
集群外訪問。
到這里,已經算部署成功了,大家肯定有疑問,部署一個如此簡單的 web 應用就這么麻煩,到底 k8s 好在哪里?我們接著往下看。
K8s 運維項目已經部署,接下來來實戰一個運維,感受一下 k8s 帶給我們的便利。
案例 1公司要做雙 11 活動,需要至少 100 個容器才能滿足用戶要求,應該怎么做?
首先,應該盡可能利用當前擁有的服務器資源,創建更多的容器來參與負載均衡,通過 docker stats 可以查看容器占用的系統資源情況。如果充分利用后仍然不能滿足需求,就根據剩余需要的容器,計算出需要購買多少機器,實現資源的合理利用。
購買服務器,將服務器作為 node 節點,join 到集群中。
執行擴容命令。
執行以下命令就能將容器擴展到 100 個。
kubectl scale deployments/notepad --replicas=100
如圖,擴展 10 個 pod 的情況,node2 和 node3 節點共同分擔負載。
也可以通過修改 deployment.yaml 中的 replicas 字段,執行 kubectl apply -f deployment.yaml去執行擴展。如果活動結束了,只需要將多余的服務器刪除,縮減容器數量即可還原到之前的效果。
案例 2雙 11 活動很火爆,但突然加了需求,需要緊急上線,如果實現滾動更新?
滾動更新就是在不宕機的情況下,實現代碼更新。執行以下命令,修改 image 即可。
kubectl set image deployments/notepad notepad=yhlben/notepad:new
也可以通過修改 deployment.yaml 中的 image 字段,執行 kubectl apply -f deployment.yaml去執行升級。
如果更新出了問題,k8s 內置了一鍵還原上個版本的命令:
kubectl rollout undo deployments/notepad
通過這 2 個案例,感覺到了 k8s 給運維帶來了很大的便利:快速高效地部署項目,支持動態擴展、滾動升級,同時還能按需優化使用的硬件資源。
總結本文的目的就是入門 k8s,通過一個簡單的集群來實現這一點,但其中也踩了好多坑,具體如下:
使用 minikube 搭建項目
能快速搭建一個單節點 k8s 環境。
但在本地使用 minikube 搭建一套 k8s 集群,很多包裝不上,全局代理也不行。
使用 google clould 上的服務器
在 gogole clould 上,解決了網絡問題,需要安裝的包都能裝上。
但由于是新服務器,需要各種安裝環境,docker,kubeadm,kubectl 等,安裝過程繁瑣,還可能會遇到報錯。
不知道哪天手滑了一下,試用賬號變成了付費賬號,贈金 $300 就這樣沒了
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105404.html
摘要:本文將分享是為何以及如何開發出最佳實踐方法來使用在中監控應用程序的。什么是監控最近有很多關于的消息,尤其是在中監控應用程序這方面。方法遵循中提及的原則,聚焦于檢測最終用戶在使用服務時關心的東西。 本文來自Weaveworks的工程師Anita Burhrle在Rancher Labs與Weaveworks聯合舉辦的Online Meetup上的技術分享。在此次分享中,嘉賓們討論了如何使...
摘要:從開始,部署管理的集群時,默認情況下會啟用授權群集端點功能。我們將首先在中創建一個新項目,該項目將使用功能與我們的集群集成。完成后單擊創建項目。這不僅意味著已被設為默認值,還能夠觸發構建。例如,負載均衡選項卡顯示已部署的以及創建的主機名。 介 紹 在這篇文章中,我們將介紹如何將GitLab的Auto DevOps功能與Rancher管理的Kubernetes集群連接起來,利用Ranch...
摘要:并且由外部控制器負責將資源轉移到這一狀態。在最后一個參數,我們傳遞了個回調函數和。這些回調函數具有實際的邏輯,并且在節點上的鏡像占用存儲發生改變時觸發。一旦啟動,將會開始對和的監控,并且調用回調函數。 Rancher Labs首席軟件工程師Alena Prokharchyk受邀在2017年12月6-8日的CNCF主辦的Kubernetes領域頂級盛會KubeCon + CloudNat...
摘要:此次發布的版本包含對和的支持,以及對的支持。版本中,的進階版監控功能以尊重多租戶環境邊界的方式部署了和。為應用目錄程序提供了特定于集群和項目的配置。在全球擁有超過一億的下載量,超過家企業客戶。 Rancher 2.2 GA版本引入的創造性新功能,將進一步實現Kubernetes-as-a-service,使企業用戶能夠專注于加速創新和推動業務價值。 showImg(https://se...
摘要:同時該版本在安全性和等關鍵功能上作出了改進年月日,發布。盡管谷歌這些年來是的主要貢獻者,但現在其他技術人員在這個項目上的貢獻量已經幾乎和谷歌持平了。這些舉動都在表明云計算市場的戰火將繼續蔓延,已經成為兵家必爭之地。年月日,宣布推出。 Kubernetes 在過去幾年中一直是云計算領域最著名的開源項目之一。20...
閱讀 3498·2023-04-25 15:52
閱讀 580·2021-11-19 09:40
閱讀 2570·2021-09-26 09:47
閱讀 1022·2021-09-22 15:17
閱讀 3547·2021-08-13 13:25
閱讀 2198·2019-08-30 15:56
閱讀 3459·2019-08-30 13:56
閱讀 2094·2019-08-30 11:27