上一篇文章我们尝试了在Oracle Cloud的容器云里创建了持久化卷,并且使用该卷创建了一个MySQL数据库的容器。这样数据库里的数据就保存在了容器外部,如果容器崩溃,那么Kubernetes会根据Deployment的定义,重新创建一个容器,而数据则不会丢失。
对于企业在使用存储来说,除了上述的数据持久性保存之外,共享性也是通常会考虑的一个因素,也就是一份存储上的数据同时被多个应用共享读写。
本文阐述如何在Oracle Cloud的容器云中创建和使用共享存储,在这篇文章中我们使用NFS的方式来实现共享。
创建文件系统
首先需要在Oracle Cloud的管理后台创建一个文件系统,菜单项位于File Storage->File Systems。
点击页面中的“Create File System”按钮,在新建文件系统的页面中点击“Edit Details”,可以对名字进行修改,实际上直接全部使用默认值也是可以的。
为了表意更清晰,我们将文件系统的名字修改为FileSystem-for-OKE,将Export路径修改为“/oke-export”,Mount Target名称不做变化。
这些Oracle Cloud中文件系统的术语的解释,可以参看官方文档。注意的是:其中Export路径在后续的容器配置中会使用到,不过这个路径的名称跟容器中会挂载到的路径没有任何关系,可以随意命名。
修改后的并且创建成功的文件系统,可以在管理后台中看到详细情况。
同样,通过oci命令行也可以获得创建成功的文件系统的信息。
$ oci fs file-system list \ > --compartment-id ocid1.tenancy.oc1..aaaaaaaaqxee2wwzpx3s6usguambydweb2q5yfx2y5ux3lwlrpaao4gdun7a \ > --availability-domain lOnA:AP-TOKYO-1-AD-1 { "data": [ { "availability-domain": "lOnA:AP-TOKYO-1-AD-1", "compartment-id": "ocid1.tenancy.oc1..aaaaaaaaqxee2wwzpx3s6usguambydweb2q5yfx2y5ux3lwlrpaao4gdun7a", "defined-tags": {}, "display-name": "FileSystem-for-OKE", "freeform-tags": {}, "id": "ocid1.filesystem.oc1.ap_tokyo_1.aaaaaaaaaaaafictnzzhillqojxwiotboawxi33lpfxs2mjnmfsc2mia", "kms-key-id": "", "lifecycle-state": "ACTIVE", "metered-bytes": 8704, "time-created": "2019-10-21T13:26:40+00:00" } ] }
复制
在创建文件系统时,Oracle Cloud会自动创建一个Mount Target,可以在管理后台中看到详细情况。
注意这里的IP地址,这个地址在后续创建容器持久化卷的时候也会使用到。
同样,通过oci命令行也可以获得创建成功的挂载目标的信息。
$ oci fs mount-target list \ --compartment-id ocid1.tenancy.oc1..aaaaaaaaqxee2wwzpx3s6usguambydweb2q5yfx2y5ux3lwlrpaao4gdun7a \ --availability-domain lOnA:AP-TOKYO-1-AD-1 { "data": [ { "availability-domain": "lOnA:AP-TOKYO-1-AD-1", "compartment-id": "ocid1.tenancy.oc1..aaaaaaaaqxee2wwzpx3s6usguambydweb2q5yfx2y5ux3lwlrpaao4gdun7a", "defined-tags": {}, "display-name": "MountTarget-20191021-1322", "export-set-id": "ocid1.exportset.oc1.ap_tokyo_1.aaaaaa4np2snfy33nzzhillqojxwiotboawxi33lpfxs2mjnmfsc2mia", "freeform-tags": {}, "id": "ocid1.mounttarget.oc1.ap_tokyo_1.aaaaaa4np2snfy34nzzhillqojxwiotboawxi33lpfxs2mjnmfsc2mia", "lifecycle-state": "ACTIVE", "private-ip-ids": [ "ocid1.privateip.oc1.ap-tokyo-1.aaaaaaaa34v43wf2b3j73kme2rtho4rlpm6kit3avszgirkpqm5uspbqnrrq" ], "subnet-id": "ocid1.subnet.oc1.ap-tokyo-1.aaaaaaaafqsuofe2e34mnfkotolakrzktxmwdasj7dyov3u3jixqablc2qgq", "time-created": "2019-10-21T13:26:42+00:00" } ] }
复制
可以参看创建文件系统的官方文档。
创建PV
创建一个PV的定义yaml文件,内容如下。server部分指定上述的Mount Target的IP地址,path部分指定上述的File System的名字。
$ cat pv-nfs.yaml apiVersion: v1 kind: PersistentVolume metadata: name: nfs spec: capacity: storage: 1Gi accessModes: - ReadWriteMany nfs: server: 10.0.10.5 path: "/oke-export"
复制
创建PV,并检查创建结果。
$ kubectl create -f pv-nfs.yaml $ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE nfs 1Gi RWX Retain Available 8s $ kubectl describe pv nfs Name: nfs Labels: <none> Annotations: pv.kubernetes.io/bound-by-controller: yes Finalizers: [kubernetes.io/pv-protection] StorageClass: Status: Available Claim: default/nfs Reclaim Policy: Retain Access Modes: RWX VolumeMode: Filesystem Capacity: 1Gi Node Affinity: <none> Message: Source: Type: NFS (an NFS mount that lasts the lifetime of a pod) Server: 10.0.10.5 Path: /oke-export ReadOnly: false Events: <none>
复制
可以看到现在PV的状态是Available,表示可用,在后续我们创建完PVC之后,这里会显示成Bound,表示该PV已经跟PVC绑定。
创建PVC
创建一个PVC的定义yaml文件,内容如下。
$ cat pvc-nfs.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs spec: accessModes: - ReadWriteMany storageClassName: "" resources: requests: storage: 1Mi
复制
创建PVC,并检查创建结果。
$ kubectl create -f pvc-nfs.yaml $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE nfs Bound nfs 1Gi RWX 4s $ kubectl describe pvc nfs Name: nfs Namespace: default StorageClass: Status: Bound Volume: nfs Labels: <none> Annotations: pv.kubernetes.io/bind-completed: yes pv.kubernetes.io/bound-by-controller: yes Finalizers: [kubernetes.io/pvc-protection] Capacity: 1Gi Access Modes: RWX VolumeMode: Filesystem Events: <none> Mounted By: <none>
复制
创建容器
这里我们使用ReplicationController类型的对象来创建Pod,这样可以指定自动创建多个容器,并共享读写指定的NFS存储。
创建一个RC的定义yaml文件,内容如下。作为测试,我们使用最简单的Nginx镜像,并且指定2个复制。
$ cat rc-nfs.yaml apiVersion: v1 kind: ReplicationController metadata: name: rc-nfs-test spec: replicas: 2 selector: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - name: nginx containerPort: 80 volumeMounts: - name: nfs mountPath: "/usr/share/nginx/html" volumes: - name: nfs persistentVolumeClaim: claimName: nfs
复制
创建RC,并检查结果。
$ kubectl create -f rc-nfs.yaml $ kubectl get rc rc-nfs-test NAME DESIRED CURRENT READY AGE rc-nfs-test 2 2 2 6m56s $ kubectl describe replicationcontrollers/rc-nfs-test Name: rc-nfs-test Namespace: default Selector: app=nginx Labels: app=nginx Annotations: <none> Replicas: 2 current / 2 desired Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: app=nginx Containers: nginx: Image: nginx Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: /usr/share/nginx/html from nfs (rw) Volumes: nfs: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: nfs ReadOnly: false Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 16m replication-controller Created pod: rc-nfs-test-bqhm9 Normal SuccessfulCreate 16m replication-controller Created pod: rc-nfs-test-8h884 $ kubectl get pods NAME READY STATUS RESTARTS AGE rc-nfs-test-8h884 1/1 Running 0 3m16s rc-nfs-test-bqhm9 1/1 Running 0 3m16s
复制
到目前为止,我们已经创建好了一组(2个)共享使用磁盘的Nginx容器,共享磁盘在容器内的挂载路径是:/usr/share/nginx/html
接下来,测试一下共享读写的效果。计划在一个容器的共享磁盘中创建index.html文件,并且写入了"test sharing disk"这样的文本,之后从另外一个容器中进行查看。
首先,在其中一个容器里创建index.html文件。
$ kubectl exec rc-nfs-test-8h884 touch /usr/share/nginx/html/index.html
复制
写入一行文本。
$ kubectl exec -it rc-nfs-test-8h884 -- /bin/bash root@rc-nfs-test-8h884:/# cd /usr/share/nginx/html/ root@rc-nfs-test-8h884:/usr/share/nginx/html# ls index.html root@rc-nfs-test-8h884:/usr/share/nginx/html# echo "test sharing disk">>/usr/share/nginx/html/index.html
复制
现在我们登录到另外一个容器中,查看是否能够读取到该内容。
$ kubectl exec rc-nfs-test-bqhm9 cat /usr/share/nginx/html/index.html test sharing disk
复制
Well Done!