k8s - Volume 简介和HostPath的使用

打印 上一主题 下一主题

主题 781|帖子 781|积分 2343


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 卷是以只读还是读写方式挂载,使用时都必要警惕,这是因为:

  • 访问主机文件系统可能会暴露特权系统凭证(比方 kubelet 的凭证)或特权 API(比方容器运行时套接字), 这些可以被用于容器逃逸或攻击集群的其他部分。
  • 具有相同设置的 Pod(比方基于 PodTemplate 创建的 Pod)可能会由于节点上的文件不同而在不同节点上表现出不同的行为。
  • 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
  1. @Component
  2. @WebFilter
  3. @Order(1)
  4. @Slf4j
  5. public class InfoFilter implements Filter {
  6.     @Autowired
  7.     private String hostname;
  8.     @Override
  9.     public void init(FilterConfig filterConfig) throws ServletException {
  10.         // Initialization code
  11.     }
  12.     @Override
  13.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  14.         HttpServletRequest httpRequest = (HttpServletRequest) request;
  15.         // Log the request information
  16.         log.info("API of hostname: {} has been called, Request Method: {}, Request URI: {}, Requested from : {}",  hostname, httpRequest.getMethod(), httpRequest.getRequestURI(), httpRequest.getRemoteAddr());
  17.         // You can log more information as needed
  18.         // Call the next filter in the chain
  19.         chain.doFilter(request, response);
  20.     }
  21.     @Override
  22.     public void destroy() {
  23.         // Cleanup code
  24.     }
  25. }
复制代码



为k8s-node1 加上label

这个例子测试 多个POD 同时为1个hostpath 写日志
所以为了方便测试, 必要把全部PODs 都部署在同1个node上。
所以我们要为k8s-node1 加上label
  1. gateman@MoreFine-S500:/app/logs$ kubectl label nodes k8s-node1 cloud-order=enabled
  2. node/k8s-node1 labeled
  3. gateman@MoreFine-S500:/app/logs$ kubectl get nodes --show-labels
  4. NAME         STATUS   ROLES                  AGE    VERSION   LABELS
  5. 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=
  6. 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
  7. 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
  8. 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 这个步骤
  1. gateman@MoreFine-S500:~/projects/coding/k8s-s/service-case/cloud-order$ gcloud compute ssh k8s-node1
  2. WARNING: This command is using service account impersonation. All API calls will be executed as [terraform@jason-hsbc.iam.gserviceaccount.com].
  3. WARNING: This command is using service account impersonation. All API calls will be executed as [terraform@jason-hsbc.iam.gserviceaccount.com].
  4. No zone specified. Using zone [europe-west2-c] for instance: [k8s-node1].
  5. External IP address was not found; defaulting to using IAP tunneling.
  6. WARNING:
  7. To increase the performance of the tunnel, consider installing NumPy. For instructions,
  8. please see https://cloud.google.com/iap/docs/using-tcp-forwarding#increasing_the_tcp_upload_bandwidth
  9. WARNING: This command is using service account impersonation. All API calls will be executed as [terraform@jason-hsbc.iam.gserviceaccount.com].
  10. Warning: Permanently added 'compute.7230880099421476498' (ED25519) to the list of known hosts.
  11. Linux k8s-node1 5.10.0-32-cloud-amd64 #1 SMP Debian 5.10.223-1 (2024-08-10) x86_64
  12. The programs included with the Debian GNU/Linux system are free software;
  13. the exact distribution terms for each program are described in the
  14. individual files in /usr/share/doc/*/copyright.
  15. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
  16. permitted by applicable law.
  17. Last login: Sat Mar  9 19:39:42 2024 from 192.168.0.35
  18. gateman@k8s-node1:~$ sudo su -
  19. root@k8s-node1:~# mkdir /k8s-shared
  20. root@k8s-node1:~# cd /k8s-shared/
  21. root@k8s-node1:/k8s-shared# ls
  22. root@k8s-node1:/k8s-shared# mkdir logs
  23. root@k8s-node1:/k8s-shared# ls
  24. logs
复制代码



编写deployment yaml

deployment-cloud-order-hostpath.yaml
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4.   labels: # label of this deployment
  5.     app: cloud-order # custom defined
  6.     author: nvd11
  7.   name: deployment-cloud-order # name of this deployment
  8.   namespace: default
  9. spec:
  10.   replicas: 3            # desired replica count, Please note that the replica Pods in a Deployment are typically distributed across multiple nodes.
  11.   revisionHistoryLimit: 10 # The number of old ReplicaSets to retain to allow rollback
  12.   selector: # label of the Pod that the Deployment is managing,, it's mandatory, without it , we will get this error
  13.             # error: error validating data: ValidationError(Deployment.spec.selector): missing required field "matchLabels" in io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector ..
  14.     matchLabels:
  15.       app: cloud-order
  16.   strategy: # Strategy of upodate
  17.     type: RollingUpdate # RollingUpdate or Recreate
  18.     rollingUpdate:
  19.       maxSurge: 25% # The maximum number of Pods that can be created over the desired number of Pods during the update
  20.       maxUnavailable: 25% # The maximum number of Pods that can be unavailable during the update
  21.   template: # Pod template
  22.     metadata:
  23.       labels:
  24.         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`
  25.     spec: # specification of the Pod
  26.       containers:
  27.       - image: europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/cloud-order:1.1.0 # image of the container
  28.         imagePullPolicy: Always
  29.         name: container-cloud-order
  30.         command: ["bash"]
  31.         args:
  32.           - "-c"
  33.           - |
  34.             java -jar -Dserver.port=8080 app.jar --spring.profiles.active=$APP_ENVIRONMENT --logging.file.name=/app/logs/cloud-order.log
  35.         env: # set env varaibles
  36.         - name: APP_ENVIRONMENT # name of the environment variable
  37.           value: prod # value of the environment variable
  38.         volumeMounts:
  39.           - name: volume-log
  40.             mountPath: /app/logs/
  41.             readOnly: false # read only is set to false
  42.         ports:
  43.         - containerPort: 8080
  44.           name: cloud-order
  45.       nodeSelector:
  46.         cloud-order: enabled
  47.       volumes:
  48.         - name: volume-log
  49.           hostPath:
  50.             path: /k8s-shared/logs # the path on the host (k8s node)
  51.             type: Directory
  52.                                                                        
  53.             
  54.       restartPolicy: Always # Restart policy for all containers within the Pod
  55.       terminationGracePeriodSeconds: 10 # The period of time in seconds given to the Pod to terminate gracefully
复制代码
注意几点,

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



部署

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



测试

多次调用cloud-order的某个api
  1. curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info
  2. curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info
  3. curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info
  4. curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info
  5. curl http://www.jp-gcp-vms.cloud:8085/cloud-order/actuator/info
复制代码
进入k8s-node1 查察相应的日志文件:
  1. root@k8s-node1:/k8s-shared/logs# tail -f cloud-order.log
  2. ...
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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 是不会由文件冲突题目的!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

徐锦洪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表