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 k8s。docker
或者去 官網交互教程。windows
建立一個集羣須要使用到 kubeadm
,它會生成證書,配置文件,安裝附加組鍵,如 kube-proxy
和 kube-dns
。幾乎全部的 Kubernetes
組件自己也運行在 Pod
裏。後端
Kubernetes 中咱們不直接管理容器,而是 Pod
。它是最小工做單元。
一個 Pod
是一個或一組運行很是緊密的容器, Pod
中的全部容器使用同一個網絡 namespace
,即相同的 IP
地址和 Port
空間。它們能夠直接用 localhost
通訊。一樣的,這些容器能夠共享存儲,當 Kubernetes
掛載 volume
到 Pod
,本質上是將 volume
掛載到 Pod
中的每個容器。
Pod
有 Pending
,Running
,Succeeded
,Failed
和 Unknown
這幾個階段。
咱們通常不本身建立 Pod
, 而是建立 Deployment
。
Kubernetes 集羣中主機分爲 master
和 node
。
Master
是 Cluster
的大腦,它負責管理集羣,主要職責是調度,決定將應用放在哪裏運行。一個主機能夠同時擁有 Master
和 Node
兩種身份。
Master
上運行着
API Server 提供 HTTP/HTTPS RESTful API。API Server 是 Kubernetes Cluster 的前端接口,各類客戶端工具(CLI 或 UI)以及 Kubernetes 其餘組件能夠經過它管理 Cluster 的各類資源。
Controller Manager
負責管理 Cluster
各類資源,保證資源處於預期的狀態。Controller Manager
由多種 controller
組成,包括 replication controller
、endpoints controller
、namespace controller
、serviceaccounts controller
等。不一樣的 controller
管理不一樣的資源。
etcd 負責保存 Kubernetes Cluster 的配置信息和各類資源的狀態信息。當數據發生變化時,etcd 會快速地通知 Kubernetes 相關組件。
Pod 網絡讓 Kubernetes Cluster 中 Pod 可以相互通訊。
Node
的職責是運行容器應用。Node
由 Master
管理,Node
負責監控並彙報容器的狀態,並根據 Master 的要求管理容器的生命週期。
每一個工做節點都有一個 Kubelet
,它是管理 節點 並與 Kubernetes Master
節點進行通訊的代理。節點 上還應具備處理容器操做的工做,例如 Docker
或 rkt
。一個 Kubernetes
工做集羣至少有三個節點。
Node
上運行的 Kubernetes 組件有
kubelet
是 Node
的 agent
,當 Scheduler
肯定在某個 Node
上運行 Pod
後,會將 Pod
的具體配置信息(image、volume 等)發送給該節點的 kubelet
,kubelet
根據這些信息建立和運行容器,並向 Master
報告運行狀態。
每一個 Node 都會運行 kube-proxy 服務,它負責將訪問 service 的 TCP/UPD 數據流轉發到後端的容器。若是有多個副本,kube-proxy 會實現負載均衡。
Pod 網絡讓 Kubernetes Cluster 中 Pod 可以相互通訊。
Kubernetes
一般不會直接建立 Pod
,而是經過 Controller
來管理 Pod
的。Controller
中定義了 Pod
的部署特性,好比有幾個副本,在什麼樣的 Node
上運行等。Kubernetes
中有多種 Controller
。
Deployment
能夠管理 Pod
的多個副本。Deployment
負責建立和更新應用程序實例。建立 Deployment
後, Kubernetes master
會將 Deployment
建立的應用程序實例調度到集羣中的各個節點。
實現了 Pod
的多副本管理。使用 Deployment
時會自動建立 ReplicaSet
,也就是說 Deployment
是經過 ReplicaSet
來管理 Pod
的多個副本,咱們一般不須要直接使用 ReplicaSet
。
用於每一個 Node
最多隻運行一個 Pod
副本的場景。好比運行每臺機器上運行一個監測系統。
可以保證 Pod
的每一個副本在整個生命週期中名稱是不變的。而其餘 Controller
不提供這個功能,當某個 Pod
發生故障須要刪除並從新啓動時,Pod
的名稱會發生變化。同時 StatefuleSet
會保證副本按照固定的順序啓動、更新或者刪除。
用於運行結束就刪除的應用。而其餘 Controller
中的 Pod
一般是長期持續運行。
Pod
在 Kubernetes
中是不穩定的,它可能被銷燬並從新建立,或者從新放置到了不一樣的 Node
,它們的 IP 可能就不相同,因此爲了讓應用穩定的訪問到 Pod
咱們就須要使用到 Service
。
Kubernetes
中的服務是一個抽象對象,它定義了一組邏輯的 Pods
和一個訪問它們的策略。服務讓互相依賴的 Pod 之間的耦合鬆動。
咱們部署了 Deployment
外界要訪問咱們的應用,或者 Pod
到 Pod
之間的訪問,就要用到 Service
。
Service
有本身的 IP 和端口,Service
爲 Pod
提供了負載均衡。
它有幾個子類型
(默認) - 在集羣中的內部IP上公開服務。此類型使服務只能從集羣中訪問。
使用NAT在羣集中每一個選定的節點的同一端口上顯示該服務。使用 :
能夠從羣集外部訪問服務。創建 ClusterIP 的超集。它相似於 docker run
中的 -p
參數。
在當前雲中建立外部負載平衡器(若是支持),併爲服務分配固定的外部IP。創建 NodePort
的超集。
用任意名稱顯示該服務,本過程經過使用該名稱返回 CNAME 記錄達成。無須使用代理。這種類型須要 v1.7 或更高版本的 kube-dns.
若是有多個用戶或項目組使用同一個 Kubernetes Cluster
,可使用 Namespace
。
Namespace
能夠將一個物理的 Cluster
邏輯上劃分紅多個虛擬 Cluster
,每一個 Cluster
就是一個 Namespace
。不一樣 Namespace
裏的資源是徹底隔離的。
默認會建立兩個 Namespace
default
建立資源時若是不指定,將被放到這個 Namespace 中。kube-system
Kubernetes 本身建立的系統資源將放到這個 Namespace 中。Taint
是設置到節點上相似於標籤,它分爲三個部分 鍵=值:效果
,它好像在描述這個節點有這些污點,Pod
要會根據本身的 Toleration
(容忍)來判斷本身要不要運行在這個節點。
Taint
和 toleration
相互配合,能夠用來避免 pod
被分配到不合適的節點上。每一個節點上均可以應用一個或多個 taint
,這表示對於那些不能容忍這些 taint
的 p
od,是不會被該節點接受的。
$ kubectl taint nodes node1 key=value:NoSchedule
# 給節點 node1 設置 taint
$ kubectl taint nodes node1 key=value:NoSchedule-
# 後面加個減號能夠刪除這個 taint
複製代碼
taint
一共有三種效果 NoSchedule
PreferNoSchedule
和 NoExecute
。
node
上有一個 pod
不能容忍的 NoSchedule
的 taint
,則 Kubernetes 不會將 pod 分配到該節點。node
上有一個 pod
不能容忍的 PreferNoSchedule
的 taint
,則 Kubernetes 會嘗試將 pod
分配到該節點。node
上有一個 pod
不能容忍的 NoExecute
的 taint
,則 Kubernetes 不會將 pod
分配到該節點,和 NoSchedule
不一樣若是 pod
已經在節點上運行它會將 pod
從該節點驅逐。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
對應的 apiVersion
是 apps/v1
,因此通常咱們通常根據 Kind
去選擇 apiVersion
。能夠在 API Reference 查看更多信息。
$ kubectl api-versions # 查看當前 kubernetes 支持的 api 版本
複製代碼
API 版本號分爲 3 種:
Alpha 測試版本
多是有缺陷的和隨時被刪除,默認狀況是關閉的。Beta 測試版本
已經測試過,支持的功能不會刪除,細節可能發生變化,默認開啓。穩定版本
版本名稱是 vX
,其中 X
是整數。imagePullPolicy
定義了鏡像拉取的規則,默認是 IfNotPresent
,就是有本地緩存就用本地緩存,沒有就去遠程拉取,若是鏡像名後的標籤是:latest
則默認爲 Always
。老是會去遠程拉取。
Pod
是不穩定的它能夠被建立,也能夠被銷燬,每一個 Pod
都會獲取它本身的 IP
地址,當它被動態地建立和銷燬,可能獲取到不一樣的 IP
,爲了咱們能夠穩定的訪問到 Pod
就須要使用到 Service
。
有了 Service
咱們就無需關係後端 Pod
,Service
會把請求代理到合適的 Pod
。
默認的 Service
是 ClusterIP
(虛擬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
複製代碼
當運行在 Pod
中的容器崩潰,重啓時,容器中保存在磁盤上的數據都會被清空,在 Docker
中咱們使用 Volume
來解決這個問題。
在 Kubernetes
中也有 Volume
當容器重啓時,Volume
中的數據不會被清除,並且 Pod
中的容器能夠共享 Volume
。可是 Kubernetes Volume
也有生命週期,當 Pod
不存在時,Kubernetes Volume
也會不存在,可是使用如 awsElasticBlockStore
這種類型的 Volume
,刪除 Pod
時不會刪除 Volume
中的數據只是卸載數據卷。
Kubernetes Volume
支持很是多的類型,如 azureDisk
configMap
secret
等等。
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
類型將節點中的目錄掛在到容器中。
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
(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
它的值 Delete
或 Retain
,也就是當咱們刪除 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
能夠將集羣外部的 HTTP
和 HTTPS
路由到集羣中的服務。
要想 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 證書。
能夠看到咱們的 Host 能夠直接填寫 postgres service 的名稱。
kubeadm
部署時會默認安裝 kube-dns
組件,kube-dns
是一個 DNS
服務器。每當有新的 Service
被建立,kube-dns
會添加該 Service
的 DNS
記錄。Cluster
中的 Pod
能夠經過 <SERVICE_NAME>.<NAMESPACE_NAME>
訪問 Service
。
因此咱們以能夠經過 postgres-cluster-ip.default
訪問,default
命名空間能夠省略,咱們就能夠寫成 postgres-cluster-ip
。
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
對象類型用來保存敏感信息,例如密碼、OAuth 令牌和 ssh key。將這些信息放在 secret
中比放在 pod
的定義或者 docker
鏡像中來講更加安全和靈活。
Secret
會以密文的方式存儲數據,避免了直接在配置文件中保存敏感信息。Secret
會以 Volume
的形式被 mount
到 Pod
,容器可經過文件的方式使用 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
和 Secret
很是相似,主要的不一樣是數據以明文的形式存放。
$ 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,還有不少監控工具。