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

相关文章

Python使用Pandas对比两列数据取最大值的五种方法

《Python使用Pandas对比两列数据取最大值的五种方法》本文主要介绍使用Pandas对比两列数据取最大值的五种方法,包括使用max方法、apply方法结合lambda函数、函数、clip方法、w... 目录引言一、使用max方法二、使用apply方法结合lambda函数三、使用np.maximum函数

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本