これは、なにをしたくて書いたもの?
- OpenShift(というかKubernetes)での、ConfigMapとSecretsのお試しに
- アプリケーションの環境変数に組み込んで試してみたい
今回は、ConigMapとSecretsを使って環境変数から値を読む、簡単なNode.jsアプリケーションを書いてみます。
ConfigMapとSecretsの説明自体は、実際に作成する時に書いていきます。
環境
今回の環境は、こちら。
$ minishift version minishift v1.23.0+91235ee $ oc version oc v3.10.0+dd10d17 kubernetes v1.10.0+b81c8f8 features: Basic-Auth GSSAPI Kerberos SPNEGO Server https://192.168.42.238:8443 openshift v3.10.0+756ae6e-40 kubernetes v1.10.0+b81c8f8
アプリケーションを書く
最初に、Node.jsでアプリケーションを書いていきます。
Expressのインストール。
$ npm i --save express
Expressのバージョンは、こちら。
"dependencies": { "express": "^4.16.3" }
アプリケーションは、「/config」でConfigMapから設定した環境変数を、「/secrets」でSecretsから設定した環境変数を 参照するように作成します。 src/server.js
const express = require('express'); const app = express(); app.get('/config', (req, res) => { const username = process.env.CONFIG_USERNAME; const password = process.env.CONFIG_PASSWORD; res.send({ config_username: username, config_password: password }); }); app.get('/secrets', (req, res) => { const username = process.env.SECRET_USERNAME; const password = process.env.SECRET_PASSWORD; res.send({ secret_username: username, secret_password: password }); }); app.listen(8080);
で、このスクリプトを「npm start」で起動するように設定。 package.json
"scripts": { "start": "node src/server.js" },
ConfigMapとSecretsを作る
続いて、このアプリケーションに設定するConfigMapとSecretsを作成します。
まずは、ConfigMapから。
ConfigMaps | Developer Guide | OKD 3.10
ConfigMapとは、文字通り設定情報ですが、設定を稼働するコンテナに含めるのではなく、デプロイ時にコンテナに提供する仕組みの ことを言うそうです。
コンテナは、ConfigMapを環境変数やコンテナの起動引数、ファイルとして参照することができるそうな。
Consuming in Environment Variables
Setting Command-line Arguments
作り方はYAMLで、ファイルから、リテラルからといくつかあるようですが、今回はリテラルから作ってみます。
参考)
ConfigMapの作成。
$ oc create configmap app-config --from-literal=config-username=cuser --from-literal=config-password=cpassword
確認。
$ oc get cm/app-config -o yaml apiVersion: v1 data: config-password: cpassword config-username: cuser kind: ConfigMap metadata: creationTimestamp: 2018-09-08T07:33:30Z name: app-config namespace: myproject resourceVersion: "27888" selfLink: /api/v1/namespaces/myproject/configmaps/app-config uid: 7bf7b343-b339-11e8-9de6-52540089d814
Secretsを作る
今度は、Secretsを作成します。
Secrets | Developer Guide | OKD 3.10
Secretsは、パスワード、OKDクライアントの設定ファイル、dockercfg、プライベートなソースリポジトリのクレデンシャルなどを 管理する仕組みのことだそうな。
Base64エンコードされ、データはtmpfs上に置かれて参照されます。Node上には置かれません、と。また、namespace内で共有することが できます。
作成できるSecretsの種類はいくつかあり、Service Account Tokenやdockercfg、TLSに関するものなどがあります。
もちろん、汎用的な設定情報としても作成することができます(type=Opaque)。
作成したSecretsは、ボリュームとしてマウントしたり、コンテナの起動引数としたり、環境変数として参照できたりします。
ConfigMapと同じですね。
Secretsの作成は、ファイルやリテラルから行います。
今回は、リテラルから作成してみます。
$ oc create secret generic app-secrets --from-literal=secret-username=suser --from-literal=secret-password=spassword
確認。
$ oc get secrets/app-secrets -o yaml apiVersion: v1 data: secret-password: c3Bhc3N3b3Jk secret-username: c3VzZXI= kind: Secret metadata: creationTimestamp: 2018-09-08T07:33:35Z name: app-secrets namespace: myproject resourceVersion: "27896" selfLink: /api/v1/namespaces/myproject/secrets/app-secrets uid: 7eec487a-b339-11e8-9de6-52540089d814 type: Opaque
$ echo -n 'c3Bhc3N3b3Jk' | base64 -d spassword
参考)
Kubernetes勉強会第1回 〜Secrets、StatefulSet、DaemonSet、API server への接続方法〜 - 世界中の羊をかき集めて
Kubernetes Secrets の紹介 – データベースのパスワードやその他秘密情報をどこに保存するか? – ゆびてく
確認
それでは、ここまで作成してきたアプリケーションとConfigMap、Secretsを使って動作確認してみます。
アプリケーションのデプロイ。
$ oc new-app [GitリポジトリのURL]
Routeの作成。
$ oc expose svc/node-config-and-secrets route "node-config-and-secrets" exposed $ oc get routes/node-config-and-secrets NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD node-config-and-secrets node-config-and-secrets-myproject.192.168.42.24.nip.io node-config-and-secrets 8080-tcp None
アプリケーションに、環境変数としてConfigMapとSecretsを取り込みます。
$ oc set env --from=configmap/app-config dc/node-config-and-secrets $ oc set env --from=secrets/app-secrets dc/node-config-and-secrets
確認。
$ curl node-config-and-secrets-myproject.192.168.42.24.nip.io/config {"config_username":"cuser","config_password":"cpassword"} $ curl node-config-and-secrets-myproject.192.168.42.24.nip.io/secrets {"secret_username":"suser","secret_password":"spassword"}
アプリケーションから、環境変数として参照できていますね。
変更してみる
ConfigMapやSecretsの変更は、今回は「oc edit」でYAMLを変更。
$ oc edit cm/app-config $ oc edit secrets/app-secrets
変更したら、DeploymentConfigをrollout。
$ oc rollout latest dc/node-config-and-secrets
これで、変更がコンテナ側にも反映されました、と。
YAMLで書こう
最後に、ここまでのことをYAMLで書き直してみます。
ConfigMap。 config-resources.yml
apiVersion: v1 kind: ConfigMap metadata: name: app-config data: config-password: cpassword config-username: cuser
Secrets。 secrets-resources.yml
apiVersion: v1 kind: Secret metadata: name: app-secrets type: Opaque data: secret-password: c3Bhc3N3b3Jk secret-username: c3VzZXI=
stringDataを使えば、Base64エンコードなしで書くこともできるようで。 secrets-resources.yml
apiVersion: v1 kind: Secret metadata: name: app-secrets type: Opaque stringData: secret-username: secret-username secret-password: secret-password
アプリケーション。 application-resources.yml
--- ## ImageStream apiVersion: v1 kind: ImageStream metadata: labels: app: node-config-and-secrets name: node-config-and-secrets --- ## BuildConfig apiVersion: v1 kind: BuildConfig metadata: labels: app: node-config-and-secrets name: node-config-and-secrets spec: triggers: - type: ConfigChange - imageChange: {} type: ImageChange source: git: uri: [GitリポジトリのURL] ref: master type: Git strategy: type: Source sourceStrategy: from: kind: ImageStreamTag name: nodejs:8 namespace: openshift output: to: kind: ImageStreamTag name: node-config-and-secrets:latest --- ## DeploymentConfig apiVersion: v1 kind: DeploymentConfig metadata: labels: app: node-config-and-secrets name: node-config-and-secrets spec: replicas: 1 selector: app: node-config-and-secrets deploymentconfig: node-config-and-secrets template: metadata: labels: app: node-config-and-secrets deploymentconfig: node-config-and-secrets spec: containers: - name: node-config-and-secrets image: node-config-and-secrets:latest imagePullPolicy: Always ports: - containerPort: 8080 protocol: TCP env: - name: CONFIG_USERNAME valueFrom: configMapKeyRef: name: app-config key: config-username - name: CONFIG_PASSWORD valueFrom: configMapKeyRef: name: app-config key: config-password - name: SECRET_USERNAME valueFrom: secretKeyRef: name: app-secrets key: secret-username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: app-secrets key: secret-password restartPolicy: Always triggers: - type: ConfigChange - type: ImageChange imageChangeParams: automatic: true containerNames: - node-config-and-secrets from: kind: ImageStreamTag name: node-config-and-secrets:latest --- ## Service apiVersion: v1 kind: Service metadata: labels: app: node-config-and-secrets name: node-config-and-secrets spec: ports: - name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 selector: app: node-config-and-secrets deploymentconfig: node-config-and-secrets --- ## Route apiVersion: v1 kind: Route metadata: labels: app: node-config-and-secrets name: node-config-and-secrets spec: port: targetPort: 8080-tcp to: kind: Service name: node-config-and-secrets
なお、今回のConfigMapおよびSecretsのキー名だと、そのまま環境変数として使うのは微妙ですが、コンテナにConfigMapやSecretsの 内容を環境変数として一括で取り込むには、こんな感じで。
spec: ... template: metadata: ... spec: containers: - name: node-config-and-secrets image: node-config-and-secrets:latest ... envFrom: - configMapRef: name: app-config - secretRef: name: app-secrets