Имеется Gorush сервер, запущенный в посте Kubernetes: запуск push-сервера Gorush в EKS за AWS LoadBalancer, к которому теперь хочется добавить возможность добавления своего файла настроек — для Staging с одними данными, и для Production — с другими.
Используем Kubernetes ConfigMap для хранения содержимого файлов настроек Gorush, которые потом покдлючим внутрь запускаемых подов и их контейнеров, и Secrets — для конфиденциальных данных.
Сейчас в файле gorush-configmap.yaml описывается дефолтный configMap для Gorush, в котором передаются настройки подключения к Redis-сервису:
apiVersion: v1 kind: ConfigMap metadata: name: gorush-config namespace: gorush data: # stat stat.engine: redis stat.redis.host: redis:6379
Кроме этого, надо добавить:
- SSL-сертификат, используемый при отравке пушей
- пароль этого сертификата
Добавим два объекта типа Kubernetes Secret — один для пароля, второй — для файла ключа аутентификации в Apple при отправке пушей.
Содержание
Kubernetes Secrets
Создаём новый файл — gorush-secrets.yaml, добавляем в него пока только тело p12-сертификата:
Т.к. у нас бинарный p12-ключ — используем тип data, получаем base64 из сертификата:
[simterm]
$ cat apns_wl.p12 | base64 MIIM9QIBAzCCDLwGCSqGSIb3DQEHAaCCDK0EggypMIIMpTCCBycGCSqGSIb3DQEHBqCCBxgwggcU AgEAMIIHDQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQI+BcNML0eE1oCAggAgIIG4KVvRBPp qRiubF1QeqOE1n6x1+k92pjpxvpJph+ZhS+1ztMSFOOIlwAPNMBYDd1Opg8x3lXCxN88OzuyFSHu nLSzqyx1b8sPEEhUejeKlzqDQczOhJTuvO9lDNZQS/4Cbn1LRlr6DbrqSexE1GRgpal5Hcc5i9rr ...
[/simterm]
Добавляем data map:
---
apiVersion: v1
kind: Secret
metadata:
name: ios-push-secret
namespace: gorush
type: Opaque
data:
ios-push-rsa-key: |
MIIM9QIBAzCCDLwGCSqGSIb3DQEHAaCCDK0EggypMIIMpTCCBycGCSqGSIb3DQEHBqCCBxgwggcU
AgEAMIIHDQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQI+BcNML0eE1oCAggAgIIG4KVvRBPp
...
Либо, если это PEM-ключ, то можно передать как stringData — без base64, просто текст:
---
apiVersion: v1
kind: Secret
metadata:
name: ios-push-secret
namespace: gorush
type: Opaque
stringData:
ios-push-rsa-key: |
-----BEGIN CERTIFICATE-----
MIIGJDCCBQygAwIBAgIIAtw7YRUahfYwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
...
Создаём секрет:
[simterm]
$ kubectl apply -f gorush-secrets.yaml secret/ios-push-secret created
[/simterm]
Проверяем:
[simterm]
$ 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
[/simterm]
Далее — этот сертификат надо смонтировать в виде файла в создаваемые поды и их контейнеры.
Kubernetes Secrets и volumeMounts — секреты, как файлы
Обновляем gorush-deployment.yaml — добавляем создание volumes из секрета:
...
volumes:
- name: ios-push-secret-vol
secret:
secretName: ios-push-secret
items:
- key: ios-push-p12-key
path: apns-crt.p12
Затем — его монтирование в под:
...
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
Что бы представить себе связи при маппинге конфигов или секретов и разделов/файлов:
kind: Secret: // сам секретname: ios-push-secret// имя секрета — используем это имя в spec > volumes > secret > secretNamedata:ios-push-rsa-key// тело сертификата
volumes: // описывается в spec, создаёт сами разделыname: ios-push-secret-vol// имя создаваемого раздела, используем в spec > containers >volumeMounts > namesecret: // в разделе будут данные типа secretsecretName: ios-push-secret// ищем секрет с name: ios-push-secretitems: // внутри секрета- key: ios-push-rsa-key// ищем Secrets > data > ios-push-rsa-keypath: apns-rsa.pem// и как будем его монтировать
volumeMounts: // описывается в spec > containersname: ios-push-secret-vol// имя раздела, который будем монтировать — spec > volumes > name: ios-push-secret-volmountPath: /data/ssl/apns-rsa.pem// полный путь монтированияsubPath: apns-rsa.pem// имя файла в каталоге, если подключаем как отдельный файл
Деплоим — проверяем:
[simterm]
$ 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
...
[/simterm]
Kubernetes Secrets и env — секреты, как переменные
Следующим шагом — надо добавить пароль от этого сертификата.
Варианта два — конфиг Gorush, или переменная окружения.
В конфиге Gorush есть параметр ios.password:
...
ios:
enabled: true
key_path: "/data/ssl/apns-crt.p12"
password: "p@ssw0rd"
production: true
...
А при использовании переменных Gorush добавляет префикс GORUSH:
...
viper.SetEnvPrefix("gorush") // will be uppercased automatically
...
Значит переменная будет GORUSH_IOS_PASSWORD.
Добавляем значение в файл секретов, в тот же ios-push-secret.
Добавляем ещё один мап, тип stringData:
---
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
Применяем:
[simterm]
$ kubectl apply -f gorush-secrets.yaml secret/ios-push-secret configured
[/simterm]
Проверяем — теперь у нас в секрете два объекта данных, повторяем describe secret:
[simterm]
$ 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
[/simterm]
Добавляем её в описание шаблона подов в файле деплоймента, используя 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
...
Деплоим, проверяем:
[simterm]
$ kubectl -n gorush exec -ti gorush-58bcd746c4-67b9n -c gorush env | grep GORUSH_IOS GORUSH_IOS_PASSWORD=p@ssw0rd
[/simterm]
Пароль на месте.
ConfigMap
Kubernetes ConfigMap — конфиги, как файлы
Последним шагом нам надо создать файл настроек, и подменить файл настроек самого Gorush.
Файл будет общий для Production и Staging, а ключи будем передавать через разные секреты для разных окружений.
Аналогично можно через переменные и ConfigMap передать разные параметры для разных окружений.
Тут используем ConfigMap для создания файла config.yml, который потом смонтируем в запускаемые контейнеры.
У Gorush уже есть файл gorush-configmap.yaml — используем его, добавляем новый конфиг с именем 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
...
Добавляем его в volumes файла деплоймента:
...
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
А затем в volumeMounts в шаблоне пода:
...
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
...
Обновляем конфигмапы:
[simterm]
$ kubectl apply -f gorush-configmap.yaml configmap/gorush-config unchanged configmap/gorush-config-file created
[/simterm]
Проверяем:
[simterm]
$ kubectl -n gorush get configmap NAME DATA AGE gorush-config 2 28h gorush-config-file 1 76s
[/simterm]
Применяем деплоймент, и проверяем конфиг в контейнере:
[simterm]
$ 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
[/simterm]
Для автообновления подов при внесении изменений в ConfigMap и Secrets — можно использовать Reloader, см. Kubernetes: ConfigMap и Secrets — auto-reload данных в подах.
Готово.