当前位置: 首页 > article >正文

挂载本地目录到k8s的pod实现持久化存储

本地目录实现持久化存储

容器是无状态的,每次重启都是新的进程,但是我们需要将一些状态数据如配置、用户数据等存到本地来方便新的容器可以拿到历史状态。先创建一个目录来存放数据,并且挂载到minikube虚拟机内(不是pod里面)。注意要新开一个终端来调用,这个命令会阻塞,不能中断。

=> mkdir storage
=> minikube mount storage:/data

可以测试一下是否成功了

=> echo aaa > storage/test.txt
=> minikube ssh 'cat /data/test.txt'
aaa

然后创建一个持久化存储卷(PersistentVolume)的配置,挂载本机目录,注意是minikube虚拟机的目录,所以是/data

apiVersion: v1          # 版本信息
kind: PersistentVolume  # 这个是一个持久化存储卷
metadata:
  name: test-local-pv   # 元数据定义名称
spec:
  capacity:
    storage: 1Ki        # 定义容量1KB,定义不定义都一样,因为目录挂载的方式取决于原始目录的容量
  storageClassName: local                 # 定义这个为了和pvc匹配,否则会绑定不了
  persistentVolumeReclaimPolicy: Retain   # pvc被删除时,pv的回收策略,retain为保留pv,手动清理
  accessModes:
    - ReadWriteMany     # 表示该卷可以被多个节点以读写的方式挂载。这意味着多个 Pod 可以同时访问这个卷并进行读写操作。
  hostPath:
    path: /data

pv是不能直接给pod访问和挂载使用的,需要使用pvc才能给到pod使用,所以写一个pvc的配置

apiVersion: v1                # 版本
kind: PersistentVolumeClaim   # pvc类型,请求持久化存储卷
metadata:
  name: test-local-pvc
spec:
  accessModes:
    - ReadWriteMany           # 这个模式表示多个节点可以同时读写这个存储。
  resources:
    requests:
      storage: 1Ki            # 要和pv匹配,不然会无法绑定
  volumeName: test-local-pv   # 指定要绑定的pv的名字
  storageClassName: local     # 同样要和pv一致

启动pv和pvc,要看一下是否启动和绑定成功

kubectl apply -f test-pv.yaml
kubectl apply -f test-pvc.yaml

pv和pvc的绑定关系使用describe看起来会更清晰一点

=> kubectl describe pv test-local-pv
Name:            test-local-pv
Labels:          <none>
Annotations:     pv.kubernetes.io/bound-by-controller: yes
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    local
Status:          Bound
Claim:           default/test-local-pvc
Reclaim Policy:  Retain
Access Modes:    RWX
VolumeMode:      Filesystem
Capacity:        1Ki
Node Affinity:   <none>
Message:
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /data
    HostPathType:
Events:            <none>

=> kubectl describe pvc test-local-pvc
Name:          test-local-pvc
Namespace:     default
StorageClass:  local
Status:        Bound
Volume:        test-local-pv
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      1Ki
Access Modes:  RWX
VolumeMode:    Filesystem
Used By:       <none>
Events:            <none>

可以看到pv和pvc绑定成功

下面要修改一下test.go,让我们的服务端可以读取和写入存储的一个文件

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

func main() {
	fmt.Println("start main")
	hostName := os.Getenv("HOSTNAME")
  // 正常请求根目录读取这个文件返回内容
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		contentBytes, err := ioutil.ReadFile("/data/test.txt")
		outStr := ""
		if err != nil {
			outStr = err.Error()
		} else {
			outStr = string(contentBytes)
		}
		fmt.Fprintf(w, "hello, world, %s, txt: '%s'\n", hostName, outStr)
	})
  // 保存文件,取xxx:xxx/save?content=xxx来存入
	http.HandleFunc("/save", func(w http.ResponseWriter, r *http.Request) {
		r.ParseForm()
		tmp := r.Form["content"]
		inputText := ""
		if len(tmp) > 0 {
			inputText = tmp[0]
		}
		ioutil.WriteFile("/data/test.txt", []byte(inputText), 0644)
		fmt.Fprintf(w, "%s", inputText)
	})
	http.HandleFunc("/exit", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("recieve exit, bye!")
		os.Exit(0)
	})
	err := http.ListenAndServe(":7878", nil)
	if err != nil {
		panic(err)
	}
	os.Exit(0)
}

修改完重新做一个镜像加载到minikube中,然后要修改一下deployment的配置来让pod使用pvc作为存储

apiVersion: apps/v1		# 版本,虽然不知道为什么,但是要写apps/v1
kind: Deployment		# 选deployment
metadata:
  name: test-dep		# 给deployment定义名字,创建的pod会以此为前缀
spec:					# deployment的要求
  strategy:
    type: RollingUpdate	# 策略为滚动更新
    rollingUpdate:
      maxUnavailable: 1	# 最多只能停止1个pod
      maxSurge: 1		# 在更新过程中,最多可以多创建多少个 Pod,本身停止了1个,创建1个,这里设置1会停1个创建2个
  replicas: 3			# pods启动3个
  selector:				# 定义deployment管理的pod选择器
    matchLabels:		# 要跟下面的template中一样,不一样会报错
      app: test
  template:				# 定义deployment管理的pod
    metadata:
      labels:			# 定义标签,要和deployment中一样
        app: test
    spec:				# pod的定义
      volumes:  # 定义要求的存储卷
        - name: test-volume         # 起个名字给pod使用
          persistentVolumeClaim:    # 对应的pvc
            claimName: test-local-pvc
      containers:
        - name: test
          image: test-con:latest
          imagePullPolicy: Never  # 使用本地镜像,不从远端拉取
          command: ["go"]
          args: ["run", "/root/test.go"]
          volumeMounts:         # 挂载到当前容器
            - mountPath: /data  # 挂载目录
              name: test-volume # 使用的volumes,是上面定义的名字
          readinessProbe:			# 就绪探针,什么时候可以开始接收流量,不会重启pod
            httpGet:
              path: /
              port: 7878
            timeoutSeconds: 1		# 探测超时时间5s
            initialDelaySeconds: 5	# 第一次探测的等待时间
            periodSeconds: 5		# 探测周期
          livenessProbe:			# 存活探针,什么时候需要杀掉这个pod,如果启动一直失败就会杀掉pod重启一个
            httpGet:
              path: /
              port: 7878
            timeoutSeconds: 1		# 探测超时时间5s
            initialDelaySeconds: 20	# 第一次探测的等待时间
            periodSeconds: 5		# 探测周期
            failureThreshold: 10	# 错误阈值,超过这个阈值将会重启pod

生效一下这个配置文件,查看pod的pvc使用情况

kubectl apply -f test-dep.yaml

查看pvc里面更能看出来挂载情况

=> kubectl describe pvc test-local-pvc
Name:          test-local-pvc
Namespace:     default
StorageClass:  local
Status:        Bound
Volume:        test-local-pv
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      1Ki
Access Modes:  RWX
VolumeMode:    Filesystem
Used By:       test-dep-6dc4bdc5bd-7mf7w
               test-dep-6dc4bdc5bd-ftv24
               test-dep-6dc4bdc5bd-w8zxf
Events:            <none>

http://www.kler.cn/a/411837.html

相关文章:

  • AX58100+STM32使用FSMC接口,运行EtherCAT Slave协议栈
  • day18 结构体
  • IDEA无法创建java8、11项目创建出的pom.xml为空
  • Taro 鸿蒙技术内幕系列(三) - 多语言场景下的通用事件系统设计
  • Hot100 - 字母异位词分组
  • sklearn中常用数据集简介
  • [java] 什么是 Apache Felix
  • wp the_posts_pagination 与分类页面搭配使用
  • git-显示顺序与提交顺序不一致的问题
  • unity3d——基础篇2刷(Mathf练习题)
  • RabbitMQ的预取值详解
  • 泷羽sec-linux进阶
  • postman的简单使用
  • 【mac】终端左边太长处理,自定义显示名称(terminal路径显示特别长)
  • 前端小练习——星辰宇宙(JS没有上限!!!)
  • 51单片机从入门到精通:理论与实践指南(一)
  • Hadoop的MapReduce详解
  • 详细描述一下Elasticsearch更新和删除文档的过程?
  • 【Linux】Ubuntu:轻量级Xfce桌面及远程连接
  • 对比C++,Rust在内存安全上做的努力
  • shell数组 Linux分文件 make工具
  • 金铲铲S13双城之战自动拿牌助手
  • emotion2vec语音情感识别 - python 实现
  • 什么是 C++ 中的 Lambda 表达式?Lambda 表达式可以捕获哪些类型的变量?有哪些捕获方式?
  • python的交互式编程
  • 触想工业显示器应用于光伏自动化设备,助力绿色低碳能源发展