k8s核心组件详细介绍教程(配超详细实例演示)
- 本文實驗環境基于上篇文章手把手從零開始搭建k8s集群超詳細教程
- 本文根據B站課程云原生Java架構師的第一課K8s+Docker+KubeSphere+DevOps學習總結而來
k8s核心組件介紹
- 1. Namespace
- 2. Pod
- 1. pod相關命令
- 2. 實例——創建一個包含redis容器的pod
- 3. Deployments
- 1. 多副本
- 2. 擴縮容
- 3. 自愈&故障轉移
- 4. 滾動更新
- 5. 版本回退
- 更多
- 4. Service
- 1. service相關命令
- 2. 實例
- 3. ClusterIP & NodePort模式
- 5. Ingress
- 6. 存儲抽象
- 1. 什么是存儲抽象
- 2. 目錄掛載——原生方式
- 3. 目錄掛載——PV&PVC方式
- 1. 創建pv池
- 2. PVC的創建與綁定
- 3. 補充
- 4. 配置文件掛載——ConfigMap
- 5. 敏感信息存儲——Secret
k8s中創建資源的方式有兩種,一種是通過對應資源的專用命令來創建,一種是以yaml配置文件的形式來創建,其中以yaml配置文件來創建/刪除資源的通用命令如下:
kubectl apply -f 文件名 # 創建資源
kubectl delete -f 文件名 # 刪除資源
1. Namespace
Namespace:名稱空間,用來對集群資源進行隔離劃分(默認只隔離資源、不隔離網絡)
當我們使用kubectl get pods -A查看所有應用時,也可以看到對應歸屬的命名空間
如果我們使用kubect get pods命令,將看不到任何應用,因為該命令是查看默認default名稱空間內的應用
📄 命名空間相關命令
# 查看所有的名稱空間
[root@k8s-master ~]# kubectl get ns
NAME STATUS AGE
default Active 21h
kube-node-lease Active 21h
kube-public Active 21h
kube-system Active 21h
kubernetes-dashboard Active 20h# 創建名稱空間
kubectl create ns hello# 刪除名稱空間(會將該名稱空間下的所有資源全部刪除)
kubectl delete ns hello
除了用命令行的形式來創建名稱空間,我們還可以用yaml配置文件的形式來創建
apiVersion: v1 # 版本號
kind: Namespace # 資源類型
metadata: # 元數據name: hello
編寫以上hello.yaml文件,然后用以下命令來創建/刪除hello名稱空間
kubectl apply -f hello.yaml
kubectl delete -f hello.yaml
2. Pod
Pod是運行中的一組容器,是kubernetes中應用的最小應用單位在k8s沒有出現之前,單個應用都是以容器的方式運行,由doker提供容器時運行環境,K8s的目的就是將這些容器管理起來,將一個或多個容器封裝起來成為一個 pod
1. pod相關命令
# 創建一個pod,--image用于指定創建pod使用的鏡像(因為pod中就是容器)
kubectl run pod名稱 --image=鏡像名# 查看default名稱空間的Pod
kubectl get pod# 查看pod描述
kubectl describe pod pod名稱# 刪除
kubectl delete pod pod名稱1 [pod名稱2...] [-n 所在命名空間]# 查看pod的運行日志
kubectl logs pod名稱# 查看pod更詳細信息(可以看到對于每個Pod,k8s都會分配一個ip,集群中的任意一個機器以及任意的應用都能通過Pod分配的ip來訪問這個Pod)
kubectl get pod -owide# 進入到pod容器中
kubectl exec -it pod名稱 -- /bin/bash
2. 實例——創建一個包含redis容器的pod
創建一個包含redis容器的pod
kubectl run mypod --image=redis
然后我們用kubectl describe pod mypod可以查看創建pod的詳細信息:
其中Events模塊可以看到創建pod的流程,首先在default命名空間封裝mypod分配到k8s-node2機器,然后拉取redis鏡像并創建啟動mypod
由于pod本質還是以容器的方式運行,只不過k8s做了封裝,所以我們仍然可以通過docker ps命令來查看到mypod容器,由于mypod被分配到k8s-node2機器,所以我們可以在該機器上查看到
此外,我們還可以通過kubectl get pod -owide查看pod的更詳細信息,假設這里創建一個包含nginx容器的pod
kubectl run mynginx --image=nginx# 可以看到對于每個pod,k8s都為其分配了一個ip地址
[root@k8s-master ~]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mynginx 1/1 Running 0 119s 192.168.169.134 k8s-node2 <none> <none># 通過pod的ip+端口號進行訪問
[root@k8s-master ~]# curl 192.168.169.134
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
可以看到對于每個pod,k8s都為其分配了一個ip地址,我們可以通過pod的ip+端口號進行訪問
由于pod本質上也是以容器的方式運行,我們可以通過kubectl exec命令進入到容器中,如下所示:我們進入到mynginx中修改nginx的默認頁面
# 進入到mynginx中
[root@k8s-master ~]# kubectl exec -it mynginx -- /bin/bash
root@mynginx:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
root@mynginx:/# cd /usr/share/nginx/html/
root@mynginx:/usr/share/nginx/html# ls
50x.html index.html
root@mynginx:/usr/share/nginx/html# echo "hello">index.html
root@mynginx:/usr/share/nginx/html# exit
exit
[root@k8s-master ~]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mynginx 1/1 Running 0 10m 192.168.169.134 k8s-node2 <none> <none>
[root@k8s-master ~]# curl 192.168.169.134
hello
可以看到頁面修改生效了,不僅在當前master機器可以對該ip進行訪問,在集群中的任意機器都可以訪問該ip
這里的ip地址所在網段就是我們前面初始化主節點時配置的--pod-network-cidr參數
📄 同樣,我們可以以yaml文件的方式來創建pod,用kubectl apply -f執行以下文件即可創建包含nginx和tomcat兩個容器的pod
apiVersion: v1
kind: Pod
metadata:labels:run: mypodname: mypod
spec:containers:- image: nginxname: nginx- image: tomcat:8.5.68name: tomcat
3. Deployments
Deployments:部署應用,用于控制Pod,使Pod擁有多副本、自愈、擴縮容等能力,接下來我們將一一演示
📄 常用命令
# 創建一個deployment
kubectl create deployment deployment名稱 --image 鏡像名# 刪除deployment
kubectl delete deployment deployment名稱# 查看所有deployment
kubectl get deployment [-A] [-owide]
1. 多副本
一個部署可以包含多個pod副本,在創建Deployment時,我們可以加上--replicas參數來指定pod的個數
比如這里創建一個包含三個nginx容器的應用部署my-dep
# 創建一個deployment應用部署my-dep,控制3個nginx pod
kubectl create deployment my-dep --image=nginx --replicas=3
# 配置文件方式
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: my-depname: my-dep
spec:replicas: 3selector:matchLabels:app: my-deptemplate:metadata:labels:app: my-depspec:containers:- image: nginxname: nginx
2. 擴縮容
當我們創建一個deployment來部署應用時,假設在兩臺機器分別部署了一個pod,但此時應用請求流量過大,兩臺機器無法負載均衡處理這些請求,此時我們通過k8s的kubectl scale命令一鍵給多個機器部署該pod,這個過程叫做擴容,與之相反,當應用高峰過去后,我們也可以使用kubectl scale命令下線幾臺機器上的pod,這個過程叫做縮容,可以騰出不需要的資源
這個過程就叫做擴縮容,除了用命令來控制之外,k8s還能做到動態的擴縮容,根據應用情況自動完成上述操作
# 將上述創建的my-dep從3個pod擴容到5個
kubectl scale deployment/my-dep --replicas=5# 將my-dep中的pod從5個縮容到2個
kubectl scale deployment/my-dep --replicas=2
也可以通過以下命令來修改創建deployment的yaml文件中的replicas字段來擴縮容
# 修改my-dep應用部署yaml配置文件中的replicas
kubectl edit deployment my-dep
3. 自愈&故障轉移
當我們通過deployment來部署應用時,應用在運行過程中可能會碰到服務器停機、容器崩潰、pod被刪除等情況,此時k8s的自愈&故障轉移能力就能很好的監控以及避免上述情況帶來的問題
接下來演示一下Deployments最基礎的自愈能力,我們對比分別使用以下兩個命令創建容器
# 方式一:直接創建pod運行
kubectl run mynginx --image=nginx# 方式二:通過創建deployment來部署pod運行
kubectl create deployment mytomcat --image=tomcat
此時,我們開啟另一個終端實時監控默認命名空間的所有pod
watch -n -1 kubectl get pod # 間隔1s查看所有pod
假如此時我們刪除這兩個pod,mynginx和mytomcat-58b8488d44-xfgff
再查看監控,可以發現mynginx直接被刪除了,而通過deployment創建的mytomcat-58b8488d44-xfgff也被刪除,但是隨后又自動啟動了一個新的tomcat pod,這就是deployment最常見的自愈能力,當deployment中的某個pod掛掉時,它會自動在其他機器再啟動一個一模一樣的pod
當然還會出現另一種情況,如果運行著pod的某個機器突然斷電了,沒法在集群中提供服務了,此時k8s會提供故障轉移功能,在另一個機器拉起同樣的一份pod提供服務,我們以上述創建包含三個nginx容器的應用部署my-dep為例進行演示
補充:由于運行的pod本質上就是一個容器,所以我們可以通過docker ps命令來查看到,比如這里我們查看my-dep中的一個nginx容器
如果我們在青云控制臺將k8s-node1機器重啟,再次查看所有pod可以看到部署在該機器上的pod容器狀態變更為Completed
過了一會,當k8s-node1這臺機器重啟后,可以看到容器自動重啟了一次
但是如果我們直接關機node1機器,等待5分鐘后,我們用kubectl get pod -w實時監控,可以看到停止的pod已結束,而是在另一臺node2機器重啟
總結來說,deployment就是來保證pod數量不被各種意外情況影響
4. 滾動更新
假如當前deployment中的pod版本要從v1升級到v2,但此時用戶仍然不斷的訪問應用,此時怎么保證更新能不間斷對用戶的處理過程呢?
k8s的滾動更新的思想是先啟動一個v2版本的pod,等該新版本的pod運行成功了,就將對應老版本的pod下線
以此類推,每個pod的更新都是新版本的pod啟動成功再將老版本下線,實現滾動更新的效果,更新過程中無需停機維護,一個pod更新完了沒有問題才會更新下一個,避免了以前一次性全部更新成新版本殺死老版本而新版本不可用的問題
📄 實現滾動更新的命令
# 將pod中的鏡像nginx更新版本,--record代表記錄此次版本更新
kubectl set image deployment/my-dep nginx=nginx:1.16.1 --recordkubectl rollout status deployment/my-dep
或者通過如下方式修改deployment的配置文件中的image信息實現更新
kubectl edit deployment/my-dep
5. 版本回退
# 查看deployment版本歷史記錄
kubectl rollout history deployment/my-dep
# 查看某個版本歷史詳情
kubectl rollout history deployment/my-dep --revision=2# 回滾(回到上次)
kubectl rollout undo deployment/my-dep
# 回滾(回到指定版本)
kubectl rollout undo deployment/my-dep --to-revision=2
實例演示:
更多
除了Deployment可以部署應用外,類似的,k8s還有StatefulSet、DaemonSet、Job 等類型資源。我們都稱為工作負載,不同工作負載的使用方向如下所示,工作中我們按需選擇即可
總結:在k8s系統中,雖然pod是應用的真正載體,但我們不直接部署pod,而是使用上述工作負載來控制pod,讓每個pod都具有更強大的功能
4. Service
Service:一組 Pods 公開為網絡服務的抽象方法,用于pod的服務發現與負載均衡假設我們以前后端分離的方式開發了一個后臺管理系統應用,我們將后端通過deployment部署了三份pod位于不同的機器上,此時前端需要請求后端api,但由于每個pod都有自己的一個ip地址,那前端請求的地址到底是三臺pod中的哪個呢?為了解決這個問題,k8s提供了
Service統一對所有pod暴露一個對外的公共地址,這樣前端只需要請求該service地址即可。此外,service還提供了對于pod的服務發現與負載均衡的功能,負載均衡就是service均勻的分擔前端來的請求到每一個pod,服務發現就是假如deployments中pod宕機或新增pod,service能及時發現,將請求交給其他pod處理
1. service相關命令
# 查看所有service
kubectl get service# 刪除service
kubectl delete service# 使用標簽檢索Pod
kubectl get pod -l app=標簽名
重要:暴露一個deployee
# 暴露deployee內容器的80端口到service的8000端口(集群內使用service的ip:port即可負載均衡的任意訪問)
# 還可以通過域名的方式進行訪問,域名的默認名稱為`服務名.所在名稱空間.svc`
kubectl expose deployment my-dep --port=8000 --target-port=80
同樣也可以用配置文件的方式創建service服務
apiVersion: v1
kind: Service
metadata:labels:app: my-depname: my-dep
spec:selector:app: my-depports:- port: 8000protocol: TCPtargetPort: 80
2. 實例
這里創建一個Deployment包含三個nginx實例,然后分別進入容器內修改其默認的頁面更改為hello 1、hello 2、hello 3
[root@k8s-master ~]# kubectl create deployment my-nginx --image=nginx --replicas=3
deployment.apps/my-nginx created
[root@k8s-master ~]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx-6b74b79f57-79lk5 1/1 Running 0 49s 192.168.36.75 k8s-node1 <none> <none>
my-nginx-6b74b79f57-cxzct 1/1 Running 0 49s 192.168.36.76 k8s-node1 <none> <none>
my-nginx-6b74b79f57-gf2sh 1/1 Running 0 49s 192.168.36.74 k8s-node1 <none> <none>
[root@k8s-master ~]# kubectl exec -it my-nginx-6b74b79f57-79lk5 -- /bin/bash
root@my-nginx-6b74b79f57-79lk5:/# cd /usr/share/nginx/html
root@my-nginx-6b74b79f57-79lk5:/usr/share/nginx/html# echo "hello 1" > index.html
root@my-nginx-6b74b79f57-79lk5:/usr/share/nginx/html# exit
exit
[root@k8s-master ~]# kubectl exec -it my-nginx-6b74b79f57-cxzct -- /bin/bash
root@my-nginx-6b74b79f57-cxzct:/# cd /usr/share/nginx/html
root@my-nginx-6b74b79f57-cxzct:/usr/share/nginx/html# echo "hello 2" > index.html
root@my-nginx-6b74b79f57-cxzct:/usr/share/nginx/html# exit
exit
[root@k8s-master ~]# kubectl exec -it my-nginx-6b74b79f57-gf2sh -- /bin/bash
root@my-nginx-6b74b79f57-gf2sh:/# cd /usr/share/nginx/html/
root@my-nginx-6b74b79f57-gf2sh:/usr/share/nginx/html# echo "hello 3" > index.html
root@my-nginx-6b74b79f57-gf2sh:/usr/share/nginx/html# exit
exit
然后我們使用一下命令給my-nginx創建一個service暴露以上三個容器的80端口
# 創建一個service—mydep,將三個nginx容器的80端口映射到my-dep的8000端口
[root@k8s-master ~]# kubectl expose deployment my-nginx --port=8000 --target-port=80
service/my-nginx exposed
[root@k8s-master ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d3h
my-nginx ClusterIP 10.96.9.101 <none> 8000/TCP 7s
[root@k8s-master ~]# curl 10.96.9.101:8000
hello 1
[root@k8s-master ~]# curl 10.96.9.101:8000
hello 2
[root@k8s-master ~]# curl 10.96.9.101:8000
hello 1
[root@k8s-master ~]# curl 10.96.9.101:8000
hello 3
[root@k8s-master ~]# curl 10.96.9.101:8000
hello 2
然后可以通過kubectl get service命令查看所有服務,然后我們直接訪問my-nginx對應服務的ip:8000即可訪問到nginx容器,且service默認為我們做了負載均衡處理
那service是如何判斷將哪些pod暴露出來的呢,是因為每個pod在部署期間綁定了一個標簽,我們可以通過如下后綴查看到
[root@k8s-master ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
my-nginx-6b74b79f57-79lk5 1/1 Running 0 80m app=my-nginx,pod-template-hash=6b74b79f57
my-nginx-6b74b79f57-cxzct 1/1 Running 0 80m app=my-nginx,pod-template-hash=6b74b79f57
my-nginx-6b74b79f57-gf2sh 1/1 Running 0 80m app=my-nginx,pod-template-hash=6b74b79f57
service就是根據標簽來選擇需要暴露的一組pods
注意:除了通過service的ip:port方式訪問之外,還可以在pod內部(注意只能在集群pod內部)通過域名的方式進行訪問,域名的默認名稱為服務名.所在名稱空間.svc
[root@k8s-master ~]# curl my-nginx.default.svc:8000
curl: (6) Could not resolve host: my-nginx.default.svc; Unknown error
# 在pod內部通過service域名方式訪問
[root@k8s-master ~]# kubectl exec -it my-nginx-6b74b79f57-79lk5 -- /bin/bash
root@my-nginx-6b74b79f57-79lk5:/# curl my-nginx.default.svc:8000
hello 1
root@my-nginx-6b74b79f57-79lk5:/# curl my-nginx.default.svc:8000
hello 3
root@my-nginx-6b74b79f57-79lk5:/# curl my-nginx.default.svc:8000
hello 2
3. ClusterIP & NodePort模式
以上我們創建service的時候沒有通過--type指令指定模式,默認就是ClusterIP模式,但這種模式只能在集群內部進行訪問
# 使用ClusterIP模式創建service,等同于沒有--type的
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP
apiVersion: v1
kind: Service
metadata:labels:app: my-depname: my-dep
spec:ports:- port: 8000protocol: TCPtargetPort: 80selector:app: my-deptype: ClusterIP
如果我們想在集群外,公網上也可以訪問,就需要使用NodePort模式,可以看到如果指定NodePort方式創建service默認分配了一個對外端口,默認范圍為30000~32767
# 使用NodePort模式創建service
kubectl expose deployment my-nginx --port=8000 --target-port=80 --type=NodePort
apiVersion: v1
kind: Service
metadata:labels:app: my-depname: my-dep
spec:ports:- port: 8000protocol: TCPtargetPort: 80selector:app: my-deptype: NodePort
通過此種方式就可以直接通過服務器公網ip:端口號進行訪問
5. Ingress
Ingress是整個集群流量的統一網關入口,K8s集群中可能會部署很多service服務,這些服務service需要對外提供功能,所有的請求流量都首先需要通過Ingress這一層,由Ingress負責將流量打給哪些服務比如這里有三臺機器,現在要部署一個商城應用,其中使用deployments a來部署訂單服務,對應兩個pod;deployments b來部署用戶服務,對應三個pods;deployments c來部署商品服務,也對應三個pod,這些pods組成了pod網絡。在這三個deployments上也對應著三個service、也就是訂單服務、用戶服務、商品服務,形成了service網絡,用于處理pod網絡的中的服務發現與負載均衡。不僅如此,K8s在service基礎上提供了一個統一的網關入口
Ingress,底層就是一個nginx來幫我們負載均衡,所有的流量都打給Ingress,由其來判斷交給哪個service進行處理。
k8s默認未安裝Ingress沒我們首先進行安裝
# 安裝Ingress
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml
或者用以下yaml配置文件進行安裝
apiVersion: v1
kind: Namespace
metadata:name: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginx---
# Source: ingress-nginx/templates/controller-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginxnamespace: ingress-nginx
automountServiceAccountToken: true
---
# Source: ingress-nginx/templates/controller-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginx-controllernamespace: ingress-nginx
data:
---
# Source: ingress-nginx/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmname: ingress-nginx
rules:- apiGroups:- ''resources:- configmaps- endpoints- nodes- pods- secretsverbs:- list- watch- apiGroups:- ''resources:- nodesverbs:- get- apiGroups:- ''resources:- servicesverbs:- get- list- watch- apiGroups:- extensions- networking.k8s.io # k8s 1.14+resources:- ingressesverbs:- get- list- watch- apiGroups:- ''resources:- eventsverbs:- create- patch- apiGroups:- extensions- networking.k8s.io # k8s 1.14+resources:- ingresses/statusverbs:- update- apiGroups:- networking.k8s.io # k8s 1.14+resources:- ingressclassesverbs:- get- list- watch
---
# Source: ingress-nginx/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmname: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx
subjects:- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginxnamespace: ingress-nginx
rules:- apiGroups:- ''resources:- namespacesverbs:- get- apiGroups:- ''resources:- configmaps- pods- secrets- endpointsverbs:- get- list- watch- apiGroups:- ''resources:- servicesverbs:- get- list- watch- apiGroups:- extensions- networking.k8s.io # k8s 1.14+resources:- ingressesverbs:- get- list- watch- apiGroups:- extensions- networking.k8s.io # k8s 1.14+resources:- ingresses/statusverbs:- update- apiGroups:- networking.k8s.io # k8s 1.14+resources:- ingressclassesverbs:- get- list- watch- apiGroups:- ''resources:- configmapsresourceNames:- ingress-controller-leader-nginxverbs:- get- update- apiGroups:- ''resources:- configmapsverbs:- create- apiGroups:- ''resources:- eventsverbs:- create- patch
---
# Source: ingress-nginx/templates/controller-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginxnamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx
subjects:- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-service-webhook.yaml
apiVersion: v1
kind: Service
metadata:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginx-controller-admissionnamespace: ingress-nginx
spec:type: ClusterIPports:- name: https-webhookport: 443targetPort: webhookselector:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:annotations:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginx-controllernamespace: ingress-nginx
spec:type: NodePortports:- name: httpport: 80protocol: TCPtargetPort: http- name: httpsport: 443protocol: TCPtargetPort: httpsselector:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginx-controllernamespace: ingress-nginx
spec:selector:matchLabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/component: controllerrevisionHistoryLimit: 10minReadySeconds: 0template:metadata:labels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/component: controllerspec:dnsPolicy: ClusterFirstcontainers:- name: controllerimage: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0imagePullPolicy: IfNotPresentlifecycle:preStop:exec:command:- /wait-shutdownargs:- /nginx-ingress-controller- --election-id=ingress-controller-leader- --ingress-class=nginx- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller- --validating-webhook=:8443- --validating-webhook-certificate=/usr/local/certificates/cert- --validating-webhook-key=/usr/local/certificates/keysecurityContext:capabilities:drop:- ALLadd:- NET_BIND_SERVICErunAsUser: 101allowPrivilegeEscalation: trueenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: LD_PRELOADvalue: /usr/local/lib/libmimalloc.solivenessProbe:failureThreshold: 5httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1readinessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1ports:- name: httpcontainerPort: 80protocol: TCP- name: httpscontainerPort: 443protocol: TCP- name: webhookcontainerPort: 8443protocol: TCPvolumeMounts:- name: webhook-certmountPath: /usr/local/certificates/readOnly: trueresources:requests:cpu: 100mmemory: 90MinodeSelector:kubernetes.io/os: linuxserviceAccountName: ingress-nginxterminationGracePeriodSeconds: 300volumes:- name: webhook-certsecret:secretName: ingress-nginx-admission
---
# Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
# before changing this value, check the required kubernetes version
# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:labels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhookname: ingress-nginx-admission
webhooks:- name: validate.nginx.ingress.kubernetes.iomatchPolicy: Equivalentrules:- apiGroups:- networking.k8s.ioapiVersions:- v1beta1operations:- CREATE- UPDATEresources:- ingressesfailurePolicy: FailsideEffects: NoneadmissionReviewVersions:- v1- v1beta1clientConfig:service:namespace: ingress-nginxname: ingress-nginx-controller-admissionpath: /networking/v1beta1/ingresses
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhook
rules:- apiGroups:- admissionregistration.k8s.ioresources:- validatingwebhookconfigurationsverbs:- get- update
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhook
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx-admission
subjects:- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
rules:- apiGroups:- ''resources:- secretsverbs:- get- create
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx-admission
subjects:- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
apiVersion: batch/v1
kind: Job
metadata:name: ingress-nginx-admission-createannotations:helm.sh/hook: pre-install,pre-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
spec:template:metadata:name: ingress-nginx-admission-createlabels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhookspec:containers:- name: createimage: docker.io/jettech/kube-webhook-certgen:v1.5.1imagePullPolicy: IfNotPresentargs:- create- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc- --namespace=$(POD_NAMESPACE)- --secret-name=ingress-nginx-admissionenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacerestartPolicy: OnFailureserviceAccountName: ingress-nginx-admissionsecurityContext:runAsNonRoot: truerunAsUser: 2000
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
apiVersion: batch/v1
kind: Job
metadata:name: ingress-nginx-admission-patchannotations:helm.sh/hook: post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
spec:template:metadata:name: ingress-nginx-admission-patchlabels:helm.sh/chart: ingress-nginx-3.33.0app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.47.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhookspec:containers:- name: patchimage: docker.io/jettech/kube-webhook-certgen:v1.5.1imagePullPolicy: IfNotPresentargs:- patch- --webhook-name=ingress-nginx-admission- --namespace=$(POD_NAMESPACE)- --patch-mutating=false- --secret-name=ingress-nginx-admission- --patch-failure-policy=Failenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacerestartPolicy: OnFailureserviceAccountName: ingress-nginx-admissionsecurityContext:runAsNonRoot: truerunAsUser: 2000
安裝完成后我們可以使用命令查看到對應的pod:
于此同時,也采用NodePort方式創建了對應的service,暴露了兩個端口,一個是http的請求端口,一個是https的請求端口
然后我們通過集群內任意一臺服務器的公網ip加上以上端口號即可訪問
這樣整個k8s網絡模型就如下所示:分為Ingress、Service、Pod三層
6. 存儲抽象
1. 什么是存儲抽象
還是假設有三臺機器,上面運行著很多pod,pod中往往有一些數據想要掛載到主機上方便修改;以前采用docker的方式就是在主機保留一個目錄一對一保存容器中的目錄數據
這樣啟動的容器越多,掛載在外面的東西也越來越多,如果K8s仍然使用這種方式,則會出現很多問題。
假如圖中黑色的pod發上宕機,k8s感知到該pod結束,會自動的進行故障轉移,5分鐘后會在別的機器重啟該pod比如2號機器,但是原pod的掛載目錄在3號機器的/tmp目錄,此時2號機器是沒有3號機器內容的,因此造成了數據的丟失。
k8s為了解決這些問題,將機器上作為掛載目錄的這一層統一管理形成存儲層。這樣以后pod內需要掛載直接請求k8s,k8s為其在存儲層分配空間,就算該pod宕機在其他機器重啟,k8s仍會讓新機器找到原存儲空間中掛載的目錄。
存儲層使用的技術很多,k8s使用的存儲層是開放的,例如可以使用專用的文件系統如Glusterfs、NFS、CephFS等。
假如我們采用NFS網絡存儲系統技術,其實現原理本質上就是在每臺機器都有存有掛載目錄的備份,且是互相同步的。加入在1號機器上掛載了/nfs/data目錄,則其余兩臺機器上都會有對應的備份目錄/bak/data,這三臺機器上對應目錄會互相同步,故障轉移后直接可以采用新機器的備用目錄,避免了pod宕機導致的數據丟失問題。
以上就是k8s的整個存儲抽象的大概簡介
2. 目錄掛載——原生方式
接下來我們來搭建一個k8s的網絡文件存儲系統,也就是存儲層的技術采用NFS方式,我們指定master機器為NFS-Server、node1和node2機器為NFS-Client,最后實現的效果兩臺客戶端同步server的數據
- 所有節點安裝nfs-utils
# 以下命令在三臺機器都執行
# 安裝nfs-utils
yum install -y nfs-utils
- 主機——配置同步目錄及暴露方式
# 以下命令只在master節點執行
# nfs主節點暴露/nfs/data目錄給所有人以非安全讀寫方式進行同步
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports# 創建暴露同步目錄
mkdir -p /nfs/data
systemctl enable rpcbind --now # 啟動rpc遠程綁定
systemctl enable nfs-server --now # 啟動nfs-server# 使配置生效
exportfs -r
- 從機——配置掛載主機同步目錄到本地目錄
# 以下命令在node1、node2兩臺機器執行
# 查看nfs-server可同步掛載的目錄
showmount -e 172.31.0.2# 掛載nfs服務器上的共享目錄到本機路徑 /root/nfs/mount
mkdir -p /nfs/mount
mount -t nfs 172.31.0.2:/nfs/data /nfs/mount# 寫入一個測試文件
echo "hello nfs server" > /nfs/mount/test.txt
從機掛載好目錄之后,我們可以進行簡單的測試,我們向從機本地掛載目錄中編寫一個txt文件,主機相應的同步目錄會自動同步更新
📄 yaml配置文件方式實例:創建一個包含兩個nginx容器的應用部署nginx-demo,將這個nginx容器pod中的 /usr/share/nginx/html 目錄掛載到主機的 /nfs/data/nginx 目錄,示意圖如下所示:
我們編寫以下yaml配置文件(注意server ip地址修改為自己主機的私網ip地址),然后使用kubectl apply命令進行配置
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-demoname: nginx-demo
spec:replicas: 2selector:matchLabels:app: nginx-demotemplate:metadata:labels:app: nginx-demospec:containers:- image: nginxname: nginxvolumeMounts: # 掛載卷- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlnfs:server: 172.31.0.2path: /nfs/data/nginx
我們在本機的 /nfs/data/nginx 目錄下編寫一個hello.html
然后我們進入任意一個pod中的 /nfs/share/nginx/html 目錄可以看到同步的文件
3. 目錄掛載——PV&PVC方式
以上方式實現了數據同步不被丟失,當pod刪除時,對應nfs-server中的同步目錄中數據不會刪除,而且nfs-server中會存在許多的同步目錄,我們應該對其的大小作出限制,這都是不完美的地方,k8s提出了另外兩種掛載方式
PV:持久卷(Persistent Volume),將應用需要持久化的數據保存到指定位置PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷規格接下來k8s的掛載方式就如下圖所示:
假如有三臺機器,這三臺機器上首先準備了一些不同大小的存儲空間,這些空間合起來可以就是一個
PV池,可以稱之為靜態供應方式,也就是提前創建好,而不是需要的時候再創建。此時當Pod需要掛載數據的時候,首先編寫一個申請書,也就是PVC,比如申請1G的空間,此時就從PV池中選出最適合的空間大小的PV進行綁定
接下來我們來模擬pv&pvc的掛載方式
1. 創建pv池
首先在nfs-server上創建三個文件夾作為存儲空間
# nfs主節點
[root@k8s-master ~]# mkdir -p /nfs/data/01
[root@k8s-master ~]# mkdir -p /nfs/data/02
[root@k8s-master ~]# mkdir -p /nfs/data/03
然后對應三個存儲空間以yaml的方式(注意server ip地址修改為自己主機的私網ip地址)創建三個PV(注意更改服務器ip地址)
apiVersion: v1
kind: PersistentVolume
metadata:name: pv01-10m
spec:capacity: # 容量storage: 10MaccessModes: # 讀寫模式- ReadWriteManystorageClassName: nfsnfs:path: /nfs/data/01server: 172.31.0.2
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv02-1gi
spec:capacity:storage: 1GiaccessModes:- ReadWriteManystorageClassName: nfsnfs:path: /nfs/data/02server: 172.31.0.2
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv03-3gi
spec:capacity:storage: 3GiaccessModes:- ReadWriteManystorageClassName: nfsnfs:path: /nfs/data/03server: 172.31.0.2
然后用kubectl apply -f上述配置文件,然后便可以用以下命令查看到所有創建的pv
# 獲取所有pv
kubectl get persistentvolume
# 可省略為
kubectl get pv
2. PVC的創建與綁定
創建一個需要200m空間的PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: nginx-pvc
spec:accessModes:- ReadWriteManyresources:requests:storage: 200MistorageClassName: nfs
創建完成后可以用以下命令查看所有的pvc
kubectl get pvc
然后我們再查看所有pv,可以看到其中一個pv已經綁定了該pvc
最后我們創建Pod時可以通過如下方式綁定剛創建的PVC
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-deploy-pvcname: nginx-deploy-pvc
spec:replicas: 2selector:matchLabels:app: nginx-deploy-pvctemplate:metadata:labels:app: nginx-deploy-pvcspec:containers:- image: nginxname: nginxvolumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlpersistentVolumeClaim: # 綁定申請書claimName: nginx-pvc
3. 補充
出了靜態供應外,還有動態供應的方式,當pod申請PVC時,k8s會根據PVC的要求自動創建一個存儲空間用于綁定掛載,不需要人手工提前創建好PV池,我們暫時不需要了解,后續通過kubesphere搭建時會自動搭建好動態供應的方式
4. 配置文件掛載——ConfigMap
ConfigMap:抽取應用配置,并且可以自動更新通過以上介紹,如果我們想要將pod中的某個目錄掛載出來,可以通過原生掛載方式,也可以使用PV&PVC的方式。
以上方式都是掛載目錄,但是我們往往需要在啟動一些pod的時候掛載其配置文件,比如啟動mysql、redis等實例等時候將其配置文件進行掛載,如何掛載配置文件呢?k8s為我們提供了
ConfigMap的方式來掛載配置文件。這樣以后我們的pod掛載配置文件時遵循以下兩步:
- 首先將需要掛載的配置文件做成配置集
- 創建pod的時候引用以上創建的配置集
接下來以redis為例展示ConfigMap配置文件掛載
-
首先編寫一個redis配置文件redis.conf
vim redis.conf# 配置文件內容 appendonly yes -
通過redis.conf創建配置集(存儲在k8s的etcd中)
# 創建配置集 kubectl create cm redis-conf --from-file=redis.conf# 查看配置集 kubectl get cm# 查看配置集redis-conf的yaml內容 kubectl get cm redis-conf -oyaml -
創建Pod引用上述配置集
apiVersion: v1 kind: Pod metadata:name: redis spec:containers:- name: redisimage: rediscommand:- redis-server- "/redis-master/redis.conf" # 指的是redis容器內部的位置ports:- containerPort: 6379# 卷掛載volumeMounts:- mountPath: /data # 容器中/data目錄采用data卷方式掛載name: data- mountPath: /redis-mastername: config # 容器中的/redis-master目錄采用config卷方式掛載volumes:- name: dataemptyDir: {}- name: configconfigMap: # 配置集name: redis-confitems:- key: redis.confpath: redis.conf -
檢查默認配置是否生效
[root@k8s-master ~]# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-demo-8564794648-9664c 1/1 Running 0 40m nginx-demo-8564794648-v8pfn 1/1 Running 0 40m nginx-deploy-pvc-79fc8558c7-jwhr8 1/1 Running 0 19m nginx-deploy-pvc-79fc8558c7-xrsb5 1/1 Running 0 19m redis 1/1 Running 7 12m # 查看配置是否生效 [root@k8s-master ~]# kubectl exec -it redis -- redis-cli 127.0.0.1:6379> CONFIG GET appendonly 1) "appendonly" 2) "yes" -
修改ConfigMap,檢查配置是否更新
# 修改redis-conf kubectl edit cm redis-conf# 修改內容如下: apiVersion: v1 data:redis.conf: |appendonly yesmaxmemory 2mbmaxmemory-policy allkeys-lru然后我們連接redis查看配置可以看到配置更新
修改了CM后,Pod里面的配置文件會跟著變,但是配置并沒有生效,需要重新啟動 Pod 才能從關聯的 ConfigMap 中獲取更新的值
原因:我們的Pod部署的中間件自己本身沒有熱更新能力
5. 敏感信息存儲——Secret
Secret 對象類型用來保存敏感信息,例如密碼、OAuth 令牌和 SSH 密鑰。 將這些信息放在 secret 中比放在 Pod 的定義或者 容器鏡像 中來說更加安全和靈活。
例如一下我們創建一個存放dockerHub賬號登錄相關信息
# 創建一個secret存放dockerHub賬號信息
kubectl create secret docker-registry leifengyang-docker \
--docker-username=leifengyang \
--docker-password=Lfy123456 \
--docker-email=534096094@qq.com# 命令格式
kubectl create secret docker-registry regcred \--docker-server=<你的鏡像倉庫服務器> \--docker-username=<你的用戶名> \--docker-password=<你的密碼> \--docker-email=<你的郵箱地址>
比如我們要拉取一個自己dockerHub上的私有鏡像時,直接拉取是報錯的,我們可以在創建鏡像時添加密鑰信息這樣就不會報錯
apiVersion: v1
kind: Pod
metadata:name: private-nginx
spec:containers:- name: private-nginximage: leifengyang/guignginx:v1.0imagePullSecrets:- name: leifengyang-docker
總結
以上是生活随笔為你收集整理的k8s核心组件详细介绍教程(配超详细实例演示)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手把手从零开始搭建k8s集群超详细教程
- 下一篇: 硬核科普:到底啥是云原生?