-
minikube
K8S 集群模擬器安裝文檔:https://minikube.sigs.k8s.io/docs/start/
https://github.com/kubernetes/minikube/releases?page=2
https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/nd7yOvdY
直接用云平臺(tái) Kubernetes
可視化搭建幽七,只需簡(jiǎn)單幾步就可以創(chuàng)建好一個(gè)集群。
優(yōu)點(diǎn):安裝簡(jiǎn)單爬骤,生態(tài)齊全骡湖,負(fù)載均衡器贱纠、存儲(chǔ)等都給你配套好,簡(jiǎn)單操作就搞定裸機(jī)安裝(Bare Metal)
至少需要兩臺(tái)機(jī)器(主節(jié)點(diǎn)响蕴、工作節(jié)點(diǎn)個(gè)一臺(tái))谆焊,需要自己安裝 Kubernetes 組件,配置會(huì)稍微麻煩點(diǎn)浦夷。
可以到各云廠商按時(shí)租用服務(wù)器辖试,費(fèi)用低辜王,用完就銷毀。
缺點(diǎn):配置麻煩罐孝,缺少生態(tài)支持呐馆,例如負(fù)載均衡器、云存儲(chǔ)莲兢。
#kubectl 安裝
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl
minikube start --driver=docker --registry-mirror=https://registry.docker-cn.com --force
#
minikube start --image-mirror-country='cn' --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --registry-mirror=https://ovfftd6p.mirror.aliyuncs.com --driver=docker --kubernetes-version v1.23.7 --force
#
minkube kubectl -- get pods -A
命令行啟動(dòng)pod
#運(yùn)行pod
kubectl run nginx --image=registry.cn-hangzhou.aliyuncs.com/heliang230/nginx:1.8.1
#查看pod
kubectl get pod -A
yml文件啟動(dòng)pod
vi pod.yml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
# 定義容器汹来,可以多個(gè)
containers:
- name: nginx-k8s # 容器名字
image: registry.cn-hangzhou.aliyuncs.com/heliang230/nginx:1.8.1 # 鏡像
#啟動(dòng)pod
kubectl apply -f pod.yml
#查看pod
kubectl get pod
Deployment啟動(dòng)pod
vi deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
# 部署名字
name: test-k8s
spec:
replicas: 2
# 用來(lái)查找關(guān)聯(lián)的 Pod,所有標(biāo)簽都匹配才行
selector:
matchLabels:
app: test-k8s
# 定義 Pod 相關(guān)數(shù)據(jù)
template:
metadata:
labels:
app: test-k8s
spec:
# 定義容器改艇,可以多個(gè)
containers:
- name: test-k8s # 容器名字
image: registry.cn-hangzhou.aliyuncs.com/heliang230/nginx:1.8.1 # 鏡像
#啟動(dòng)pod
kubectl apply -f deployment.yml
常用命令
# 部署應(yīng)用
kubectl apply -f app.yaml
# 查看 deployment
kubectl get deployment
# 查看 pod
kubectl get pod -o wide
# 查看 pod 詳情
kubectl describe pod pod-name
# 查看 log
kubectl logs pod-name
# 進(jìn)入 Pod 容器終端收班, -c container-name 可以指定進(jìn)入哪個(gè)容器。
kubectl exec -it pod-name -- bash
# 伸縮擴(kuò)展副本
kubectl scale deployment test-k8s --replicas=5
# 把集群內(nèi)端口映射到節(jié)點(diǎn)
kubectl port-forward pod-name 8090:8080
# 查看歷史
kubectl rollout history deployment test-k8s
# 回到上個(gè)版本
kubectl rollout undo deployment test-k8s
# 回到指定版本
kubectl rollout undo deployment test-k8s --to-revision=2
# 刪除部署
kubectl delete deployment test-k8s
#刪除pod
kubectl delete pod test-k8s
#擴(kuò)縮容-容器
kubectl scale --help
kubectl scale -replicas=3 pod名稱
kubectl scale -replicas=3 pod名稱 -f foo.yaml
kubectl scale --replicas=3 deploy my-nginx
更多命令
# 查看全部
kubectl get all
# 重新部署
kubectl rollout restart deployment test-k8s
# 命令修改鏡像遣耍,--record 表示把這個(gè)命令記錄到操作歷史中
kubectl set image deployment test-k8s test-k8s=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error --record
# 暫停運(yùn)行闺阱,暫停后炮车,對(duì) deployment 的修改不會(huì)立刻生效舵变,恢復(fù)后才應(yīng)用設(shè)置
kubectl rollout pause deployment test-k8s
# 恢復(fù)
kubectl rollout resume deployment test-k8s
# 輸出到文件
kubectl get deployment test-k8s -o yaml >> app2.yaml
# 刪除全部資源
kubectl delete all --all
Service
- Service 通過(guò) label 關(guān)聯(lián)對(duì)應(yīng)的 Pod
- Servcie 生命周期不跟 Pod 綁定,不會(huì)因?yàn)?Pod 重創(chuàng)改變 IP
- 提供了負(fù)載均衡功能瘦穆,自動(dòng)轉(zhuǎn)發(fā)流量到不同 Pod
- 可對(duì)集群外部提供訪問(wèn)端口
- 集群內(nèi)部可通過(guò)服務(wù)名字訪問(wèn)
vi service.yaml
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
type: ClusterIP
ports:
- port: 80 # 本 Service 的端口
targetPort: 80 # 容器端口
應(yīng)用配置 kubectl apply -f service.yaml
查看服務(wù) kubectl get svc
查看服務(wù)詳情 kubectl describe svc test-k8s
如果要在集群外部訪問(wèn)纪隙,可以通過(guò)端口轉(zhuǎn)發(fā)實(shí)現(xiàn)(只適合臨時(shí)測(cè)試用):
kubectl port-forward service/test-k8s 80:80
對(duì)外暴露服務(wù)
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
# 默認(rèn) ClusterIP 集群內(nèi)可訪問(wèn),NodePort 節(jié)點(diǎn)可訪問(wèn)扛或,LoadBalancer 負(fù)載均衡模式(需要負(fù)載均衡器才可用)
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
nodePort: 31000 # 節(jié)點(diǎn)端口绵咱,范圍固定 30000 ~ 32767
多端口
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
name: test-k8s # 必須配置
targetPort: 8080 # 容器端口
nodePort: 31000 # 節(jié)點(diǎn)端口,范圍固定 30000 ~ 32767
- port: 8090
name: test-other
targetPort: 8090
nodePort: 32000
StatefulSet
StatefulSet 是用來(lái)管理有狀態(tài)的應(yīng)用熙兔,例如數(shù)據(jù)庫(kù)悲伶。
前面我們部署的應(yīng)用,都是不需要存儲(chǔ)數(shù)據(jù)住涉,不需要記住狀態(tài)的麸锉,可以隨意擴(kuò)充副本,每個(gè)副本都是一樣的舆声,可替代的花沉。
而像數(shù)據(jù)庫(kù)、Redis 這類有狀態(tài)的媳握,則不能隨意擴(kuò)充副本碱屁。
StatefulSet 會(huì)固定每個(gè) Pod 的名字
部署 StatefulSet 類型的 Mongodb
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: mongodb
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 僅本地沒有鏡像時(shí)才遠(yuǎn)程拉,Always 永遠(yuǎn)都是從遠(yuǎn)程拉蛾找,Never 永遠(yuǎn)只用本地鏡像娩脾,本地沒有則報(bào)錯(cuò)
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
type: ClusterIP
# HeadLess
clusterIP: None
ports:
- port: 27017
targetPort: 27017
kubectl apply -f mongo.yaml
StatefulSet 特性
Service 的 CLUSTER-IP 是空的,Pod 名字也是固定的打毛。
Pod 創(chuàng)建和銷毀是有序的柿赊,創(chuàng)建是順序的架曹,銷毀是逆序的。
Pod 重建不會(huì)改變名字闹瞧,除了IP绑雄,所以不要用IP直連
數(shù)據(jù)持久化
介紹
kubernetes 集群不會(huì)為你處理數(shù)據(jù)的存儲(chǔ),我們可以為數(shù)據(jù)庫(kù)掛載一個(gè)磁盤來(lái)確保數(shù)據(jù)的安全奥邮。
你可以選擇云存儲(chǔ)万牺、本地磁盤、NFS洽腺。
本地磁盤:可以掛載某個(gè)節(jié)點(diǎn)上的目錄脚粟,但是這需要限定 pod 在這個(gè)節(jié)點(diǎn)上運(yùn)行
云存儲(chǔ):不限定節(jié)點(diǎn),不受集群影響蘸朋,安全穩(wěn)定核无;需要云服務(wù)商提供,裸機(jī)集群是沒有的藕坯。
NFS:不限定節(jié)點(diǎn)团南,不受集群影響
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
serviceName: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 僅本地沒有鏡像時(shí)才遠(yuǎn)程拉,Always 永遠(yuǎn)都是從遠(yuǎn)程拉炼彪,Never 永遠(yuǎn)只用本地鏡像吐根,本地沒有則報(bào)錯(cuò)
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data/db # 容器里面的掛載路徑
name: mongo-data # 卷名字,必須跟下面定義的名字一致
volumes:
- name: mongo-data # 卷名字
hostPath:
path: /data/mongo-data # 節(jié)點(diǎn)上的路徑
type: DirectoryOrCreate # 指向一個(gè)目錄辐马,不存在時(shí)自動(dòng)創(chuàng)建
Storage Class (SC)
將存儲(chǔ)卷劃分為不同的種類拷橘,例如:SSD,普通磁盤喜爷,本地磁盤冗疮,按需使用。文檔
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
iopsPerGB: "10"
fsType: ext4
Persistent Volume (PV)
描述卷的具體信息檩帐,例如磁盤大小术幔,訪問(wèn)模式。文檔轿塔,類型特愿,Local 示例
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodata
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem # Filesystem(文件系統(tǒng)) Block(塊)
accessModes:
- ReadWriteOnce # 卷可以被一個(gè)節(jié)點(diǎn)以讀寫方式掛載
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /root/data
nodeAffinity:
required:
# 通過(guò) hostname 限定在某個(gè)節(jié)點(diǎn)創(chuàng)建存儲(chǔ)卷
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
Persistent Volume Claim (PVC)
對(duì)存儲(chǔ)需求的一個(gè)申明,可以理解為一個(gè)申請(qǐng)單勾缭,系統(tǒng)根據(jù)這個(gè)申請(qǐng)單去找一個(gè)合適的 PV
還可以根據(jù) PVC 自動(dòng)創(chuàng)建 PV揍障。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodata
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "local-storage"
resources:
requests:
storage: 2Gi
為什么要這么多層抽象
- 更好的分工,運(yùn)維人員負(fù)責(zé)提供好存儲(chǔ)俩由,開發(fā)人員不需要關(guān)注磁盤細(xì)節(jié)毒嫡,只需要寫一個(gè)申請(qǐng)單。
- 方便云服務(wù)商提供不同類型的,配置細(xì)節(jié)不需要開發(fā)者關(guān)注兜畸,只需要一個(gè)申請(qǐng)單努释。
- 動(dòng)態(tài)創(chuàng)建,開發(fā)人員寫好申請(qǐng)單后咬摇,供應(yīng)商可以根據(jù)需求自動(dòng)創(chuàng)建所需存儲(chǔ)卷伐蒂。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
image: mongo:5.0
imagePullPolicy: IfNotPresent
name: mongo
volumeMounts:
- mountPath: /data/db
name: mongo-data
volumes:
- name: mongo-data
persistentVolumeClaim:
claimName: mongodata
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
clusterIP: None
ports:
- port: 27017
protocol: TCP
targetPort: 27017
selector:
app: mongodb
type: ClusterIP
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodata
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem # Filesystem(文件系統(tǒng)) Block(塊)
accessModes:
- ReadWriteOnce # 卷可以被一個(gè)節(jié)點(diǎn)以讀寫方式掛載
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /root/data
nodeAffinity:
required:
# 通過(guò) hostname 限定在某個(gè)節(jié)點(diǎn)創(chuàng)建存儲(chǔ)卷
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodata
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "local-storage"
resources:
requests:
storage: 2Gi
ConfigMap & Secret
數(shù)據(jù)庫(kù)連接地址,這種可能根據(jù)部署環(huán)境變化的肛鹏,我們不應(yīng)該寫死在代碼里逸邦。
Kubernetes 為我們提供了 ConfigMap,可以方便的配置一些變量在扰。文檔
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-config
data:
mongoHost: mongodb-0.mongodb
# 應(yīng)用
kubectl apply -f configmap.yaml
# 查看
kubectl get configmap mongo-config -o yaml
Secret
一些重要數(shù)據(jù)缕减,例如密碼、TOKEN芒珠,我們可以放到 secret 中桥狡。文檔,配置證書
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
# Opaque 用戶定義的任意數(shù)據(jù)皱卓,更多類型介紹 https://kubernetes.io/zh/docs/concepts/configuration/secret/#secret-types
type: Opaque
data:
# 數(shù)據(jù)要 base64裹芝。https://tools.fun/base64.html
mongo-username: bW9uZ291c2Vy
mongo-password: bW9uZ29wYXNz
# 應(yīng)用
kubectl apply -f secret.yaml
# 查看
kubectl get secret mongo-secret -o yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 僅本地沒有鏡像時(shí)才遠(yuǎn)程拉,Always 永遠(yuǎn)都是從遠(yuǎn)程拉好爬,Never 永遠(yuǎn)只用本地鏡像局雄,本地沒有則報(bào)錯(cuò)
imagePullPolicy: IfNotPresent
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
# Secret 的所有數(shù)據(jù)定義為容器的環(huán)境變量,Secret 中的鍵名稱為 Pod 中的環(huán)境變量名稱
# envFrom:
# - secretRef:
# name: mongo-secret
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret