Skip to content

Running on Kubernetes

Lucas Teske edited this page Jan 12, 2021 · 2 revisions

Sample deployment

This a WIP tutorial how to start a remote-signer instance inside a kubernetes cluster. This is a simple tutorial how to run remote-signer as a single-instance with private keys inside kubernetes secrets. You might also want to check Cluster Mode for extended configuration.

Creating secrets with private key

The first thing you should do is to create a secret inside kubernetes with the private key you want remote-signer to load it. To do so first you need to encode it with base64 so it can be put inside a yaml file. For these examples we will assume that the key has the fingerprint as 0551F452ABE463A4. You can also use this process to inject public keys to be pre-loaded when the remote-signer starts.

Using gpg command

gpg -a --export-secret-key 0551F452ABE463A4 | base64 -w0

This should give a result like this:

LS0tLS1C ... LS0tCg==

With the private key file

cat key_0551F452ABE463A4.gpg | base64 -w0

This should give a result like this:

LS0tLS1C ... LS0tCg==

Creating the secret yaml

The yaml for creating a kubernetes secret will follow this pattern:

apiVersion: v1
kind: Secret
metadata:
  name: remote-signer
  namespace: default
data:
  key_0551F452ABE463A4: LS0tLS1C ... LS0tCg==
type: Opaque

Where in the data section you can add more than one keys to be preloaded by remote-signer on load. These can be either public or private keys. Just make sure they are in the following format:

  key_FINGERPRINT: BASE64_ENCODED_KEY

After that you can run the following command to apply the secrets:

kubectl apply -f my-remote-signer-secret.yaml

Creating the Remote Signer Deployment Yaml

This step is pretty straightforward. Just make sure you have the secrets set up in the previous step. The yaml you should follow the following pattern:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: remote-signer
  namespace: default
spec:
  minReadySeconds: 2
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      quan.to/servicename: remote-signer
  template:
    metadata:
      labels:
        quan.to/servicename: remote-signer
    spec:
      containers:
      - env:
        - name: DATABASE_NAME
          value: remote_signer
        - name: ENABLE_RETHINKDB_SKS
          value: "false"
        - name: KEYS_BASE64_ENCODED
          value: "false"
        - name: KEY_PREFIX
          value: key_
        - name: PRIVATE_KEY_FOLDER
          value: /secrets/
        - name: READONLY_KEYPATH
          value: "true"
        - name: SKS_SERVER
          value: https://keyserver.ubuntu.com
        image: quantocommons/remote-signer:latest
        imagePullPolicy: Always
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /tests/ping
            port: 5100
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 2
          successThreshold: 1
          timeoutSeconds: 2
        name: remote-signer
        ports:
        - containerPort: 5100
          name: 5100tcp02
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /tests/ping
            port: 5100
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 2
          successThreshold: 2
          timeoutSeconds: 2
        resources: {}
        securityContext:
          allowPrivilegeEscalation: false
          capabilities: {}
          privileged: false
          procMount: Default
          readOnlyRootFilesystem: false
          runAsNonRoot: false
        stdin: true
        tty: true
        volumeMounts:
        - mountPath: /secrets
          name: remote-signer
          readOnly: true
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: contaquanto
      restartPolicy: Always
      volumes:
      - name: remote-signer
        secret:
          defaultMode: 256
          optional: false
          secretName: remote-signer

Then you can use kubectl to start the deployment:

kubectl apply -f my-remote-signer-deployment.yaml

Creating the Remote Signer Service Discovery Yaml

The service discovery entry is needed for accessing the remote-signer instance(s) inside the cluster. For this example we will make a service discovery with port 5100 exposed (which is the main remote-signer port):

apiVersion: v1
kind: Service
metadata:
  name: remote-signer
  namespace: default
spec:
  type: ClusterIP
  selector:
    quan.to/servicename: remote-signer
  ports:
  - name: 5100tcp02
    port: 5100
    protocol: TCP
    targetPort: 5100
  sessionAffinity: None
  type: ClusterIP
kubectl apply -f my-remote-signer-service-discovery.yaml

Then you can test it in another pod by acessing: http://remote-signer.default:5100/tests/ping:

$ curl http://remote-signer.default:5100/tests/ping
OK

A full deployment file is available at: https://github.com/quan-to/chevron/tree/develop/config/kubernetes