1. 程式人生 > >通過搭建MySQL掌握k8s(Kubernetes)重要概念(上):網路與持久卷

通過搭建MySQL掌握k8s(Kubernetes)重要概念(上):網路與持久卷

上一篇"通過例項快速掌握k8s(Kubernetes)核心概念"講解了k8s的核心概念,有了核心概念整個骨架就完整了,應付無狀態程式已經夠了,但還不夠豐滿。應用程式分成兩種,無狀態和有狀態的。一般的前段和後端程式都是無狀態的,而資料庫是有狀態的,他需要把資料儲存起來,這樣即使斷電,資料也不會丟失。要建立有狀態的程式,還需要引入另外一些k8s概念。它們雖然不是核心,但也很重要,共有三個,持久卷,網路和引數配置。掌握了這些之後,基本概念就已經做到了全覆蓋,k8s就已經入門了。我們通過搭建MySQL來熟悉這些k8s概念。容器本身是無狀態的,一旦出現問題它會被隨時銷燬,它儲存的資料也就丟失了。MySQL需要一個能儲存資料的持久層,在容器被銷燬之後仍然存在,k8s叫它持久卷。

建立和驗證MySQL映象:

在k8s上安裝MySQL之前,先用Docker驗證一下MySQL映象:

docker run --name test-mysql -p 3306:33060 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

“root”是根(root)使用者的password,這裡是在建立MySQL容器時指定“root”使用者的password。“test-MySQL”是容器的名字。“mysql:5.7”用的是docker庫裡的“MySQL”5.7版本。這次沒有用最新的8.0版,因為新版跟以前的客戶端不相容,需要修改很多東西。所用的映象是全版的Linux,因而檔案比較大,有400M。

容器建好了之後,鍵入“docker logs test-mysql”,檢視日誌。

...
2019-10-03T06:18:50.439784Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.17'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.
2019-10-03T06:18:50.446543Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060

檢視容器狀態。

vagrant@ubuntu-xenial:~$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
3b9c50420f5b        mysql:latest        "docker-entrypoint.s…"   11 minutes ago      Up 11 minutes       3306/tcp, 33060/tcp   test-mysql

為了驗證MySQL,需要在虛機上安裝MySQL客戶端。

sudo apt-get -y -f install mysql-client

完成之後,鍵入“docker inspect test-mysql”找到容器IP地址, 下面顯示"172.17.0.2"是容器IP地址。

vagrant@ubuntu-xenial:~$ docker inspect test-mysql
...
 "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
...

鍵入“mysql -h 172.17.0.2 -P 3306 --protocol=tcp -u root -p”登入到MySQL,"172.17.0.2"是MySQL的IP地址,“3306”是MySQL埠,是在建立映象時設定的對外開放的埠,“root”是使用者名稱,“-p”是password的引數選項。敲入命令後,系統要求輸入password,輸入後,顯示已成功連線到MySQL。

vagrant@ubuntu-xenial:~$ mysql -h 172.17.0.2 -P 3306 --protocol=tcp -u root -p
...
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.27 MySQL Community Server (GPL)
...

在k8s上安裝MySQL

在k8s上安裝MySQL分成三個部分,建立部署檔案,建立服務檔案和安裝測試。

部署(Deployment)檔案

下面是部署配置檔案。在上一篇文章中已經詳細講解了檔案格式,所有的k8s的配置檔案格式都是相同的。“template”之上是部署配置,從“template”向下是Pod配置。從“containers”開始是Pod裡面的容器配置。“env:”是環境變數,這裡通過環境變數來設定資料庫的使用者名稱和口令,後面還會詳細講解。MySQL的埠是“3306”

apiVersion: apps/v1
kind: Deployment  # 型別是部署 
metadata:
  name: mysql-deployment  # 物件的名字
spec:
  selector:
    matchLabels:
      app: mysql #用來繫結label是“mysql”的Pod
  strategy:
    type: Recreate
  template:   # 開始定義Pod 
    metadata:
      labels:
        app: mysql  #Pod的Label,用來標識Pod
    spec:
      containers: # 開始定義Pod裡面的容器
        - image: mysql:5.7
          name: mysql-con
          imagePullPolicy: Never
          env:   #  定義環境變數
            - name: MYSQL_ROOT_PASSWORD  #  環境變數名
              value: root  #  環境變數值
            - name: MYSQL_USER
              value: dbuser
            - name: MYSQL_PASSWORD
              value: dbuser
          args: ["--default-authentication-plugin=mysql_native_password"]
          ports:
            - containerPort: 3306 # mysql埠 
              name: mysql 

服務(Service)檔案

下面是服務配置檔案,這個與上一篇講的配置基本相同,這裡就不解釋了。

apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  labels:
    app: mysql
spec:
  type: NodePort
  selector:
      app: mysql
  ports:
  - protocol : TCP
    nodePort: 30306
    port: 3306
    targetPort: 3306 

安裝測試:

有了配置檔案後,下面就開始建立MySQL。在建立時要按照順序,依次進行,先從最底層的物件開始建立。

建立部署和服務:

kubectl apply -f mysql-deployment
kubectl apply -f mysql-service.yaml

檢視服務:

vagrant@ubuntu-xenial:~$ kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP          3h42m
mysql-service   NodePort    10.102.253.32   <none>        3306:30306/TCP   3h21m

“mysql-service”的埠(PORT(S))有兩個,“3306”是k8s內部埠,“30306”是外部埠。由於“NodePort”已經打開了對外埠,這時就可以在虛擬機器上通過“30306”埠訪問MySQL。

vagrant@ubuntu-xenial:~$  mysql -h localhost -P 30306 --protocol=tcp -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.27 MySQL Community Server (GPL)
...
mysql>

這時本地虛機已經與k8s聯通了,下一步就可以在宿主機( 筆記本)上用圖形客戶端來訪問MySQL了。我是在Vagrant裡設定了私有網路,設定的虛機IP地址是 "192.168.50.4”,就用這個地址和30306埠來訪問MySQL。

網路:

這裡的網路有兩層含義,一層是k8s網路,就是讓k8s內部服務之間可以互相訪問,並且從k8s叢集外部可以訪問它內部的服務。另一層是宿主機(筆記本)和虛機之間的網路,就是在宿主機上可以訪問虛機。這兩層都通了之後,就可以在宿主機直接訪問k8s叢集裡面的MySQL。

k8s網路:

k8s的網路也有兩層含義,一個是叢集內部的,k8s有內部DNS,可以通過服務名進行定址。另一個是從叢集外部訪問叢集內部服務,一共有四種方式,詳情請見“Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?”

  • LoadBalancer:Load Balancer不是由K8s來管理的。k8s通過Load Balancer把外部請求轉發給內部服務。這種方法要求有Load Balancer,一般雲環境裡會提供,但自己的本地環境就沒有了。不過Minikube提供了一個程式可以模擬Load Balancer。你只要鍵入“minikube tunnel ”,它就會模擬Load Balancer,對請求進行轉發。只不過當你在使用“Load Balancer”時(在Minikube環境裡),每次執行服務時產生的IP和埠是隨機的,不能控制,使用起來不太方便,但在正式環境裡就沒有這個問題。

下面是服務資訊,“EXTERNAL-IP”是"pending",說明外部網路不通。

$ kubectl get service
NAME            TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP      10.96.0.1        <none>        443/TCP        31d
nginx-service   LoadBalancer   10.104.228.212   <pending>     80:31999/TCP   45h

下面是在執行“minikube tunnel ”(在另一個視窗執行)之後的服務資訊,“EXTERNAL-IP”是 “10.104.228.212”。這時Minikube的LoadBalancer已經起作用了,現在就可以通過IP地址從外部訪問k8s內部的服務了,“80”是k8s內部埠,“31999”是k8s對外埠。

$ kubectl get service
NAME            TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)        AGE
kubernetes      ClusterIP      10.96.0.1        <none>           443/TCP        31d
nginx-service   LoadBalancer   10.104.228.212   10.104.228.212   80:31999/TCP   45h 

這是一種比較好的方式,但不能控制它的IP地址和埠,因此我暫時沒有采用它。

  • NodePort:這種方法可以在每個Node上開放一個對外埠,每一個指向這個埠的請求都被轉發給一個服務。它的好處是你可以指定一個固定的埠(埠的取值範圍只能是30000–32767),這樣我在筆記本上訪問MySQL時就不用更換埠了。 如果你不指定,系統會隨機分配一個。它的缺點是每個埠只能有一個服務,而且埠取值受限制,因此不適合生產環境。但在Windows環境,由於我用Vagrant固定了虛機的IP地址,這個問題就不存在了。因此它是最好的選擇。
  • ClusterIP: 這個只能在k8s叢集內部定址。

  • Ingress: 這是推薦的方法,一般在生產環境中使用。Load balancer的問題是每一個服務都要有一個Load balancer,服務多了之後會很麻煩,這時就會用Ingress,它的缺點是配置起來比較複雜。Minikube自帶了一個基於Nginx的Ingress控制器,只需執行“minikube addons enable ingress”,就行了。但Ingress的設定較複雜,因此這裡沒有用它。

虛擬機器網路:

這裡講的是宿主機(筆記本)和虛機之間的互相訪問,主要是從宿主機訪問虛機。我用的是Vagrant, 因此要在Vagran的配置檔案(Vagrantfile)裡進行配置。它有兩種方法:

  • 埠轉發:它可以把筆記本上特定埠的請求轉發到虛機的指定埠,還是比較方便的。只是如果事先不知道是哪個埠,或埠是變化的,就比較麻煩。Vagrant的配置命令:“config.vm.network "forwarded_port", guest: 3306, host: 3306, auto_correct: true”
  • 私有網路:這是一種很靈活的方式。可以給宿主機和虛機各自設定一個固定的IP地址,這樣可以雙向互訪。任何埠都沒有問題,唯一的缺點就是你要事先確定IP地址。詳情請參見“Vagrant reverse port forwarding?”。Vagrant的配置命令:“config.vm.network "private_network", ip: "192.168.50.4”

當配置私有網路時,需要在筆記本的VirtualBox上配置“Host-only Adapter”,如下圖所示。

但這會造成在Vagrant啟動Minikube時產生如下錯誤:“VBoxManage.exe: error: Failed to create the host-only adapter”。這是VirtualBox的一個Bug,你可以下載一個軟體解決,詳見這裡. 這個軟體已經是四年之前的了,開始還擔心是否與現在的VirtualBox版本相容,結果很好用,而且它是一個單獨執行的軟體,不會與現在的軟體衝突。只要在啟動虛機之前,用管理員身份執行這個補丁就行了。另外一個問題是,我原來使用的是5.x版的VirtualBox,上圖中只能選“NAT”,不能選“Host-only Adapter”,升級到6.X之後才能選“Host-only Adapter”。但當虛機重新啟動之後,它會自動變回“NAT”,不過私有網路還是可用。

建立持久卷(PersistentVolume):

k8s卷的概念包括卷和持久卷。

卷(volume):

卷是k8s的儲存概念,它依附於Pod,不能單獨存在。但它不是在容器層。因此如果容器被重新啟動,卷仍然在。但如果Pod重新啟動,卷就丟失了。如果一個Pod裡有多個容器,那麼這些容器共享Pod的卷。你可以把卷看成是一個目錄,裡面可以儲存各種檔案。k8s支援各種型別的卷,例如本地檔案系統和各種雲端儲存。

持久卷(PersistentVolume):

是對卷的一個封裝,目的是為了更好地管理卷。它的生命週期不需要與Pod繫結,它可以獨立於Pod存在。

持久卷申請(PersistentVolumeClaim):

是對持久卷資源的一個申請,你可以申請特定的儲存容量的大小和訪問模式,例如讀寫模式或只讀模式。k8s會根據持久卷申請分配適合的持久卷,如果沒有合適的,系統會自動建立一個。持久卷申請是對持久卷的一個抽象,就像程式設計裡的介面(Interface),它可以有不同的具體實現(持久卷)。例如,阿里雲和華為雲支援的儲存系統不同,它生成的持久卷也不相同。持久卷是與特定的儲存實現繫結的。那你要把程式從阿里雲移植到華為雲,怎麼保證配置檔案的相容性呢?你就用持久卷申請來做這個介面,它只規定儲存容量大小和訪問模式,而由阿里雲和華為雲自動生成各自雲裡滿足這個介面需求的持久卷. 不過,它還有一個限制條件,那就是持久卷申請和持久卷的StorageClass需要匹配,這使它沒有介面靈活。後面會詳細講解。

動態持久卷:

在這種情況下,你只需建立持久卷申請(不需要單獨建立持久卷),然後把持久卷申請與部署繫結。系統會按照持久卷申請自動建立持久卷。下面是持久卷申請配置檔案。其中“storage:1Gi”,是指申請的空間大小是1G。

持久卷申請配置檔案:
shell apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim labels: app: mysql spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi #持久卷的容量是 1 GB
掛載持久卷申請的部署:

下面是掛載了持久卷申請的部署配置檔案。它通過把持久卷申請當做持久捲來使用,與Pod進行繫結。請閱讀檔案裡有關持久卷的註釋。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - image: mysql:5.7
          name: mysql-con
          imagePullPolicy: Never
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: root
            - name: MYSQL_USER
              value: dbuser
            - name: MYSQL_PASSWORD
              value: dbuser
          args: ["--default-authentication-plugin=mysql_native_password"]
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts: # 掛載Pod上的捲到容器
            - name: mysql-persistent-storage # Pod上卷的名字,與“volumes”名字匹配
              mountPath: /var/lib/mysql # 掛載的Pod的目錄
      volumes:   # 掛載持久捲到Pod
        - name: mysql-persistent-storage # 持久卷名字, 與“volumMounts”名字匹配
          persistentVolumeClaim: 
            claimName: mysql-pv-claim  # 持久卷申請名字

這裡只指定了Pod的掛載目錄,並沒有指定虛擬機器(宿主機)的目錄,後面會講到如何找到虛擬機器的目錄(系統自動分配掛載目錄)。

執行部署:

鍵入“kubectl apply -f mysql-volume.yaml”建立持久卷申請,在建立它的同時,系統自動建立持久卷。

檢視持久卷申請

vagrant@ubuntu-xenial:~/dockerimages/kubernetes/mysql$ kubectl get pvc
NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql-pv-claim   Bound    pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa   1Gi        RWO            standard       10m

檢視持久卷申請詳細資訊

vagrant@ubuntu-xenial:/mnt$ kubectl describe pvc mysql-pv-claim
Name:          mysql-pv-claim
Namespace:     default
StorageClass:  standard
Status:        Bound
Volume:        pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa
Labels:        app=mysql
...

顯示持久卷:

vagrant@ubuntu-xenial:/mnt$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   REASON   AGE
pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa   1Gi        RWO            Delete           Bound    default/mysql-pv-claim   standard                24h

鍵入“kubectl describe pv pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa”, 顯示持久卷詳細資訊。從這裡可以看出,虛擬機器上的持久卷在如下位置:“Path: /tmp/hostpath-provisioner/pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa”。

vagrant@ubuntu-xenial:/mnt$ kubectl describe pv pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa
Name:            pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa
Labels:          <none>
Annotations:     hostPathProvisionerIdentity: 19948fdf-e67f-11e9-8fbd-026a5b40726f
                 pv.kubernetes.io/provisioned-by: k8s.io/minikube-hostpath
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    standard
Status:          Bound
Claim:           default/mysql-pv-claim
Reclaim Policy:  Delete
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        1Gi
Node Affinity:   <none>
Message:
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /tmp/hostpath-provisioner/pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa
    HostPathType:
Events:            <none>

檢視MySQL目錄資訊:

vagrant@ubuntu-xenial:/tmp/hostpath-provisioner/pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa$ ls -al
total 188488
drwxrwxrwx 6  999 docker     4096 Oct  4 13:23 .
drwxr-xr-x 3 root root       4096 Oct  4 12:58 ..
-rw-r----- 1  999 docker       56 Oct  4 12:58 auto.cnf
-rw------- 1  999 docker     1679 Oct  4 12:59 ca-key.pem
-rw-r--r-- 1  999 docker     1107 Oct  4 12:59 ca.pem
-rw-r--r-- 1  999 docker     1107 Oct  4 12:59 client-cert.pem
-rw------- 1  999 docker     1679 Oct  4 12:59 client-key.pem
-rw-r----- 1  999 docker      668 Oct  4 13:21 ib_buffer_pool
-rw-r----- 1  999 docker 79691776 Oct  4 13:23 ibdata1
-rw-r----- 1  999 docker 50331648 Oct  4 13:23 ib_logfile0
-rw-r----- 1  999 docker 50331648 Oct  4 12:58 ib_logfile1
-rw-r----- 1  999 docker 12582912 Oct  4 13:24 ibtmp1
drwxr-x--- 2  999 docker     4096 Oct  4 12:58 mysql
drwxr-x--- 2  999 docker     4096 Oct  4 12:58 performance_schema
-rw------- 1  999 docker     1679 Oct  4 12:59 private_key.pem
-rw-r--r-- 1  999 docker      451 Oct  4 12:59 public_key.pem
-rw-r--r-- 1  999 docker     1107 Oct  4 12:59 server-cert.pem
-rw------- 1  999 docker     1675 Oct  4 12:59 server-key.pem
drwxr-x--- 2  999 docker     4096 Oct  4 13:18 service_config
drwxr-x--- 2  999 docker    12288 Oct  4 12:58 sys

持久卷的回收模式:

當持久卷和持久卷申請被刪除後,它有三種回收模式。

  • 保持(Retain):當持久卷申請被刪除後,持久卷仍在。你可以手動回收持久卷裡的資料。
  • ** 刪除(Delete)**:持久卷申請和持久卷都被刪除,底層儲存的資料也會被刪除。當使用動態持久卷時,預設的模式是Delete。當然,你可以在持久卷被建立之後修改它的回收模式。
  • ** 回收(Recycle)**:這種方式已經不推薦使用了,建議用Retain代替。

靜態持久卷:

動態持久卷的一個問題是它的預設回收模式是“刪除”,這樣當虛機重新啟動後,持久卷會被刪除。當你重新執行部署時,k8s會建立一個新的MySQL,這樣原來MySQL裡的新建資訊就會丟失,這是我們不願意看到的。雖然你可以手動修改回收方式為“保持”,但還是要手動回收原來持久卷裡的資料。
一個解決辦法是把持久卷建在宿主機上,這樣即使虛機出了問題被重新啟動,MySQL裡的新建資訊依然不會丟失。如果是在雲上,就會有專門的的儲存層,如果是本地,大致有三種方式:

  • Local:把儲存從宿主機掛載到k8s叢集上. 詳情請參見:"Volumes".
  • HostPath:也是把儲存從宿主機掛載到k8s叢集上,但它有許多限制,例如只支援單節點(Node),而且只支援“ReadWriteOnce”模式。詳情請參見: "hostPath as volume in kubernetes".
  • NFS:網路檔案系統,這種是最靈活的,但需要安裝NFS伺服器。詳情請參見:"Kubernetes Volumes Guide".

我選擇了比較簡單的“Local”方式。在這種方式下,必須單獨建立持久卷,不能 只建立持久卷申請而讓系統自動建立持久卷。

下面是使用“Local”方式的配置檔案,它把持久卷和持久卷申請寫在了一個檔案裡。當用“Local”方式時,需要設定“nodeAffinity”部分,其中“values:- minikube” 的“Minikube”是k8s叢集Node的名字,“Minikube”只支援一個Node,既是“Master Node”,又是“Worker Node”。

持久卷和申請的配置檔案:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  storageClassName:  standard #持久卷儲存型別,它需要與持久卷申請的型別相匹配
  local:
    path: /home/vagrant/database/mysql #宿主機的目錄
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - minikube # Node的名字
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: mysql
spec:
  accessModes:
    - ReadWriteOnce
  # storageClassName:  # 這裡的儲存型別註釋掉了
  resources:
    requests:
      storage: 1Gi #1 GB

如果不知道Node名字,可用如下命令檢視:

vagrant@ubuntu-xenial:/$ kubectl get node
NAME       STATUS   ROLES    AGE    VERSION
minikube   Ready    master   6d3h   v1.15.2

改用靜態持久卷之後,只有持久卷配置檔案發生了變化,部署和服務的配置檔案沒有變。重新執行持久卷和部署,成功之後,即使重啟虛擬機器,MySQL裡面的新建內容也沒有丟失。

注意這裡storageClassName的用法。k8s規定持久卷和持久卷申請的storageClassName必須匹配,這時才會把持久卷分配給持久卷申請。我們這裡的持久卷申請沒有指定storageClassName,這時系統會使用預設的storageClass。

檢視是否安裝了預設的storageClass

vagrant@ubuntu-xenial:/$ kubectl get sc
NAME                 PROVISIONER                AGE
standard (default)   k8s.io/minikube-hostpath   6d3h
vagrant@ubuntu-xenial:/$

檢視預設的storageClass詳細資訊

vagrant@ubuntu-xenial:/$ kubectl describe sc
Name:                  standard
IsDefaultClass:        Yes
Annotations:           storageclass.kubernetes.io/is-default-class=true
Provisioner:           k8s.io/minikube-hostpath
Parameters:            <none>
AllowVolumeExpansion:  <unset>
MountOptions:          <none>
ReclaimPolicy:         Delete
VolumeBindingMode:     Immediate
Events:                <none>

從這裡可以看出,Minikube安裝了預設的storageClass,它的名字是“standard”。上面的持久卷申請裡沒有指定storageClass,因此係統使用預設的storageClass與之匹配,而上面的持久卷的storageClassName是“standard”,正好能配上。詳情請見“Dynamic Provisioning and Storage Classes in Kubernetes”

踩過的坑:

  1. 使用Hyper-V還是VirtualBox

Hyper-V和VirtualBox是不相容的,只能選一個(當然你可以在這兩者之間切換,但太麻煩了)。我在Windows上裝了VirtualBox,執行正常。進入Vagrant之後,安裝了“ubuntu”版的Linux。這時,當你啟動Minikube時,可以鍵入“minikube start --vm-driver=virtualbox”,但系統顯示“This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory”。我按照網上的建議去修改BIOS的“VT-X/AMD-v”,但我的BIOS就沒有這個選項。其他的方法也都試過了,沒有一個成功的。但因為已經裝了VirtualBox,就不能用Hyper-V了。就只能用另外一個方法,使用命令“minikube start --vm-driver=none”。幸好這個方法工作得很好。

當用“minikube start --vm-driver=virtualbox”時,你是先建了虛擬機器,再在虛擬機器上執行Minikube。當用“minikube start --vm-driver=none”時,是直接在宿主機上執行Minikube。但由於我的Windows版本不能直接支援k8s,我已經在Windows上裝了Linux虛機,並用Vagrant進行管理。如果用“minikube start --vm-driver=virtualbox”,就是在Linux虛機上又裝了一個虛機。現在用“minikube start --vm-driver=none”,表面上看是在宿主機上執行,實際上已經執行在Windows的Linux虛機上了。

  1. 登入k8s叢集

當用“minikube start --vm-driver=none”啟動Minikube時,不能用“minikube ssh”登入k8s叢集,因為這時已經沒有虛機了,是直接安裝在宿主機上,因此不需要“minikube ssh”。但你可以登入到Pod上,可用如下命令:
" kubectl exec -ti mysql-deployment-56c9cf5857-fffth -- /bin/bash"。其中“mysql-deployment-56c9cf5857-fffth”是Pod名字。

  1. 建立重名PV或PVC

當原來的PV或PVC還在,而你又建立了一個新的PV, 並與原來的重名,則會得到如下錯誤:
The persistentvolumeclaim "mysql-pv-claim" is invalid: spec: forbidden: is immutable after creation except resources.requests for bound claims
這時,你需要將原來的PV或PVC刪掉,再重新建立新的。

請繼續閱讀下篇“通過搭建MySQL掌握k8s(Kubernetes)重要概念(下):引數配置”

索引:

  1. 通過例項快速掌握k8s(Kubernetes)核心概念
  2. Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?
  3. Vagrant reverse port forwarding?
  4. hostPath as volume in kubernetes
  5. Volumes
  6. Kubernetes Volumes Guide
  7. Dynamic Provisioning and Storage Classes in Kubernetes

本文由部落格一文多發平臺 OpenWrite 釋出!