在 Kubernetes 中,我可以同时部署只读文件和可写文件吗?
In Kubernetes, can I have a deployment with both read only and writable files?
我目前正在 运行 从数据库中提取并设置为只读的部署。不幸的是,部署在没有通知的情况下因合作而冻结,所以我想出了将代码写入日志文件并让 liveness 探测器检查文件是否最新的想法。
这已经过测试并且效果很好,但是,问题是越过了只读部分。如您所知,我无法在只读模式下创建或写入文件,因此当我的代码尝试这样做时,我会收到权限被拒绝的错误并且部署结束。我想我可以通过在容器中包含两个文件路径并使用来解决这个问题:
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
如能解释您看到的解决方案或错误,我们将不胜感激。谢谢!
allowedHostPaths
与 hostPath 卷挂载相关(也称为主机系统文件夹中的绑定挂载)。与容器图像内的东西无关。你可能想要的是 readOnlyRootFilesystem: true
就像你现在拥有的那样加上一个 emptyDir 卷安装在 /code/logs
设置为可由容器的用户写入。
我目前正在 运行 从数据库中提取并设置为只读的部署。不幸的是,部署在没有通知的情况下因合作而冻结,所以我想出了将代码写入日志文件并让 liveness 探测器检查文件是否最新的想法。
这已经过测试并且效果很好,但是,问题是越过了只读部分。如您所知,我无法在只读模式下创建或写入文件,因此当我的代码尝试这样做时,我会收到权限被拒绝的错误并且部署结束。我想我可以通过在容器中包含两个文件路径并使用来解决这个问题:
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
如能解释您看到的解决方案或错误,我们将不胜感激。谢谢!
allowedHostPaths
与 hostPath 卷挂载相关(也称为主机系统文件夹中的绑定挂载)。与容器图像内的东西无关。你可能想要的是 readOnlyRootFilesystem: true
就像你现在拥有的那样加上一个 emptyDir 卷安装在 /code/logs
设置为可由容器的用户写入。