k8s - Volume 简介和HostPath的使用

2024-09-02 12:36

本文主要是介绍k8s - Volume 简介和HostPath的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

K8S 的持久化

K8S 实现持久化存储的方法有很多种
例如 卷 (Volume), 持久卷(PV), 临时卷(EV) 等, 还有很多不常用的选项上图没有列出来

其中Volume 本身也分很多种
包括

Secret, configMap(之前的文章covered了), hostPath, emptyDir等
本文主要focus on hostPath



HostPath 的简介

官方定义:
hostPath 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用提供了强大的逃生舱。

简单来讲就是让k8s node 的目录or 文件map在你的POD 容器里
至于为什么上面提到的逃生舱, 是因为假如你的POD 崩溃了or 被shutdown, 我们仍然可以在node对应的path上找到我们想要的数据(前提是把相应的数据output 到hostpath)

但是 官方并不推荐使用hostpath 把数据输出到node上
建议用local PersisentVolume代替, 主要是安全风险的原因

原因:
如果你通过准入时的验证来限制对节点上特定目录的访问,这种限制只有在你额外要求所有 hostPath 卷的挂载都是只读的情况下才有效。如果你允许不受信任的 Pod 以读写方式挂载任意主机路径, 则该 Pod 中的容器可能会破坏可读写主机挂载卷的安全性。

无论 hostPath 卷是以只读还是读写方式挂载,使用时都需要小心,这是因为:

  1. 访问主机文件系统可能会暴露特权系统凭证(例如 kubelet 的凭证)或特权 API(例如容器运行时套接字), 这些可以被用于容器逃逸或攻击集群的其他部分。
  2. 具有相同配置的 Pod(例如基于 PodTemplate 创建的 Pod)可能会由于节点上的文件不同而在不同节点上表现出不同的行为。
  3. hostPath 卷的用量不会被视为临时存储用量。 你需要自己监控磁盘使用情况,因为过多的 hostPath 磁盘使用量会导致节点上的磁盘压力。



HostPath 的类型

除了必需的 path 属性外,你还可以选择为 hostPath 卷指定 type。

valuedesc
“”空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
DirectoryOrCreate如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
Directory在给定路径上必须存在的目录。
FileOrCreate如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
File在给定路径上必须存在的文件。
Socket在给定路径上必须存在的 UNIX 套接字。
CharDevice(仅 Linux Node) 在给定路径上必须存在的字符设备。
BlockDevice(仅 Linux Node) 在给定路径上必须存在的块设备。



例子

这个例子是测试多个pod同时往1个hostpath 写日志


添加filter 让其可以输出api 调用日志

我们先为springboot cloud-order service 增加1个filter

@Component
@WebFilter
@Order(1)
@Slf4j
public class InfoFilter implements Filter {@Autowiredprivate String hostname;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// Initialization code}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) request;// Log the request informationlog.info("API of hostname: {} has been called, Request Method: {}, Request URI: {}, Requested from : {}",  hostname, httpRequest.getMethod(), httpRequest.getRequestURI(), httpRequest.getRemoteAddr());// You can log more information as needed// Call the next filter in the chainchain.doFilter(request, response);}@Overridepublic void destroy() {// Cleanup code}
}



为k8s-node1 加上label

这个例子测试 多个POD 同时为1个hostpath 写日志
所以为了方便测试, 需要把所有PODs 都部署在同1个node上。

所以我们要为k8s-node1 加上label

gateman@MoreFine-S500:/app/logs$ kubectl label nodes k8s-node1 cloud-order=enabled
node/k8s-node1 labeled
gateman@MoreFine-S500:/app/logs$ kubectl get nodes --show-labels
NAME         STATUS   ROLES                  AGE    VERSION   LABELS
k8s-master   Ready    control-plane,master   190d   v1.23.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ingress=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
k8s-node0    Ready    <none>                 190d   v1.23.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ingress=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node0,kubernetes.io/os=linux
k8s-node1    Ready    <none>                 190d   v1.23.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,cloud-order=enabled,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux
k8s-node3    Ready    <none>                 169d   v1.23.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node3,kubernetes.io/os=linux

可以见到, cloud-order=enabled 这个label 已经加上到了k8s-node1



在k8s-node1 提前创建1个folder

这个例子用的类型是Directory

当然如果用DirectoryOrCreate 是可以skip 这个步骤

gateman@MoreFine-S500:~/projects/coding/k8s-s/service-case/cloud-order$ gcloud compute ssh k8s-node1
WARNING: This command is using service account impersonation. All API calls will be executed as [terraform@jason-hsbc.iam.gserviceaccount.com].
WARNING: This command is using service account impersonation. All API calls will be executed as [terraform@jason-hsbc.iam.gserviceaccount.com].
No zone specified. Using zone [europe-west2-c] for instance: [k8s-node1].
External IP address was not found; defaulting to using IAP tunneling.
WARNING: To increase the performance of the tunnel, consider installing NumPy. For instructions,
please see https://cloud.google.com/iap/docs/using-tcp-forwarding#increasing_the_tcp_upload_bandwidthWARNING: This command is using service account impersonation. All API calls will be executed as [terraform@jason-hsbc.iam.gserviceaccount.com].
Warning: Permanently added 'compute.7230880099421476498' (ED25519) to the list of known hosts.
Linux k8s-node1 5.10.0-32-cloud-amd64 #1 SMP Debian 5.10.223-1 (2024-08-10) x86_64The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Mar  9 19:39:42 2024 from 192.168.0.35
gateman@k8s-node1:~$ sudo su -
root@k8s-node1:~# mkdir /k8s-shared
root@k8s-node1:~# cd /k8s-shared/
root@k8s-node1:/k8s-shared# ls
root@k8s-node1:/k8s-shared# mkdir logs
root@k8s-node1:/k8s-shared# ls
logs



编写deployment yaml

deployment-cloud-order-hostpath.yaml

apiVersion: apps/v1
kind: Deployment
metadata:labels: # label of this deploymentapp: cloud-order # custom definedauthor: nvd11name: deployment-cloud-order # name of this deploymentnamespace: default
spec:replicas: 3            # desired replica count, Please note that the replica Pods in a Deployment are typically distributed across multiple nodes.revisionHistoryLimit: 10 # The number of old ReplicaSets to retain to allow rollbackselector: # label of the Pod that the Deployment is managing,, it's mandatory, without it , we will get this error # error: error validating data: ValidationError(Deployment.spec.selector): missing required field "matchLabels" in io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector ..matchLabels:app: cloud-orderstrategy: # Strategy of upodatetype: RollingUpdate # RollingUpdate or RecreaterollingUpdate:maxSurge: 25% # The maximum number of Pods that can be created over the desired number of Pods during the updatemaxUnavailable: 25% # The maximum number of Pods that can be unavailable during the updatetemplate: # Pod templatemetadata:labels:app: cloud-order # label of the Pod that the Deployment is managing. must match the selector, otherwise, will get the error Invalid value: map[string]string{"app":"bq-api-xxx"}: `selector` does not match template `labels`spec: # specification of the Podcontainers:- image: europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/cloud-order:1.1.0 # image of the containerimagePullPolicy: Alwaysname: container-cloud-ordercommand: ["bash"]args: - "-c"- |java -jar -Dserver.port=8080 app.jar --spring.profiles.active=$APP_ENVIRONMENT --logging.file.name=/app/logs/cloud-order.logenv: # set env varaibles- name: APP_ENVIRONMENT # name of the environment variablevalue: prod # value of the environment variablevolumeMounts:- name: volume-logmountPath: /app/logs/readOnly: false # read only is set to falseports:- containerPort: 8080name: cloud-ordernodeSelector:cloud-order: enabledvolumes:- name: volume-loghostPath:path: /k8s-shared/logs # the path on the host (k8s node)type: DirectoryrestartPolicy: Always # Restart policy for all containers within the PodterminationGracePeriodSeconds: 10 # The period of time in seconds given to the Pod to terminate gracefully

注意几点,

  1. 启动命令加上 --logging.file.name=/app/logs/cloud-order.log 让日志输出到指定位置
  2. 加上volume-log 这个hostpath, 映射的主机路径是 /k8s-shared/logs
  3. volumemount 那里把 volume-log mount在了 /app/logs
  4. 使用nodeSelector 让pods 都部署在1个node



部署

gateman@MoreFine-S500:~/projects/coding/k8s-s/service-case/cloud-order/volumes$ kubectl delete deployment deployment-cloud-order
deployment.apps "deployment-cloud-order" deleted
gateman@MoreFine-S500:~/projects/coding/k8s-s/service-case/cloud-order/volumes$ kubectl apply -f deployment-cloud-order-hostpath.yaml 
deployment.apps/deployment-cloud-order created
gateman@MoreFine-S500:~/projects/coding/k8s-s/service-case/cloud-order/volumes$ kubectl get pods
NAME                                         READY   STATUS      RESTARTS       AGE
deployment-bq-api-service-6f6ffc7866-8djx9   1/1     Running     3 (13d ago)    18d
deployment-bq-api-service-6f6ffc7866-g4854   1/1     Running     12 (13d ago)   61d
deployment-bq-api-service-6f6ffc7866-lwxt7   1/1     Running     14 (13d ago)   64d
deployment-bq-api-service-6f6ffc7866-mxwcq   1/1     Running     11 (13d ago)   61d
deployment-cloud-order-ff4989c97-h8ktj       1/1     Running     0              7s
deployment-cloud-order-ff4989c97-xg2x2       1/1     Running     0              7s
deployment-cloud-order-ff4989c97-zc2dq       1/1     Running     0              7s



测试

多次调用cloud-order的某个api

curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info
curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info
curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info
curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info
curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info

进入k8s-node1 查看相应的日志文件:

root@k8s-node1:/k8s-shared/logs# tail -f cloud-order.log...
2024-09-01T14:28:14.298Z  INFO 1 --- [http-nio-8080-exec-1] com.home.clouduser.filter.InfoFilter     : API of hostname: deployment-cloud-order-ff4989c97-h8ktj has been called, Request Method: GET, Request URI: /actuator/info, Requested from : 192.168.0.35
2024-09-01T14:28:15.384Z  INFO 1 --- [http-nio-8080-exec-2] com.home.clouduser.filter.InfoFilter     : API of hostname: deployment-cloud-order-ff4989c97-h8ktj has been called, Request Method: GET, Request URI: /actuator/info, Requested from : 192.168.0.35
2024-09-01T14:28:15.856Z  INFO 1 --- [http-nio-8080-exec-2] com.home.clouduser.filter.InfoFilter     : API of hostname: deployment-cloud-order-ff4989c97-zc2dq has been called, Request Method: GET, Request URI: /actuator/info, Requested from : 192.168.0.35
2024-09-01T14:28:17.211Z  INFO 1 --- [http-nio-8080-exec-3] com.home.clouduser.filter.InfoFilter     : API of hostname: deployment-cloud-order-ff4989c97-h8ktj has been called, Request Method: GET, Request URI: /actuator/info, Requested from : 192.168.0.35
2024-09-01T14:28:18.183Z  INFO 1 --- [http-nio-8080-exec-4] com.home.clouduser.filter.InfoFilter     : API of hostname: deployment-cloud-order-ff4989c97-h8ktj has been called, Request Method: GET, Request URI: /actuator/info, Requested from : 192.168.0.35
2024-09-01T14:28:19.128Z  INFO 1 --- [http-nio-8080-exec-2] com.home.clouduser.filter.InfoFilter     : API of hostname: deployment-cloud-order-ff4989c97-xg2x2 has been called, Request Method: GET, Request URI: /actuator/info, Requested from : 192.168.0.35

可以见到 , 由于loadbalancer 的关系, 多个pods轮流被调用, 但是都可以写进同1个hostpath内的日志文件

所以如果用append 方式(例如写日子) 多个pod 写同1个host path 是不会由文件冲突问题的!

这篇关于k8s - Volume 简介和HostPath的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1129973

相关文章

Mysql中RelayLog中继日志的使用

《Mysql中RelayLog中继日志的使用》MySQLRelayLog中继日志是主从复制架构中的核心组件,负责将从主库获取的Binlog事件暂存并应用到从库,本文就来详细的介绍一下RelayLog中... 目录一、什么是 Relay Log(中继日志)二、Relay Log 的工作流程三、Relay Lo

使用Redis实现会话管理的示例代码

《使用Redis实现会话管理的示例代码》文章介绍了如何使用Redis实现会话管理,包括会话的创建、读取、更新和删除操作,通过设置会话超时时间并重置,可以确保会话在用户持续活动期间不会过期,此外,展示了... 目录1. 会话管理的基本概念2. 使用Redis实现会话管理2.1 引入依赖2.2 会话管理基本操作

Springboot请求和响应相关注解及使用场景分析

《Springboot请求和响应相关注解及使用场景分析》本文介绍了SpringBoot中用于处理HTTP请求和构建HTTP响应的常用注解,包括@RequestMapping、@RequestParam... 目录1. 请求处理注解@RequestMapping@GetMapping, @PostMappin

springboot3.x使用@NacosValue无法获取配置信息的解决过程

《springboot3.x使用@NacosValue无法获取配置信息的解决过程》在SpringBoot3.x中升级Nacos依赖后,使用@NacosValue无法动态获取配置,通过引入SpringC... 目录一、python问题描述二、解决方案总结一、问题描述springboot从2android.x

SpringBoot整合AOP及使用案例实战

《SpringBoot整合AOP及使用案例实战》本文详细介绍了SpringAOP中的切入点表达式,重点讲解了execution表达式的语法和用法,通过案例实战,展示了AOP的基本使用、结合自定义注解以... 目录一、 引入依赖二、切入点表达式详解三、案例实战1. AOP基本使用2. AOP结合自定义注解3.

Python中Request的安装以及简单的使用方法图文教程

《Python中Request的安装以及简单的使用方法图文教程》python里的request库经常被用于进行网络爬虫,想要学习网络爬虫的同学必须得安装request这个第三方库,:本文主要介绍P... 目录1.Requests 安装cmd 窗口安装为pycharm安装在pycharm设置中为项目安装req

使用Python将PDF表格自动提取并写入Word文档表格

《使用Python将PDF表格自动提取并写入Word文档表格》在实际办公与数据处理场景中,PDF文件里的表格往往无法直接复制到Word中,本文将介绍如何使用Python从PDF文件中提取表格数据,并将... 目录引言1. 加载 PDF 文件并准备 Word 文档2. 提取 PDF 表格并创建 Word 表格

使用Python实现局域网远程监控电脑屏幕的方法

《使用Python实现局域网远程监控电脑屏幕的方法》文章介绍了两种使用Python在局域网内实现远程监控电脑屏幕的方法,方法一使用mss和socket,方法二使用PyAutoGUI和Flask,每种方... 目录方法一:使用mss和socket实现屏幕共享服务端(被监控端)客户端(监控端)方法二:使用PyA

Python使用Matplotlib和Seaborn绘制常用图表的技巧

《Python使用Matplotlib和Seaborn绘制常用图表的技巧》Python作为数据科学领域的明星语言,拥有强大且丰富的可视化库,其中最著名的莫过于Matplotlib和Seaborn,本篇... 目录1. 引言:数据可视化的力量2. 前置知识与环境准备2.1. 必备知识2.2. 安装所需库2.3

Python数据验证神器Pydantic库的使用和实践中的避坑指南

《Python数据验证神器Pydantic库的使用和实践中的避坑指南》Pydantic是一个用于数据验证和设置的库,可以显著简化API接口开发,文章通过一个实际案例,展示了Pydantic如何在生产环... 目录1️⃣ 崩溃时刻:当你的API接口又双叒崩了!2️⃣ 神兵天降:3行代码解决验证难题3️⃣ 深度