視頻鏈接
云原生Java架構(gòu)師的第一課K8s+Docker+KubeSphere+DevOps_嗶哩嗶哩_bilibili
基礎(chǔ)架構(gòu)

基礎(chǔ)架構(gòu)

Namespace
Namespace(命名空間),用于隔離k8s資源

通過(guò)命令行創(chuàng)建命名空間
# 創(chuàng)建/刪除命名空間
kubectl create ns hello
# 刪除命名空間,刪除命名空間時(shí),會(huì)將該命名空間下部署的所有資源一并刪除
kubectl delete ns hello
# 查詢(xún)所有命名空間
kubectl get ns
通過(guò)Yaml文件創(chuàng)建命名空間,使用kubectl apply -f 文件名.yaml添加配置
apiVersion: v1
kind: Namespace
metadata:
name: hello
通過(guò)Yaml文件添加或刪除資源
kubectl apply -f 文件名.yaml
kubectl delete -f 文件名.yaml
Pod
Pod是指運(yùn)行中的一組容器(一個(gè)Pod可以裝多個(gè)容器),是k8s中應(yīng)用的最小單位。


# 查詢(xún)所有pod
kubectl get pods -A
# 查詢(xún)?cè)撁臻g下的所有pod
kubectl get pods -n 命名空間
# 創(chuàng)建pod
kubectl run mynginx --image=nginx
# 刪除pod
kubectl delete pod mynginx
# 查看pod運(yùn)行日志
kubectl logs mynginx
# k8s會(huì)為每一個(gè)pod創(chuàng)建一個(gè)Ip
kubectl get pod -o wide
# 集群中的任意一個(gè)機(jī)器以及任意的應(yīng)用都能通過(guò)Pod分配的ip來(lái)訪問(wèn)這個(gè)Pod
curl 192.168.169.136
# 進(jìn)入容器
kubectl exec -it mynginx -- /bin/bash
# 輸出pod的詳細(xì)信息
kubectl describe pod mynginx

通過(guò)Yaml文件創(chuàng)建Pod
apiVersion: v1
kind: Pod
metadata:
labels:
run: mynginx
name: mynginx
# namespace: default
spec:
containers:
- image: nginx
name: mynginx
# 一個(gè)pod部署多個(gè)容器
apiVersion: v1
kind: Pod
metadata:
labels:
run: myapp
name: myapp
spec:
containers:
- image: nginx
name: nginx
- image: tomcat:8.5.68
name: tomcat
Deployment
控制Pod,使Pod擁有多副本,自愈,擴(kuò)縮容等功能
# 普通方式創(chuàng)建pod
kubectl run mynginx --image=nginx
# deployment方式創(chuàng)建pod,pod擁有自愈能力,被delete后會(huì)重新部署
kubectl create deployment mytomcat --image=tomcat:8.5.68
# deployment方式創(chuàng)建pod,多個(gè)副本
kubectl create deployment mytomcat --image=tomcat:8.5.68 --replicas=3
# 刪除deployment
kubectl delete deployment mytomcat
# 查詢(xún)deployment
kubectl get deployment
使用yaml文件創(chuàng)建Deployment多副本
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-dep
name: my-dep
spec:
replicas: 3
selector:
matchLabels:
app: my-dep
template:
metadata:
labels:
app: my-dep
spec:
containers:
- image: nginx
name: nginx
擴(kuò)縮容
kubectl scale -n 命名空間 deployment mynginx --replicas=5
Deployment滾動(dòng)更新

# 滾動(dòng)更新
kubectl set image deployment/my-dep nginx=nginx:1.16.1 --record
kubectl rollout status deployment/my-dep
版本回退
#歷史記錄
kubectl rollout history deployment/my-dep
#查看某個(gè)歷史詳情
kubectl rollout history deployment/my-dep --revision=2
#回滾(回到上次)
kubectl rollout undo deployment/my-dep
#回滾(回到指定版本)
kubectl rollout undo deployment/my-dep --to-revision=2
其他工作負(fù)載
除了Deployment,k8s還有 StatefulSet 、DaemonSet 、Job 等 類(lèi)型資源。我們都稱(chēng)為 工作負(fù)載。
有狀態(tài)應(yīng)用使用 StatefulSet 部署,無(wú)狀態(tài)應(yīng)用使用 Deployment 部署
https://kubernetes.io/zh/docs/concepts/workloads/controllers/

Service
將一組Pods公開(kāi)為網(wǎng)絡(luò)服務(wù)的抽象方法

# 將服務(wù)暴露出去
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP
# 查詢(xún)service
kubectl get service
ClusterIP(默認(rèn)就是ClusterIp)
這種方式提供的IP是k8s集群的局域網(wǎng)IP,只能在集群內(nèi)訪問(wèn)
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP
apiVersion: v1
kind: Service
metadata:
labels:
app: my-dep
name: my-dep
spec:
ports:
- port: 8000 # 容器端口
protocol: TCP
targetPort: 80 # servcie端口
selector:
app: my-dep
type: ClusterIP
NodePort

這種方式會(huì)開(kāi)放k8s集群所有機(jī)器的端口(NodePort范圍在 30000-32767 之間),通過(guò)任意節(jié)點(diǎn)IP:端口進(jìn)行訪問(wèn)


kubectl expose deployment my-dep --port=8000 --target-port=80 --type=NodePort
apiVersion: v1
kind: Service
metadata:
labels:
app: my-dep
name: my-dep
spec:
ports:
- port: 8000
protocol: TCP
targetPort: 80
selector:
app: my-dep
type: NodePort
Ingress(k8s網(wǎng)關(guān),就是nginx)

1、安裝
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml
# yaml文件下載后修改下ingress鏡像拉取的地址,避免鏡像拉取失敗,參考下面的圖片
# registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0
# 檢查安裝的結(jié)果
kubectl get pod,svc -n ingress-nginx
# 最后別忘記把svc暴露的端口要放行
修改拉取ingress鏡像的地址

啟動(dòng)成功后,可以看到ingress對(duì)80以及443端口做了映射

使用
官網(wǎng)地址:https://kubernetes.github.io/ingress-nginx/
使用ingress部署ngxinx以及tomcat
# 部署nginx,并且創(chuàng)建service將服務(wù)暴露
kubectl create deployment my-nginx --image=nginx
kubectl expose deployment my-nginx --port=8000 --target-port=80
# 部署tomcat,并且創(chuàng)建service將服務(wù)暴露
kubectl create deployment my-tomcat --image=tomcat:8.5.68
kubectl expose deployment my-tomcat --port=8080 --target-port=8080
部署nginx成功

部署tomcat成功

# 通過(guò)yaml文件方式部署ngxin以及tomcat
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 2
selector:
matchLabels:
app: my-nginx
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- name: nginx
image: nginx
# ports:
# - containerPort: 9000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-tomcat
spec:
replicas: 2
selector:
matchLabels:
app: my-tomcat
template:
metadata:
labels:
app: my-tomcat
spec:
containers:
- name: tomcat
image: tomcat:8.5.68
# ports:
# - containerPort: 9000
---
apiVersion: v1
kind: Service
metadata:
labels:
app: my-nginx
name: my-nginx
spec:
selector:
app: my-nginx
ports:
- port: 8000
protocol: TCP
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: my-tomcat
name: my-tomcat
spec:
selector:
app: my-tomcat
ports:
- port: 8080
protocol: TCP
targetPort: 8080
配置ingress域名訪問(wèn)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-host-bar
spec:
ingressClassName: nginx
rules:
- host: "nginx.ingress.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-nginx
port:
number: 8000
- host: "tomcat.ingress.com"
http:
paths:
- pathType: Prefix
path: "/" # 把請(qǐng)求會(huì)轉(zhuǎn)給下面的服務(wù),下面的服務(wù)一定要能處理這個(gè)路徑,不能處理就是404
backend:
service:
name: my-tomcat
port:
number: 8080
配置成功后,通過(guò)kubeclt get ingress命令查看所有ingress配置

本地測(cè)試的話修改下hosts文件

查看ingress對(duì)外開(kāi)放的端口

測(cè)試連通性


ingress請(qǐng)求轉(zhuǎn)發(fā)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2 #啟用請(qǐng)求轉(zhuǎn)發(fā), /$2作用是以/做正則分組匹配,剔除第二個(gè)分組的路徑,會(huì)將a.com/b轉(zhuǎn)發(fā)到a.com。a.com/b/c轉(zhuǎn)發(fā)到a.com/c
name: ingress-host-bar
spec:
ingressClassName: nginx
rules:
- host: "tomcat.ingress.com"
http:
paths:
- pathType: Prefix
path: "/nginx(/|$)(.*)" #
backend:
service:
name: my-nginx
port:
number: 8000
訪問(wèn)結(jié)果

如果沒(méi)有配置轉(zhuǎn)發(fā)的話,"/nginx"路徑下無(wú)html頁(yè)面正常來(lái)說(shuō)應(yīng)該會(huì)返回404.但是由于這里配置了請(qǐng)求轉(zhuǎn)發(fā),"/nginx"路徑的請(qǐng)求被轉(zhuǎn)發(fā)到根目錄,所以返回了ngxin的首頁(yè)
ingress流量限制
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-limit-rate
annotations:
nginx.ingress.kubernetes.io/limit-rps: "1" # 流量限制,一秒只處理一個(gè)請(qǐng)求
spec:
ingressClassName: nginx
rules:
- host: "nginx.ingress.com"
http:
paths:
- pathType: Exact
path: "/"
backend:
service:
name: my-nginx
port:
number: 8000
頻繁請(qǐng)求測(cè)試結(jié)果

配置和存儲(chǔ)
NFS,網(wǎng)絡(luò)文件系統(tǒng)
NFS(Network File System,網(wǎng)絡(luò)文件系統(tǒng))是當(dāng)前主流異構(gòu)平臺(tái)共享文件系統(tǒng)之一。主要應(yīng)用在UNIX環(huán)境下。最早是由Sun Microsystems開(kāi)發(fā),現(xiàn)在能夠支持在不同類(lèi)型的系統(tǒng)之間通過(guò)網(wǎng)絡(luò)進(jìn)行文件共享,廣泛應(yīng)用在FreeBSD、SCO、Solaris等異構(gòu)操作系統(tǒng)平臺(tái),允許一個(gè)系統(tǒng)在網(wǎng)絡(luò)上與他人共享目錄和文件。通過(guò)使用NFS,用戶(hù)和程序可以像訪問(wèn)本地文件一樣訪問(wèn)遠(yuǎn)端系統(tǒng)上的文件,使得每個(gè)計(jì)算機(jī)的節(jié)點(diǎn)能夠像使用本地資源一樣方便地使用網(wǎng)上資源。換言之,NFS可用于不同類(lèi)型計(jì)算機(jī)、操作系統(tǒng)、網(wǎng)絡(luò)架構(gòu)和傳輸協(xié)議運(yùn)行環(huán)境中的網(wǎng)絡(luò)文件遠(yuǎn)程訪問(wèn)和共享。 [4]
NFS的工作原理是使用客戶(hù)端/服務(wù)器架構(gòu),由一個(gè)客戶(hù)端程序和服務(wù)器程序組成。服務(wù)器程序向其他計(jì)算機(jī)提供對(duì)文件系統(tǒng)的訪問(wèn),其過(guò)程稱(chēng)為輸出。NFS客戶(hù)端程序?qū)蚕砦募到y(tǒng)進(jìn)行訪問(wèn)時(shí),把它們從NFS服務(wù)器中“輸送”出來(lái)。文件通常以塊為單位進(jìn)行傳輸。其大小是8KB(雖然它可能會(huì)將操作分成更小尺寸的分片)。NFS傳輸協(xié)議用于服務(wù)器和客戶(hù)機(jī)之間文件訪問(wèn)和共享的通信,從而使客戶(hù)機(jī)遠(yuǎn)程地訪問(wèn)保存在存儲(chǔ)設(shè)備上的數(shù)據(jù)。
基于NFS掛載共享目錄
- 1.所有節(jié)點(diǎn)執(zhí)行
# 所有機(jī)器安裝
yum install -y nfs-utils
- 2.主節(jié)點(diǎn)執(zhí)行
# nfs配置文件
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
mkdir -p /nfs/data
systemctl enable rpcbind --now
systemctl enable nfs-server --now
# 配置生效
exportfs -r
- 3.從節(jié)點(diǎn)
# 顯示主節(jié)點(diǎn)共享的目錄
showmount -e 主節(jié)點(diǎn)ip地址
mkdir -p /nfs/data
# 掛載共享目錄
mount -t nfs 主節(jié)點(diǎn)IP:/nfs/data /nfs/data
# 寫(xiě)入測(cè)試文件
echo "hello nfs server" > /nfs/data/test.txt
- 4.給Deployment掛載數(shù)據(jù)盤(pán)
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-nginx
name: my-nginx
spec:
replicas: 2
selector:
matchLabels:
app: my-nginx
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
nfs:
server: 主節(jié)點(diǎn)IP地址
path: /nfs/data/nginx
ConfigMap
所有應(yīng)用配置的抽象,便于統(tǒng)一管理
- 通過(guò)命令行創(chuàng)建ConfigMap
kubectl create cm redis-conf --from-file=redis.conf
- 通過(guò)yaml文件創(chuàng)建ConfigMap
# data是key-value形式,具體配置保存在其中,key:默認(rèn)是文件名 value:配置文件的內(nèi)容
apiVersion: v1
data:
redis.conf: |
appendonly yes
maxmemory 2mb
kind: ConfigMap
metadata:
name: redis-conf
namespace: default
- 使用kubectl get cm查詢(xún)所有ConfigMap

- 創(chuàng)建Pod,掛載ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
command: #啟動(dòng)時(shí)附加參數(shù)
- redis-server
- "/redis-master/redis.conf" #指的是redis容器內(nèi)部的位置
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /redis-master #會(huì)為容器創(chuàng)建/redis-master文件夾
name: config
volumes:
- name: config # 名字與volumeMounts中一致,配置文件會(huì)保存到volumeMounts聲明的路徑下
configMap:
name: redis-conf # 這里與創(chuàng)建的ConfigMap的name一致
items:
- key: redis.conf # 這里指定ConfigMap中data的key
path: redis.conf
- 檢查配置
# 進(jìn)入容器內(nèi)部查看配置文件是否存在
kubectl exec -it redis -- /bin/bash
cd /redis-master
cat redis.conf
# 進(jìn)入redis-cli查看配置是否生效
kubectl exec -it redis -- redis-cli
127.0.0.1:6379> CONFIG GET appendonly
127.0.0.1:6379> CONFIG GET requirepass


- ConfigMap常用命令
# 查詢(xún)所有ConfigMap
kubectl get cm
# 修改指定的ConfigMap,修改ConfigMap后,所有使用了該ConfigMap進(jìn)行啟動(dòng)的容器中的配置文件會(huì)一并被修改
kubectl edit cm ConfigMap聲明的name
# 刪除ConfigMap
kubectl delete cm ConfigMap聲明的name
Secret
Secret 對(duì)象類(lèi)型用來(lái)保存敏感信息,例如密碼、OAuth 令牌和 SSH 密鑰。 將這些信息放在 secret 中比放在 Pod 的定義或者 容器鏡像 中來(lái)說(shuō)更加安全和靈活。
- 創(chuàng)建Secret
kubectl create secret docker-registry leifengyang-docker \
--docker-username=leifengyang \
--docker-password=Lfy123456 \
--docker-email=534096094@qq.com
- 啟動(dòng)Pod指定Secret
apiVersion: v1
kind: Pod
metadata:
name: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
imagePullSecrets:
- name: leifengyang-docker
PV&PVC
PV:持久卷(Persistent Volume),將應(yīng)用需要持久化的數(shù)據(jù)保存到指定位置
PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷規(guī)格
- 創(chuàng)建PV
apiVersion: v1
kind: PersistentVolume # 指定類(lèi)型為PV
metadata:
name: pv01-10m
spec:
capacity:
storage: 500M # 指定存儲(chǔ)空間大小為500M
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/01
server: NFS主機(jī)IP
- 創(chuàng)建PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 200Mi # PVC申請(qǐng)200M空間
storageClassName: nfs
- 創(chuàng)建Pod并綁定PVC
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy-pvc
name: nginx-deploy-pvc
spec:
replicas: 2
selector:
matchLabels:
app: nginx-deploy-pvc
template:
metadata:
labels:
app: nginx-deploy-pvc
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim: # 綁定PVC后會(huì)自動(dòng)分配到合適的PV中
claimName: nginx-pvc