Kubernetes - 如何提取秘密 tar 文件?

Kubernetes - how do I extract a secret tar file?

我已经安装了两个 tar 文件作为机密。我想将它们安装到我的容器中,然后解压内容。创建秘密的命令如下:

kubectl create secret generic orderer-genesis-block --from-file=./channel-artifacts/genesis.block

kubectl create secret generic crypto-config --from-file=crypto-config.tar

kubectl create secret generic channel-artifacts --from-file=channel-artifacts.tar

下面是我kubectl apply:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fabric-orderer-01
spec:
  selector:
    matchLabels:
      app: fabric-orderer-01
  replicas: 1
  template:
    metadata:
      labels:
        app: fabric-orderer-01
    spec:
      initContainers:
      - name: init-channel-artifacts
        image: busybox
        volumeMounts:
        - name: channel-artifacts
          mountPath: /hlf/channel-artifacts
        command: ['sh', '-c', 'tar -xf /hlf/channel-artifacts/channel-artifacts.tar']
      containers:
      - name: fabric-orderer-01
        image: hyperledger/fabric-orderer:1.4.9
        env:
        - name: ORDERER_CFG_PATH
          value: /hlf/
        - name: CONFIGTX_ORDERER_ADDRESSES
          value: "orderer.example.com:7050"
        - name: ORDERER_GENERAL_LISTENADDRESS
          value: 0.0.0.0
        - name: ORDERER_GENERAL_LISTENPORT
          value: "7050"
        - name: ORDERER_GENERAL_LOGLEVEL
          value: debug
        - name: ORDERER_GENERAL_LOCALMSPID
          value: OrdererMSP
        - name: ORDERER_GENERAL_GENESISMETHOD
          value: file
        - name: ORDERER_GENERAL_GENESISFILE
          value: /hlf/genesis.block
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: fabricfiles-01
          mountPath: /fabric
        - name: orderer-genesis-block
          mountPath: /hlf/
          readOnly: true
        - name: crypto-config
          mountPath: /hlf/crypto-config
          readOnly: true
        - name: channel-artifacts
          mountPath: /hlf/channel-artifacts
          readOnly: true
      volumes:
      - name: orderer-genesis-block
        secret:
          secretName: orderer-genesis-block
      - name: crypto-config
        secret:
          secretName: crypto-config
      - name: channel-artifacts
        secret:
          secretName: channel-artifacts
      - name: fabricfiles-01
        persistentVolumeClaim:
          claimName: fabric-pvc-01

我的部署成功了,但是当我 bash 进入我的 pod 时,我没有看到我的 tar 文件被提取。我只看到我的 tar 个文件 /hlf/channel-artifacts/channel-artifacts.tar/hlf/crypto-config/crypto-config.tar。我应该如何提取它们的内容?

当您创建一个 initContainer 并执行此命令时:

command: ['sh', '-c', 'tar -xvf /hlf/channel-artifacts/channel-artifacts.tar']

它默认为此容器路径运行。 我通过添加 pwdls -l 命令来检查这一点。

整行是:

command: ['sh', '-c', 'tar -xvf /hlf/channel-artifacts/channel-artifacts.tar ; pwd ; ls -l']

您可以通过以下方式从 initContainer 获取日志:

kubectl logs fabric-orderer-01-xxxxxx -c init-channel-artifacts

输出为:

channel-artifacts.txt # first line for -v option so tar was untared indeed
/ # working directory
total 44
drwxr-xr-x    2 root     root         12288 May  3 21:57 bin
-rw-rw-r--    1 1001     1002            32 May 10 14:15 channel-artifacts.txt # file which was in tar
drwxr-xr-x    5 root     root           360 May 11 08:41 dev
drwxr-xr-x    1 root     root          4096 May 11 08:41 etc
drwxr-xr-x    4 root     root          4096 May 11 08:41 hlf
drwxr-xr-x    2 nobody   nobody        4096 May  3 21:57 home
dr-xr-xr-x  225 root     root             0 May 11 08:41 proc
drwx------    2 root     root          4096 May  3 21:57 root
dr-xr-xr-x   13 root     root             0 May 11 08:41 sys
drwxrwxrwt    2 root     root          4096 May  3 21:57 tmp
drwxr-xr-x    3 root     root          4096 May  3 21:57 usr
drwxr-xr-x    1 root     root          4096 May 11 08:41 var

如您所见,您的文件存储在容器的 / 路径中,这意味着当此容器终止时,其文件系统也将终止,您的文件也将消失。

一旦我们知道发生了什么,就该解决它了。 首先也是重要的事情是秘密是只读的,应该以准备好的形式使用,你不能像你想在你的例子中那样将文件写入秘密。

另一种选择是您可以将您的秘密解压缩到持久卷:

command: ['sh', '-c', 'tar -xvf /hlf/channel-artifacts/channel-artifacts.tar -C /hlf/fabric']

然后使用 postStart hook 作为主容器,例如将您的文件复制到所需位置或创建 simlinks,您将不需要将您的秘密安装到主容器。

postStart hook (reference) 的简单示例:

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]

小通知是

Kubernetes sends the postStart event immediately after the Container is created. There is no guarantee, however, that the postStart handler is called before the Container's entrypoint is called.

要解决此问题,您可以在入口点之前的主容器中添加 sleep 5。这是一个以 nginx 图像开头的容器部分的示例(对于您的图像,它会有所不同):

containers:
      - name: main-container
        image: nginx
        command: ["bash", "-c", 'sleep 5 ; echo "daemon off;" >> /etc/nginx/nginx.conf ; nginx']

这将解决您的问题。你也可以使用这种方法解压你的文件,你甚至不需要 initContainer

不清楚为什么要使用 tar 用于此目的,因为您可以将小文件存储在 secretsconfigmaps 中并使用 subPath 直接挂载它们,其中不需要额外的步骤就需要它们(你可以阅读它并找到一个例子here

要安全地使用机密,您应该考虑例如HashiCorp Vault (Vault with kubernetes)