在 Kubernetes 中,我可以同时使用只读和可写文件进行部署吗?

Posted

技术标签:

【中文标题】在 Kubernetes 中,我可以同时使用只读和可写文件进行部署吗?【英文标题】:In Kubernetes, can I have a deployment with both read only and writable files? 【发布时间】:2021-11-11 21:29:57 【问题描述】:

我目前正在运行从数据库中提取并设置为只读的部署。不幸的是,部署在没有通知的情况下冻结了 coaction,所以我想出了将代码写入日志文件并让 liveness probe 检查文件是否是最新的想法。

这已经过测试并且效果很好,但是问题超出了只读部分。如您所知,我无法在只读模式下创建或写入文件,因此当我的代码尝试这样做时,我收到权限被拒绝错误并且部署结束。我想我可以通过在容器中包含两个文件路径并使用来解决这个问题:

allowedHostPaths:
- pathPrefix: "/code"
  readonly: true
- pathPrefix: "/code/logs"
  readonly: false

并告诉代码写入“日志”文件,但这不起作用。为什么要将我的所有代码都放在只读文件中,但还要有一个可以读取和写入的日志文件?

这是我的 Dockerfile:

FROM python:3.9.7-alpine3.14
RUN mkdir -p /code/logs
WORKDIR /code
COPY requirements.txt .
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
COPY src/ .
CMD [ "python", "code.py"]

这是我的 yaml 文件:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default'
    apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
    seccomp.security.alpha.kubernetes.io/defaultProfileName:  'runtime/default'
    apparmor.security.beta.kubernetes.io/defaultProfileName:  'runtime/default'
spec:
  privileged: false # Required to prevent escalations to root.
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes: # Allow core volume types.
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'
    - 'downwardAPI'
    - 'persistentVolumeClaim'
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
 supplementalGroups:
    rule: 'MustRunAs'
    ranges:
      - min: 1
        max: 65535
 runAsGroup:
   rule: 'MustRunAs'
   ranges:
     - min: 1
       max: 65535
 fsGroup:
   rule: 'MustRunAs'
   ranges:
     - min: 1
       max: 65535
 readOnlyRootFilesystem: true
 allowedHostPaths:
   - pathPrefix: "/code"
     readOnly: true
   - pathPrefix: "/code/logs"
     readOnly: false

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: psp:restricted 
rules:
  - apiGroups: 
    - policy
    resources: 
      - podsecuritypolicies
    verbs:
      - use
    resourceNames:
      - restricted 

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: manage-app
  namespace: default
subjects:
  - kind: User
    name: my-app-sa
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: psp:restricted
  apiGroup: rbac.authorization.k8s.io

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  selector:
    matchLabels:
      app: orbservice
  template:
    metadata:
      labels:
        app: orbservice
    spec:
      serviceAccountName: my-app-sa
      securityContext:
        runAsUser: 1000
        runAsGroup: 3000
        fsGroup: 2000
      containers:
        - name: my-app
          image: app:v0.0.1
          resources:
            limits:
              memory: "128Mi"
              cpu: "500m"
          livenessProbe:
            exec:
              command:
                - python
                - check_logs.py
            initialDelaySeconds: 60
            periodSeconds: 30
            failureThreshold: 1

我们将不胜感激您看到的解决方案或错误的解释。谢谢!

【问题讨论】:

【参考方案1】:

allowedHostPaths 与 hostPath 卷挂载有关(又名绑定挂载到主机系统的文件夹中)。与容器图像内的东西无关。您可能想要的是readOnlyRootFilesystem: true,就像您现在拥有的一样,加上一个安装在/code/logs 的emptyDir 卷,设置为容器用户可写。

【讨论】:

以上是关于在 Kubernetes 中,我可以同时使用只读和可写文件进行部署吗?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在扩展中使用非只读计算属性?

OpenStack 上 Kubernetes 中节点(minions)的水平自动缩放

同时从多个线程访问只读数据是不是明智?

给你的Kubernetes集群建一个只读账户(防止高管。。。后)

如何在 Android 设备中找到所有只读存储?

kubernetes创建一个dashboard只读权限的用户(具有exec权限)