OpenShift:以非 root 身份访问挂载的文件系统

OpenShift: Accessing mounted file-system as non-root

我正在尝试 运行 Chart Museum 作为 OpenShift 中的非根用户。这是我的 YAML 的快照。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: chart-museum
  namespace: demo
spec:
  selector:
    matchLabels:
      app: chart-museum
  replicas: 1
  template:
    metadata:
      labels:
        app: chart-museum
    spec:
      volumes:
        - name: pvc-charts
          persistentVolumeClaim:
            claimName: pvc-charts      
      containers:
        - name: chart-museum
          securityContext:
            fsGroup: 1000
          image: chartmuseum/chartmuseum:latest
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef:
                name: chart-museum
          volumeMounts:
            - name: pvc-charts
              mountPath: "/charts"

如您所见,我已将spec.containers.securityContext.fsGroup设置为1000,这与图表博物馆Dockerfile中的用户ID相同,如下所示。

FROM alpine:3.10.3
RUN apk add --no-cache cifs-utils ca-certificates \
    && adduser -D -u 1000 chartmuseum
COPY bin/linux/amd64/chartmuseum /chartmuseum
USER 1000
ENTRYPOINT ["/chartmuseum"]

然而,当我尝试 upload a chart 时,我收到 /charts 的权限被拒绝消息。我该如何解决这个问题?

它与 Kubernetes 以及给定持久卷的定义方式有关。您可以在 related GH Issue.

中查看所有讨论和可能的解决方法

在您的 dockerfile 中添加 chmod/chown 行:

FROM alpine:3.10.3
RUN apk add --no-cache cifs-utils ca-certificates \
    && adduser -D -u 1000 chartmuseum
COPY bin/linux/amd64/chartmuseum /chartmuseum
RUN chmod +xr /chartmuseum
RUN chown 1000:1000 /chartmuseum
USER 1000
ENTRYPOINT ["/chartmuseum"]

修改您的 spec.template.spec.containers.securityContext 以确保用户和组将被强制执行。

      containers:
        - name: chart-museum
          securityContext:
            runAsUser: 1000
            runAsGroup: 1000
            fsGroup: 1000

这就是我解决问题的方法。

  1. 下载二进制文件 curl -LO https://s3.amazonaws.com/chartmuseum/release/latest/bin/linux/amd64/chartmuseum
  2. 更改权限chmod +xr chartmuseum
  3. 创建一个新的 Dockerfile,如下所示。基本上,对 chown 命令使用用户名而不是 ID,这样二进制文件和存储位置归 chartmuseum 用户所有,而不是 root.
FROM alpine:3.10.3
RUN apk add --no-cache cifs-utils ca-certificates \
    && adduser -D -u 1000 chartmuseum
COPY chartmuseum /chartmuseum
RUN chown chartmuseum:chartmuseum /chartmuseum
RUN chown chartmuseum:chartmuseum /charts
USER chartmuseum
ENTRYPOINT ["/chartmuseum"]
  1. 构建并将生成的 Docker 图像推送到例如somerepo/chartmuseum:0.0.0.
  2. 使用如下所示的 k8s 清单。根据需要编辑命名空间。 注意PersistentVolumeClaim的创建不在此处介绍。
kind: ConfigMap
apiVersion: v1
metadata:
  name: chart-museum
  namespace: demo
data:
  DEBUG: 'true'
  STORAGE: local
  STORAGE_LOCAL_ROOTDIR: "/charts"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: chart-museum
  namespace: demo
spec:
  selector:
    matchLabels:
      app: chart-museum
  replicas: 1
  template:
    metadata:
      labels:
        app: chart-museum
    spec:
      volumes:
        - name: pvc-charts
          persistentVolumeClaim:
              claimName: pvc-charts
      containers:
        - name: chart-museum
          image: somerepo/chartmuseum:0.0.0
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef:
                name: chart-museum
          volumeMounts:
            - mountPath: "/charts"
              name: pvc-charts
          resources:
            limits:
              memory: "128Mi"
              cpu: "500m"
      imagePullSecrets:
        - name: us.icr.io.secret
---              
apiVersion: v1
kind: Service
metadata:
  labels:
    app: chart-museum
  name: chart-museum
  namespace: demo
spec:
  type: ClusterIP
  ports:
    - name: 8080-tcp
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: chart-museum
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  labels:
    app: chart-museum
  name: chart-museum
  namespace: demo
spec:
  port:
    targetPort: 8080-tcp
  tls:
    insecureEdgeTerminationPolicy: Redirect
    termination: edge
  to:
    kind: Service
    name: chart-museum

清单创建一个 ConfigMap 对象并使用 PersistentVolumeClaim 到 'replicate' 命令到 运行 本地图表博物馆(如 https://chartmuseum.com/ 所述)

 docker run --rm -it \
  -p 8080:8080 \
  -v $(pwd)/charts:/charts \
  -e DEBUG=true \
  -e STORAGE=local \
  -e STORAGE_LOCAL_ROOTDIR=/charts \
  chartmuseum/chartmuseum:latest

清单中的 ServiceRoute 将存储库暴露给外部世界。

  1. 创建对象后,在oc get route/chart-museum -n demo中输入HOST/PORT值,在地址栏中输入https并回车。您应该会看到图表博物馆的欢迎页面。这意味着安装成功。