Kubernetes: ConfigMaps and Secrets on a Gorush server example
Tags: kubernetes, tutorial
Published: 2020-02-14 16:11:44

---
title: Kubernetes: ConfigMaps and Secrets on a Gorush server example
published: true
date: 2020-02-14 13:42:41 UTC
tags: Kubernetes,tutorial
canonical_url: https://rtfm.co.ua/en/kubernetes-configmaps-and-secrets-on-a-gorush-server-example/
---


![](https://rtfm.co.ua/wp-content/uploads/2017/06/kuber-1.png)We have a Gorush server from the [Kubernetes: running a push-server with Gorush behind an AWS LoadBalancer](https://rtfm.co.ua/en/kubernetes-running-a-push-server-with-gorush-behind-an-aws-loadbalancer/) post, and I’d like to ad an ability to configure it via a Github repository and run it with a different set of settings – for Staging and Production environments.

Let’s use Kubernetes [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) to store a config-file content, and Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) – for confidential data.

At this moment in the `gorush-configmap.yaml` we have  default configMap for the Gorush with Redis connection settings:

```
apiVersion: v1
kind: ConfigMap
metadata:
  name: gorush-config
  namespace: gorush
data:
  # stat
  stat.engine: redis
  stat.redis.host: redis:6379
```

Also, need to add:

- an SSL certificate used for Apple Push service authentification
- a password for this certificate

We will add two secrets – one for the password, and one for the key-file.

### Kubernetes Secrets

Create a new file `gorush-secrets.yaml` and add a p12-key body.

As this is p12 – use the `data` type for the secret, get your certificate in the `base64`:

```
$ cat apns\_wl.p12 | base64
MIIM9QIBAzCCDLwGCSqGSIb3DQEHAaCCDK0EggypMIIMpTCCBycGCSqGSIb3DQEHBqCCBxgwggcU
AgEAMIIHDQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQI+BcNML0eE1oCAggAgIIG4KVvRBPp
qRiubF1QeqOE1n6x1+k92pjpxvpJph+ZhS+1ztMSFOOIlwAPNMBYDd1Opg8x3lXCxN88OzuyFSHu
nLSzqyx1b8sPEEhUejeKlzqDQczOhJTuvO9lDNZQS/4Cbn1LRlr6DbrqSexE1GRgpal5Hcc5i9rr
...
```

Add a `data` map named _ios-push-rsa-key_:

```
---
apiVersion: v1
kind: Secret
metadata:
  name: ios-push-secret
  namespace: gorush
type: Opaque
data:
  ios-push-rsa-key: |
    MIIM9QIBAzCCDLwGCSqGSIb3DQEHAaCCDK0EggypMIIMpTCCBycGCSqGSIb3DQEHBqCCBxgwggcU
    AgEAMIIHDQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQI+BcNML0eE1oCAggAgIIG4KVvRBPp
    ...
```

Or. if it is a PEM-encoded key – you can use `stringData` without `base64`, just a plaintext:

```
---
apiVersion: v1
kind: Secret
metadata:
  name: ios-push-secret
  namespace: gorush
type: Opaque
stringData:
  ios-push-rsa-key: |
    -----BEGIN CERTIFICATE-----
    MIIGJDCCBQygAwIBAgIIAtw7YRUahfYwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
    BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
    ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
...
```

Create the secret:

```
$ kubectl apply -f gorush-secrets.yaml
secret/ios-push-secret created
```

Check it:

```
$ kubectl -n gorush describe secret ios-push-secret
Name:         ios-push-secret
Namespace:    gorush
Labels:       <none>
Annotations:
Type:         Opaque
Data

====

ios-push-rsa-key:  4586 bytes
```

Now, we need to mount this certificate to pods and containers.

#### Kubernetes Secrets and `volumeMounts` – secrets, as files

Update the `gorush-deployment.yaml` file – add [`volumes`](https://kubernetes.io/docs/concepts/storage/volumes/) from the sectret:

```
...
      volumes:
      - name: ios-push-secret-vol
        secret:
          secretName: ios-push-secret
          items:
          - key: ios-push-p12-key
            path: apns-crt.p12
```

And add it to the pod’s template:

```
...
    spec:
      containers:
      - image: appleboy/gorush
        name: gorush
        imagePullPolicy: Always
        ports:
        - containerPort: 8088
...
        volumeMounts:
        - name: ios-push-secret-vol
          mountPath: /data/ssl/apns-crt.p12
          subPath: apns-crt.p12
          readOnly: true
```

To make it clear – how they all are tied to each other:

- `kind: Secret`: // just a Secret type
  - `name: ios-push-secret` // a secret name –  will use in the _spec > volumes > secret > secretName_
  - `data`:
    - `ios-push-rsa-key` // a cert body
- `volumes`: // set in the _spec_, will add volumes
  - `name: ios-push-secret-vol` // a created volume name, will be used in the _spec > containers >volumeMounts > name_
  - `secret`: // defining a data to be used
    - `secretName: ios-push-secret` // lookup a secret with the _name: ios-push-secret_ name
    - `items`: // andinsideofthesecret
      - `- key: ios-push-rsa-key` // look for the _Secrets > data > ios-push-rsa-key_
      - `path: apns-rsa.pem` // and how it wmust be mounted
- `volumeMounts`: // used in the _spec > containers_
  - `name: ios-push-secret-vol` // a volume name to mount – _spec > volumes > name: ios-push-secret-vol_
  - `mountPath: /data/ssl/apns-rsa.pem` // a full mount path
  - `subPath: apns-rsa.pem` // a file name in a directory if a Secret is mounted as a dedicated file

Deploy and check:

```
$ kubectl -n gorush exec -ti gorush-7ff8fd9f4c-gds8r -c bastion cat /data/ssl/apns-rsa.pem
Bag Attributes
friendlyName: Apple Push Services: \*\*\*
localKeyID: C0 3A 96 69 CB C4 9E E6 14 EB 43 1F 31 30 97 4D 85 89 A0 8D
subject=/UID=\*\*\*/CN=Apple Push Services: \*\*\*/OU=7MF8BB6LXN/O=\*\*\*/C=VG
issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authorit
-----BEGIN CERTIFICATE-----
MIIGJDCCBQygAwIBAgIIAtw7YRUahfYwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
...
```

#### Kubernetes Secrets and `env` – secrets, as environment variables

The following step is to add a password for this certificate.

Theis are two options – using a config file, or via variables.

In the config file, Gorush has an `ios.password` parameter:

```
...
    ios:
      enabled: true
      key_path: "/data/ssl/apns-crt.p12"
      password: "p@ssw0rd"
      production: true
...
```

And if using a variable – Gorush will add a [`GORUSH`](https://github.com/appleboy/gorush/blob/master/config/config.go#L224) prefix:

```
... 
viper.SetEnvPrefix("gorush") // will be uppercased automatically
...
```

So, our variable name will be `GORUSH_IOS_PASSWORD`.

Add new values to the _ios-push-secret_.

Add an additional map with the `stringData` type:

```
---
apiVersion: v1
kind: Secret
metadata:
  name: ios-push-secret
  namespace: gorush-stage
type: Opaque
data:
  ios-push-p12-key: |
    MIIM9QIBAzCCDLwGCSqGSIb3DQEHAaCCDK0EggypMIIMpTCCBycGCSqGSIb3DQEHBqCCBxgwggcU
    AgEAMIIHDQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQI+BcNML0eE1oCAggAgIIG4KVvRBPp
...
stringData:
  ios-push-p12-pass: p@ssw0rd
```

Check it:

```
$ kubectl apply -f gorush-secrets.yaml
secret/ios-push-secret configured
```

And check now – there must be two objects in the secret – view them using `describe secret`:

```
$ kubectl -n gorush describe secret ios-push-secret
Name:         ios-push-secret
Namespace:    gorush
Labels:       <none>
Annotations:
Type:         Opaque
Data

====

ios-push-p12-key:   3321 bytes
ios-push-p12-pass:  13 bytes
```

Add the `GORUSH_IOS_PASSWORD` variable to the deployment using  `secretKeyRef`:

```
...
    spec:
      containers:
      - image: appleboy/gorush
        name: gorush
        imagePullPolicy: Always
        ports:
        - containerPort: 8088
...
        env:
        - name: GORUSH_IOS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: ios-push-secret
              key: ios-push-p12-pass
        volumeMounts:
        - name: ios-push-secret-vol
          mountPath: /data/ssl/apns-crt.p12
          subPath: apns-crt.p12
          readOnly: true
...
```

Deploy and check:

```
$ kubectl -n gorush exec -ti gorush-58bcd746c4-67b9n -c gorush env | grep GORUSH\_IOS
GORUSH\_IOS\_PASSWORD=p@ssw0rd
```

It’s here.

### ConfigMap

#### Kubernetes ConfigMap – configs, as files

The last thing to do is to add a dedicated config-file for the Gorush itself.

The file will be the same for the Production and Staging, but keys will be passed from a varicose Secrets.

In the same way, using variables and a ConfigMap we can pass any other parameters for different environments.

So, let use a ConfigMap to keep the `config.yml` file’s content to map it later to pods.

Gorush already has a `gorush-configmap.yaml` file – add a new config called _gorush-config-file_:

```
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: gorush-config
  namespace: gorush
data:
  # stat
  stat.engine: redis
  stat.redis.host: redis:6379
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: gorush-config-file
  namespace: gorush
data:
  gorush-config-file: |
    core:
      enabled: true
      mode: "release"
      port: "8088"
      max_notification: 1000
      sync: false
...
```

Add it to the `volumes` in our deployment:

```
...
      volumes:
      - name: ios-push-secret-vol
        secret:
          secretName: ios-push-secret
          items:
          - key: ios-push-p12-key
            path: apns-crt.p12
      - name: gorush-config-file-vol
        configMap:
          name: gorush-config-file
          items:
            - key: gorush-config-file
              path: config.yml
```

And the on the `volumeMounts` in the pods template:

```
...
    spec:
      containers:
      - image: appleboy/gorush
        name: gorush
        imagePullPolicy: Always
        ports:
        - containerPort: 8088
        ...
        env:
        - name: GORUSH_IOS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: ios-push-secret
              key: ios-push-p12-pass
        volumeMounts:
        - name: ios-push-secret-vol
          mountPath: /data/ssl/apns-crt.p12
          subPath: apns-crt.p12
          readOnly: true
        - name: gorush-config-file-vol
          mountPath: /config.yml
          readOnly: true
          subPath: config.yml
...
```

Update configmaps:

```
$ kubectl apply -f gorush-configmap.yaml
configmap/gorush-config unchanged
configmap/gorush-config-file created
```

Check them:

```
$ kubectl -n gorush get configmap
NAME                 DATA   AGE
gorush-config        2      28h
gorush-config-file   1      76s
```

Apply the deployment and check config in a pod:

```
$ kubectl -n gorush-stage exec -ti gorush-6bc78df55d-9w9m8 -c gorush cat /config.yml
core:
enabled: true
mode: "release"
port: "8088"
max\_notification: 1000
sync: false
...
ios:
enabled: true
key\_path: "/data/ssl/apns-crt.p12"
password: ""
production: true
```

To auto-apply new values from ConfigMaps or Secrets – you can use the Reloader controller, see the [Kubernetes: ConfigMap and Secrets – data auto-reload in pods](https://rtfm.co.ua/en/kubernetes-configmap-and-secrets-data-auto-reload-in-pods/ "Permalink to Kubernetes: ConfigMap and Secrets – data auto-reload in pods") post.

Done.

### Similar posts

- <small>09/03/2019</small> [Kubernetes: part 4 – AWS EKS authentification, aws-iam-authenticator and AWS IAM](https://rtfm.co.ua/en/kubernetes-part-4-aws-eks-authentification-aws-iam-authenticator-and-aws-iam/)  
- <small>08/15/2019</small> [Kubernetes: part 3 – AWS EKS overview and manual EKS cluster set up](https://rtfm.co.ua/en/kubernetes-part-3-aws-eks-overview-and-manual-eks-cluster-set-up/)
- <small>02/13/2020</small> [Kubernetes: ConfigMap and Secrets – data auto-reload in pods](https://rtfm.co.ua/en/kubernetes-configmap-and-secrets-data-auto-reload-in-pods/)  
- <small>07/25/2019</small> [Kubernetes: part 1 – architecture and main components overview](https://rtfm.co.ua/en/kubernetes-part-1-architecture-and-main-components-overview/)