Kubernetes 零基礎入門

Kubernetes 是 Google 團隊發起並維護的基於 Docker 的開源容器集羣管理系統,它不只支持常見的雲平臺,並且支持內部數據中心。它的目標是管理跨多個主機的容器,提供基本的部署,維護以及運用伸縮,主要實現語言爲 Go 語言。前端

最初,Google 開發了一個叫 Borg 的系統(如今命令爲 Omega)來調度如此龐大數量的容器和工做負載。在積累了這麼多年的經驗後,Google 決定重寫這個容器管理系統,並將其貢獻到開源社區,讓全世界都能受益。它就是 Kubernetes。node

建於 Docker 之上的 Kubernetes 能夠構建一個容器的調度服務,其目的是讓用戶透過 Kubernetes 集羣來進行雲端容器集羣的管理,而無需用戶進行復雜的設置工做。它是當前最流行的容器編排引擎。nginx

安裝環境

安裝 Kubernetes 須要安裝git

  • kubeadm: 用來初始化集羣的指令。
  • kubelet: 在集羣中的每一個節點上用來啓動 pod 和 container 等。
  • kubectl: 是 Kubernetes 命令行工具,用來與集羣通訊的命令行工具。

咱們可使用 minikube 來快速安裝開發和學習環境。github

安裝好 minikube 能夠執行以下命令建立虛擬機web

$ minikube start 
    # --vm-driver hyperv \
    # --hyperv-virtual-switch PVS \
    --image-mirror-country cn \
    --registry-mirror https://dockerhub.azk8s.cn \
    --v 7 \
    --alsologtostderr
複製代碼

若是是 windows 10 可使用 hyperv, 須要設置 --vm-driver--hyperv-virtual-switch 參數,須要使用管理員權限。sql

$ minikube status # 安裝完成後,查看一下狀態

$ kubectl cluster-info # 查看一下集羣信息

$ minikube dashboard # 開啓 Kubernetes web UI 控制檯
複製代碼

還可使用在線的 play with k8sdocker

或者去 官網交互教程windows

概念

建立一個集羣須要使用到 kubeadm,它會生成證書,配置文件,安裝附加組鍵,如 kube-proxykube-dns。幾乎全部的 Kubernetes 組件自己也運行在 Pod 裏。後端

Pod

Kubernetes 中咱們不直接管理容器,而是 Pod。它是最小工做單元。

一個 Pod 是一個或一組運行很是緊密的容器, Pod 中的全部容器使用同一個網絡 namespace,即相同的 IP 地址和 Port 空間。它們能夠直接用 localhost 通訊。一樣的,這些容器能夠共享存儲,當 Kubernetes 掛載 volumePod,本質上是將 volume 掛載到 Pod 中的每個容器。

PodPendingRunningSucceededFailedUnknown 這幾個階段。

咱們通常不本身建立 Pod, 而是建立 Deployment

Master

Kubernetes 集羣中主機分爲 masternode

MasterCluster 的大腦,它負責管理集羣,主要職責是調度,決定將應用放在哪裏運行。一個主機能夠同時擁有 MasterNode 兩種身份。

Master 上運行着

kube-apiserver

API Server 提供 HTTP/HTTPS RESTful API。API Server 是 Kubernetes Cluster 的前端接口,各類客戶端工具(CLI 或 UI)以及 Kubernetes 其餘組件能夠經過它管理 Cluster 的各類資源。

kube-controller-manager

Controller Manager 負責管理 Cluster 各類資源,保證資源處於預期的狀態。Controller Manager 由多種 controller 組成,包括 replication controllerendpoints controllernamespace controllerserviceaccounts controller 等。不一樣的 controller 管理不一樣的資源。

etcd

etcd 負責保存 Kubernetes Cluster 的配置信息和各類資源的狀態信息。當數據發生變化時,etcd 會快速地通知 Kubernetes 相關組件。

Pod 網絡

Pod 網絡讓 Kubernetes Cluster 中 Pod 可以相互通訊。

Node

Node 的職責是運行容器應用。NodeMaster 管理,Node 負責監控並彙報容器的狀態,並根據 Master 的要求管理容器的生命週期。

每一個工做節點都有一個 Kubelet,它是管理 節點 並與 Kubernetes Master 節點進行通訊的代理。節點 上還應具備處理容器操做的工做,例如 Dockerrkt。一個 Kubernetes 工做集羣至少有三個節點。

Node 上運行的 Kubernetes 組件有

kubelet

kubeletNodeagent,當 Scheduler 肯定在某個 Node 上運行 Pod 後,會將 Pod 的具體配置信息(image、volume 等)發送給該節點的 kubeletkubelet 根據這些信息建立和運行容器,並向 Master 報告運行狀態。

kube-proxy

每一個 Node 都會運行 kube-proxy 服務,它負責將訪問 service 的 TCP/UPD 數據流轉發到後端的容器。若是有多個副本,kube-proxy 會實現負載均衡。

Pod 網絡

Pod 網絡讓 Kubernetes Cluster 中 Pod 可以相互通訊。

Controller

Kubernetes 一般不會直接建立 Pod,而是經過 Controller 來管理 Pod 的。Controller 中定義了 Pod 的部署特性,好比有幾個副本,在什麼樣的 Node 上運行等。Kubernetes 中有多種 Controller

Deployment

Deployment 能夠管理 Pod 的多個副本。Deployment 負責建立和更新應用程序實例。建立 Deployment 後, Kubernetes master 會將 Deployment 建立的應用程序實例調度到集羣中的各個節點。

ReplicaSet

實現了 Pod 的多副本管理。使用 Deployment 時會自動建立 ReplicaSet,也就是說 Deployment 是經過 ReplicaSet 來管理 Pod 的多個副本,咱們一般不須要直接使用 ReplicaSet

DaemonSet

用於每一個 Node 最多隻運行一個 Pod 副本的場景。好比運行每臺機器上運行一個監測系統。

StatefuleSet

可以保證 Pod 的每一個副本在整個生命週期中名稱是不變的。而其餘 Controller 不提供這個功能,當某個 Pod 發生故障須要刪除並從新啓動時,Pod 的名稱會發生變化。同時 StatefuleSet 會保證副本按照固定的順序啓動、更新或者刪除。

Job

用於運行結束就刪除的應用。而其餘 Controller 中的 Pod 一般是長期持續運行。

Service

PodKubernetes 中是不穩定的,它可能被銷燬並從新建立,或者從新放置到了不一樣的 Node,它們的 IP 可能就不相同,因此爲了讓應用穩定的訪問到 Pod 咱們就須要使用到 Service

Kubernetes 中的服務是一個抽象對象,它定義了一組邏輯的 Pods 和一個訪問它們的策略。服務讓互相依賴的 Pod 之間的耦合鬆動。

咱們部署了 Deployment 外界要訪問咱們的應用,或者 PodPod 之間的訪問,就要用到 Service

Service 有本身的 IP 和端口,ServicePod 提供了負載均衡。

它有幾個子類型

ClusterIP

(默認) - 在集羣中的內部IP上公開服務。此類型使服務只能從集羣中訪問。

NodePort

使用NAT在羣集中每一個選定的節點的同一端口上顯示該服務。使用 :能夠從羣集外部訪問服務。創建 ClusterIP 的超集。它相似於 docker run 中的 -p 參數。

LoadBalancer

在當前雲中建立外部負載平衡器(若是支持),併爲服務分配固定的外部IP。創建 NodePort 的超集。

ExternalName

用任意名稱顯示該服務,本過程經過使用該名稱返回 CNAME 記錄達成。無須使用代理。這種類型須要 v1.7 或更高版本的 kube-dns.

Namespace

若是有多個用戶或項目組使用同一個 Kubernetes Cluster,可使用 Namespace

Namespace 能夠將一個物理的 Cluster 邏輯上劃分紅多個虛擬 Cluster,每一個 Cluster 就是一個 Namespace。不一樣 Namespace 裏的資源是徹底隔離的。

默認會建立兩個 Namespace

  • default 建立資源時若是不指定,將被放到這個 Namespace 中。
  • kube-system Kubernetes 本身建立的系統資源將放到這個 Namespace 中。

Taint 和 Toleration

Taint 是設置到節點上相似於標籤,它分爲三個部分 鍵=值:效果,它好像在描述這個節點有這些污點,Pod 要會根據本身的 Toleration(容忍)來判斷本身要不要運行在這個節點。

Tainttoleration 相互配合,能夠用來避免 pod 被分配到不合適的節點上。每一個節點上均可以應用一個或多個 taint ,這表示對於那些不能容忍這些 taintpod,是不會被該節點接受的。

$ kubectl taint nodes node1 key=value:NoSchedule
# 給節點 node1 設置 taint
$ kubectl taint nodes node1 key=value:NoSchedule-
# 後面加個減號能夠刪除這個 taint
複製代碼

效果

taint 一共有三種效果 NoSchedule PreferNoScheduleNoExecute

  • 若是 node 上有一個 pod 不能容忍的 NoScheduletaint,則 Kubernetes 不會將 pod 分配到該節點。
  • 若是 node 上有一個 pod 不能容忍的 PreferNoScheduletaint,則 Kubernetes 會嘗試pod 分配到該節點。
  • 若是 node 上有一個 pod 不能容忍的 NoExecutetaint,則 Kubernetes 不會將 pod 分配到該節點,和 NoSchedule 不一樣若是 pod 已經在節點上運行它會將 pod 從該節點驅逐。

tolerations

Pod 能夠經過配置文件它的 toleration

tolerations:
- key: "key1"
 operator: "Equal"
 value: "value1"
 effect: "NoSchedule"
# operator 是 Equal,須要 鍵 值 效果徹底匹配
- key: "key2"
 operator: "Exists"
 effect: "NoSchedule"
# 若是 operator 是 Exists 則不能指定 value
- operator: "Exists"
# 表示這個 toleration 能容忍任意 taint
tolerations:
- key: "key3"
 operator: "Exists"
# key 要匹配,效果任意
- key: "key4"
 operator: "Equal"
 value: "value4"
 effect: "NoExecute"
 tolerationSeconds: 3600
# tolerationSeconds 表明 node 設置了上面的 taint,
# Pod 還能夠在上面運行 `tolerationSeconds` 秒,若是不設置則能夠一直運行
複製代碼

新版本的 Kubernetes 能夠自動給 node 設置 taint,如 node.kubernetes.io/not-ready

出於安全考慮,默認配置下 Kubernetes 不會將 Pod 調度到 Master 節點。若是但願將 master 也看成 Node 使用,能夠執行。

$ kubectl taint node node1 node-role.kubernetes.io/master-
# 去除
$ kubectl taint node k8s-master node-role.kubernetes.io/master='':NoSchedule
# 恢復
複製代碼
$ kubectl describe node node1
# 咱們能夠經過 kubectl describe 查看節點的 taint
複製代碼

使用

咱們如今使用 Kubernetes 建立一個小應用。

咱們在 deployment 中運行 4 個 Pod 副本,使用 NodePort 類型的 service 暴露咱們的 deployment,讓外部能夠訪問到。

可使用本地的 minikube 或 Kubernetes 交互教程中的虛擬機。

$ kubectl run es --image=elasticsearch:2 --port=9200
# kubectl run 有點相似 docker run 它會建立並運行指定類型的鏡像
# 它也支持 `--rm` `--env` `--command` `--restart` 等這些參數
# 上面咱們建立一個 Deployment,Deployment 會建立 ReplicaSet
# 由 ReplicaSet 建立 Pod
# `--image` 用來指定鏡像
# `--port` 是容器須要暴露的端口
# `--replicas` 參數爲建立多少個副本,默認是 1
複製代碼
$ kubectl get deploy
# deploy 也能夠寫成 deployments
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
es                    1/1     1            1           30s
$ kubectl get po
# po 也能夠寫成 pods
NAME                                   READY   STATUS    RESTARTS   AGE
es-6994df7bf8-cchzb                    1/1     Running   0          51s
複製代碼

kubectl get 可讓咱們獲取集羣的各類資源信息,好比 kubectl get nodes 獲取集羣節點信息,kubectl get namespaces 來獲取命令空間信息。

咱們如今啓動了一個 deployment 它裏面有一個運行着 elasticsearch 容器的 pod。可是咱們如今還不能訪問到它,想要訪問到它咱們須要 service 的幫助。

$ kubectl expose deploy es --port=9200 --target-port=9200 --type=NodePort
service/es exposed
# kubectl expose 將資源暴露成新的 service
# 上面咱們將名爲 es 的 deployment 資源暴露出來
# `--type` 將類型設置爲 NodePort 
# `--port` 指定服務的端口,其餘 deplyment 能夠經過這個端口訪問到咱們 es deplyment
# `--target-port` 目標端口 service 會將流量導入到這個端口
$ kubectl get services
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
es                    NodePort    10.99.113.186   <none>        9200:32687/TCP   11s
# 能夠看到咱們的服務被隨機映射到了 32687 端口
$ curl `hostname -i`:32687
{
  "name" : "Firelord",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "-QGqxWm3RTCrCv0wDAQJ9A",
  "version" : {
    "number" : "2.4.6",
    "build_hash" : "5376dca9f70f3abef96a77f4bb22720ace8240fd",
    "build_timestamp" : "2017-07-18T12:17:44Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.4"
  },
  "tagline" : "You Know, for Search"
}
# 如今咱們就能夠訪問到 es deployment 了
複製代碼

如今想把咱們的 pod 增長 4 個,就須要用到 kubectl scale 命令。

$ kubectl scale --replicas=4 deployment/es
deployment.extensions/es scaled
# kubectl scale 用來伸縮 
# Deployment, ReplicaSet, Replication Controller, 或 StatefulSet 的大小
# 咱們這裏將 es 應用建立 4 個副本
$ kubectl get deploy
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
es                    4/4     4            4           3m49s
$ kubectl get po
NAME                                   READY   STATUS    RESTARTS   AGE
es-6994df7bf8-brhfw                    1/1     Running   0          3m59s
es-6994df7bf8-bvmkk                    1/1     Running   0          19s
es-6994df7bf8-ffv7c                    1/1     Running   0          19s
es-6994df7bf8-z4kkf                    1/1     Running   0          19s
$ curl `hostname -i`:32687
{
  "name" : "Claudette St. Croix"
}
$ curl `hostname -i`:32687
{
  "name" : "Firelord"
}
# 請求會被負載均衡到 4 個節點中的一個
複製代碼

咱們還能夠滾動更新

$ kubectl set image dployment/es es=elasticsearch:5
# 滾動跟新 elasticsearch:2 到 elasticsearch:5
# kubectl set 能夠用來配置更新資源,它有多個子命令如 `image` `env` 等
# 上面命令咱們將 es deployment 的 es 容器的鏡像更新到 elasticsearch:5
$ kubectl describe pod es
# kubectl describe 用來查看資源詳情相似於 docker inspect
# kubectl describe 類型 前綴
Containers:
  es:
    Image:          elasticsearch:5 # 鏡像如今已是版本 5 了
    Port:           9200/TCP
    Host Port:      0/TCP
    State:          Running
複製代碼

還能夠撤銷回去

$ kubectl rollout undo deployment/es
# kubectl rollout 用來管理回滾
# kubectl rollout undo 回滾到以前的版本
# `--to-revision=0` 回滾版本 默認 0(上一個版本)
$ kubectl describe po es
Containers:
  es:
    Image:          elasticsearch:2 # 變回版本 2 了
    Port:           9200/TCP
    Host Port:      0/TCP
    State:          Running
複製代碼

配置文件

咱們除了使用 命令式 來建立資源,還可使用 yaml 配置文件。不一樣於 docker-compose,Kubernetes 中一個配置文件只建立一個對象。使用配置文件咱們建立或更新資源只用 kubectl apply 這一個命令就能夠了。

咱們如今使用配置文件建立一個 drupal 網站。

首先新建一個 k8s 目錄,而後再裏面建立一個 drupal-deploy.yml 文件

apiVersion: apps/v1
Kind: Deployment # 要建立對象的類型
metadata: # 元數據
 name: drupal-deployment  # 對象名稱
 namespace: default # 命名空間,默認 default
 labels: # 標籤
 app: drupal-deployment
spec: # 配置
 replicas: 1 # 指望的副本,默認 1
 minReadySeconds: 0 # 應用準備時間,默認 0
 selector: # 選擇要管理的 Pod
 matchLabels: # 須要與 Pod 的 label 匹配
 app: drupal-pod
 template: # pod 的配置
 metadata: # pod 的元數據
 labels: # 標籤
 app: drupal-pod
 spec: # 配置
 containers: # Pod 中的容器
 - name: drupal # 名稱
 image: drupal # 鏡像
 imagePullPolicy: IfNotPresent
                  # IfNotPresent(默認)Always 或 Never
 ports: # 暴露的端口
 - containerPort: 80
 protocol: TCP
                      # TCP(默認), UDP, 或 SCTP
 tolerations: # Pod 容忍
 - key: key
 operator: Exists
 restartPolicy: Always # Pod 重啓規則
            # Always(默認), OnFailure, 或 Never
複製代碼

apiVersion 是 api 的版本,它控制能建立什麼樣的對象,好比咱們要建立一個 Deployment 對應的 apiVersionapps/v1,因此通常咱們通常根據 Kind 去選擇 apiVersion。能夠在 API Reference 查看更多信息。

$ kubectl api-versions # 查看當前 kubernetes 支持的 api 版本
複製代碼

API 版本號分爲 3 種:

  • Alpha 測試版本 多是有缺陷的和隨時被刪除,默認狀況是關閉的。
  • Beta 測試版本 已經測試過,支持的功能不會刪除,細節可能發生變化,默認開啓。
  • 穩定版本 版本名稱是 vX,其中 X 是整數。

imagePullPolicy 定義了鏡像拉取的規則,默認是 IfNotPresent,就是有本地緩存就用本地緩存,沒有就去遠程拉取,若是鏡像名後的標籤是:latest 則默認爲 Always。老是會去遠程拉取。

Service

Pod 是不穩定的它能夠被建立,也能夠被銷燬,每一個 Pod 都會獲取它本身的 IP 地址,當它被動態地建立和銷燬,可能獲取到不一樣的 IP,爲了咱們能夠穩定的訪問到 Pod 就須要使用到 Service

有了 Service 咱們就無需關係後端 PodService 會把請求代理到合適的 Pod

默認的 ServiceClusterIP(虛擬IP),ClusterIP 服務只可以在集羣內部能夠訪問,沒法被外部直接訪問。

kube-proxy 負責爲 ExternalName 之外的類型的服務實現一種形式的虛擬IP

如今咱們再建立一個 drupal-cluster-ip.yml

apiVersion: v1
kind: Service
metadata:
 name: drupal-cluster-ip
spec:
 type: ClusterIP
    # ClusterIP(默認), ExternalName, NodePort, 或 LoadBalancer
 sessionAffinity: None
    # None(默認) 或 ClientIP
    # 若是想讓同一個客戶端的請求鏈接到同一個 Pod 能夠設置爲 ClientIP
 selector: # 經過標籤選擇 Pods
 app: drupal-pod
 ports:
 - port: 80
          # Service 的 port
 targetPort: 80
          # 目標(pod)的 port
 protocol: TCP
          # TCP(默認), UDP 或 SCTP
 name: http
          # 名稱,當有多個端口時必填
複製代碼

而後咱們建立 postgres-cluster-ip.yml

apiVersion: v1
kind: Service
metadata:
 name: postgres-cluster-ip
spec:
 selector:
 app: postgres-pod
 ports:
 - port: 5432
 targetPort: 5432
複製代碼

Volumes

當運行在 Pod 中的容器崩潰,重啓時,容器中保存在磁盤上的數據都會被清空,在 Docker 中咱們使用 Volume 來解決這個問題。

Kubernetes 中也有 Volume 當容器重啓時,Volume 中的數據不會被清除,並且 Pod 中的容器能夠共享 Volume。可是 Kubernetes Volume 也有生命週期,當 Pod 不存在時,Kubernetes Volume 也會不存在,可是使用如 awsElasticBlockStore 這種類型的 Volume,刪除 Pod 時不會刪除 Volume 中的數據只是卸載數據卷。

Kubernetes Volume 支持很是多的類型,如 azureDisk configMap secret 等等。

emptyDir

emptyDir 類型是一個空的文件夾,當 Pod 被建立時,它也被建立,當 Pod 被刪除時,它裏面的數據將被永久刪除。

apiVersion: v1
kind: Pod
metadata:
 name: test-pd
spec:
 containers:
 - image: k8s.gcr.io/test-webserver
 name: test-container
 volumeMounts: # 掛在到容器中的位置
 - mountPath: /cache
 name: cache-volume
 volumes: # 定義數據卷
 - name: cache-volume # 數據卷名稱
 emptyDir:
 medium: Memory
        # 空字符串(默認) 或 Memory
        # 該存儲介質的是什麼空字符串表明節點默認的媒介
 sizeLimit: 1Gi # 數據卷大小,默認未定義
複製代碼

hostPath

hostPath 類型將節點中的目錄掛在到容器中。

apiVersion: v1
kind: Pod
metadata:
 name: test-pd
spec:
 containers:
 - image: k8s.gcr.io/test-webserver
 name: test-container
 volumeMounts:
 - mountPath: /test-pd
 name: test-volume
 volumes:
 - name: test-volume
 hostPath:
 path: /data
      # 節點中的路徑
 type: DirectoryOrCreate # 是目錄,當不存在時自動建立
      # 默認空字符串,表明掛載 hostPath 以前不會執行任何檢查
      # File, Directory, FileOrCreate, DirectoryOrCreate 等等
複製代碼

Persistent Volumes

Persistent Volumes(PV)是羣集中的一塊存儲,它生命週期獨立於任何 pod

Persistent Volume Claim(PVC)是用戶對存儲的請求,PVC 消耗 PV 資源,PVC 能夠要求特定的大小和訪問模式的存儲。

咱們使用 PVC 來請求不一樣大小的 PV,集羣管理員會根據請求找到符合的 PV,若是不存在則會建立符合要求的 PV

咱們的應用的 postgres 使用 PV,建立一個 db-pvc.yml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: db-pvc
spec:
 accessModes: # 訪問模式
 - ReadWriteOnce
 volumeMode: Filesystem # 默認 Filesystem
 resources:
 requests:
 storage: 1Gi # 請求的存儲大小
 storageClassName: standard # 選擇屬於這個類的 PV
  # 特定類的 `PV` 只能綁定到請求該類的 `PVC`
 selector:
 matchLabels:
 release: stable # 選擇特定標籤的 PV
複製代碼

一共有三中訪問模式

  • ReadWriteOnce 被一個節點掛載讀寫
  • ReadOnlyMany – 被多個節點掛載可讀
  • ReadWriteMany – 被多個節點掛載讀寫

咱們也能夠手動建立一個 PersistentVolume,配置它的 persistentVolumeReclaimPolicy 它的值 DeleteRetain ,也就是當咱們刪除 PVC 時,PV 的中的數據是所有刪除仍是保留。

而後再建立 postgres-deploy.yml 文件

apiVersion: apps/v1
kind: Deployment 
metadata:
 name: postgres-deployment
spec:
 selector:
 matchLabels:
 app: postgres-pod
 template:
 metadata:
 labels:
 app: postgres-pod
 spec:
 volumes:
 - name: postgres-volume
 persistentVolumeClaim:
 claimName: db-pvc
 containers:
 - name: postgres
 image: postgres
 env: # 設置容器的環境變量
 - name: POSTGRES_PASSWORD
 value: password
 ports:
 - containerPort: 5432
 volumeMounts:
 - name: postgres-volume
 mountPath: /var/lib/postgresql/data
 subPath: postgres
                      # Volume 中的子目錄
                      # 防止將 Volume 中其餘文件也掛載進來
複製代碼

Ingress

Ingress 能夠將集羣外部的 HTTPHTTPS 路由到集羣中的服務。

要想 ingress 生效,必須有一個 ingress controller 知足它。

咱們使用 ingress-nginx 這個 ingress controller,咱們可使用以下命令安裝它。

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
複製代碼

若是使用 minikube 能夠執行

minikube addons enable ingress
複製代碼

也可使用 Helm 安裝(Kubernetes 包管理器,功能強大)。

helm install stable/nginx-ingress --name my-nginx
複製代碼

如今來建立 ingress-service.yml 文件。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
 name: ingress-service
 annotations: # 和資源一塊兒存儲的鍵值對,它至關於一個額外的配置
    kubernetes.io/ingress.class: nginx
    # 表示咱們使用 ingress-nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
    # 將 url 前綴重寫爲 /,如 /api/ 將會變成 /
spec:
 rules:
 - http:
 paths:
 - path: / # 該路徑的 url 所有代理到咱們的 drupal-cluster-ip
 backend:
 serviceName: drupal-cluster-ip
 servicePort: 80
複製代碼

好了如今咱們就能夠建立應用了。

$ kubectl apply -f k8s
複製代碼

kubectl apply 來應用配置文件,-f 後面能夠是文件,文件夾 或 url。

咱們可使用命令查看建立狀態

$ kubectl get svc # 查看 services
$ kubectl get deploy 查看 deployments
$ kubectl get po # 查看 pods
$ kubectl get pv # 查看 Persistent Volumes
$ kubectl get pvc # 查看 Persistent Volume Claim
複製代碼

發現所有建立成功後咱們就能夠去瀏覽器訪問咱們的應用了。

$ minikube ip # 獲取虛擬機 ip,輸入到瀏覽器中
複製代碼

當咱們打開咱們的瀏覽器這個地址,會發現會跳轉到 https 鏈接,而後瀏覽器報不安全的錯誤,咱們要點高級繼續訪問咱們的網站才能瀏覽咱們的應用。

由於咱們 ingress 默認是 https 的,咱們能夠看見證書是一個假證書。

咱們可使用 cert manager 來自動配置和管理 TLS 證書。

DNS

能夠看到咱們的 Host 能夠直接填寫 postgres service 的名稱。

kubeadm 部署時會默認安裝 kube-dns 組件,kube-dns 是一個 DNS 服務器。每當有新的 Service 被建立,kube-dns 會添加該 ServiceDNS 記錄。Cluster 中的 Pod 能夠經過 <SERVICE_NAME>.<NAMESPACE_NAME> 訪問 Service

因此咱們以能夠經過 postgres-cluster-ip.default 訪問,default 命名空間能夠省略,咱們就能夠寫成 postgres-cluster-ip

控制 Pod 運行的 Node

Kubernetes 中可使用 label 來控制 Pod 運行的節點。

$ kubectl label pods foo unhealthy=true
# 給節點 foo 設置 label unhealthy=true
$ kubectl get node --show-labels
# 查看節點的 label
$ kubectl label --overwrite pods foo status=unhealthy
# 修改 node foo 的label
$ kubectl label pods --all status=unhealthy
# 給全部這個 namespace 中的節點添加指定 label
$ kubectl label pods foo bar-
# 後面加 - 號能夠刪除節點上的 label
複製代碼

給節點設置了 label 後,咱們就可使用配置文件中的 nodeSelector 來指定

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
spec:
 selector:
 matchLabels:
 app: nginx
 replicas: 2
 template:
 metadata:
 labels:
 app: nginx
 spec:
 containers:
 - name: nginx
 image: nginx:1.7.9
 ports:
 - containerPort: 80
 nodeSelector: # 選擇要運行的節點
 env: test
複製代碼

若是咱們如今把節點的這個標籤刪除了,會發現 Pod 還運行在這個節點,不會從新部署。

Secret

Secret 對象類型用來保存敏感信息,例如密碼、OAuth 令牌和 ssh key。將這些信息放在 secret 中比放在 pod 的定義或者 docker 鏡像中來講更加安全和靈活。

Secret 會以密文的方式存儲數據,避免了直接在配置文件中保存敏感信息。Secret 會以 Volume 的形式被 mountPod,容器可經過文件的方式使用 Secret 中的敏感數據。

咱們能夠經過文件來建立 Secret

$ kubectl create secret generic my-secret \
    --from-file=./username.txt \
    --from-file=./password.txt
複製代碼

也能夠經過 yaml 文件建立

apiVersion: v1
kind: Secret
metadata:
 name: mysecret
data: # 每一項必須是 base64 編碼
 username: YWRtaW4=
 password: MWYyZDFlMmU2N2Rm
複製代碼
kubectl create -f ./secret.yaml # 建立 secret
複製代碼

而後咱們就能夠在 Pod 中使用它

kind: Pod
apiVersion: v1
metadata:
 name: secret-test-pod
 labels:
 name: secret-test
spec:
 volumes:
 - name: secret-volume
 secret:
 secretName: mysecret
 items: # 可選,自定義訪問的 secret
 - key: password
 path: a/pass
 containers:
 - name: ssh-test-container
 image: mySshImage
 volumeMounts:
 - name: secret-volume
 readOnly: true
 mountPath: /etc/secret # 掛載的目錄
複製代碼

如今咱們就能夠經過 /etc/secret/username/etc/secret/a/pass 訪問咱們的 Secret 了。

咱們還能夠經過環境變量訪問咱們的 Secret。

apiVersion: v1
metadata:
 name: secret-test-pod
spec:
 containers:
 - name: ssh-test-container
 image: mySshImage
 env:
 - name: SECRET
 valueFrom:
 secretKeyRef:
 name: mysecret
 key: username
複製代碼

configMap

ConfigMap 能夠用來保存應用配置信息,ConfigMapSecret 很是相似,主要的不一樣是數據以明文的形式存放。

$ kubectl create configmap myconfigmap \
    --from-file=./config1 \
    --from-file=./config2
複製代碼

經過文件建立 configMap。每一個文件內容對應一個信息條目。

咱們也可使用 yaml 文件。

apiVersion: v1
kind: ConfigMap
metadata:
 name: special-config
data:
  game.properties: | # | 表示保留換行符  enemies: aliens
 lives: 3
    enemies.cheat: true
    enemies.cheat.level: noGoodRotten
    secret.code.passphrase: UUDDLRLRBABAS
    secret.code.allowed: true
    secret.code.lives: 30

--- # 文件的開頭,能夠將多個配置寫入一個文件中

apiVersion: v1
kind: Pod
metadata:
 name: dapi-test-pod
spec:
 containers:
 - name: test-container
 image: k8s.gcr.io/busybox
 command: [ "/bin/sh", "-c", "ls /etc/config/" ]
 volumeMounts:
 - name: config-volume
 mountPath: /etc/config
 volumes:
 - name: config-volume
 configMap:
 name: special-config
 restartPolicy: Never
複製代碼

secret 同樣也能夠經過環境變量來使用,只是將 secretKeyRef 換爲 configMapKeyRef

可視化監控

除了上面介紹的 kubernetes dashboard,還有不少監控工具。

  • Prometheus Operator 是 CoreOS 開發的基於 Prometheus 的 Kubernetes 監控方案,也多是目前功能最全面的開源方案

更多

Docker 零基礎入門

Docker Compose 零基礎入門

Docker Swarm 零基礎入門

相關文章
相關標籤/搜索