返回总目录页

kubernetes之数据管理

 volume

emptyDir


[machangwei@mcwk8s-master ~]$ kubectl apply -f mcwVolume1.yml #部署emptydir pod/producer-consumer created [machangwei@mcwk8s-master ~]$ cat mcwVolume1.yml apiVersion: v1 kind: Pod metadata: name: producer-consumer spec: containers: - image: busybox name: producer volumeMounts: - mountPath: /producer_dir name: shared-volume args: - /bin/sh - -c - echo "hello world" >/producer_dir/hello ; sleep 30000 - image: busybox name: consumer volumeMounts: - mountPath: /consumer_dir name: shared-volume args: - /bin/sh - -c - cat /consumer_dir/hello ; sleep 30000 volumes: - name: shared-volume emptyDir: {}

######定义一个volumes,使用空字典代表它是个空目录,起个名字。规格容器下,有两个镜像代表两个容器。这是pod种类资源。
#元数据名称就是运行的pod的名称。pod下两个容器,下面这行结果,ready下应该是两个容器,但是暂时是0个容器准备好。容器正在创建中
#容器下有镜像。每个镜像下做配置,一个镜像的配置就是一个容器。镜像下的名称就是容器的名称。指定逻辑卷挂载,指定这个容器的逻辑卷
#挂载路径是容器里哪个目录,需要挂载的逻辑卷名称是哪个。后面定义逻辑卷的时候有定义它的名称。然后这个容器的args参数,就是启动容器后,
#要运行的命令,这里生产者是每隔睡眠时间个单位,就写入数据到挂载目录下的某个文件。消费者就是每个睡眠个时间单位,去查看(消费)被挂载目录的文件
#由于两者是同一个volume挂载上去的,所以这个pod中的两个容器共享这一个volume。而这个volume实质就是一个目录,请往下看 [machangwei@mcwk8s
-master ~]$ kubectl get pod NAME READY STATUS RESTARTS AGE producer-consumer 0/2 ContainerCreating 0 84s [machangwei@mcwk8s-master ~]$ kubectl describe pod producer-consumer Name: producer-consumer Namespace: default Priority: 0 Node: mcwk8s-node1/10.0.0.5 Start Time: Fri, 18 Feb 2022 20:20:38 +0800 Labels: <none> Annotations: <none> Status: Running IP: 10.244.1.15 IPs: IP: 10.244.1.15 Containers: producer: Container ID: docker://e9a06c83f73861d15a115cc95665d19d8b6ef024546d339cc049d1571840cad7 Image: busybox Image ID: docker-pullable://busybox@sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678 Port: <none> Host Port: <none> Args: /bin/sh -c echo "hello world" >/producer_dir/hello ; sleep 30000 State: Running Started: Fri, 18 Feb 2022 20:21:54 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /producer_dir from shared-volume (rw) /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-spkgq (ro) consumer: Container ID: docker://634dc8fe053cc6ea1ee0f5f818cac6a7babbd5f84804579386382e2d2c6d1b40 Image: busybox Image ID: docker-pullable://busybox@sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678 Port: <none> Host Port: <none> Args: /bin/sh -c cat /consumer_dir/hello ; sleep 30000 State: Running Started: Fri, 18 Feb 2022 20:22:11 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /consumer_dir from shared-volume (rw) /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-spkgq (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: shared-volume: Type: EmptyDir (a temporary directory that shares a pod's lifetime) Medium: SizeLimit: <unset> kube-api-access-spkgq: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m39s default-scheduler Successfully assigned default/producer-consumer to mcwk8s-node1 Normal Pulling 105s kubelet Pulling image "busybox" Normal Pulled 89s kubelet Successfully pulled image "busybox" in 16.349119305s Normal Created 89s kubelet Created container producer Normal Started 83s kubelet Started container producer Normal Pulling 83s kubelet Pulling image "busybox" Normal Pulled 67s kubelet Successfully pulled image "busybox" in 16.122373015s Normal Created 67s kubelet Created container consumer Normal Started 66s kubelet Started container consumer [machangwei@mcwk8s-master ~]$ kubectl get pod NAME READY STATUS RESTARTS AGE producer-consumer 2/2 Running 0 2m55s [machangwei@mcwk8s-master ~]$ kubectl logs producer-consumer error: a container name must be specified for pod producer-consumer, choose one of: [producer consumer] [machangwei@mcwk8s-master ~]$ [machangwei@mcwk8s-master ~]$ kubectl logs producer-consumer consumer hello world [machangwei@mcwk8s-master ~]$ kubectl get pod -o wide #查看pod所在的host NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES producer-consumer 2/2 Running 0 6m19s 10.244.1.15 mcwk8s-node1 <none> <none> [root@mcwk8s-node1 ~]$ docker ps|grep producer-consumer #pod部署主机上查看跟这个pod有关的容器。两个容器和pod在容一个host 634dc8fe053c busybox "/bin/sh -c 'cat /co…" 13 minutes ago Up 13 minutes k8s_consumer_producer-consume_default_d32da9de-8574-458a-97c7-31cf9107f0a1_0 e9a06c83f738 busybox "/bin/sh -c 'echo \"h…" 13 minutes ago Up 13 minutes k8s_producer_producer-consume_default_d32da9de-8574-458a-97c7-31cf9107f0a1_0 173864534fcb registry.aliyuncs.com/google_containers/pause:3.6 "/pause" 14 minutes ago Up 13 minutes k8s_POD_producer-consumer_default_d32da9de-8574-458a-97c7-31cf9107f0a1_0 #它们的命名时部署配置中镜像下的名字是容器名,pod的POD,然后三者后面都是接pod名称producer-consumer
#看下面的,可以看到生产这容器和消费者容器源目录都是一样的,挂载的目标目录是各自容器中指定的目录。有的时候,可能容器改变,可能源目录和目标目录
发生了变化,当容器好了后,应该就都是如下类似。的 [root@mcwk8s
-node1 ~]$ docker inspect e9a06c8|grep -iA 8 "mounts" "Mounts": [ { "Type": "bind", "Source": "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume", "Destination": "/producer_dir", "Mode": "Z", "RW": true, "Propagation": "rprivate" }, [root@mcwk8s-node1 ~]$ docker inspect 634dc8|grep -iA 8 "mounts" "Mounts": [ { "Type": "bind", "Source": "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume", "Destination": "/consumer_dir", "Mode": "Z", "RW": true, "Propagation": "rprivate" }, [root@mcwk8s-node1 ~]$

查看逻辑卷在物理机中的实际位置。以及两个容器操作后的数据

[root@mcwk8s-node1 ~]$ ls /var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume
hello
[root@mcwk8s-node1 ~]$ cat /var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume/hello
hello world
[root@mcwk8s-node1 ~]$ ls /var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/
kubernetes.io~empty-dir kubernetes.io~projected

[root@mcwk8s-node1 ~]$ docker inspect 634dc8
[
    {
        "Id": "634dc8fe053cc6ea1ee0f5f818cac6a7babbd5f84804579386382e2d2c6d1b40",
        "Created": "2022-02-18T12:22:10.65373133Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "cat /consumer_dir/hello ; sleep 30000"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 91494,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-02-18T12:22:11.920497543Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:beae173ccac6ad749f76713cf4440fe3d21d1043fe616dfbe30775815d1d0f6a",
        "ResolvConfPath": "/var/lib/docker/containers/173864534fcb27ce32342a5b5ba9edc4adc3731c6a629f4175e3bedf173b1dc2/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/173864534fcb27ce32342a5b5ba9edc4adc3731c6a629f4175e3bedf173b1dc2/hostname",
        "HostsPath": "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/etc-hosts",
        "LogPath": "/var/lib/docker/containers/634dc8fe053cc6ea1ee0f5f818cac6a7babbd5f84804579386382e2d2c6d1b40/634dc8fe053cc6ea1ee0f5f818cac6a7babbd5f84804579386382e2d2c6d1b40-json.log",
        "Name": "/k8s_consumer_producer-consumer_default_d32da9de-8574-458a-97c7-31cf9107f0a1_0",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume:/consumer_dir:Z",
                "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~projected/kube-api-access-spkgq:/var/run/secrets/kubernetes.io/serviceaccount:ro,Z",
                "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/etc-hosts:/etc/hosts:Z",
                "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/containers/consumer/61a05b66:/dev/termination-log:Z"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "container:173864534fcb27ce32342a5b5ba9edc4adc3731c6a629f4175e3bedf173b1dc2",
            "PortBindings": null,
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": null,
            "DnsOptions": null,
            "DnsSearch": null,
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "container:173864534fcb27ce32342a5b5ba9edc4adc3731c6a629f4175e3bedf173b1dc2",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 1000,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": [
                "seccomp=unconfined"
            ],
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 2,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "kubepods-besteffort-podd32da9de_8574_458a_97c7_31cf9107f0a1.slice",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 100000,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/asound",
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/b45ab6cc1d2f691b9529c5dc413b8bcaa62350a62a43d9b2d45f2f2cdc7fb63d-init/diff:/var/lib/docker/overlay2/5c9e2add80e4eb9b40376cc60407679fdc4b510a0c146356397e8a769c1a307c/diff",
                "MergedDir": "/var/lib/docker/overlay2/b45ab6cc1d2f691b9529c5dc413b8bcaa62350a62a43d9b2d45f2f2cdc7fb63d/merged",
                "UpperDir": "/var/lib/docker/overlay2/b45ab6cc1d2f691b9529c5dc413b8bcaa62350a62a43d9b2d45f2f2cdc7fb63d/diff",
                "WorkDir": "/var/lib/docker/overlay2/b45ab6cc1d2f691b9529c5dc413b8bcaa62350a62a43d9b2d45f2f2cdc7fb63d/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume",
                "Destination": "/consumer_dir",
                "Mode": "Z",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~projected/kube-api-access-spkgq",
                "Destination": "/var/run/secrets/kubernetes.io/serviceaccount",
                "Mode": "ro,Z",
                "RW": false,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/etc-hosts",
                "Destination": "/etc/hosts",
                "Mode": "Z",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/containers/consumer/61a05b66",
                "Destination": "/dev/termination-log",
                "Mode": "Z",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "producer-consumer",
            "Domainname": "",
            "User": "0",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "KUBERNETES_PORT_443_TCP_PROTO=tcp",
                "KUBERNETES_PORT_443_TCP_PORT=443",
                "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
                "KUBERNETES_SERVICE_HOST=10.96.0.1",
                "KUBERNETES_SERVICE_PORT=443",
                "KUBERNETES_SERVICE_PORT_HTTPS=443",
                "KUBERNETES_PORT=tcp://10.96.0.1:443",
                "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "cat /consumer_dir/hello ; sleep 30000"
            ],
            "Healthcheck": {
                "Test": [
                    "NONE"
                ]
            },
            "Image": "busybox@sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "annotation.io.kubernetes.container.hash": "2c893f27",
                "annotation.io.kubernetes.container.restartCount": "0",
                "annotation.io.kubernetes.container.terminationMessagePath": "/dev/termination-log",
                "annotation.io.kubernetes.container.terminationMessagePolicy": "File",
                "annotation.io.kubernetes.pod.terminationGracePeriod": "30",
                "io.kubernetes.container.logpath": "/var/log/pods/default_producer-consumer_d32da9de-8574-458a-97c7-31cf9107f0a1/consumer/0.log",
                "io.kubernetes.container.name": "consumer",
                "io.kubernetes.docker.type": "container",
                "io.kubernetes.pod.name": "producer-consumer",
                "io.kubernetes.pod.namespace": "default",
                "io.kubernetes.pod.uid": "d32da9de-8574-458a-97c7-31cf9107f0a1",
                "io.kubernetes.sandbox.id": "173864534fcb27ce32342a5b5ba9edc4adc3731c6a629f4175e3bedf173b1dc2"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {}
        }
    }
]
[root@mcwk8s-node1 ~]$ 
描述某个容器的详情
[root@mcwk8s-node1 ~]$ docker ps|grep producer-consumer  
634dc8fe053c   busybox                                              "/bin/sh -c 'cat /co…"    3 hours ago   Up 3 hours             k8s_consumer_producer-consumer_default_d32da9de-8574-458a-97c7-31cf9107f0a1_0
e9a06c83f738   busybox                                              "/bin/sh -c 'echo \"h…"   3 hours ago   Up 3 hours             k8s_producer_producer-consumer_default_d32da9de-8574-458a-97c7-31cf9107f0a1_0
173864534fcb   registry.aliyuncs.com/google_containers/pause:3.6    "/pause"                  3 hours ago   Up 3 hours             k8s_POD_producer-consumer_default_d32da9de-8574-458a-97c7-31cf9107f0a1_0
[root@mcwk8s-node1 ~]$ 
[root@mcwk8s-node1 ~]$ 
[root@mcwk8s-node1 ~]$ docker inspect 634dc8|grep  -iA 8 "mounts"
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume",
                "Destination": "/consumer_dir",
                "Mode": "Z",
                "RW": true,
                "Propagation": "rprivate"
            },
[root@mcwk8s-node1 ~]$ docker exec -it 634d cat /consumer_dir/hello 
hello world
[root@mcwk8s-node1 ~]$ ls /var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume
hello
[root@mcwk8s-node1 ~]$ cat /var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume/hello 
hello world
[root@mcwk8s-node1 ~]$ echo -e "   mcw">>/var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume/hello
[root@mcwk8s-node1 ~]$ docker exec -it 634d cat /consumer_dir/hello  #修改host目录,容器中显示被修改后的
hello world
   mcw
[root@mcwk8s-node1 ~]$ docker exec -it 634d touch /consumer_dir/mcw.txt #容器中修改,host中也是修改后的
[root@mcwk8s-node1 ~]$ ls /var/lib/kubelet/pods/d32da9de-8574-458a-97c7-31cf9107f0a1/volumes/kubernetes.io~empty-dir/shared-volume
hello  mcw.txt
[root@mcwk8s-node1 ~]$ 

hostPath

[machangwei@mcwk8s-master ~]$ kubectl get pod --all-namespaces|grep apiserver  
kube-system   kube-apiserver-mcwk8s-master            1/1     Running   15 (110m ago)   28d
[machangwei@mcwk8s-master ~]$ kubectl  edit --namespace=kube-system pod kube-apiserver-mcwk8s-master
......
    volumeMounts: #我们查看apiserver服务的配置。 
    - mountPath: /etc/ssl/certs #可以看到挂载容器中的三个目录,使用某个名称的volume,是否只读挂载
      name: ca-certs  #下面有定义用来挂载的volume
      readOnly: true
    - mountPath: /etc/pki
      name: etc-pki
      readOnly: true
    - mountPath: /etc/kubernetes/pki
      name: k8s-certs
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  hostNetwork: true
  nodeName: mcwk8s-master
  preemptionPolicy: PreemptLowerPriority
  priority: 2000001000
  priorityClassName: system-node-critical
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    operator: Exists
  volumes:
  - hostPath:   #host主机path目录被映射到使用这个容器的目录中,起个名字后面通过名字使用这个host上的目录
      path: /etc/ssl/certs
      type: DirectoryOrCreate
    name: ca-certs
  - hostPath:
      path: /etc/pki
      type: DirectoryOrCreate
    name: etc-pki
  - hostPath:
      path: /etc/kubernetes/pki
      type: DirectoryOrCreate
    name: k8s-certs

外部Storage Provider

云硬盘存储

PersistentVolume & PersistentVolumeClaim

persistent [pəˈsɪstənt] [pərˈsɪstənt]

 

adj. 持久的; 持续的; 坚持不懈的; 执著的; 不屈不挠的; 连绵的; 反复出现的;

 

claim [kleɪm] [kleɪm]
v. 宣称; 声称; 断言; 要求(拥有); 索取; 认领; 索要; 引起(注意); 获得; 夺走,夺去(生命);
n. 声明; 宣称; 断言; (尤指对财产、土地等要求拥有的)所有权; (尤指向公司、政府等)索款,索赔;

PersistentVolume & PersistentVolumeClaim   pv &pvc

pv持久化volume,pvc持久化volume申请。

NFS PersistentVolume

nfs服务器

参考:https://www.cnblogs.com/machangwei-8/articles/15487295.html#_label5

[root@mcwk8s-master ~]$ showmount -e 10.0.0.4  #先部署好nfs服务器,这里nfs的共享目录是/nfsdata
Export list for 10.0.0.4:
/nfsdata *
[root@mcwk8s-master ~]$ 

要使用外部存储,这里使用nfs挂载存储,得有nfs服务器。上面已经部署好了。

pv

[machangwei@mcwk8s-master ~]$ vim nfs-pv1.yml
[machangwei@mcwk8s-master ~]$ kubectl apply -f nfs-pv1.yml 
persistentvolume/mypv1 created
[machangwei@mcwk8s-master ~]$ cat nfs-pv1.yml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv1
    server: 10.0.0.4
[machangwei@mcwk8s-master ~]$ kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Available           nfs                     21s

配置pv,配置api版本,种类是持久化逻辑卷。元数据名称就是逻辑卷名称。

规格中容量存储设置,访问模式是什么,这里设置该pv只能读写模式挂载一个节点。模式还有ReadWriteMany 能以读写模式挂载到多个节点;ReadOnlyMany 能以只读模式挂载到多个节点。

定义持久化逻辑卷重新声明策略,即回收策略。Reain 需要管理员手工回;Recycle清除PV中的数据,;Delete删除存储提供者上对应的资源

定义存储类名称,这里是使用nfs存储。nfs的信息需要设置,提供的挂载path是什么,访问服务地址是什么

pvc

种类是持久化逻辑卷声明;api版本多少,元数据名称设置逻辑卷名称;规则里设置访问模式,这里是以读写模式可以挂载到单个节点;资源是多少,请求存储大小是多少设置。存储类的名称是nfs

[machangwei@mcwk8s-master ~]$ cat nfs-pvc1.yml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mypvc1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs
[machangwei@mcwk8s-master ~]$ kubectl apply -f nfs-pvc1.yml 
persistentvolumeclaim/mypvc1 created
[machangwei@mcwk8s-master ~]$ kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc1   Bound    mypv1    1Gi        RWO            nfs            8s
[machangwei@mcwk8s-master ~]$ kubectl get pvc -o wide  #查看到pvc绑定的pv,声明之后就绑定了逻辑卷
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
mypvc1   Bound    mypv1    1Gi        RWO            nfs            18s   Filesystem
[machangwei@mcwk8s-master ~]$ kubectl get pv -o wide  #查看到pv被pvc绑定了,
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE     VOLUMEMODE
mypv1   1Gi        RWO            Recycle          Bound    default/mypvc1   nfs                     2m40s   Filesystem

pod还有报错了

[machangwei@mcwk8s-master ~]$ cat pod1.yml 
kind: Pod
apiVersion: v1
metadata:
  name: mypod1
spec:
  containers:
    - name: mypod1
      image: busybox
      args:
      - /bin/sh
      - -c
      - sleep 30000
      volumeMounts:
      - mountPath: "/mydata"
        name: mydata
  volumes:
    - name: mydata
      persistentVolumeClaim:
        claimName: mypvc1

#pod中使用创建的pvc。种类是pod,元数据名称设置pod名称。规格里设置容器信息。容器逻辑卷和镜像是同一级下的,挂载容器中指定路径是什么,使用哪个逻辑卷名称;下面定义了这个
#使用的逻辑卷,这个逻辑卷怎么定义的?逻辑卷定义和容器同级,定义逻辑卷名称,持久化逻辑卷声明的名字是哪个,就是之前创建好的哪个pvc。这样修改容器中的那个目录,容器对应该主机的
#某个逻辑卷目录,而该目录又被挂载nfs挂载着,这样容器就间接访问到了nfs上的目录 [machangwei@mcwk8s
-master ~]$ kubectl apply -f pod1.yml pod/mypod1 created [machangwei@mcwk8s-master ~]$ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mypod1 0/1 ContainerCreating 0 16s <none> mcwk8s-node1 <none> <none> [machangwei@mcwk8s-master ~]$ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mypod1 0/1 ContainerCreating 0 33s <none> mcwk8s-node1 <none> <none> [machangwei@mcwk8s-master ~]$ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mypod1 0/1 ContainerCreating 0 62s <none> mcwk8s-node1 <none> <none> [machangwei@mcwk8s-master ~]$ kubectl describe pod mypod1 Name: mypod1 Namespace: default Priority: 0 Node: mcwk8s-node1/10.0.0.5 Start Time: Sat, 19 Feb 2022 01:21:32 +0800 Labels: <none> Annotations: <none> Status: Pending IP: IPs: <none> Containers: mypod1: Container ID: Image: busybox Image ID: Port: <none> Host Port: <none> Args: /bin/sh -c sleep 30000 State: Waiting Reason: ContainerCreating Ready: False Restart Count: 0 Environment: <none> Mounts: /mydata from mydata (rw) /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-28s6l (ro) Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True Volumes: mydata: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: mypvc1 ReadOnly: false kube-api-access-28s6l: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 80s default-scheduler Successfully assigned default/mypod1 to mcwk8s-node1 Warning FailedMount 13s (x8 over 77s) kubelet MountVolume.SetUp failed for volume "mypv1" : mount failed: exit status 32 Mounting command: mount Mounting arguments: -t nfs 10.0.0.4:/nfsdata/pv1 /var/lib/kubelet/pods/d1ba5034-28ad-4898-a7aa-3551bc330a4b/volumes/kubernetes.io~nfs/mypv1 Output: mount: wrong fs type, bad option, bad superblock on 10.0.0.4:/nfsdata/pv1, missing codepage or helper program, or other error (for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.<type> helper program) In some cases useful info is found in syslog - try dmesg | tail or so. [machangwei@mcwk8s-master ~]$ #由上可知,就是将网络存储挂载到host本地某个目录

解决上面的pod部署挂载问题

缺少包

上面的原因是,由于部署pod在节点上,从节点上把nfs服务(在主上)挂载到节点1,
由于缺少包,无法挂载,导致pod无法在节点上做挂载。
在节点1无法挂载nfs
[root@mcwk8s-node1 ~]$ mount -t nfs 10.0.0.4:/nfsdata/ /root/mcw/
mount: wrong fs type, bad option, bad superblock on 10.0.0.4:/nfsdata/,
       missing codepage or helper program, or other error
       (for several filesystems (e.g. nfs, cifs) you might
       need a /sbin/mount.<type> helper program)

       In some cases useful info is found in syslog - try
       dmesg | tail or so.
原因,缺少包,安装一下。
[root@mcwk8s-node1 ~]$ yum install nfs-utils ^C
[root@mcwk8s-node1 ~]$ mount -t nfs 10.0.0.4:/nfsdata/ /root/mcw/
[root@mcwk8s-node1 ~]$ df -h|tail -1 #可以正常挂载了
10.0.0.4:/nfsdata         19G  3.9G   15G  22% /root/mcw
[root@mcwk8s-node1 ~]$ df -h  #过一会看pv1已经挂载上了
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   19G  2.6G   16G  14% /
devtmpfs                 478M     0  478M   0% /dev
tmpfs                    489M     0  489M   0% /dev/shm
tmpfs                    489M   51M  438M  11% /run
tmpfs                    489M     0  489M   0% /sys/fs/cgroup
/dev/sda1                797M  125M  673M  16% /boot
tmpfs                    877M   12K  877M   1% /var/lib/kubelet/pods/9b74614a-6d0b-439c-8ea5-cf1583be7a5a/volumes/kubernetes.io~projected/kube-api-access-6hk5l
tmpfs                    877M   12K  877M   1% /var/lib/kubelet/pods/57f73623-751b-41a3-883e-62c025c49f92/volumes/kubernetes.io~projected/kube-api-access-wv8cc
overlay                   19G  2.6G   16G  14% /var/lib/docker/overlay2/c3a132cb506fe3db901260f4e8e40ab73c20b6dbb8904c545bd6c12e45af2ce9/merged
overlay                   19G  2.6G   16G  14% /var/lib/docker/overlay2/9c92a061f975e8f573fc9b895664adeeec375d7609c6e00fd5facada9a525a13/merged
shm                       64M     0   64M   0% /var/lib/docker/containers/fc176c43633f8e6362d47f6bbec6f2f556685bbe51564fe189cf58cd9bf69fa5/mounts/shm
shm                       64M     0   64M   0% /var/lib/docker/containers/3bbd8916f1ae8819e27eb1269afa524eca1c60a5d0b8df56dbbf314217c063a0/mounts/shm
overlay                   19G  2.6G   16G  14% /var/lib/docker/overlay2/914fc6440a30892ef51129fb445349c082d79ffb0fd79d62769384c7920e983a/merged
overlay                   19G  2.6G   16G  14% /var/lib/docker/overlay2/fe20b74227debccec19071237760ba6c37be72eadccc3999490a8aeae432919a/merged
tmpfs                     98M     0   98M   0% /run/user/0
tmpfs                    877M   12K  877M   1% /var/lib/kubelet/pods/d1ba5034-28ad-4898-a7aa-3551bc330a4b/volumes/kubernetes.io~projected/kube-api-access-28s6l
10.0.0.4:/nfsdata/pv1     19G  3.9G   15G  22% /var/lib/kubelet/pods/d1ba5034-28ad-4898-a7aa-3551bc330a4b/volumes/kubernetes.io~nfs/mypv1
overlay                   19G  2.6G   16G  14% /var/lib/docker/overlay2/b316299270c3541708659a9bbd6c65bb6d1fe4fa713460ad298866e1096adb0a/merged
shm                       64M     0   64M   0% /var/lib/docker/containers/b35f15c56b2e6f635dd346a9352fa0cbcb77ec9ba3f9a53b62f7bb53cb249e30/mounts/shm
overlay                   19G  2.6G   16G  14% /var/lib/docker/overlay2/bda202921f17c4ec866e22f2517af01a6df6434e4107b05588f4a001d8b5ec49/merged


但是验证的时候,报错只读
[machangwei@mcwk8s-master ~]$ kubectl exec mypod1 touch /mydata/hello
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
touch: /mydata/hello: Read-only file system
command terminated with exit code 1

去节点上查看pod写入不了
[root@mcwk8s-node1 ~]$ docker exec -it e09 touch /mydata/mcw.txt
touch: /mydata/mcw.txt: Read-only file system


这个无法从容器中写入文件到nfs存储里,跟容器有关吗。下面直接通过挂载的方式,将某个目录挂载上去了,但是写入文件容易显示只读。说明这是nfs服务端的问题。

[root@mcwk8s-node1 ~]$ mount -t nfs 10.0.0.4:/nfsdata/pv1 /root/mcw/
[root@mcwk8s-node1 ~]$ df -h|grep mcw
10.0.0.4:/nfsdata/pv1 19G 3.9G 15G 22% /root/mcw
[root@mcwk8s-node1 ~]$ touch /root/mcw/test.txt
touch: cannot touch ‘/root/mcw/test.txt’: Read-only file system
[root@mcwk8s-node1 ~]$

nfs问题导致的容器无法写入数据到外部存储的问题解决

这个无法从容器中写入文件到nfs存储里,跟容器有关吗。下面直接通过挂载的方式,
将某个目录挂载上去了,但是写入文件容易显示只读。说明这是nfs服务端的问题。
[root@mcwk8s-master ~]$ cat /etc/exports
/nfsdata *
/nfsdata/pv1 *
[root@mcwk8s-master ~]$ vim /etc/exports
[root@mcwk8s-master ~]$ cat /etc/exports
/nfsdata * (rw,sync,all_squash)
/nfsdata/pv1 * (rw,sync,all_squash)
[root@mcwk8s-master ~]$ systemctl restart nfs
[root@mcwk8s-master ~]$ showmount -e 10.0.0.4
Export list for 10.0.0.4:
/nfsdata/pv1 *
/nfsdata     *

然后再去节点1上挂载发现还是不能写入文件
[root@mcwk8s-node1 ~]$ mount  -t nfs 10.0.0.4:/nfsdata/pv1 /root/mcw/
[root@mcwk8s-node1 ~]$ df -h|grep mcw
10.0.0.4:/nfsdata/pv1     19G  3.9G   15G  22% /root/mcw
[root@mcwk8s-node1 ~]$ touch /root/mcw/test.txt
touch: cannot touch ‘/root/mcw/test.txt’: Read-only file system

再次修改nfs配置,*代表所有ip网段,后面将小括号里的设置,弄成和ip间是没有空格的,这样才生效了
[root@mcwk8s-master ~]$ vim /etc/exports
[root@mcwk8s-master ~]$ cat /etc/exports
/nfsdata *(rw,sync,all_squash)
/nfsdata/pv1 *(rw,sync,all_squash)
[root@mcwk8s-master ~]$ systemctl restart nfs
[root@mcwk8s-master ~]$ showmount -e 10.0.0.4
Export list for 10.0.0.4:
/nfsdata/pv1 *
/nfsdata     *
[root@mcwk8s-master ~]$ 

再次去节点1上访问,发现成功创建
[root@mcwk8s-node1 ~]$ touch /root/mcw/test.txt
[root@mcwk8s-node1 ~]$ ls /root/mcw/
test.txt
[root@mcwk8s-node1 ~]$ df -h|grep mcw
10.0.0.4:/nfsdata/pv1     19G  3.9G   15G  22% /root/mcw

主节点上也可以看到这个文件
[root@mcwk8s-master ~]$ ls /nfsdata/pv1/
test.txt


也可以正常从容器中写入文件到nfs服务器
[machangwei@mcwk8s-master ~]$ kubectl get pod
NAME     READY   STATUS    RESTARTS   AGE
mypod1   1/1     Running   0          177m
[machangwei@mcwk8s-master ~]$ kubectl exec mypod1 ls /mydata
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
test.txt
[machangwei@mcwk8s-master ~]$ kubectl exec mypod1 touch /mydata/mcw.txt
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[machangwei@mcwk8s-master ~]$ ls /nfsdata/pv1/
mcw.txt  test.txt


节点1上看挂载目录,首先是10.0.0.4:/nfsdata/pv1这个目录重新被挂载了,
虽然df查看只显示/root/mcw,但是也是可以通过之前那个mypv1目录去访问到nfs服务器上的文件的
当把/root/mcw卸载后,那么之前那个mypv1就显示出来了。并且可以正常使用
[root@mcwk8s-node1 ~]$ df -h|grep pv1
10.0.0.4:/nfsdata/pv1     19G  3.9G   15G  22% /root/mcw
[root@mcwk8s-node1 ~]$ ls /var/lib/kubelet/pods/d1ba5034-28ad-4898-a7aa-3551bc330a4b/volumes/kubernetes.io~nfs/mypv1
mcw.txt  test.txt
[root@mcwk8s-node1 ~]$ unmout /root/mcw/
-bash: unmout: command not found
[root@mcwk8s-node1 ~]$ unmount /root/mcw/
-bash: unmount: command not found
[root@mcwk8s-node1 ~]$ unmount /root/mcw/
unalias        unexpand       unicode_stop   unix2dos       unix_chkpwd    unlink         unshare        unxz           
uname          unicode_start  uniq           unix2mac       unix_update    unset          until          
[root@mcwk8s-node1 ~]$ umount /root/mcw/
[root@mcwk8s-node1 ~]$ df -h|grep pv1
10.0.0.4:/nfsdata/pv1     19G  3.9G   15G  22% /var/lib/kubelet/pods/d1ba5034-28ad-4898-a7aa-3551bc330a4b/volumes/kubernetes.io~nfs/mypv1
[root@mcwk8s-node1 ~]$ ls /var/lib/kubelet/pods/d1ba5034-28ad-4898-a7aa-3551bc330a4b/volumes/kubernetes.io~nfs/mypv1
mcw.txt  test.txt

回收PV

会删除nfs数据的回收pv

[machangwei@mcwk8s-master ~]$ kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc1   Bound    mypv1    1Gi        RWO            nfs            3h31m
[machangwei@mcwk8s-master ~]$ kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Bound    default/mypvc1   nfs                     3h33m
[machangwei@mcwk8s-master ~]$ kubectl delete pvc mypvc1 #删除pvc失败,pvc状态也变成终止,而不是绑定
persistentvolumeclaim "mypvc1" deleted

^C
[machangwei@mcwk8s-master ~]$ kubectl delete pvc mypvc1
persistentvolumeclaim "mypvc1" deleted
^C
[machangwei@mcwk8s-master ~]$ 
[machangwei@mcwk8s-master ~]$ kubectl get pod  #删除pod,再删除pvc,pvc成功删除,网上说是删除pod,再删pvc,pv,应该就是这个顺序吧
NAME     READY   STATUS    RESTARTS   AGE
mypod1   1/1     Running   0          3h28m
[machangwei@mcwk8s-master ~]$ kubectl delete pod mypod1
pod "mypod1" deleted
[machangwei@mcwk8s-master ~]$ kubectl get pvc
No resources found in default namespace.
[machangwei@mcwk8s-master ~]$ kubectl get pod  #删除pvc的时候创建了回收pv的容器
NAME                 READY   STATUS              RESTARTS   AGE
recycler-for-mypv1   0/1     ContainerCreating   0          33s
[machangwei@mcwk8s-master ~]$ kubectl get pv  #状态现在是空闲,pv可以重新被其它pvc声明绑定。在删除pvc的过程中应该是被释放的状态,那时是不能被其它pvc绑定
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Available           nfs                     3h41m
[machangwei@mcwk8s-master ~]$ 
[machangwei@mcwk8s-master ~]$ ls /nfsdata/pv1/  #删除pvc后,pv虽然空闲了,但是pv对应的
[machangwei@mcwk8s-master ~]$ #nfs服务器存储数据都被删除了。这是回收策略决定的,所以当我们要
[machangwei@mcwk8s-master ~]$ #删除pvc时,一定要知道pv使用的什么回收策略,防止本来不想删除pv数据的,但是被删掉的情况发生
[machangwei@mcwk8s-master ~]$ #删除pvc,但是不删除外部存储nfs上的数据,得用Retain的回收策略

不会删除nfs服务端数据的回收pv

[machangwei@mcwk8s-master ~]$ cat nfs-pvc1.yml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mypvc1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs
[machangwei@mcwk8s-master ~]$ cat nfs-pv1.yml  #将pv的回收策略修改为Retain,这样删除pvc就不会删除掉nfs服务端数据了
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv1
    server: 10.0.0.4
[machangwei@mcwk8s-master ~]$ 
[machangwei@mcwk8s-master ~]$ 
[machangwei@mcwk8s-master ~]$ kubectl apply -f nfs-pv1.yml 
persistentvolume/mypv1 configured
[machangwei@mcwk8s-master ~]$ kubectl get pv  #查看可知,现在回收策略已经修改了
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Retain           Available           nfs                     3h56m
[machangwei@mcwk8s-master ~]$ kubectl apply -f nfs-pvc1.yml 

persistentvolumeclaim/mypvc1 created
[machangwei@mcwk8s-master ~]$ 
[machangwei@mcwk8s-master ~]$ kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc1   Bound    mypv1    1Gi        RWO            nfs            10s
[machangwei@mcwk8s-master ~]$ cat pod1.yml 
kind: Pod
apiVersion: v1
metadata:
  name: mypod1
spec:
  containers:
    - name: mypod1
      image: busybox
      args:
      - /bin/sh
      - -c
      - sleep 30000
      volumeMounts:
      - mountPath: "/mydata"
        name: mydata
  volumes:
    - name: mydata
      persistentVolumeClaim:
        claimName: mypvc1
[machangwei@mcwk8s-master ~]$ kubectl apply -f pod1.yml #部署pod
pod/mypod1 created
[machangwei@mcwk8s-master ~]$ kubectl get pod -o wide  
NAME     READY   STATUS    RESTARTS   AGE     IP            NODE           NOMINATED NODE   READINESS GATES
mypod1   1/1     Running   0          3m16s   10.244.2.16   mcwk8s-node2   <none>           <none>
[machangwei@mcwk8s-master ~]$ kubectl exec mypod1 touch ls /mydata  
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[machangwei@mcwk8s-master ~]$ ls /nfsdata/pv1/  #查看nfs服务端没有数据
[machangwei@mcwk8s-master ~]$ kubectl exec mypod1 touch  /mydata/mcw.txt #执行容器名字,后接命令。这样就相当于进入容器执行命令
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[machangwei@mcwk8s-master ~]$ ls /nfsdata/pv1/  #容器中创建了文件,可以看到nfs服务端已经存在这个文件了
mcw.txt
[machangwei@mcwk8s-master ~]$ 
[machangwei@mcwk8s-master ~]$ kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc1   Bound    mypv1    1Gi        RWO            nfs            7m10s
[machangwei@mcwk8s-master ~]$ kubectl delete pvc mypvc1 #此时删除pvc,卡住很长时间不动


再开一个xshell会话,将使用pvc的pod删除掉,
[machangwei@mcwk8s-master ~]$ kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Retain           Bound    default/mypvc1   nfs                     4h5m
[machangwei@mcwk8s-master ~]$ kubectl get pod
NAME     READY   STATUS    RESTARTS   AGE
mypod1   1/1     Running   0          8m31s
[machangwei@mcwk8s-master ~]$ kubectl delete pod mypod1 #当删除掉pod后,pvc也立即删除了,pv不再是绑定状态,暂时是被释放的状态
pod "mypod1" deleted
[machangwei@mcwk8s-master ~]$ 

pod删除后,pvc也被删除了,应该是需要删除pod,才能删除掉pvc吧,目前看是这个样子。
[machangwei@mcwk8s-master ~]$ kubectl delete pvc mypvc1
persistentvolumeclaim "mypvc1" deleted
[machangwei@mcwk8s-master ~]$ kubectl get pv #删除掉pvc后,发现状态一直是被释放的,只有状态是空闲的,才能重新部署pvc使用这个pv,也就是才能被其它pvc申请
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM            STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Retain           Released   default/mypvc1   nfs                     4h7m
[machangwei@mcwk8s-master ~]$ ls /nfsdata/pv1/  #查看到即使删除了pvc,但是外部存储数据nfs服务端的数据还是存在的。
mcw.txt
[machangwei@mcwk8s-master ~]$

让pv中的数据重新被使用

[machangwei@mcwk8s-master ~]$ #retain回收策略,被释放的状态,对应的pvc不存在了,
[machangwei@mcwk8s-master ~]$ kubectl get pv  #pv下面的数据还想被重新使用,
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM            STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Retain           Released   default/mypvc1   nfs                     4h16m
[machangwei@mcwk8s-master ~]$ kubectl get pvc
No resources found in default namespace.
[machangwei@mcwk8s-master ~]$ kubectl delete pv mypv1  #那么需要删除pv,

persistentvolume "mypv1" deleted
[machangwei@mcwk8s-master ~]$ 
[machangwei@mcwk8s-master ~]$ ls /nfsdata/pv1/  #这种情况的pv删除是不会将外部数据删除掉的
mcw.txt
[machangwei@mcwk8s-master ~]$ kubectl apply -f nfs-pv1.yml  #然后重新部署pv,pvc,pod
persistentvolume/mypv1 created
[machangwei@mcwk8s-master ~]$ kubectl get pv   #重新部署了pv,pv空闲可被pvc声明使用
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Retain           Available           nfs                     12s
[machangwei@mcwk8s-master ~]$ kubectl apply -f nfs-pvc1.yml 
persistentvolumeclaim/mypvc1 created
[machangwei@mcwk8s-master ~]$ kubectl apply -f pod1.yml 
pod/mypod1 created
[machangwei@mcwk8s-master ~]$ kubectl get pod 
NAME     READY   STATUS    RESTARTS   AGE
mypod1   1/1     Running   0          4m26s
[machangwei@mcwk8s-master ~]$ kubectl exec mypod1 ls /mydata  #然后发现pod下容器重新使用这个数据了。也就是这种情况下数据是能保留下来的
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
mcw.txt
[machangwei@mcwk8s-master ~]$ ls /nfsdata/pv1/
mcw.txt
[machangwei@mcwk8s-master ~]$ 

PV动态供给

 AWS EBS 支持pv动态供给,以后补充

https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner

mysql数据库持久化逻辑卷使用案例(nfs)

查看部署配置文件

[machangwei@mcwk8s-master ~]$ cat mysql-pv.yml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 1Gi
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfsdata/mysql-pv
    server: 10.0.0.4
[machangwei@mcwk8s-master ~]$ cat mysql-pvc.yml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs
[machangwei@mcwk8s-master ~]$ cat mysql.yml 
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
  - port: 3306
  selector:
    app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pvc   
[machangwei@mcwk8s-master ~]$ 

详解配置文件

[machangwei@mcwk8s-master ~]$ cat mysql-pv.yml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 1Gi
  persistentVolumeReclaimPolicy: Retain  #使用Reatin回收策略,即使删除pv,pvc,数据也不清除
  storageClassName: nfs
  nfs:
    path: /nfsdata/mysql-pv
    server: 10.0.0.4
[machangwei@mcwk8s-master ~]$ cat mysql-pvc.yml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs
[machangwei@mcwk8s-master ~]$ cat mysql.yml 
apiVersion: v1
kind: Service  #服务种类
metadata:
  name: mysql #元数据名称是服务名称
spec:  #查看规则
  ports:  #服务使用端口是什么
  - port: 3306
  selector:  #使用哪个选择器这里是使用app mysql的选择器。应该是创建app mysql 标签,后面选择器匹配的时候用把
    app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:  #选择器匹配标签带有app mysql 的
    matchLabels:
      app: mysql
  template:  #查看模板
    metadata:  元数据标签是app mysql 模板规则如下
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.6  #容器使用哪个镜像
        name: mysql    #容器的名称是什么
        env:
        - name: MYSQL_ROOT_PASSWORD  #容器内环境变量咋样,这里定义了mysql用户密码
          value: password
        ports:
        - containerPort: 3306 #端口下,容器端口用的是哪个,并且是什么名字
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage #容器逻辑卷挂载吗,和容器同级。
          mountPath: /var/lib/mysql  #容器内部挂载目录
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pvc   
[machangwei@mcwk8s-master ~]$ 

部署pv,pvc ,service,deployment

[machangwei@mcwk8s-master ~]$ kubectl apply -f  mysql-pv.yml
persistentvolume/mysql-pv unchanged
[machangwei@mcwk8s-master ~]$ kubectl apply -f  mysql-pvc.yml
persistentvolumeclaim/mysql-pvc created
[machangwei@mcwk8s-master ~]$ kubectl get pv,pvc
NAME                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
persistentvolume/mysql-pv   1Gi        RWO            Retain           Bound    default/mysql-pvc   nfs                     4m22s

NAME                              STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/mysql-pvc   Bound    mysql-pv   1Gi        RWO            nfs            11s

[machangwei@mcwk8s-master ~]$ kubectl apply -f mysql.yml 
service/mysql unchanged
deployment.apps/mysql created
[machangwei@mcwk8s-master ~]$ kubectl get service
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP    29d
mysql        ClusterIP   10.97.19.121   <none>        3306/TCP   9m22s
[machangwei@mcwk8s-master ~]$ kubectl get pod
NAME                   READY   STATUS              RESTARTS   AGE
mysql-dbffc69d-trvvb   0/1     ContainerCreating   0          8m25s

查看是卡住了,mysq-pv目录没有,挂载上又卸载不下来了
  Normal   Scheduled    8m7s                            default-scheduler  Successfully assigned default/mysql-dbffc69d-trvvb to mcwk8s-node2
  Warning  FailedMount  <invalid> (x11 over <invalid>)  kubelet            MountVolume.SetUp failed for volume "mysql-pv" : mount failed: exit status 32
Mounting command: mount
Mounting arguments: -t nfs 10.0.0.4:/nfsdata/mysql-pv /var/lib/kubelet/pods/6392d0d9-15be-4ba9-a338-61f290e6f999/volumes/kubernetes.io~nfs/mysql-pv
Output: mount.nfs: mounting 10.0.0.4:/nfsdata/mysql-pv failed, reason given by server: No such file or directory
  Warning  FailedMount  <invalid> (x3 over <invalid>)  kubelet  Unable to attach or mount volumes: unmounted volumes=[mysql-persistent-storage], unattached volumes=[mysql-persistent-storage kube-api-access-v6lfr]: timed out waiting for the condition
我删除这个pod也卡在删不掉,找到pod所在节点,然后把这个挂载上的目录,手动执行命令umount卸载掉,然后就把这pod删除了,随后生成新的pod,运行起来了
[machangwei@mcwk8s-master ~]$ kubectl delete pod mysql-dbffc69d-trvvb
pod "mysql-dbffc69d-trvvb" deleted

后面重新部署

[machangwei@mcwk8s-master ~]$ ls
mysql-pvc.yml  mysql-pv.yml  mysql.yml
[machangwei@mcwk8s-master ~]$ kubectl apply -f mysql-pv.yml 
persistentvolume/mysql-pv created
[machangwei@mcwk8s-master ~]$ kubectl apply -f mysql-pvc.yml 
persistentvolumeclaim/mysql-pvc created
[machangwei@mcwk8s-master ~]$ kubectl apply -f mysql.yml 
service/mysql created
deployment.apps/mysql created

报错
  ----     ------     ----                  ----               -------
  Normal   Scheduled  13m                   default-scheduler  Successfully assigned default/mysql-dbffc69d-292lp to mcwk8s-node2
  Normal   Pulling    13m                   kubelet            Pulling image "mysql:5.6"
  Normal   Pulled     10m                   kubelet            Successfully pulled image "mysql:5.6" in 2m17.834341538s
  Normal   Created    9m24s (x5 over 10m)   kubelet            Created container mysql
  Normal   Started    9m24s (x5 over 10m)   kubelet            Started container mysql
  Normal   Pulled     9m24s (x4 over 10m)   kubelet            Container image "mysql:5.6" already present on machine
  Warning  BackOff    3m13s (x37 over 10m)  kubelet            Back-off restarting failed container

  
  [root@mcwk8s-node2 ~]$ docker ps -a
CONTAINER ID   IMAGE          COMMAND    CREATED      STATUS                  PORTS     NAMES
75829eceaae7 dd3b2a5dcb48  "docker-entrypoint.s…" About a minute ago   Exited (1) About a minute ago  k8s_mysql_mysql-dbffc69d-292lp_default_e9825a68-47b0-471d-8280-b95bd51c4068_6

  去节点上查看MySQL容器日志,报错
  [root@mcwk8s-node2 ~]$ docker logs 758
2022-02-19 11:16:19+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.6.51-1debian9 started.
chown: changing ownership of '/var/lib/mysql/': Operation not permitted

解决方法,给nfs添加配置no_root_squash
[root@mcwk8s-master ~]$ cat /etc/exports
/nfsdata *(rw,sync)
[root@mcwk8s-master ~]$ vim /etc/exports
[root@mcwk8s-master ~]$ cat /etc/exports
/nfsdata *(rw,sync,no_root_squash)
[root@mcwk8s-master ~]$ systemctl restart nfs
[root@mcwk8s-master ~]$ showmount -e localhost
Export list for localhost:
/nfsdata *
[root@mcwk8s-master ~]$ 

进入MySQL并创建数据

[machangwei@mcwk8s-master ~]$ kubectl run -it  --rm --image=mysql:5.6 --restart=Never mysql-mcwclient -- mysql -h 10.103.171.207  -P3306 -ppassword
If you don't see a command prompt, try pressing enter.
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.03 sec)

mysql> create database mcwtest;
Query OK, 1 row affected (0.08 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mcwtest            |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.03 sec)

mysql> use mcwtest;
Database changed
mysql> create table my_id(id int(4))
    -> ;
Query OK, 0 rows affected (0.25 sec)

mysql> insert my_i values(111);
ERROR 1146 (42S02): Table 'mcwtest.my_i' doesn't exist
mysql> insert my_id values(111);
Query OK, 1 row affected (0.05 sec)

mysql> select * from my_id;
+------+
| id   |
+------+
|  111 |
+------+
1 row in set (0.00 sec)

mysql> \q
Bye
pod "mysql-mcwclient" deleted
[machangwei@mcwk8s-master ~]$ kubectl get pod -o wide
NAME                   READY   STATUS    RESTARTS   AGE   IP           NODE           NOMINATED NODE   READINESS GATES
mysql-dbffc69d-jhvvz   1/1     Running   0          27m   10.244.1.4   mcwk8s-node1   <none>           <none>
[machangwei@mcwk8s-master ~]$ 

关闭node1模拟故障

[root@mcwk8s-node1 ~]$ shutdown now

Connection closed by foreign host.

Disconnected from remote host(mcw05) at 20:19:00.

Type `help' to learn how to use Xshell prompt.
[c:\~]$ 

验证服务故障转移

 

[machangwei@mcwk8s-master ~]$ kubectl get pod -o wide
NAME                   READY   STATUS    RESTARTS   AGE   IP           NODE           NOMINATED NODE   READINESS GATES
mysql-dbffc69d-jhvvz   1/1     Running   0          38m   10.244.1.4   mcwk8s-node1   <none>           <none>
[machangwei@mcwk8s-master ~]$ kubectl describe pod mysql-dbffc69d-jhvvz
.....
Warning  NodeNotReady            111s               node-controller    Node is not ready

  Warning  NodeNotReady            5m29s              node-controller    Node is not ready
[machangwei@mcwk8s-master ~]$ 当发现节点5分钟左右没准备好的时候,就开始运行新的pod,并部署mysql服务的pod在可用节点上。
[machangwei@mcwk8s-master ~]$ kubectl get pod -o wide
NAME                   READY   STATUS        RESTARTS   AGE    IP            NODE           NOMINATED NODE   READINESS GATES
mysql-dbffc69d-ch2vg   1/1     Running       0          2m9s   10.244.2.18   mcwk8s-node2   <none>           <none>
mysql-dbffc69d-jhvvz   1/1     Terminating   0          43m    10.244.1.4    mcwk8s-node1   <none>           <none>
[machangwei@mcwk8s-master ~]$ #还是用之前的命令来连接。--后面应该是连接命令吧。-h指定集群服务ip,指定端口和密码
[machangwei@mcwk8s-master ~]$ kubectl get service  #--rm是退出后就删的pod.
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP    29d
mysql        ClusterIP   10.103.171.207   <none>        3306/TCP   79m
[machangwei@mcwk8s-master ~]$ kubectl run -it  --rm --image=mysql:5.6 --restart=Never mysql-mcwclient -- mysql -h 10.103.171.207  -P3306 -ppassword
If you don't see a command prompt, try pressing enter. #当我们要进入MySQL命令行,需要按enter。不用一直等待,因为等着没用

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mcwtest            |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.02 sec)

mysql> use mcwtest;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------+
| Tables_in_mcwtest |
+-------------------+
| my_id             |
+-------------------+
1 row in set (0.01 sec)

mysql> select * from my_id;
+------+
| id   |
+------+
|  111 |
+------+
1 row in set (0.02 sec)

mysql> \q
Bye
pod "mysql-mcwclient" deleted

到root下查看数据库的数据存放地址,也就是nfs服务端上。我们设置了即使删除pv,pvc也是不删除数据的。如上可知,当数据库所在主机down之后,那么过一段时间,会重新从其它节点上运行新的pod,旧的pod还存在,只是状态是终止。
[root@mcwk8s-master ~]$
[root@mcwk8s-master ~]$ ls /nfsdata/mysql-pv/
auto.cnf  ibdata1  ib_logfile0  ib_logfile1  mcwtest  mysql  performance_schema
[root@mcwk8s-master ~]$ ls /nfsdata/mysql-pv/mcwtest/
db.opt  my_id.frm  my_id.ibd
[root@mcwk8s-master ~]$ ls /nfsdata/mysql-pv/mcwtest/ -lh
total 112K
-rw-rw----. 1 polkitd ssh_keys   65 Feb 19 20:08 db.opt
-rw-rw----. 1 polkitd ssh_keys 8.4K Feb 19 20:09 my_id.frm
-rw-rw----. 1 polkitd ssh_keys  96K Feb 19 20:09 my_id.ibd
[root@mcwk8s-master ~]$ ls /nfsdata/mysql-pv/ -lh
total 109M
-rw-rw----. 1 polkitd ssh_keys   56 Feb 19 19:23 auto.cnf
-rw-rw----. 1 polkitd ssh_keys  12M Feb 19 20:24 ibdata1
-rw-rw----. 1 polkitd ssh_keys  48M Feb 19 20:24 ib_logfile0
-rw-rw----. 1 polkitd ssh_keys  48M Feb 19 19:21 ib_logfile1
drwx------. 2 polkitd ssh_keys   54 Feb 19 20:09 mcwtest
drwx------. 2 polkitd ssh_keys 4.0K Feb 19 19:25 mysql
drwx------. 2 polkitd ssh_keys 4.0K Feb 19 19:21 performance_schema

删除资源

[machangwei@mcwk8s-master ~]$ kubectl get deployment
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
mysql   1/1     1            1           19h
[machangwei@mcwk8s-master ~]$ ls
mysql-pvc.yml  mysql-pv.yml  mysql.yml
[machangwei@mcwk8s-master ~]$ kubectl delete -f mysql.yml 
service "mysql" deleted
deployment.apps "mysql" deleted
[machangwei@mcwk8s-master ~]$ kubectl delete -f mysql-pvc.yml
persistentvolumeclaim "mysql-pvc" deleted
[machangwei@mcwk8s-master ~]$ kubectl delete -f mysql-pv.yml
persistentvolume "mysql-pv" deleted
[machangwei@mcwk8s-master ~]$ ls /nfsdata/mysql-pv/
auto.cnf  ibdata1  ib_logfile0  ib_logfile1  mcwtest  mysql  performance_schema

 

 

参考学习书籍:每天5分钟玩转kubernetes  ---cloudman

 

posted @ 2022-02-19 20:50  马昌伟  阅读(379)  评论(0编辑  收藏  举报
博主链接地址:https://www.cnblogs.com/machangwei-8/