達觀資料:kubernetes簡介和實戰(下)
七、Label
Label是識別Kubernetes物件的標籤,以key/value的方式附加到物件上(key最長不能超過63位元組,value可以為空,也可以是不超過253位元組的字串)。
Label不提供唯一性,並且實際上經常是很多物件(如Pods)都使用相同的label來標誌具體的應用。Label定義好後其他物件可以使用Label Selector來選擇一組相同label的物件(比如ReplicaSet和Service用label來選擇一組Pod)。Label Selector支援以下幾種方式:
- 等式,如app=nginx和env!=production
- 集合,如env in(production, qa)
- 多個label(它們之間是AND關係),如app=nginx,env=test
八、Service Account
8.1 Service account作用
Service account是為了方便Pod裡面的程序呼叫Kubernetes API或其他外部服務。
8.2 Serviceaccount使用場景
執行在pod裡的程序需要呼叫Kubernetes API以及非Kubernetes API的其它服務。Service Account它並不是給kubernetes叢集的使用者使用的,而是給pod裡面的程序使用的,它為pod提供必要的身份認證。
與User account區別
- User account是為人設計的,而service account則是為了Pod中的程序
- User account是跨namespace的,而service account則是僅侷限它所在的namespace
實戰名稱空間
apiVersion: v1 kind: Namespace metadata: name:datagrand labels: name: test
建立namespace:test kubectl create -f ./test.yaml 檢視名稱空間test的sa kubectl get sa -n test 檢視名稱空間test生成的default kubectl get sa default -o yaml -n test
我們可以建立Deployment時,使用這個test名稱空間了,如上例Deployment實戰。
8.3 Service Account鑑權
Service Account為服務提供了一種方便的認知機制,但它不關心授權的問題。可以配合RBAC來為Service Account鑑權:
- 配置--authorization-mode=RBAC和--runtime-config= ofollow,noindex"> http:// rbac.authorization.k8s.io /v1alpha1
- 配置--authorization-rbac-super-user=admin
- 定義Role、ClusterRole、RoleBinding或ClusterRoleBinding
8.4 實戰鑑權
我們在Kubernetes Dashboard1.8.3部署中,碰到首次登入出現訪問許可權報錯的問題,原因就是ServiceAccount的建立問題。
apiVersion:rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name:kubernetes-dashboard labels: k8s-app: kubernetes-dashboard roleRef: apiGroup:rbac.authorization.k8s.io kind:ClusterRole name:cluster-admin subjects: - kind:ServiceAccount name:kubernetes-dashboard namespace:kube-system
九、Secret
9.1 Secret介紹
Secret解決了密碼、token、金鑰等敏感資料的配置問題,而不需要把這些敏感資料暴露到映象或者Pod Spec中。Secret可以以Volume或者環境變數的方式使用。
9.2 Secret型別
- Opaque(default):任意字串,base64編碼格式的Secret,用來儲存密碼、金鑰等
- http:// kubernetes.io/service-a ccount-token :作用於ServiceAccount,就是kubernetes的Service Account中所說的。即用來訪問Kubernetes API,由Kubernetes自動建立,並且會自動掛載到Pod的/run/secrets/ http:// kubernetes.io/serviceac count 目錄中
- http:// kubernetes.io/dockercfg : 作用於Docker registry,使用者下載docker映象認證使用。用來儲存私有docker registry的認證資訊
實戰Opaque Secret型別
Opaque型別的資料是一個map型別,要求value是base64編碼格式: 建立admin賬戶 echo -n "admin" | base64 YWRtaW4= echo -n "1f2d1e2e67df" | base64 MWYyZDFlMmU2N2Rm
建立secret.yaml cat >> secrets.yml << EOF apiVersion: v1 kind: Secret metadata: name:mysecret type: Opaque data: password:MWYyZDFlMmU2N2Rm username:YWRtaW4=
建立secret kubectl create -f secrets.yml
檢視secret執行狀態 kubectl get secret --all-namespaces
9.3 Secret使用方式
- Volume方式
- 以環境變數方式
實戰Secret使用Volume方式
apiVersion: v1 kind: Pod metadata: name: mypod labels: name: wtf spec: volumes: - name:secrets secret: secretName: mysecret containers: - image:nginx:1.7.9 name: nginx volumeMounts: - name:secrets mountPath:"/etc/secrets" readOnly:true ports: - name: cp containerPort: 5432 hostPort:5432
說明:這樣就可以通過檔案的方式掛載到容器內,在/etc/secrets目錄下回生成這個檔案。
9.4 實戰Secret使用環境變數方式
apiVersion:extensions/v1beta1 kind: Deployment metadata: name:wordpress-deployment spec: replicas: 2 template: metadata: labels: app:wordpress spec: containers: - name:"wordpress" image:"wordpress:latest" ports: -containerPort: 80 env: - name:WORDPRESS_DB_USER valueFrom: secretKeyRef: name: mysecret key: username - name:WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password
檢視Pod執行狀態 kubectl get po NAMEREADYSTATUSRESTARTSAGE wordpress-deployment-6b569fbb7d-8qcpg1/1Running02m wordpress-deployment-6b569fbb7d-xwwkg1/1Running02m
進入容器內部檢視環境變數 kubectl exec -itwordpress-deployment-694f4c79b4-cpsxw /bin/bash root@wordpress-deployment-694f4c79b4-cpsxw:/var/www/html#env WORDPRESS_DB_USER=admin WORDPRESS_DB_PASSWORD=1f2d1e2e67df
十、ConfigMap
10.1 Configure說明
ConfigMaps允許你將配置檔案、命令列引數或環境變數中讀取的配置資訊與docker image分離,以保持集裝箱化應用程式的便攜性。即ConfigMapAPI給我們提供了向容器中注入配置資訊的機制。
10.2 理解ConfigMaps和Pods
ConfigMap API資源用來儲存key-value pair配置資料,這個資料可以在pods裡使用,或者被用來為像controller一樣的系統元件儲存配置資料。雖然ConfigMap跟Secrets類似,但是ConfigMap更方便的處理不含敏感資訊的字串。
注意: ConfigMaps不是屬性配置檔案的替代品。ConfigMaps只是作為多個properties檔案的引用。你可以把它理解為Linux系統中的/etc目錄,專門用來儲存配置檔案的目錄。
實戰建立ConfigMap
kind: ConfigMap apiVersion: v1 metadata: creationTimestamp: 2016-02-18T19:14:38Z name:example-config namespace:default data: example.property.1: hello example.property.2: world example.property.file: |- property.1=value-1 property.2=value-2 property.3=value-3
data一欄包括了配置資料,ConfigMap可以被用來儲存單個屬性,也可以用來儲存一個配置檔案。配置資料可以通過很多種方式在Pods裡被使用。ConfigMaps可以被用來:
- 設定環境變數的值
- 在容器裡設定命令列引數
- 在資料卷裡面建立config檔案
十一、Volum
11.1 為什麼需要Volume
容器磁碟上檔案的生命週期是短暫的,這就使得在容器中執行重要應用時出現一些問題。比如,當容器崩潰時,kubelet會重啟它,但是容器中的檔案將丟失--容器以乾淨的狀態(映象最初的狀態)重新啟動。
其次,在Pod中同時執行多個容器時,這些容器之間通常需要共享檔案。Kubernetes中的Volume抽象就很好的解決了這些問題。
11.2 Volume背景
Docker中也有一個volume的概念,儘管它稍微寬鬆一些,管理也很少。在Docker中,卷就像是磁碟或是另一個容器中的一個目錄。它的生命週期不受管理,直到最近才有了local-disk-backed卷。Docker現在提供了卷驅動程式,但是功能還非常有限(例如Docker1.7只允許每個容器使用一個卷驅動,並且無法給卷傳遞引數)。
Kubernetes中的卷有明確的壽命——與封裝它的Pod相同。所以,卷的生命比Pod中的所有容器都長,當這個容器重啟時資料仍然得以儲存。當然,當Pod不再存在時,卷也將不復存在。也許更重要的是,Kubernetes支援多種型別的卷,Pod可以同時使用任意數量的卷。要使用卷,需要為pod指定為卷(spec.volumes欄位)以及將它掛載到容器的位置(spec.containers.volumeMounts欄位)。
11.3 Volume型別
Kubernetes支援以下型別的卷:
awsElasticBlockStore、azureDisk、azureFile、cephfs、csi、downwardAPI、emptyDir、fc (fibre channel)、flocker、gcePersistentDisk、gitRepo、glusterfs、hostPath、iscsi、local、nfs、persistentVolumeClaim、projected、portworxVolume、quobyte、rbd、scaleIO、secret、storageos、vsphereVolume等
11.4 K8S的儲存系統分類
K8S的儲存系統從基礎到高階大致分為三個層次:普通Volume,Persistent Volume和動態儲存供應。
11.5 普通Volume
最簡單的普通Volume是單節點Volume。它和Docker的儲存卷類似,使用的是Pod所在K8S節點的本地目錄。
11.6 persistent volume
它和普通Volume的區別是什麼呢?
普通Volume和使用它的Pod之間是一種靜態繫結關係,在定義Pod的檔案裡,同時定義了它使用的Volume。Volume是Pod的附屬品,我們無法單獨建立一個Volume,因為它不是一個獨立的K8S資源物件。而Persistent Volume簡稱PV是一個K8S資源物件,所以我們可以單獨建立一個PV。 它不和Pod直接發生關係,而是通過Persistent Volume Claim,簡稱PVC來實現動態繫結。 Pod定義裡指定的是PVC,然後PVC會根據Pod的要求去自動繫結合適的PV給Pod使用。
PV的訪問模式有三種:
- ReadWriteOnce:是最基本的方式,可讀可寫,但只支援被單個Pod掛載
- ReadOnlyMany:可以以只讀的方式被多個Pod掛載
- ReadWriteMany:這種儲存可以以讀寫的方式被多個Pod共享。比較常用的是NFS
一般來說,PV和PVC的生命週期分為5個階段:
- Provisioning,即PV的建立,可以直接建立PV(靜態方式),也可以使用StorageClass動態建立
- Binding,將PV分配給PVC
- Using,Pod通過PVC使用該Volume
- Releasing,Pod釋放Volume並刪除PVC
- Reclaiming,回收PV,可以保留PV以便下次使用,也可以直接從雲端儲存中刪除
根據這5個階段,Volume的狀態有以下4種:
- Available:可用
- Bound:已經分配給PVC
- Released:PVC解綁但還未執行回收策略
- Failed:發生錯誤
變成Released的PV會根據定義的回收策略做相應的回收工作。有三種回收策略:
- Retain就是保留現場,K8S什麼也不做,等待使用者手動去處理PV裡的資料,處理完後,再手動刪除PV
- Delete K8S會自動刪除該PV及裡面的資料
- Recycle K8S會將PV裡的資料刪除,然後把PV的狀態變成Available,又可以被新的PVC繫結使用
在實際使用場景裡,PV的建立和使用通常不是同一個人。這裡有一個典型的應用場景:管理員建立一個PV池,開發人員建立Pod和PVC,PVC裡定義了Pod所需儲存的大小和訪問模式,然後PVC會到PV池裡自動匹配最合適的PV給Pod使用。
前面在介紹PV的生命週期時,提到PV的供給有兩種方式,靜態和動態。其中動態方式是通過StorageClass來完成的,這是一種新的儲存供應方式。
使用StorageClass有什麼好處呢?除了由儲存系統動態建立,節省了管理員的時間,還有一個好處是可以封裝不同型別的儲存供PVC選用。在StorageClass出現以前,PVC繫結一個PV只能根據兩個條件,一個是儲存的大小,另一個是訪問模式。在StorageClass出現後,等於增加了一個繫結維度。
比如這裡就有兩個StorageClass,它們都是用谷歌的儲存系統,但是一個使用的是普通磁碟,我們把這個StorageClass命名為slow。另一個使用的是SSD,我們把它命名為fast。在PVC裡除了常規的大小、訪問模式的要求外,還通過annotation指定了Storage Class的名字為fast,這樣這個PVC就會繫結一個SSD,而不會繫結一個普通的磁碟。限於篇幅問題,這裡簡單說一下emptyDir、nfs、PV和PVC。
十二、實戰--emptyDir
12.1 emptyDir說明
EmptyDir型別的volume創建於pod被排程到某個宿主機上的時候,而同一個pod內的容器都能讀寫EmptyDir中的同一個檔案。一旦這個pod離開了這個宿主機,EmptyDir中的資料就會被永久刪除。所以目前EmptyDir型別的volume主要用作臨時空間,比如Web伺服器寫日誌或者tmp檔案需要的臨時目錄。
apiVersion: v1 kind: Pod metadata: labels: name:test-emptypath role: master name: test-emptypath spec: containers: - name:test-emptypath image:nginx:1.7.9 volumeMounts: - name:log-storage mountPath:/tmp/ volumes: - name:log-storage emptyDir: {}
實戰使用共享卷的標準多容器Pod
apiVersion: v1 kind: Pod metadata: name:datagrand spec: containers: - name: test1 image:nginx:1.7.9 volumeMounts: - name:log-storage mountPath:/usr/share/nginx/html - name: test2 image:centos volumeMounts: - name:log-storage mountPath:/html command:["/bin/sh","-c"] args: - whiletrue;do data>> /html/index.html; sleep 1; done volumes: - name:log-storage emptyDir:{}
簡單解釋下上面的內容:在這個例子中,我們定義了一個名為HTML的卷。它的型別是emptyDir,這意味著當一個Pod被分配到一個節點時,卷先被建立,並只要Pod在節點上執行時,這個卷仍存在。正如名字所說,它最初是空的。
第一容器執行nginx的伺服器並將共享卷掛載到目錄/ usr /share/ nginx /html。第二容器使用centos的映象,並將共享卷掛載到目錄/HTML。每一秒,第二容器添加當前日期和時間到index.html檔案中,它位於共享卷。當用戶發出一個HTTP請求到Pod,nginx的伺服器讀取該檔案並將其傳遞給響應請求的使用者。
十三、實戰--NFS卷
13.1 NFS卷說明
nfs卷允許將現有的NFS(網路檔案系統)共享掛載到你的容器中。不像emptyDir,當刪除Pod時,nfs卷的內容被保留,卷僅僅是被解除安裝。這意味著NFS卷可以預填充資料,並且可以在pod之間“切換”資料。NFS可以被多個寫入者同時掛載。
13.2 NFS卷使用注意
- 請先部署好自己的NFS服務
- 在使用共享之前,必須執行自己的NFS伺服器並執行共享
實戰pod內的檔案共享
apiVersion: v1 kind: Pod metadata: name:nginx-test labels: app: nginx spec: containers: - name: nginx image:nginx:1.7.9 ports: -containerPort: 80 volumeMounts: #Mount thepath to the container - mountPath:"/tmp/" name:pv0003 volumes: - name: pv0003 nfs: #fixed:This ip is the addressof the nfs server server:192.168.246.169 #fixed:This path is sharedexternally by the nfs server path:"/data"
13.3 實戰PV和PVC
nfs作為k8s的網路儲存驅動,可以滿足持久儲存業務的需求,支援多節點讀寫。下面是兩個Pod同時使用一個永續性volume例項。
#建立PV apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv spec: capacity: storage: 4Gi accessModes: -ReadWriteMany nfs: server:192.168.246.168##NFS伺服器的ip地址 path:"/data"##NFS伺服器上的共享目錄
#建立PVC apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc spec: accessModes: - ReadWriteMany storageClassName: "" resources: requests: storage:3Gi
#建立Deployment apiVersion: apps/v1 kind: Deployment metadata: name:nginx-deployment labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app:nginx spec: containers: - name:nginx image:nginx:1.7.9 volumeMounts: -mountPath: "/wtf" name: datadir volumes: - name:datadir persistentVolumeClaim: claimName: nfs-pvc-containerPort: 80
十四、Service
Kubernetes Pod是有生命週期的,它們可以被建立,也可以被銷燬,然而一旦被銷燬生命就永遠結束。 通過ReplicaSets能夠動態地建立和銷燬Pod(例如,需要進行擴縮容,或者執行滾動升級)。
每個Pod都會獲取它自己的IP地址,即使這些IP地址不總是穩定可依賴的。這會導致一個問題:在Kubernetes叢集中,如果一組Pod(稱為backend)為其它Pod(稱為frontend)提供服務,那麼那些frontend該如何發現,並連線到這組Pod中的哪些backend呢?
14.1 什麼是Service
Kubernetes Service定義了這樣一種抽象:一個Pod的邏輯分組,一種可以訪問它們的策略——通常稱為微服務。這一組Pod能夠被Service訪問到,通常是通過Label Selector(檢視下面瞭解,為什麼可能需要沒有selector的Service)實現的。
舉個例子,考慮一個圖片處理backend,它運行了3個副本。這些副本是可互換的—— frontend不需要關心它們呼叫了哪個backend副本。然而組成這一組backend程式的Pod實際上可能會發生變化,frontend客戶端不應該也沒必要知道,而且也不需要跟蹤這一組backend的狀態。Service定義的抽象能夠解耦這種關聯。
對Kubernetes叢集中的應用,Kubernetes提供了簡單的Endpoints API,只要Service中的一組Pod發生變更,應用程式就會被更新。對非Kubernetes叢集中的應用,Kubernetes提供了基於VIP的網橋的方式訪問Service,再由Service重定向到backend Pod。
14.2 定義Service
1)有selector的單埠Service
一個Service在Kubernetes中是一個REST物件,和Pod類似。像所有的REST物件一樣,Service定義可以基於POST方式,請求apiserver建立新的例項。例如,假定有一組Pod,它們對外暴露了9376埠,同時還被打上"app=MyApp"標籤。
kind: Service
apiVersion: v1
metadata:
name:my-service
spec:
selector:
app: MyApp
ports:
- protocol:TCP
port: 80
targetPort: 9376
上述配置將建立一個名稱為“my-service”的Service物件,它會將請求代理到使用TCP埠9376,並且具有標籤"app=MyApp"的Pod上。這個Service將被指派一個IP地址(通常稱為“Cluster IP”),它會被服務的代理使用(見下面)。該Service的selector將會持續評估,處理結果將被POST到一個名稱為“my-service”的Endpoints物件上。
需要注意的是,Service能夠將一個接收埠對映到任意的targetPort。 預設情況下,targetPort將被設定為與port欄位相同的值。可能更有趣的是,targetPort可以是一個字串,引用了backend Pod的一個埠的名稱。但是,實際指派給該埠名稱的埠號,在每個backend Pod中可能並不相同。對於部署和設計Service,這種方式會提供更大的靈活性。例如,可以在backend軟體下一個版本中,修改Pod暴露的埠,並不會中斷客戶端的呼叫。
Kubernetes Service能夠支援TCP和UDP協議,預設TCP協議。
2)有selector的多埠Service
很多Service需要暴露多個埠。對於這種情況,Kubernetes支援在Service物件中定義多個埠。當使用多個埠時,必須給出所有的埠的名稱,這樣Endpoint就不會產生歧義,例如:
kind: Service apiVersion: v1 metadata: name:my-service spec: selector: app: MyApp ports: - name:http protocol: TCP port: 80 targetPort: 9376 - name:https protocol: TCP port:443 targetPort: 9377
3)沒有selector的Service
Service抽象了該如何訪問Kubernetes Pod,但也能夠抽象其它型別的backend,例如:
- 希望在生產環境中使用外部的資料庫叢集,但測試環境使用自己的資料庫。
- 希望服務指向另一個Namespace中或其它叢集中的服務。
- 正在將工作負載轉移到Kubernetes叢集,和執行在Kubernetes叢集之外的backend。
根據以上的應用場景,我們都能夠定義沒有selector的Service,如下:
kind: Service apiVersion: v1 metadata: name:my-service spec: ports: - protocol:TCP port: 80 targetPort: 9376
由於這個Service沒有selector,就不會建立相關的Endpoints物件。可以手動將Service對映到指定的Endpoints:
kind: Endpoints apiVersion: v1 metadata: name:my-service subsets: - addresses: - ip:10.0.0.3##Endpoint IP = PodIP +ContainerPort ports: - port:9376
注意:Endpoint IP地址不能是loopback(127.0.0.0/8)、link-local(169.254.0.0/16)、或者link-local多播(224.0.0.0/24)。訪問沒有selector的Service,與有selector的Service的原理相同。請求將被路由到使用者定義的Endpoint(該示例中為10.0.0.3:9376)。
14.3 釋出服務——服務型別
對一些應用(如Frontend)的某些部分,可能希望通過外部(Kubernetes叢集外部)IP地址暴露Service。Kubernetes ServiceTypes允許指定一個需要的型別的Service,預設是ClusterIP型別。Type的取值以及行為如下:
- ClusterIP通過叢集的內部IP暴露服務,選擇該值,服務只能夠在叢集內部可以訪問,這也是預設的ServiceType。
- NodePort通過每個Node上的IP和靜態埠(NodePort)暴露服務。NodePort服務會路由到ClusterIP服務,這個ClusterIP服務會自動建立。通過請求:,可以從叢集的外部訪問一個NodePort服務。
- LoadBalancer使用雲提供商的負載均衡器,可以向外部暴露服務。外部的負載均衡器可以路由到NodePort服務和ClusterIP服務。
- ExternalName通過返回CNAME和它的值,可以將服務對映到externalName欄位的內容(例如,http://foo.bar.example.com)。沒有任何型別代理被建立,這隻有Kubernetes 1.7或更高版本的kube-dns才支援。
14.4 NodePort型別
如果設定type的值為"NodePort",Kubernetes master將從給定的配置範圍內(預設:30000-32767)分配埠,每個Node將從該埠(每個Node上的同一埠)代理到Service。該埠將通過Service的spec.ports[*].nodePort欄位被指定。 如果需要指定的埠號,可以配置nodePort的值,系統將分配這個埠,否則呼叫API將會失敗(比如,需要關心埠衝突的可能性)。
十五、kubernetes實戰--edusoho平臺建立
15.1 檔案目錄結構
# pwd /data # tree -L 3 . ├── mysql │├── conf ││└── my.cnf │└── data │├── auto.cnf │├── edusoho │├── ibdata1 │├── ib_logfile0 │├── ib_logfile1 │├── mysql │└── performance_schema ├── nginx │├── conf ││└── nginx.conf │├── edusoho ││├── api ││├── app ││├── bootstrap ││├── plugins ││├── src ││├── vendor ││├── vendor_user ││└── web │└── log │└── error.log ├── php │├── log ││└── php-fpm.log │├── php-fpm.conf │├── php.ini │└── www.conf
15.2 Pod的yaml檔案
apiVersion: v1 kind: Pod metadata: name:lamp-edusoho labels: app:lamp-edusoho restartPolicy: Always spec: containers: - name: nginx abels: app:lamp-nginx image:dockerhub.datagrand.com/global/nginx:v1 ports: -containerPort: 80 volumeMounts: - name:datadir mountPath: "/var/log/nginx/error.log" subPath:./nginx/log/error.log - name:datadir mountPath: "/etc/nginx/nginx.conf" subPath:./nginx/conf/nginx.conf - name:datadir mountPath: "/usr/share/nginx/html" subPath:./nginx/edusoho - name: php image:dockerhub.datagrand.com/global/php:v1 ports: -containerPort: 9000 volumeMounts: -mountPath: /usr/local/php/etc/php-fpm.conf name:datadir subPath:./php/php-fpm.conf -mountPath: /usr/local/php/etc/php-fpm.d/www.conf name:datadir subPath:./php/www.conf -mountPath: /usr/local/php/etc/php.ini name:datadir subPath:./php/php.ini -mountPath: /usr/local/php/var/log/php-fpm.log name:datadir subPath:./php/log/php-fpm.log -mountPath: /usr/share/nginx/html name:datadir subPath:./nginx/edusoho - name: mysql image:dockerhub.datagrand.com/global/mysql:5.6 ports: -containerPort: 3306 env: - name:MYSQL_ROOT_PASSWORD value:"123456" - name:MYSQL_DATABASE value:"edusoho" - name:MYSQL_USER value:"edusoho" - name:MYSQL_PASSWORD value:"edusoho" args:['--character-set-server=utf8'] volumeMounts: - name:datadir mountPath: "/var/lib/mysql" subPath:./mysql/data - name:datadir mountPath: "/etc/my.cnf" subPath:./mysql/conf/my.cnf volumes: - name:datadir persistentVolumeClaim: claimName:nfs-pvc
15.3 PV的yaml檔案
apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv spec: capacity: storage: 4Gi accessModes: -ReadWriteMany nfs: server:192.168.246.168##NFS伺服器的ip地址 path:"/data"##NFS伺服器上的共享目錄
15.4 PVC的yaml檔案
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc spec: accessModes: -ReadWriteMany storageClassName: "" resources: requests: storage:3Gi
15.5 Service的yaml檔案
apiVersion: v1 kind: Service metadata: name: edusoho labels: app: edusoho spec: type: NodePort ports: - port: 80 nodePort:32756 selector: app:lamp-edusoho
15.6 命令彙總
檢視Pod kubectl get po -o wide 檢視Service kubectl get svc 進入容器內部某個應用,如這裡的nginx kubectl exec -it lamp-edusoho -c nginx /bin/bash
15.7訪問安裝Edusoho平臺
http://192.168.246.168:32756/install/start-install.php 說明:這裡的192.168.246.168是kubernetes的node節點IP,32756是Service中定義的nodePort。
參考文件
- kubernetes概念--Service: https:// kubernetes.io/docs/conc epts/services-networking/service/
- kubernetes官網教程: https:// kubernetes.io/docs/tuto rials/
- Kubernetes中的Persistent Volume解析: https:// jimmysong.io/posts/kube rnetes-persistent-volume/
關於作者
吳騰飛: 達觀資料運維工程師 ,負責達觀資料系統平臺和應用業務的快速部署、監控、優化及維護,設計並研發自動化運維工具和平臺,資料庫的日常維護。
對自動化運維,Docker容器、虛擬化技術和容器編排kubernetes相關領域有濃厚興趣。