16

If i create a secret from an id_rsa file using kubectl as:

kubectl create secret generic hcom-secret --from-file=ssh-privatekey=./.ssh/id_rsa

And then mount the secret into the container

"volumeMounts": [
        {"name": "cfg", "readOnly": false, "mountPath": "/home/hcom/.ssh"}
      ]

"volumes": [
      {"name": "cfg", "secret": { "secretName": "hcom-ssh" }}
    ],

The resultant file is not id_rsa but ssh-privatekey and the permits that are on it are not 600 which ssh expects

Is this a correct approach, or can anyone please detail how this should be done?

Aatif Akhter
  • 2,126
  • 1
  • 25
  • 46
Kevin Taylor
  • 163
  • 1
  • 1
  • 5
  • If you want the name to be id_rsa, you should probably be doing `--from-file=id_rsa=./.ssh/id_rsa` – ffledgling Sep 19 '16 at 11:25
  • id_rsa is not a valid file name - the regex validation fails. Even if I generate a json file and try to edit it and use id_rsa as the file name, it will not load that secret – Kevin Taylor Sep 20 '16 at 11:53
  • I see, it seems like Kubernetes has an odd restriction where secret names (and other names, such as labels), must be valid DNS names, conforming to `[a-z0-9]([-a-z0-9]*[a-z0-9])?` here's the [relevant code](https://github.com/kubernetes/kubernetes/blob/7f2d0c0f710617ef1f5eec4745b23e0d3f360037/pkg/util/validation.go#L26) – ffledgling Sep 20 '16 at 12:00
  • I can actually live with the filename as I can pass it to ssh using -i but I have to alter the permission level to 600 within my docker container – Kevin Taylor Sep 20 '16 at 12:07

2 Answers2

18

The official Kubernetes docs for secrets cover this exact use-case.

To create the secret, use:

$ kubectl create secret generic my-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub

To mount the secret in your containers, use the following Pod config:

{
  "kind": "Pod",
  "apiVersion": "v1",
  "metadata": {
    "name": "secret-test-pod",
    "labels": {
      "name": "secret-test"
    }
  },
  "spec": {
    "volumes": [
      {
        "name": "secret-volume",
        "secret": {
          "secretName": "my-secret"
        }
      }
    ],
    "containers": [
      {
        "name": "ssh-test-container",
        "image": "mySshImage",
        "volumeMounts": [
          {
            "name": "secret-volume",
            "readOnly": true,
            "mountPath": "/etc/secret-volume"
          }
        ]
      }
    ]
  }
}

Kubernetes doesn't actually have a way to control file permissions for a secret as of now, but a recent Pull Request did add support for changing the path of secrets. This support was added with 1.3 as per this comment

Here are the permissions related Github Issues:

Sheena
  • 15,590
  • 14
  • 75
  • 113
ffledgling
  • 11,502
  • 8
  • 47
  • 69
  • Thanks - I see from that PR that it is actually in 1.4 but not in 1.3. Also for completeness the document that you posted here is inaccurate because it actually states that it will mount a file called id_rsa and also the mount refers to a secret called ssh-key-secret and yet the kubectl line creates a secret called my-secret. – Kevin Taylor Sep 20 '16 at 12:35
  • I see, feel free to propose an edit and I'll accept it, if that's not possible, I'll add in the edits later today. – ffledgling Sep 20 '16 at 12:41
  • seems that doing so does not preserve newlines, so far I'm ending up having troubles using the keys without newlines. A workaround exists ? – Ben Nov 16 '16 at 11:17
  • 1
    has file permissions been confirmed to work? i think i'm using 1.6 and with a similar setup, the ssh key and config have full read and write permissions – Christian Feb 07 '18 at 17:27
  • A workarround is add in the entrypoint: if [ -f /home/jenkins/.ssh/id_rsa ]; then echo "Setting correct permission for ssh private key" chmod 600 `pwd`.ssh/id_rsa fi – NicoKowe Jul 16 '19 at 11:31
10

Since kubernetes-1.4 things got simpler. Here's my take how to improve the official Kubernetes howto.

To create the secret, use:

kubectl create secret generic ssh-keys --from-file=id_rsa=/path/to/.ssh/id_rsa --from-file=id_rsa.pub=/path/to/.ssh/id_rsa.pub

To mount the secret in your containers, use the following Pod config:

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
  labels:
    name: secret-test
spec:
  volumes:
  - name: ssh-keys-v
    secret:
      secretName: ssh-keys
      defaultMode: 0600 
  containers:
  - name: ssh-test-container
    image: mySshImage
    volumeMounts:
    - name: ssh-keys-v
      readOnly: true
      # container will see /root/.ssh/id_rsa as usual:
      mountPath: "/root/.ssh"

Also nitpick: the id_rsa.pub is hardly ever used, I wouldn't bother to secretize it until required.

kubanczyk
  • 5,184
  • 1
  • 41
  • 52