Docker從入門到掉坑(五):繼續挖一挖 k8s
在之前的幾篇文章中,主要還是講解了關於簡單的docker容器該如何進行管理和操作及k8s上手避坑,在接下來的這篇文章開始,我們將繼續對k8s模組的學習
pod是啥
在k8s裡面,有很多新的技術概念,其中有一個東西被稱之為pod。pod是k8s叢集裡面執行和部署的最小單元,它的設計理念是,一個pod可以承載多個容器,並且共享網路地址和檔案系統,內部的容器通過程序間的通訊相互訪問。
官方圖片附上:
複製控制器(Replication Controller,RC)
通常我們在k8s叢集裡面會有成千上百個pod,那麼對於pod的管理也是需要有一定的機制,k8s內部有個叫做RC(Replication Controller) 的複製控制器。
RC主要的是監控pod節點的數目,當我們在啟動pod的時候希望有多個pod副本,可以使用RC來控制啟動的數目,如果期間有部分pod掛掉了,RC會自動進行重啟pod。
k8s裡面常見的pod操作場景
1.在實操的過程中,如果你遇到了下邊的這種情況,某個pod一直起不來
[root@localhost ~]# kubectl get pods NAME READY STATUS RESTARTS AGE mysql-rc-p8blq 0/1 ErrImagePull 0 16h nginx 1/1 Running 0 29h nginx-deployment-54f57cf6bf-f9p92 0/1 ContainerCreating 0 77s nginx-deployment-54f57cf6bf-mqq7x 0/1 ImagePullBackOff 0 18m nginx-deployment-9f46bb5-kwxwh 0/1 ImagePullBackOff 0 13m tomcat-565cd88dc7-qlqtk 1/1 Running 0 2d3h
這個時候pod可能會出現啟動失敗的情況,那麼這個時候該如何去終止對應的pod呢?
通過以下的命令來對容器進行刪除即可:
[root@localhost k8s]# kubectl delete -f ./mysql-rc.yaml replicationcontroller "mysql-rc" deleted [root@localhost k8s]# kubectl delete -f ./mysql-svc.yaml service "mysql-svc" deleted [root@localhost k8s]# kubectl delete -f ./nginx-deployment.yaml deployment.apps "nginx-deployment" deleted [root@localhost k8s]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 29h tomcat-565cd88dc7-qlqtk 1/1 Running 0 2d3h
2.如何執行單容器的pods
kubectl run example --image=nginx
3.檢視某個pod詳細資訊
[root@localhost k8s]# kubectl get pod nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 29h 172.17.0.7 minikube <none> <none>
4.檢視某pod裡面的詳情描述內容
[root@localhost k8s]# kubectl describe pod nginx Name: nginx Namespace: default Priority: 0 Node: minikube/10.1.10.51 Start Time: Mon, 02 Dec 2019 09:49:28 +0800 Labels: app=pod-example Annotations: <none> Status: Running IP: 172.17.0.7 IPs: IP: 172.17.0.7 Containers: web: Container ID: docker://53d066b49233d17724b8fd0d5a4d6a963f33e6ea4e0805beb7745ee267683ed8 Image: nginx Image ID: docker-pullable://nginx@sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566 Port: 80/TCP Host Port: 0/TCP State: Running Started: Mon, 02 Dec 2019 09:51:22 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-7mltd (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-7mltd: Type: Secret (a volume populated by a Secret) SecretName: default-token-7mltd Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: <none>
5.替換pod對應的配置規則檔案
kubectl replace --force -f 規則檔案
6.假設說你在操控pod節點的過程中不小心寫錯了映象的地址,導致pod啟動失敗,這個時候我們可以刪除機器上邊的某個pod節點,例如:
刪除一個name為nginx的pod節點:
[root@localhost k8s]# kubectl delete pod nginx pod "nginx" deleted
7.刪除某臺機器上邊deployment資訊:
[root@localhost k8s]# kubectl delete deployment tomcat deployment.apps "tomcat" deleted
8.多容器pod啟動的步驟
我們啟動多個容器的pod時候,最好使用create命令來操作,並且在建立的時候最好是使用yaml(或者json格式)這種檔案來對容器的啟動進行管理:
kubectl create -f FILE
通常啟動pod的yaml檔案的格式基本如下:
apiVersion: v1 kind: Pod metadata: name: rss-site labels: app: web spec: containers: - name: 容器1 image: 映象名1 ports: - containerPort: 80 - name: 容器1 image: 映象名2 ports: - containerPort: 88 spec:
如果啟動過程中需要有多個docker容器,那麼就寫多個name,image,ports這類配置即可。
在k8s的pod啟動過程中,如果出現多次發現映象拉取失敗的情況,通常是因為映象源地址出錯,這時候需要重置docker映象源地址:
# vi /etc/docker/daemon.json { "registry-mirrors": ["http://hub-mirror.c.163.com"] } systemctl restart docker.service
設定好這份json檔案之後,我們進行restart操作即可。
編寫好了yaml檔案之後,再次使用 kubectl create -f FILE命令即可。
最後通過kubectl get pod指令來驗證pod的狀態即可。
同理,如果我們需要用pod裝載java程式的話,例如說是springboot應用,只需要將springboot應用打包成docker映象,然後在yml配置裡面引入就好了。
9.檢視pod內部節點的日誌資訊
kubectl logs <pod_name> kubectl logs -f <pod_name> #類似tail -f的方式檢視(tail -f 實時檢視日誌檔案 tail -f 日誌檔案log)
前邊我們主要都是講解一些基於容器化技術的實戰,操作了這麼多容器化的api命令,其背後架構的設計思路卻又是怎樣的呢?
10.kubernetes的基本架構
用一句簡單的話語來介紹,kubernetes就是一個容器的叢集管理系統,通過kubernetes可以實現對於容器叢集化的自動化部署,自動化擴容,維護等作用。
kubernetes叢集是由一個master來負責對各個節點進行管理的,其中被管理的各個node節點可能會是一些虛擬機器或者小型機器。在每個node節點上都會運作有各種各樣的pod,而pod通常會是各種各樣的docker容器。
基本的架構圖如下所示:
Master模組
kubectl主要的作用是對kubernetes傳送命令,通過使用apiserver來呼叫kubernets對內部的各個node節點進行部署和控制。
ApiServer的主要工作就是對各個node節點進行增刪改查,提到對節點資料的操作,我們不得不得說明一下etcd。etcd主要是儲存一些節點的資料資訊,並且每次kubectl傳送過來的指令都會被apiserver先儲存到etcd中。
Controller manager 的作用主要是監控各個容器的情況。Controller manager會通過監聽Api Server裡面的提供的一個List Watch介面來監控各個叢集資源的資料,從而調整資源的狀態。
舉個栗子來講:
在成百上千的微服務系統中,假設說某個節點出現了crash,那麼這個時候Controller manager就會自動地進行節點的修復,故障轉移,這樣就能很好地減輕了運維人員的壓力。
Scheduler 主要是一個排程的作用,將容器部署到指定的機器上邊,然後將pod和node資源進行對映,當節點數目變多了之後,scheduler會自動進行資源的分配。所以說白了,Scheduler是老大,它來決定每個pod要放置在哪個node上邊,並且命令kubelet進行容器的部署。
Node模組
Node是k8s的工作節點,Node 一般是一個虛擬機器或者物理機,每個 node 上都執行三個服務,分別是Container runtime,kubelet,kube-proxy三類。
kubelet 主要是負責接收master的命令,並且執行,同時還要維護容器的生命週期。
kube-proxy 主要的作用就是負責負載均衡,處理流量的轉發問題。
Container runtime 是負責映象管理以及pod和容器的真正執行。
從K8s的系統架構、技術概念和設計理念,我們可以看到K8s系統最核心的兩個設計理念:一個是容錯性,一個是易擴充套件性。容錯性實際是保證K8s系統穩定性和安全性的基礎,易擴充套件性是保證K8s對變更友好,可以快速迭代增加新功能的基礎。