首页 > 解决方案 > 当根文件系统为只读时,如何将证书添加到 POD/Container 的证书存储区

问题描述

我有一个.net coredockerized 并在 Kubernetes 集群 (AKS) 中运行的应用程序。

我想应用 securityContextreadOnlyRootFilesystem = true来满足要求Immutable (read-only) root filesystem should be enforced for containers

安全上下文:特权:假 readOnlyRootFilesystem:真

对于.net core app我想读取 TLS 证书并想添加到 POD/Container 的证书存储中并在启动时执行此操作,我有以下代码,

var cert = new X509Certificate2(Convert.FromBase64String(File.ReadAllText(Environment.GetEnvironmentVariable("cert_path"))));
                AddCertificate(cert, StoreName.Root);

问题是当我设置readOnlyRootFilesystem = true时,应用程序出现以下错误,

异常:System.Security.Cryptography.CryptographicException:无法将 X509 证书添加到存储区。---> System.IO.IOException: System.IO.FileSystem.CreateDirectory(String fullPath) 处的只读文件系统

这是说只读文件系统我不能添加证书。有没有办法克服这个问题?

更新

如果我设置emptyDir: {},我得到以下错误?我可以在哪里添加它?

spec.template.spec.volumes[0].csi: Forbidden: may not specify more than 1 volume type

          volumeMounts:
        - name: secrets-store
          mountPath: /app/certs
      securityContext:
        privileged: false
        readOnlyRootFilesystem: true
        allowPrivilegeEscalation: false
        runAsNonRoot: true
        runAsUser: 1000   
  volumes:
  - name: secrets-store
    emptyDir: {}
    csi:
      driver: secrets-store.csi.k8s.io
      readOnly: true
      volumeAttributes:
        secretProviderClass: azure-kvname

标签: c#kubernetesasp.net-core-3.1azure-aks

解决方案


在您定义为证书存储路径的位置,附加一个非只读卷。如果您只希望该数据在 pod 存在时持续存在,那么emptyDir类型的卷将非常适合该账单。

例如,如果您正在使用这样的部署创建 pod:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ct
  name: ct
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ct
  template:
    metadata:
      labels:
        app: ct
    spec:
      containers:
      - image: myapp
        name: myapp
        env:
        - name: cert_path
          value: /etc/certstore
        securityContext:
          readOnlyRootFilesystem: true

您可以按如下方式设置 emptyDir:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ct
  name: ct
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ct
  template:
    metadata:
      labels:
        app: ct
    spec:
      containers:
      - image: myapp
        name: myapp
        env:
        - name: cert_path
          value: /etc/certstore
        securityContext:
          readOnlyRootFilesystem: true
        volumeMounts:
        - mountPath: /etc/certstore
          name: certstore
      volumes:
      - name: certstore
        emptyDir: {}

其他类型的卷也可以。如果您想在 pod 循环时保留这些证书,则可以使用 persistentVolumeClaim 为您获取持久卷。

emptyDir 不会是只读的,但容器的根文件系统的其余部分将是只读的,这应该满足您的安全要求。


推荐阅读