Имеется 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 данных в подах.
Готово.