>>> 目錄 <<<
一、概述
二、核心組件
三、基本概念
四、系統架構
五、鏡像制作
六、服務編排
七、持續部署
八、故障排查
>>> 正文 <<<
一、 概述
Kubernetes是容器集群管理系統,是一個開源的平台,可以實現容器集群的自動化部署、自動擴縮容、維護等功能。Kubernetes特點:
☛ 可移植: 支持公有雲,私有雲,混合雲,多重雲
☛ 可擴展: 模塊化, 插件化, 可掛載, 可組合
☛ 自動化: 自動部署,自動重啟,自動復制,自動伸縮/擴展
二、 核心組件
1) 主要組件
● etcd:保存了整個集群的狀態;
● apiserver:提供了資源操作的唯一入口,並提供訪問控制、API注冊和發現等機制;
● scheduler:負責資源的調度,按照預定的調度策略將Pod調度到相應的機器上;
● controller manager:負責維護集群的狀態,比如故障檢測、自動擴展、滾動更新等;
● kubelet:負責維護容器的生命周期,同時也負責數據卷(CVI)和網絡(CNI)的管理;
● kube-proxy:負責為Service提供集群內部的服務發現和負載均衡;
● Container runtime:負責鏡像管理以及Pod和容器的真正運行(CRI);
2) 擴展組件
● kube-dns:負責為整個集群提供DNS服務
● Metrics:提供資源監控
● Dashboard:提供GUI
● Ingress Controller:為服務提供外網入口
● Federation:提供跨可用區的集群
● Fluentd-elasticsearch:提供集群日志采集、存儲與查詢
三、 基本概念
1) 集群管理
◆ Master:K8s集群的管理節點,負責整個集群的管理和控制。
◆ Node:K8s集群的工作節點,負責集群中的工作負載。
◆ Namespace:為K8s集群提供虛擬的隔離作用。
◆ Label:通過給指定資源捆綁一個或多個不同的資源標簽,來實現多維度的資源分組管理。
2) 資源管理
◆ Pod:K8s集群中運行部署應用的最小單元,可以支持多容器。
◆ RC:K8s集群中最早的保證Pod高可用的API對象,之后擴展匹配模式新增了RS。
◆ Deployment:一個應用模式更廣的API對象,通過操作RS進行創建、更新、滾動升級服務。
◆ StatefulSet:K8s提供的管理有狀態應用的負載管理控制器API。
◆ DaemonSet:確保其創建的Pod在集群中的每一台(或指定)Node上都運行一個副本。
◆ Job:K8s用來控制批處理型任務的API對象,之后基於時間管理新增了CronJob。
◆ Service:定義了一個服務的多個Pod邏輯合集和訪問Pod的策略,實現服務發現和負載均衡。
◆ HPA:實現基於CPU使用率(或在使用自定義指標)的Pod自動伸縮的功能。
3) 存儲管理
◆ Secret:用來保存和傳遞密碼、密鑰、認證憑證這些敏感信息的對象。
◆ ConfigMap:將配置信息與鏡像內容分離,以使容器化的應用程序具有可移植性。
◆ Volume:是Pod中能夠被多個容器訪問的共享目錄。
◆ PV:持久化存儲和與之相關聯的持久化存儲聲明(PVC),使得K8s集群具備了存儲的邏輯抽象能力。
四、 系統架構
1) 集群高可用
K8s作為容器應用的管理中心,通過對Pod的數量進行監控,並且根據主機或容器失效的狀態將新的Pod調度到其他Node上,實現了應用層的高可用性。
針對K8s集群高可用性還應包含以下兩個層面的考慮:Etcd 數據存儲的高可用性(至少3台)和Master組件的高可用性。
這里我們采用 Hproxy + Keepalive 高可用方案,並且與 Etcd 服務、Master組件均部署到同一節點。
2) 控制管理
K8s集群的管理和控制主要由Master節點負責,它來負責具體的執行過程,我們后面執行的所有命令基本都是在Master節點上運行的。
Master節點通常會占據一個獨立的服務器,其主要原因是它太重要了,是整個集群的“首腦”,如果宕機或者不可用,那么對集群內容器應用的管理都將失效。
3) 工作負載
K8s集群中的計算能力由Node提供,最初Node稱為服務節點Minion,后來改名為Node。
K8s集群中的Node也就等同於Mesos集群中的Slave節點,是所有Pod運行所在的工作主機,可以是物理機也可以是虛擬機。
4) 系統監控
Prometheus(普羅米修斯)是一套開源的監控、報警、時間序列數據庫的組合。
基本原理是通過HTTP協議周期性抓取被監控組件的狀態,這樣做的好處是任意組件只要提供HTTP接口就可以接入監控系統,不需要任何SDK或者其他的集成過程。
這樣做非常適合作為虛擬化環境監控系統,比如Docker、Kubernetes。
組件說明:
■ Prometheus:負責實現對K8s集群監控數據的獲取,存儲以及查詢。
■ PrometheusOperator:為Prometheus實例的部署和管理提供了簡單的監視定義。
■ KubeStateMetrics:是K8s集群資源使用情況的聚合器,收集數據給K8s集群內使用(如HPA)。
■ AlertManager:負責將告警信息重復數據刪除,分組和路由到正確的接收者集成。
■ NodeExporter:用於采集集群中各個節點的資源使用情況。
■ Grafana:一個跨平台的開源的度量分析和可視化工具。
5) 日志收集
ELK分別指Elastic公司的Elasticsearch、Logstash、Kibana。在比較舊的ELK架構中,Logstash身兼日志的采集、過濾兩職。
但由於Logstash基於JVM,性能有一定限制,因此,目前業界更推薦使用Go語言開發Fliebeat代替Logstash的采集功能,Logstash只作為了日志過濾的中間件。
組件說明:
■ Filebeat:一個輕量型的單一功能數據采集器。
■ Logstash:能夠同時從多個來源采集數據,轉換數據,將數據發送到諸如ES中。
■ Elasticsearch:一個實時、分布式、可擴展的搜索引擎,通常用於索引和搜索大量日志數據。
■ Kibana:可以讓用戶在 ES 中使用圖形和圖表對數據進行可視化。
6) 鏡像倉庫
Harbor是一個開源鏡像倉庫,可通過基於角色的訪問控制來保護鏡像,新版本的Harbor還增加了掃描鏡像中的漏洞並將鏡像簽名為受信任。
作為CNCF孵化項目,Harbor提供合規性,性能和互操作性,以幫助你跨Kubernetes和Docker等雲原生計算平台持續,安全地管理鏡像。
Harbor組件均以Docker容器方式啟動,因此,你可以將其部署在任何支持Docker的Linux發行版上。
五、 鏡像制作
1) 鏡像構建
# 適用java1.8服務 FROM hub.jhmy.com/base/java:1.8 # 維護者 MAINTAINER zhangfan # 工作目錄 WORKDIR /root # 復制文件到鏡像 COPY *.jar . COPY lib/ lib/ COPY hosts.bak . # 查看當前目錄 RUN ls -l . # 容器啟動時運行命令 CMD ["./run.sh"]
構建鏡像示例:docker build -t hub.jhmy.com/test/jmnbservice .
2) 容器結構
當容器啟動時,一個新的可寫層被加載到鏡像的頂部。
這一層通常被稱作“容器層”,其余層都稱作“鏡像層”。
啟動容器示例:docker run -dit --name=myapp hub.jhmy.com/test/jmnbservice
進入容器示例:docker exec -it jmnbservice bash
六、 服務編排
1) ConfigMap資源定義
主要定義配置文件內容。
apiVersion: v1 kind: ConfigMap metadata: name: jmnbservice namespace: default data: application.properties: | server.port=1111 spring.server.port=2222 spring.dubbo.port=3333 logging.config=classpath:logback-spring.xml logback.logdir=/home/jhmyPro/xsr/logs logback.maxHistory=7 logback.totalSizeCap=10GB logback.maxFileSize=128MB dubbo.registry.address=zookeeper://10.11.12.13:2181 spring.application.name=JmNbService ......
2) Deployment資源定義
需要定義Pod副本數、匹配標簽、容器名稱、對應鏡像、監聽端口、環境變量(java運行參數)、資源限制(cpu和memory)、掛載配置等。
apiVersion: apps/v1 kind: Deployment metadata: name: jmnbservice namespace: default spec: replicas: 2 selector: matchLabels: app: jmnbservice project: nb template: metadata: labels: app: jmnbservice project: nb annotations: version: "20200321" spec: containers: - name: jmnbservice image: hub.jhmy.com/test/jmnbservice:latest imagePullPolicy: Always env: - name: JVM_OPTS value: "-Xms1024m -Xmx1024m" ports: - name: spring containerPort: 1111 - name: server containerPort: 2222 - name: dubbo containerPort: 3333 resources: limits: cpu: 200m memory: 2Gi requests: cpu: 100m memory: 1Gi volumeMounts: - name: config mountPath: /root/application.properties subPath: application.properties - name: html mountPath: /usr/local/nginx/html/clientexe - name: log mountPath: /home volumes: - name: config configMap: name: jmnbservice - name: html persistentVolumeClaim: claimName: nginxhtml - name: log hostPath: path: /home type: DirectoryOrCreate
3) Service資源定義
主要定義匹配Pod標簽、暴露方式、以及暴露端口。
apiVersion: v1 kind: Service metadata: name: jmnbservice namespace: default spec: type: NodePort selector: app: jmnbservice project: nb ports: - name: spring port: 1111 nodePort: 30121 - name: server port: 2222 nodePort: 30122 - name: dubbo port: 3333 nodePort: 30123
七、 持續部署
1) 部署應用
部署應用之前,請確保相關編排文件均已開發完成。至此,我們可以執行 kubectl create/apply 命令進行部署。
推薦使用apply,這樣可以避免重復部署時報錯,而且有利於編排文件修改更新,即當你修改編排文件后,只需要再次執行apply命令即可完成更新。
當然,如果你需要確保此次部署為唯一創建且信息完整,請使用create命令,並且你可以使用 kubectl delete 命令刪除資源。
最后我們可以使用 -f 標簽指定具體編排文件,也可以指定路徑,批量執行。
[root@k8s-32 JmDiService]# ls ConfigMap.yaml Deployment.yaml Service.yaml [root@k8s-32 JmDiService]# kubectl apply -f . configmap/jmdiservice created deployment.apps/jmdiservice created service/jmdiservice created [root@k8s-32 JmDiService]# kubectl get cm; kubectl get deploy; kubectl get svc NAME DATA AGE jmdiservice 1 70s NAME READY UP-TO-DATE AVAILABLE AGE jmdiservice 2/2 2 2 70s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE jmdiservice NodePort 10.102.153.176 <none> 20036:30111/TCP 69s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d16h
2) 滾動更新
通常進行應用升級,都是鏡像版本的升級,我們可以使用 kubectl set image 命令設置新的鏡像名稱即可;
如果需要更新具體資源字段,則可以使用 kubectl patch 命令;當然,你也可以使用 kubectl edit 命令編輯資源對象。
[root@k8s-32 JmDiService]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE jmdiservice 2/2 2 2 4h54m [root@k8s-32 JmDiService]# kubectl set image deployment/jmdiservice jmdiservice=hub.jhmy.com/project-test/jmdiservice:latest deployment.apps/jmdiservice image updated [root@k8s-32 JmDiService]# kubectl patch deployment/jmdiservice --patch '{"spec": {"template": {"metadata": {"annotations":{"version": "20200506" }}}}}' deployment.apps/jmdiservice patched
3) 版本回滾
我們使用上面更新應用時K8S都會記錄下當前的配置文件,保存為一個revision (版本),這樣就可以通過這個版本回滾到特定的時間。
我們可以通過 kubectl rollout history 命令查看歷史記錄,並通過 kubectl rollout undo 撤銷本次發布回滾到上一個部署版本,也可以使用--to-revision標簽回滾到指定版本。
[root@k8s-32 JmDiService]# kubectl rollout history deployment/jmdiservice deployment.apps/jmdiservice REVISION CHANGE-CAUSE 1 <none> 2 <none> 3 <none> [root@k8s-32 JmDiService]# kubectl rollout undo --to-revision=2 deployment/jmdiservice deployment.apps/jmdiservice rolled back
4) CICD流程
八、 故障排查
1) 查看系統Event
通過 kubectl describe pod 命令,可以顯示Pod創建時的配置定義、狀態等信息,還可以顯示與該Pod相關的最近的Event事件, 事件信息對於查錯非常有用。
2) 查看容器日志
在需要排查容器內部應用程序生成的日志時, 我們可以使用 kubectl logs <pod_name> 命令。
3) 查看K8s服務日志
K8s服務默認使用systemd系統管理,那么systemd的journal系統會接管服務程序的輸出日志。
我們可以 tailf /var/log/messages 查看系統日志,也可以使用 journalctl 工具來查看k8s組件的日志。
4) 尋求幫助
◎ Kubernetes官方網站任務詳解:https://kubernetes.io/zh/docs/tasks/
◎ Kubernetes GitHub庫問題列表:https://github.com/kubernetes/kubernetes/issues
作者:Leozhanggg
出處:https://www.cnblogs.com/leozhanggg/p/12837025.html
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。