K8S太火了!花10分鐘玩轉它不香麼?

個人Mall電商實戰項目一直使用的是Docker容器化部署,有不少朋友建議搞個Kubernetes部署。最近正好在學習Kubernetes,準備更新一波!今天咱們先來學習下Kubernetes的核心概念和基本使用,但願對你們有所幫助!

SpringBoot實戰電商項目mall(40k+star)地址:https://github.com/macrozheng/mallhtml

Kubernetes簡介

Kubernetes(簡稱K8S,K和S之間有8個字母)是用於自動部署,擴展和管理容器化應用程序的開源系統。它將組成應用程序的容器組合成邏輯單元,以便於管理和服務發現。Kubernetes 源自Google 15 年生產環境的運維經驗,同時凝聚了社區的最佳創意和實踐。node

Kubernetes具備以下特性:linux

  • 服務發現與負載均衡:無需修改你的應用程序便可使用陌生的服務發現機制。
  • 存儲編排:自動掛載所選存儲系統,包括本地存儲。
  • Secret和配置管理:部署更新Secrets和應用程序的配置時沒必要從新構建容器鏡像,且沒必要將軟件堆棧配置中的祕密信息暴露出來。
  • 批量執行:除了服務以外,Kubernetes還能夠管理你的批處理和CI工做負載,在指望時替換掉失效的容器。
  • 水平擴縮:使用一個簡單的命令、一個UI或基於CPU使用狀況自動對應用程序進行擴縮。
  • 自動化上線和回滾:Kubernetes會分步驟地將針對應用或其配置的更改上線,同時監視應用程序運行情況以確保你不會同時終止全部實例。
  • 自動裝箱:根據資源需求和其餘約束自動放置容器,同時避免影響可用性。
  • 自我修復:從新啓動失敗的容器,在節點死亡時替換並從新調度容器,殺死不響應用戶定義的健康檢查的容器。

Minikube簡介

Minikube是一種輕量級的Kubernetes實現,可在本地計算機上建立VM並部署僅包含一個節點的簡單集羣,Minikube可用於Linux、MacOS和Windows系統。Minikube CLI提供了用於引導集羣工做的多種操做,包括啓動、中止、查看狀態和刪除。nginx

Kubernetes核心概念

因爲Kubernetes有不少核心概念,學習它們對理解Kubernetes的使用頗有幫助,因此咱們先來學習下這些核心概念。

Node

Kubernetes集羣是指Kubernetes協調一個高可用計算機集羣,每一個計算機做爲獨立單元互相鏈接工做。git

一個Kubernetes集羣包含兩種類型的資源:github

  • Master:負責管理整個集羣。協調集羣中的全部活動,例如調度應用、維護應用的所需狀態、應用擴容以及推出新的更新。
  • Node:用於託管正在運行的應用。能夠是一個虛擬機或者物理機,它在Kubernetes集羣中充當工做機器的角色,每一個Node都有Kubelet,它管理Node並且是Node與Master通訊的代理,Node還具備用於處理容器操做的工具,例如Docker或rkt。

Deployment

Deployment負責建立和更新應用程序的實例。建立Deployment後,Kubernetes Master 將應用程序實例調度到集羣中的各個節點上。若是託管實例的節點關閉或被刪除,Deployment控制器會將該實例替換爲羣集中另外一個節點上的實例。這提供了一種自我修復機制來解決機器故障維護問題。web

可使用Kubernetes命令行界面Kubectl建立和管理Deployment。Kubectl使用Kubernetes API與集羣進行交互。docker

Pod

Pod至關於邏輯主機的概念,負責託管應用實例。包括一個或多個應用程序容器(如 Docker),以及這些容器的一些共享資源(共享存儲、網絡、運行信息等)。centos

Service

Service是一個抽象層,它定義了一組Pod的邏輯集,併爲這些Pod支持外部流量暴露、負載平衡和服務發現。api

儘管每一個Pod 都有一個惟一的IP地址,可是若是沒有Service,這些IP不會暴露在羣集外部。Service容許您的應用程序接收流量。Service也能夠用在ServiceSpec標記type的方式暴露,type類型以下:

  • ClusterIP(默認):在集羣的內部IP上公開Service。這種類型使得Service只能從集羣內訪問。
  • NodePort:使用NAT在集羣中每一個選定Node的相同端口上公開Service。使用<NodeIP>:<NodePort>從集羣外部訪問Service。是ClusterIP的超集。
  • LoadBalancer:在當前雲中建立一個外部負載均衡器(若是支持的話),併爲Service分配一個固定的外部IP。是NodePort的超集。
  • ExternalName:經過返回帶有該名稱的CNAME記錄,使用任意名稱(由spec中的externalName指定)公開Service。不使用代理。

Docker安裝

因爲Kubernetes運行須要依賴 容器運行時(負責運行容器的軟件),現比較通用的容器運行時有Docker、containerd和CRI-O。這裏選擇Docker,先在Linux服務器上安裝好Docker環境。
  • 安裝yum-utils
yum install -y yum-utils device-mapper-persistent-data lvm2
  • 爲yum源添加docker倉庫位置:
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  • 安裝Docker:
yum install docker-ce
  • 啓動Docker:
systemctl start docker

Minikube安裝

  • 首先咱們須要下載Minikube的二進制安裝包並安裝:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
  • 而後使用以下命令啓動Minikube:
minikube start
  • 若是你使用的是root用戶的話會沒法啓動並提示以下信息,那是由於Minikube不容許使用root權限啓動,須要建立一個非root帳號再啓動;
* minikube v1.16.0 on Centos 7.6.1810
* Automatically selected the docker driver
* The "docker" driver should not be used with root privileges.
* If you are running minikube within a VM, consider using --driver=none:
*   https://minikube.sigs.k8s.io/docs/reference/drivers/none/

X Exiting due to DRV_AS_ROOT: The "docker" driver should not be used with root privileges.
  • 這裏建立了一個屬於docker用戶組的macro用戶,並切換到該用戶;
# 建立用戶
useradd -u 1024 -g docker macro
# 設置用戶密碼
passwd macro
# 切換用戶
su macro
  • 再次使用minikube start命令啓動Minikube,啓動成功後會顯示以下信息:
* To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
* Preparing Kubernetes v1.20.0 on Docker 20.10.0 ...
  - Generating certificates and keys ...
  - Booting up control plane ...
  - Configuring RBAC rules ...
* Verifying Kubernetes components...
* Enabled addons: default-storageclass, storage-provisioner
* kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

Kubernetes的使用

建立集羣

經過Minikube咱們能夠建立一個單節點的K8S集羣,集羣管理Master和負責運行應用的Node都部署在此節點上。
  • 查看Minikube的版本號:
minikube version
minikube version: v1.16.0
commit: 9f1e482427589ff8451c4723b6ba53bb9742fbb1
  • 查看kubectl的版本號,第一次使用會直接安裝kubectl:
minikube kubectl version
Client Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.0", GitCommit:"af46c47ce925f4c4ad5cc8d1fca46c7b77d13b38", GitTreeState:"clean", BuildDate:"2020-12-08T17:59:43Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.0", GitCommit:"af46c47ce925f4c4ad5cc8d1fca46c7b77d13b38", GitTreeState:"clean", BuildDate:"2020-12-08T17:51:19Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"}
  • 若是你想直接使用kubectl命令的話,能夠將其複製到/bin目錄下去:
# 查找kubectl命令的位置
find / -name kubectl
# 找到以後複製到/bin目錄下
cp /mydata/docker/volumes/minikube/_data/lib/minikube/binaries/v1.20.0/kubectl /bin/
# 直接使用kubectl命令
kubectl version
  • 查看集羣詳細信息:
kubectl cluster-info
Kubernetes control plane is running at https://192.168.49.2:8443
KubeDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
  • 查看集羣中的全部Node,能夠發現Minikube建立了一個單節點的簡單集羣:
kubectl get nodes
NAME       STATUS   ROLES                  AGE   VERSION
minikube   Ready    control-plane,master   46m   v1.20.0

部署應用

一旦運行了K8S集羣,就能夠在其上部署容器化應用程序。經過建立Deployment對象,能夠指揮K8S如何建立和更新應用程序的實例。
  • 指定好應用鏡像並建立一個Deployment,這裏建立一個Nginx應用:
kubectl create deployment kubernetes-nginx --image=nginx:1.10
  • 建立一個Deployment時K8S會產生以下操做:

    • 選擇一個合適的Node來部署這個應用;
    • 將該應用部署到Node上;
    • 當應用異常關閉或刪除時從新部署應用。
  • 查看全部Deployment:
kubectl get deployments
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
kubernetes-nginx      1/1     1            1           21h
  • 咱們能夠經過kubectl proxy命令建立一個代理,這樣就能夠經過暴露出來的接口直接訪問K8S的API了,這裏調用了查詢K8S版本的接口;
[macro@linux-local root]$ kubectl proxy
Starting to serve on 127.0.0.1:8001
[root@linux-local ~]# curl http://localhost:8001/version
{
  "major": "1",
  "minor": "20",
  "gitVersion": "v1.20.0",
  "gitCommit": "af46c47ce925f4c4ad5cc8d1fca46c7b77d13b38",
  "gitTreeState": "clean",
  "buildDate": "2020-12-08T17:51:19Z",
  "goVersion": "go1.15.5",
  "compiler": "gc",
  "platform": "linux/amd64"
}

查看應用

經過對運行應用的Pod進行操做,能夠查看容器日誌,也能夠執行容器內部命令。
  • 查看K8s中全部Pod的狀態:
kubectl get pods
NAME                                   READY   STATUS             RESTARTS   AGE
kubernetes-nginx-78bcc44665-8fnnn      1/1     Running            1          21h
  • 查看Pod的詳細狀態,包括IP地址、佔用端口、使用鏡像等信息;
kubectl describe pods
Name:         kubernetes-nginx-78bcc44665-8fnnn
Namespace:    default
Priority:     0
Node:         minikube/192.168.49.2
Start Time:   Tue, 05 Jan 2021 13:57:46 +0800
Labels:       app=kubernetes-nginx
              pod-template-hash=78bcc44665
              version=v1
Annotations:  <none>
Status:       Running
IP:           172.17.0.7
IPs:
  IP:           172.17.0.7
Controlled By:  ReplicaSet/kubernetes-nginx-78bcc44665
Containers:
  nginx:
    Container ID:   docker://31eb1277e507ec4cf8a27b66a9f4f30fb919d17f4cd914c09eb4cfe8322504b2
    Image:          nginx:1.10
    Image ID:       docker-pullable://nginx@sha256:6202beb06ea61f44179e02ca965e8e13b961d12640101fca213efbfd145d7575
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 06 Jan 2021 09:22:40 +0800
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Tue, 05 Jan 2021 14:24:55 +0800
      Finished:     Tue, 05 Jan 2021 17:32:48 +0800
    Ready:          True
    Restart Count:  1
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-dhr4b (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-dhr4b:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-dhr4b
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:          <none>
  • 將Pod的名稱設置爲環境變量,方便以後使用$POD_NAME來應用Pod的名稱:
export POD_NAME=kubernetes-nginx-78bcc44665-8fnnn
  • 查看Pod打印的日誌:
kubectl logs $POD_NAME
  • 使用exec能夠在Pod的容器中執行命令,這裏使用env命令查看環境變量:
kubectl exec $POD_NAME -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kubernetes-nginx-78bcc44665-8fnnn
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
NGINX_VERSION=1.10.3-1~jessie
HOME=/root
  • 進入容器內部並執行bash命令,若是想退出容器可使用exit命令:
kubectl exec -ti $POD_NAME -- bash

公開暴露應用

默認Pod沒法被集羣外部訪問,須要建立Service並暴露端口才能被外部訪問。
  • 建立一個Service來暴露kubernetes-nginx這個Deployment:
kubectl expose deployment/kubernetes-nginx --type="NodePort" --port 80
  • 查看K8S中全部Service的狀態:
kubectl get services
NAME               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes         ClusterIP   10.96.0.1        <none>        443/TCP        5h16m
kubernetes-nginx   NodePort    10.105.177.114   <none>        80:31891/TCP   5s
  • 查看Service的詳情,經過NodePort屬性能夠獲得暴露到外部的端口;
kubectl describe services/kubernetes-nginx
Name:                     kubernetes-nginx
Namespace:                default
Labels:                   app=kubernetes-nginx
Annotations:              <none>
Selector:                 app=kubernetes-nginx
Type:                     NodePort
IP Families:              <none>
IP:                       10.106.227.54
IPs:                      10.106.227.54
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30158/TCP
Endpoints:                172.17.0.7:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
  • 經過CURL命令經過Minikube IP:NodePort IP能夠訪問Nginx服務,此時將打印Nginx主頁信息;
curl $(minikube ip):30158
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

標籤的使用

經過給資源添加Label,能夠方便地管理資源(如Deployment、Pod、Service等)。
  • 查看Deployment中所包含的Label;
kubectl describe deployment
Name:                   kubernetes-nginx
Namespace:              default
CreationTimestamp:      Tue, 05 Jan 2021 13:57:46 +0800
Labels:                 app=kubernetes-nginx
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=kubernetes-nginx
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
  • 經過Label查詢Pod:
kubectl get pods -l app=kubernetes-nginx
NAME                                READY   STATUS    RESTARTS   AGE
kubernetes-nginx-78bcc44665-8fnnn   1/1     Running   1          21h
  • 經過Label查詢Service:
kubectl get services -l app=kubernetes-nginx
NAME               TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes-nginx   NodePort   10.106.227.54   <none>        80:30158/TCP   4m44s
  • 給Pod添加Label:
kubectl label pod $POD_NAME version=v1
  • 查看Pod的詳細信息,能夠查看Label信息:
kubectl describe pods $POD_NAME
Name:         kubernetes-nginx-78bcc44665-8fnnn
Namespace:    default
Priority:     0
Node:         minikube/192.168.49.2
Start Time:   Tue, 05 Jan 2021 13:57:46 +0800
Labels:       app=kubernetes-nginx
              pod-template-hash=78bcc44665
              version=v1
  • 經過Label查詢Pod:
kubectl get pods -l version=v1
  • 經過Label刪除服務:
kubectl delete service -l app=kubernetes-nginx
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP        30h

可視化管理

Dashboard是基於網頁的K8S用戶界面。你可使用Dashboard將容器應用部署到K8S集羣中,也能夠對容器應用排錯,還能管理集羣資源。
  • 查看Minikube內置插件,默認狀況下Dashboard插件未啓用:
minikube addons list
|-----------------------------|----------|--------------|
|         ADDON NAME          | PROFILE  |    STATUS    |
|-----------------------------|----------|--------------|
| dashboard                   | minikube | disabled     |
| default-storageclass        | minikube | enabled ✅   |
|-----------------------------|----------|--------------|
  • 啓用Dashboard插件:
minikube addons enable dashboard
  • 開啓Dashboard,經過--url參數不會打開管理頁面,並能夠在控制檯得到訪問路徑:
minikube dashboard --url
* Verifying dashboard health ...
* Launching proxy ...
* Verifying proxy health ...
http://127.0.0.1:44469/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
  • 要想從外部訪問Dashboard,須要從使用kubectl設置代理才行,--address設置爲你的服務器地址;
kubectl proxy --port=44469 --address='192.168.5.94' --accept-hosts='^.*' &
  • 從外部訪問服務器須要開啓防火牆端口;
# 切換到root用戶
su -
# 開啓端口
firewall-cmd --zone=public --add-port=44469/tcp --permanent
# 重啓防火牆
firewall-cmd --reload
  • 經過以下地址便可訪問Dashboard:
http://192.168.5.94:44469/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
  • 查看K8S集羣中的資源狀態信息:

  • 經過yaml腳本建立K8S資源:

  • 查看K8S中全部Pod的狀態信息,經過更多按鈕能夠查看容器日誌和執行內部命令。

總結

當咱們的應用須要部署在多個物理機上時,傳統的作法是一個個物理機器去部署。若是咱們使用了K8S的話,就能夠把這些物理機認爲是一個集羣,只需經過K8S把應用部署到集羣便可,無需關心物理機的部署細節。同時K8S提供了水平擴容、自動裝箱、自動修復等功能,大大減小了應用集羣化部署的工做量。

參考資料

官方文檔:https://kubernetes.io/zh/docs...

本文 GitHub https://github.com/macrozheng/mall-learning 已經收錄,歡迎你們Star!
相關文章
相關標籤/搜索