Kubernetes權威指南 第一章:Kubernetes入門


Kubernetes是什么

  • 官網

https://kubernetes.io/

中文版:https://kubernetes.io/zh/

image-20191203155553918

  • Kubernetes是谷歌十幾年大規模容器管理經驗的成果
  • 是Borg的一個開源版本
  • 基於容器技術的分布式架構方案

Service簡介

  • Kubernetes以Service為核心,Service有如下特征
    • 唯一名稱
    • 擁有一個虛擬ip和端口
    • 提供某種遠程服務能力
    • 被映射到提供這種服務能力的一組容器應用上

Pod簡介

  • Pod運行在Node主機中
  • Pod是Kubernetes管理的最小運行單元
  • 通常一個Node運行上百個Pod
  • 每個Pod有一個特殊的Pause容器,負責網絡棧和Volume掛載卷
  • 只有提供服務的那組Pod才會被映射為一個服務

為什么要使用Kubernetes

一旦搭建好Kubernetes環境后,后續對於應用的部署與運維,使用Kubernetes就非常方便了

Hello World

Kubernetes的安裝先不講了

  • 現在要做的事情是
    • 使用Kubernetes部署MySQL與JavaWeb程序
    • JavaWeb可以訪問Kubernetes
  • 基本步驟
    • MySQL副本集
    • MySQL Service
    • JavaWeb副本集
    • JavaWeb Service

下面的幾個yaml文件在

https://github.com/nbcoolkid/learning/tree/master/k8s

MySQL RC

  • mysql-rc.yaml
apiVersion: v1
# 表名這是一個副本集
kind: ReplicationController
metadata:
# RC的名稱,全局唯一
  name: mysql
spec:
# 期待的Pod數量
  replicas: 1
  selector:
    app: mysql
# 根據此模板創建Pod副本
  template:
    metadata:
      labels:
# Pod副本擁有的標簽,對應RC的Selector      
        app: mysql
    spec:
      containers:
      - name: mysql
        image: registry.cn-hangzhou.aliyuncs.com/sherry/mysql:5.7
        ports:
# 容器應用監聽的端口號        
        - containerPort: 3306
# 注入容器內的環境變量        
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"

注意這里的yaml文件,不可以有制表符,我們一律使用空格鍵代替

編寫完文件后,使用apply命令做個文件格式檢查

➜  k8s git:(master) ✗ kubectl apply -f mysql-rc.yaml
replicationcontroller/mysql created
  • 創建RC
➜  k8s git:(master) ✗ kubectl create -f mysql-rc.yaml
replicationcontroller/mysql created
  • 查看創建結果
➜  k8s git:(master) ✗ kubectl get rc
NAME    DESIRED   CURRENT   READY   AGE
mysql   1         1         1       4m17s
  • 查看創建的Pod情況
➜  k8s git:(master) ✗ kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
mysql-wg9sp   1/1     Running   0          5m16s
  • dashboard

其實通過dashboard,也能看到啟動情況

image-20191204124739155

MySQL Service

  • mysql-svc.yaml
apiVersion: v1
kind: Service           # 表名這是一個Kubernetes Service
metadata:
  name: mysql           # Service全局名稱
spec:
  ports:
    - port: 3306        # Service對外提供的端口
  selector:
    app: mysql          # Service對應的Pod擁有此標簽,所有擁有此標簽的pod都歸我管
  • 創建Service
➜  k8s git:(master) ✗ kubectl create -f mysql-svc.yaml
service/mysql created
  • 查看創建結果
➜  k8s git:(master) ✗ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    175m
mysql        ClusterIP   10.105.55.185   <none>        3306/TCP   84s

可以發現,MySQL服務被分配了一個值為10.105.55.185CLUSTER-IP,端口為3306

此時,Kubernetes集群中其他創建的Pod就可以通過這個ip+端口進行連接和訪問了

這里的ip,是Service創建后由Kubernetes系統自動分配的,

其他Pod無法余弦知道,所以需要有一個服務發現機制來找到這個服務。

現在,我們根據Service的唯一名稱獲取到ip和端口

JavaWeb RC

  • myweb-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: myweb
spec:
  replicas: 2
  selector:
    app: myweb
  template:
    metadata:
      labels:
        app: myweb
    spec:
      containers:
        - name: myweb
          image: kubeguide/tomcat-app:v1
          ports:
          - containerPort: 8080

在Tomcat容器內部,應用將使用環境變量MYSQL_SERVICE_HOST的值連接MySQL,更安全的做法是使用服務的名稱mysql進行訪問

  • 創建RC
➜  k8s git:(master) ✗ kubectl create -f myweb-rc.yaml
replicationcontroller/myweb created
  • 驗證
➜  k8s git:(master) ✗ kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
mysql-ck4j5   1/1     Running   0          164m
myweb-8dhr9   1/1     Running   0          3m11s
myweb-nm75w   1/1     Running   0          3m11s

JavaWeb Service

  • myweb-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: myweb
spec:
  type: NodePort
  ports:
    - port: 8080
      nodePort: 30001
  selector:
    app: myweb

type: NodePortnodePort: 30001,表明此Service開啟了NodePort方式的外網訪問模式

  • 啟動
➜  k8s git:(master) ✗ kubectl create -f myweb-svc.yaml 
service/myweb created
  • 驗證
➜  k8s git:(master) ✗ kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          5h47m
mysql        ClusterIP   10.105.55.185   <none>        3306/TCP         174m
myweb        NodePort    10.101.31.133   <none>        8080:30001/TCP   41s

驗證

經過上述步驟,我們通過dashbaord查看到底啟動了哪些服務

  • Service

image-20191204155811477

  • RC

image-20191204155830187

  • Pod

image-20191204155844792

我們可以使用 http://虛擬機ip:30001/demo/ 的方式來進行驗證訪問

那么怎么獲取這個虛擬機的ip呢?

我這里使用的是minikube安裝的Kubernetes環境,安裝后,在虛擬機中的Linux,賬號是root,密碼為空

然后使用ipconfig|more命令就能看到ip

image-20191204172927321

ok,至此,我們的hello world完畢

基本概念與術語

Kubernetes中的大部分概念,包括Node、Pod、Replication Controller、Service,都可以被看做一種資源對象

幾乎所有的資源對象都可以通過kubectl進行增刪改查操作,並持久化到etcd中

apiVersion:v1

聲明當前這個資源對象歸屬於v1這個核心API

大部分的資源對象都歸屬於v1這個核心API

Master

Kubernetes集群的控制節點,一般在生產環境至少部署3台作為高可用

所有的Kubernetes指令都是發給Master,由Master去管理集群中的節點

  • Master上運行着以下核心進程
    • Kubernetes API Server:kube-apiserver,集群控制入口
    • Kubernetes Controller Manager:kube-controller-manager,資源對象管理
    • Kubernetes Scheduler:kube-scheduler,資源調度
  • Master上通常還部署etcd服務,因為Kubernetes里的所有資源對象數據都保存在etcd中

Node

  • 工作節點,運行應用程序
  • Node上運行着以下核心進程
    • kubelet:負責Pod對應容器的創建、啟停,與Master的協作,實現集群管理
    • kube-proxy:實現Kubernetes Service的通信,負載均衡的重要組件
    • docker
  • Node可以在Kubernetes運行期間動態加入集群
    • 前提是Node節點已經安裝好了上述核心進程
    • 默認情況下,kubelet會向Master注冊自己
  • 如果某個Node失聯,Master會觸發“工作負載大轉移”的自動流程

Pod

image-20191205154759114

  • Pod運行在Node上

  • Pod有一個Pause根容器

  • Pod內容器可以和Kubernetes集群中任意的Pod內的容器進行直接通信

  • PodIP+容器端口=Endpoint,代表此Pod內的某個服務的對外通信地址

    • 一般一個應用會暴露兩個Endpoint,一個服務端口,一個管理端口
  • 可以配置Pod對資源期望的最低要求和最高要求(CPU、內存)

        resources:
# 設置一個較小的值,符合容器平時工作負載下的資源需求        
        	requests:
# 內存占用,默認單位為字節,一般我們使用Mi,表示兆        	
        		memory: "64Mi"
# 以1/1000為最小單位,100m表示0.1個CPU
# 不管是在一個1Core的機器還是8Core的機器上,100m代表的含義都是一樣的
        		cpu: "250m"
# 設置一個較大的值,符合容器峰值負載下的資源需求        		
# 當容器試圖使用超過這個量的資源時,可能被Kubernetes殺掉並重啟
        	limits:
        		memory: "128Mi"
        		cpu: "500m"

Label

  • Label是鍵值對,key和value均由用戶自定義
  • 一個Label可以被附加到多個資源上,一個資源可以定義任意數量的Label
  • Label通常在資源定義時確定,也可以在對象創建后動態添加與刪除
  • Label定義后,通過 Label Selector(標簽選擇器)進行查詢和篩選
    • Selector有基於等式與基於集合兩種
    • name=redis-slave,匹配所有具備
    • name!=redis-slave,匹配所有不具備
    • name in (redis-master,redis-slave)
    • name not in (pho-frontend)
    • 多個表達式之間用,分割
    • 多個表達式之間是AND關系

image-20191205160338840

  • matchLabels與matchExpressions

image-20191205160510193

Replication Controller/Replica Set

  • RC定義內容包括

    • 期待Pod的數量
    • 刪選Pod的Label Selector
    • Pod數量不滿足時用於創建新Pod的template
  • 一個完整的RC定義案例

image-20191205161023635

確保擁有tier=frontend標簽的Pod在Kubernetes集群中始終只有一個副本

  • 刪除RC,並不會刪除通過該RC創建好的Pod
    • 如果要刪除RC對於的Pod,可以設置replicas值為0,然后更新RC
    • kubectl提供stop、delete命令,來一次性刪除RC及其對應的Pod
  • 在應用升級的時候
    • 其實就是一個新的容器鏡像替代舊版本的過程
    • 通過改變RC中Pod模板的鏡像版本,實現滾動升級

image-20191205161308683

image-20191205161322793

Deployment

為了更好的解決Pod的編排問題,Deployment內部使用Replica Set

我們把Deployment當做一次RC的升級即可

image-20191205161448346

Horizontal Pod Autoscaler

HPA用於實現Pod的橫向自動擴容

image-20191205161935202

image-20191205161951442

image-20191205161848069

StatefulSet

image-20191205162253693

image-20191205162309660

Service

image-20191205162359992

Kubernetes內部的服務,最終是通過Service暴露出去的

Service整個生命周期內,擁有唯一不變的ip

Job

image-20191205162722437

image-20191205162732899

Volume

  • Volume是Pod中能夠被多個容器訪問的共享目錄
  • Kubernetes中的Volume概念、用途、目的,與Docker中的Volume類似,但又有不同
    • Kubernetes中的Volume定義在Pod中
    • Kubernetes中的Volume與Pod的生命周期相同,與容器不同
    • Kubernetes支持多種文件系統的Volume,如:GlusterFS、Ceph等

image-20191205163706720

image-20191205163722382

image-20191205163749818

image-20191205163803715

image-20191205163817663

image-20191205163831445

image-20191205163939409

Persistent Volume

image-20191205164208298

image-20191205164219938

image-20191205164230527

Namespace

命名空間,一般用於實現多租戶的資源個例

image-20191205164508775

image-20191205164518843

Annotation

image-20191205164618162

ConfigMap

image-20191205164634581

image-20191205164648822

本文由博客一文多發平台 OpenWrite 發布!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM