【问题标题】:how to add certificate to POD/Container 's cert store when root filesystem is read-only当根文件系统为只读时,如何将证书添加到 POD/Container 的证书存储区
【发布时间】:2021-10-22 01:19:35
【问题描述】:

我有一个 .net core 应用程序,它是 dockerized 并在 Kubernetes 集群 (AKS) 中运行。

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

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

对于.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

【问题讨论】:

  • programmerq的解决方案对你有帮助吗?
  • 没有。我将秘密卷与 CSI 驱动程序结合使用。如果我尝试添加 mptyDir: {}。它给出错误:spec.template.spec.volumes[0].csi: Forbidden: may not specify more than 1 volume type
  • 检查我的问题的update 部分。

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


【解决方案1】:

在您定义为证书存储路径的位置,附加一个非只读卷。如果您只希望该数据在 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 不会是只读的,但容器的根文件系统的其余部分将是只读的,这应该满足您的安全要求。

【讨论】:

  • 感谢您的回复。我正在使用CSI Secret Driver 进行卷安装,这是我的配置,volumeMounts: - name: secrets-store mountPath: /app/certs
  • 现在当我尝试设置 emptyDir 时,volumes: - name: secrets-store emptyDir: {} csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: azure-kvname 出现错误,spec.template.spec.volumes[0].csi: Forbidden: may not specify more than 1 volume type
  • 我无法删除上述 csi 驱动程序的readOnly: true,否则会给出不同的错误,MountVolume.SetUp failed for volume "secrets-store" : rpc error: code = InvalidArgument desc = Readonly is not true in request
  • 您肯定需要将 emptyDir 设置为 emptyDir 而不是秘密。机密本质上是只读的。 emptyDir 只是一个您将拥有写入权限的目录。
  • 我同意先生,但我们有任何解决方案可以将emptyDir 放在哪里。请参阅我在update 问题和错误部分的尝试。谢谢。
【解决方案2】:

总的来说,programmerq 建议的解决方案看起来不错。

至于这个错误:

spec.template.spec.volumes[0].csi:禁止:不能指定超过 1 个卷类型

曾几何时,我收到此错误,因为我尝试启动特定卷类型,但使用kubectl apply 回到emptyDir。但是,旧卷仍然存在在服务器端。 kubectl 尝试合并两个卷规格,结果出现问题。

this site你可以找到解释:

  • 如果准入插件开启,管理员可以指定默认的StorageClass。所有没有storageClassName 的 PVC 只能绑定到该默认值的 PV。通过在StorageClass 对象中将注释storageclass.kubernetes.io/is-default-class 设置为等于“true”来指定默认StorageClass。如果管理员没有指定默认值,集群会响应 PVC 创建,就好像准入插件已关闭一样。如果指定了多个默认值,准入插件将禁止创建所有 PVC。

另见this question

确保您的卷已正确创建,旧卷不存在,然后尝试programmerq 建议的解决方案。

【讨论】:

  • 感谢@Mikołaj Głodziak。我的卷不是持久卷。我删除了我的 POD 部署并尝试使用 emptyDir 再次创建 POD,但仍然出现同样的错误。
  • 如果我在 YAML csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: azure-kvname 中删除了 CSI 部分,则没有错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 2016-12-22
  • 1970-01-01
  • 2021-03-21
相关资源
最近更新 更多