簡單入門Kubernetes

什麼是Kubernetes

  • 官網

https://kubernetes.io/java

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

image-20191203155553918

  • 我的理解
    • 基於容器技術
    • 分佈式架構
    • 彈性伸縮
    • 隔離物理機
    • 和谷歌的Borg有關係
    • 用於部署、管理、運維咱們的應用

Kubernetes核心概念

Kubernetes中的大部分概念,如:Node、Pod、Replication Controller、Service,均可以被視做一種資源對象。幾乎全部的資源對象均可以經過Kubernetes提供的kubectl工具執行CRUD,並將其保存在etcd中進行持久化存儲。mysql

從這個角度看,Kubernetes是一個高度自動化的資源控制系統linux

它經過比較etcd中保存的資源指望值與當前環境的實際資源狀態之間的差別,實現自動控制和自動糾錯的高級功能git

image-20191203142830394

Service

  • 擁有惟一的名稱
  • 擁有一個虛擬IP和端口號
  • 可以提供某種遠程服務能力
  • 被映射到提供這種服務能力的一組容器應用上

Node

  • 物理機
  • 雲上的虛擬機

反正就是一臺機器就對了web

一般一個節點運行幾百個Podsql

Replication Controller

副本集docker

它可以保證Pod持續運行,而且在任什麼時候候都有指定數量的Pod副本,在此基礎上提供一些高級特性,好比滾動升級和彈性伸縮api

image-20191203171838235

RC會在每一個節點上建立Pod,Pod上若是有相應的Images能夠直接建立,若是沒有,則會拉取這個鏡像再進行建立tomcat

在Kubernetes集羣中,只要爲須要擴容的Service關聯到Pod建立的一個RC,服務擴容和升級就會變得很是簡單

  • 一個RC文件,包含如下三個關鍵信息

    • 目標Pod的定義
    • 目標Pod須要運行的副本數量
    • 要監控的目標Pod的標籤
  • 刪除RC,並不會刪除經過該RC建立好的Pod
    • 若是要刪除RC對於的Pod,能夠設置replicas值爲0,而後更新RC
    • kubectl提供stop、delete命令,來一次性刪除RC及其對應的Pod
  • 在應用升級的時候
    • 其實就是一個新的容器鏡像替代舊版本的過程
    • 經過改變RC中Pod模板的鏡像版本,實現滾動升級

ReplicaSet

Replica Set是Replication Controller的下一代

當前惟一的區別就是RS支持基於集合的Label Selector

image-20191204192025741

咱們不多單獨設置RS,主要是被Deployment這個更高層的資源對象所使用

從而造成一整套Pod建立、刪除、更新的編排機制

Replica Set和Deployment這兩個重要的資源對象,主鍵替代了RC的做用

Deployment

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

咱們把Deployment當作一次RC的升級便可

image-20191204192447038

image-20191204192459539

image-20191204192531881

Pod

image-20191204181720871

Pod是Kubernetes管理的最小運行單元

一個Pod規定了其可以使用的硬件資源,達到隔離的做用

Pod內運行一個特殊的Container---Pause,在Pod內的其餘Container,共享Pause的網絡棧和Volume掛載卷

  • Pause
    • 用pause這個不易死亡的容器表明pod的存活與否
    • pod內的多個業務容器共享Pause的IP,共享Pause掛載的Volume
  • Kubernetes爲每一個Pod都分配了惟一IP--->Pod IP
  • 一個Pod內的多個容器共享Pod IP
  • 一個Pod內的容器與另外Node上的Pod容器能夠直接通訊

Container

鏡像啓動後,就是Container

Container運行在Pod中,多個緊密相關聯的Container,咱們通常會讓他們運行在同一個Pod

Label

Kubernetes中的各個對象,均可以打上Label標籤

標籤是name=mysql這樣子的鍵值對

一個資源對象能夠定義任意數量的Label,同一個Label也能夠被添加到任意數量的資源對象上

Kubernetes架構設計

image-20191203170709992

Master

  • Master是集羣控制節點

  • 負責運行管理相關的進程
  • 一般Master單獨佔用一個服務器,若是須要高可用,建議部署3臺服務器
  • 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會觸發「工做負載大轉移」的自動流程

HelloWorld

Kubernetes的安裝先不講了

  • 如今要作的事情是
    • 使用Kubernetes部署MySQL與JavaWeb程序
    • JavaWeb能夠訪問Kubernetes
  • 基本步驟
    • MySQL副本集
    • MySQL Service
    • JavaWeb副本集
    • JavaWeb Service

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資源對象

在hello world中,咱們已經使用yaml格式的方式,聲明瞭RC和Service兩種資源對象

其實還能夠是JSON格式(不經常使用)

基礎

下面咱們具體講講每個配置

# 聲明須要用到的api版本
#Kubernetes平臺採用的是核心+外圍擴展的設計思路
#常見的核心資源對象都歸屬於v1這個核心api
apiVersion: v1
# 表名這是一個副本集,還能夠是 Pod、Service等
kind: ReplicationController
metadata:
# RC的名稱,全局惟一
  name: mysql
  labels:
    name: XXX # 定義了一個標籤,name=XXX
# 定義容器組     
spec:
# 期待的Pod數量
  replicas: 1
# selector是標籤選擇器,這裏表示,當前容器組處理擁有app=mysql標籤的Pod  
  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
        resources:
# 設置一個較小的值,符合容器平時工做負載下的資源需求        
            requests:
# 內存佔用,默認單位爲字節,通常咱們使用Mi,表示兆         
                memory: "64Mi"
# 以1/1000爲最小單位,100m表示0.1個CPU
# 不論是在一個1Core的機器仍是8Core的機器上,100m表明的含義都是同樣的
                cpu: "250m"
# 設置一個較大的值,符合容器峯值負載下的資源需求               
# 當容器試圖使用超過這個量的資源時,可能被Kubernetes殺掉並重啓
            limits:
                memory: "128Mi"
                cpu: "500m"
        ports:
# 容器應用監聽的端口號,PodIP+這個端口,組成了新的概念:Endpoint
# 表明此Pod裏的一個服務進程的對外通訊地址
        - containerPort: 3306
# 注入容器內的環境變量        
        env:
        - name: MYSQL_SERVICE_HOST
            value: "mysql"
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"

Selector表達式

image-20191204190825504

kubectl命令詳解

詳細命令的使用,經過kubectl help得到

查看

  • 查看Node
➜  k8s git:(master) ✗ kubectl get nodes
NAME       STATUS   ROLES    AGE   VERSION
minikube   Ready    master   8h    v1.16.2
  • 查看某個node詳情

這裏的minikube是node的name

➜  k8s git:(master) ✗ kubectl describe node minikube
Name:               minikube
Roles:              master
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=minikube
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/master=
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Wed, 04 Dec 2019 10:02:05 +0800
Taints:             <none>
Unschedulable:      false
Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  MemoryPressure   False   Wed, 04 Dec 2019 18:12:44 +0800   Wed, 04 Dec 2019 10:02:01 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Wed, 04 Dec 2019 18:12:44 +0800   Wed, 04 Dec 2019 10:02:01 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Wed, 04 Dec 2019 18:12:44 +0800   Wed, 04 Dec 2019 10:02:01 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            True    Wed, 04 Dec 2019 18:12:44 +0800   Wed, 04 Dec 2019 10:02:01 +0800   KubeletReady                 kubelet is posting ready status
Addresses:
  InternalIP:  192.168.99.105

本文由博客一文多發平臺 OpenWrite 發佈!

相關文章
相關標籤/搜索