繁体   English   中英

当根文件系统为只读时如何将证书添加到 POD/Container 的证书库

[英]how to add certificate to POD/Container 's cert store when root filesystem is read-only

我有一个.net core应用程序,它已在 Kube.netes 集群 (AKS) 中运行。

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

securityContext:特权:false 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

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

通常, programmerq 建议的解决方案看起来不错。

至于这个错误:

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

曾几何时,我收到此错误是因为我尝试启动特定的卷类型,但使用kubectl apply返回到emptyDir 但是,旧卷仍然存在于服务器端。 kubectl试图合并两个卷规范,这导致了一个问题。

此站点上,您可以找到解释:

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

另请参阅此问题

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM