---
title: Kubernetesハンズオン - 5. ConfigMap/Secretで設定情報の管理
tags: ["Kubernetes Handson", "Kubernetes", "PKS"]
categories: ["Dev", "CaaS", "Kubernetes"]
date: 2019-09-23T10:55:30Z
updated: 1970-01-01T00:00:00Z
---

実行環境に依存するようなアプリケーションの設定情報はコンテナイメージに埋め込むべきではなく、
環境変数などコンテナの外から埋め込まれるべきです。

Kubernetesにはアプリケーションと設定を分離するための仕組みとして`ConfigMap`と`Secret`が用意されています。
`ConfigMap`は一般的な設定情報を`Secret`には機密情報を保存します。

**目次**

<!-- toc -->

### ConfigMap

`ConfigMap`は設定情報の集合のように扱えます。`ConfigMap`に保存した設定をコンテナに対して、環境変数として設定したり、
あるいはファイル形式でマウントすることができます。

例えば、`making/hello-pks`イメージの[`application.properties`](https://github.com/making/hello-pks/blob/master/src/main/resources/application.properties)には

```
management.endpoint.shutdown.enabled=true
```

という設定があります。この設定は`/actuator/shutdown`にPOSTでリクエストを送るとアプリケーションがシャットダウンするエンドポイントを有効にするので、
ここではデプロイ時に無効にしたいと考えます。

また、デプロイ時には画像などの静的ファイルのcache period(3日間)を設定するために次の設定もします。

```
spring.resources.cache.period=3d
```

これらの設定をConfigMapを使って行います。


`ConfigMap`を適用する前に、静的ファイルにアクセスしてもキャッシュの設定が含まれていないことを確認します。
`curl -I http://<ServiceのLoad BalancerのIPまたはHost名>:8080/pks.png`を実行して、HTTPレスポンスヘッダを確認してください。

```
curl -I http://<ServiceのLoad BalancerのIPまたはHost名>:8080/pks.png
```
出力結果
```
HTTP/1.1 200 OK
transfer-encoding: chunked
Last-Modified: Mon, 9 Apr 2018 17:26:03 GMT
Content-Length: 4488
Content-Type: image/png
Accept-Ranges: bytes
```

同様に`/actuator/shutdown`にPOSTリクエストを送ってアプリケーションをシャットダウンしてください。

```
curl -XPOST http://<ServiceのLoad BalancerのIPまたはHost名>:8080/actuator/shutdown
```
実行結果
```json
{
  "message" : "Shutting down, bye..."
}
```

なお、シャットダウンしてもReplicaSetにより、コンテナは再起動します。

#### 環境変数の設定

ConfigMapの値をコンテナの環境変数に埋め込みます。

まずはConfigMapを作成します。`hello-pks-config.yml`を作成して、次の内容を記述してください。

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: hello-pks-config
data:
  management.endpoint.shutdown.enabled: "false" # 値は文字列である必要があり、booleanと区別するためクオートする必要がある
  spring.resources.cache.period: 3d
```

`data`以下にKey-Value形式で設定情報を定義できます。
`kubectl apply`でConfigMapをデプロイしてください。

```
kubectl apply -f hello-pks-config.yml
```
出力結果
```
configmap "hello-pks-config" created
```

`kubctl get configmap`でConfigMap一覧を確認できます。

```
kubectl get configmap
```
出力結果
```
NAME               DATA      AGE
hello-pks-config   1 
```

次にコンテナの環境変数にConfigMapから値を取得して埋め込みます。
Spring Bootの場合、プロパティ名は大文字と_区切りの環境変数でも設定できますので、
環境変数`MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED`と`SPRING_RESOURCES_CACHE_PERIOD`を設定します。


`hello-pks.yml`を次のように変更してください。

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  # ...
  template:
    # ...
    spec:
      containers:
      - image: making/hello-pks:0.0.2
        name: hello-pks
        ports:
        - containerPort: 8080
        env:
        # ...
        - name: MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED
          valueFrom:
            configMapKeyRef:
              name: hello-pks-config
              key: management.endpoint.shutdown.enabled
        - name: SPRING_RESOURCES_CACHE_PERIOD
          valueFrom:
            configMapKeyRef:
              name: hello-pks-config
              key: spring.resources.cache.period
```

`env[].value`の代わりに`env[].valueFrom.configMapKeyRef`を使ってConfigMapから値を参照できます。

`kubectl apply`でこの設定を適用してください。

```
kubectl apply -f hello-pks.yml
```
出力結果
```
deployment "hello-pks" configured
```

`kubectl get pod`を実行して`STATUS`が`Running`になっていることを確認してください。


再度、`curl -I http://<ServiceのLoad BalancerのIPまたはHost名>:8080/pks.png`を実行して、HTTPレスポンスヘッダを確認してください。

```
curl -I http://<ServiceのLoad BalancerのIPまたはHost名>:8080/pks.png
```
出力結果
```
HTTP/1.1 200 OK
transfer-encoding: chunked
Last-Modified: Mon, 9 Apr 2018 17:26:03 GMT
Cache-Control: max-age=259200
Content-Length: 4488
Content-Type: image/png
Accept-Ranges: bytes
```

`Cache-Control`ヘッダに`max-age=259200`(3日間)が設定されていることが分かります。

シャットダウンエンドポイントが無効になっていることも確認してください。

```
curl -XPOST http://<ServiceのLoad BalancerのIPまたはHost名>:8080/actuator/shutdown
```
出力結果
```json
{
  "timestamp" : "2018-04-17T16:48:00.074+0000",
  "path" : "/actuator/shutdown",
  "status" : 404,
  "error" : "Not Found",
  "message" : null
}
```

> `ConfigMap`のデータを全て環境変数に埋め込みたい場合、一つずつしなくとも[`envFrom`](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-pod-environment-variables)を使うことができます。

#### 設定ファイルとしてマウント

`ConfigMap`に設定ファイルの内容をそのまま保存し、環境変数ではなくファイルとしてコンテナにマウントすることができます。

`hello-pks-config.yml`の内容を次のように変更してください。

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: hello-pks-config
data:
  application.properties: |-
      management.endpoint.shutdown.enabled=false
      spring.resources.cache.period=3d
```

プロパティのKey-Valueを一つ一つ定義する代わりに、`application.properties`というキーに対する値にプロパティファイルの内容を全て設定しています。
`kubectl apply`で変更を適用してください。

```
kubectl apply -f hello-pks-config.yml
```
実行結果
```
configmap "hello-pks-config" configured
```

次にこの`ConfigMap`をマウントします。

Spring Bootは[アプリケーション実行ディレクトリ直下の`/config`ディレクトリに存在する`application.properties`を読み込みます](https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files)。
今回使用しているockerイメージの[デフォルトのカレントディレクトリは`/`](https://docs.docker.com/engine/reference/run/#workdir)なので、`/config`直下に`application.properties`をマウントできれれば起動時にこの設定が読み込まれます。この設定ファイルの方が優先度が高いです。

`hello-pks.yml`を次のように変更してください。

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  # ...
  template:
    # ...
    spec:
      containers:
      - image: making/hello-pks:0.0.2
        name: hello-pks
        ports:
        - containerPort: 8080
        volumeMounts: # 追加
        - name: application-properties
          mountPath: /config
          readOnly: true
        env:
        # ...
        # MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLEDおよび
        # SPRING_RESOURCES_CACHE_PERIODは削除してください
      volumes: # 追加(インデントに注意)
      - name: application-properties
        configMap:
          name: hello-pks-config
          items:
          - key: application.properties
            path: application.properties
```

`spec.template.volumes`にマウントできるファイルシステムを定義し、
実際にマウント対象のコンテナの`spec.template.spec.containers[].volumenMounts`にマウントするディレクトリを設定します。

`kubectl apply`でこの設定を適用してください。

```
kubectl apply -f hello-pks.yml
```
出力結果
```
deployment "hello-pks" configured
```

`kubectl get pod`を実行して`STATUS`が`Running`になっていることを確認してください。

`/actuator/env`エンドポイントにアクセスすると読み込まれているプロパティ一覧を出力することができます。

```
curl http://<ServiceのLoad BalancerのIPまたはHost名>:8080/actuator/env
```
出力結果
```json
{
  "activeProfiles" : [ ],
  "propertySources" : [ {
    "name" : "server.ports",
    "properties" : ...
  }, {
    "name" : "systemProperties",
    "properties" : ...
  }, {
    "name" : "systemEnvironment",
    "properties" : ...
  }, {
    "name" : "applicationConfig: [file:./config/application.properties]",
    "properties" : {
      "management.endpoint.shutdown.enabled" : {
        "value" : "false",
        "origin" : "URL [file:./config/application.properties]:1:38"
      },
      "spring.resources.cache.period" : {
        "value" : "3d",
        "origin" : "URL [file:./config/application.properties]:2:31"
      }
    }
  }, {
    "name" : "applicationConfig: [classpath:/application.properties]",
    "properties" : ...
  } ]
}
```

`/config/application.properties`が読み込まれていることを確認してください。上位のプロパティの方が優先度が高いです。

> 流れの都合上、Spring Bootアプリを題材に`ConfigMap`を説明しましたが、Spring Bootのプロパティは環境変数やシステムプロパティ変えたほうが便利で、あまり`ConfigMap`を使う機会はないかもしれません。次に説明する`Secret`は使います。<br>
> `ConfigMap`は設定ファイルでしか設定できないアプリをデプロイする際に便利です。

### Secret

`ConfigMap`には任意のデータを格納できますが、パスワードやプライベートキーなど機密性の高いデータを保存する場所として`Secret`が用意されています。

> ただし、`Secret`のデータが暗号化されて保存される訳ではありません。

#### 環境変数の設定

ここでは`Secret`にユーザー名とパスワードを保存し、`hello-pks`アプリケーションの認証に使用します。

まずは、認証に対応させたバージョンのDockerイメージに更新するため、イメージのタグを`0.0.4`にしてください。

`hello-pks.yml`は次の通りです。

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 50%
  selector:
    matchLabels:
      app: hello-pks
  template:
    metadata:
      labels:
        app: hello-pks
    spec:
      containers:
      - image: making/hello-pks:0.0.4 # <-- バージョン変更
        name: hello-pks
        ports:
        - containerPort: 8080
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: NODE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /actuator/info
            port: 8080
          initialDelaySeconds: 20
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 1
```


`kubectl apply`で変更を適用してください。

```
kubectl apply -f hello-pks.yml
```
出力結果
```
deployment "hello-pks" configured
```

Podが起動したら、`curl -I http://<ServiceのLoad BalancerのIPまたはHost名>:8080/actuator/env`を実行してください。

```
curl -I http://<ServiceのLoad BalancerのIPまたはHost名>:8080/actuator/env
```
出力結果
```
HTTP/1.1 401 Unauthorized
transfer-encoding: chunked
WWW-Authenticate: Basic realm="Realm"
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
```

401エラーになり、Basic認証が求められます。
このBasic認証のユーザー名、パスワードはそれぞれ環境変数`SPRING_SECURITY_USER_NAME`、`SPRING_SECURITY_USER_PASSWORD`で上書き可能です。


`Secret`を作成します。`hello-pks-secret.yml`に次の内容を記述してください。ユーザー名は`pksuser`、パスワードは`Y4nys7f11`とします。

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: hello-pks-secret
type: Opaque
data:
  spring.security.user.name: cGtzdXNlcg==
  spring.security.user.password: WTRueXM3ZjEx
```

YAML中の`Secret`の`data`の値はBase64でエンコードする必要があります。
次のように値をエンコードして、設定してください。

```
echo -n pksuser | base64
echo -n Y4nys7f11 | base64
```

`base64`コマンドを使う代わりに、次のように作成すると便利です。

```
kubectl create secret generic hello-pks-secret \
  --from-literal=spring.security.user.name=pksuser \
  --from-literal=spring.security.user.password=Y4nys7f11 \
  --dry-run \
  -o yaml > hello-pks-secret.yml
```

あるいは`data`の代わりに`stringData`を使用すればBase64エンコーディングをする必要がありません。

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: hello-pks-secret
type: Opaque
stringData:
  spring.security.user.name: pksuser
  spring.security.user.password: Y4nys7f11
```

`kubectl apply -f hello-pks-secret.yml`を実行してください。


`kubectl get secret`でSecret一覧を確認できます。

```
kubectl get secret
```
出力結果
```
NAME                  TYPE                                  DATA      AGE
default-token-nkp9k   kubernetes.io/service-account-token   3         2d
hello-pks-secret      Opaque                                2         10s
```

`hello-pks-secret.yml`はGitなどバージョン管理システムに**チェックインしないよう**に気をつけて下さい。


`hello-pks.yml`を次のように変更してください。

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  # ...
  template:
    # ...
    spec:
      containers:
      - image: making/hello-pks:0.0.4
        name: hello-pks
        ports:
        - containerPort: 8080
        env:
        # ...
        - name: SPRING_SECURITY_USER_NAME
          valueFrom:
            secretKeyRef:
              name: hello-pks-secret
              key: spring.security.user.name
        - name: SPRING_SECURITY_USER_PASSWORD
          valueFrom:
            secretKeyRef:
              name: hello-pks-secret
              key: spring.security.user.password
```

`kubectl apply`で変更内容を反映してください。

```
kubectl apply -f hello-pks.yml
```
出力結果
```
deployment "hello-pks" configured
```

`curl`のオプションに`-u pksuser:Y4nys7f11`を付けて`/actuator/env`にアクセスしてください。

```
curl -I -u pksuser:Y4nys7f11 http://<ServiceのLoad BalancerのIPまたはHost名>:8080/actuator/env
```
出力結果
```
HTTP/1.1 200 OK
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Content-Length: 12116
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
```

#### TLS証明書の設定

次はSecretにTLS証明書を保存し、この証明書を使って`hello-pks`アプリケーションのHTTPS対応を行います。

今回はアプリケーションのドメインとして[sslip.io](https://sslip.io)を使用します。

`sslip.io`は、例えば`192-168-0-1.sslip.io`というドメイン名解決すると`192.168.0.1`を返す、DNSサービスです。
この機能により、任意のIPアドレスに対して、ドメイン名を持つことができます。
任意のアルファベットと`-`を先頭につけた`hello-192-168-0-1.sslip.io`というドメインでも`192.168.0.1`が返ります。

Node VMのIPアドレスが`x.y.z.w`の場合、`hello-pks-x-y-z-w.sslip.io`を`hello-pks`アプリケーションのドメインにします。

まずは`*.sslip.io`に対して、`openssl`コマンドでTLS自己署名証明書を作成します。[こちら](https://raw.githubusercontent.com/aws-quickstart/quickstart-pivotal-cloudfoundry/master/scripts/gen_ssl_certs.sh)からスクリプトをダウンロードし、次のコマンドを実行してください。
```
chmod +x gen_ssl_certs.sh
./gen_ssl_certs.sh sslip.io
```
作成された`sslip.io.crt`が証明書、`sslip.io.key`が秘密鍵です。

TLS証明書のSecretは特別に`--cert`と`--key`オプションで`kubectl create secret`で作成できます。次のコマンドを実行してください。

```
kubectl create secret tls hello-pks-tls \
  --cert=sslip.io.crt \
  --key=sslip.io.key \
  --dry-run \
  -o yaml \
  > hello-pks-tls.yml

kubectl apply -f hello-pks-tls.yml
```
出力結果
```
secret "hello-pks-tls" created
```

> ServiceのExternal IPがHost名の場合は、`./gen_ssl_certs.sh <External IPのホスト名>`でも良いです。<br>
> ELBの場合は例えば`./gen_ssl_certs.sh ap-northeast-1.elb.amazonaws.com`でも良いです。<br>
> この場合は、次のようにSecretを作成してください。
>
> ```
> kubectl create secret tls hello-pks-tls \
>   --cert=ap-northeast-1.elb.amazonaws.com.crt \
>   --key=ap-northeast-1.elb.amazonaws.com.key \
>   --dry-run \
>   -o yaml \
>   > hello-pks-tls.yml
> 
> kubectl apply -f hello-pks-tls.yml
> ```

`kubectl get secret`でSecret一覧を確認してください。

```
kubectl get secret
```
出力結果
```
NAME                  TYPE                                  DATA      AGE
default-token-nkp9k   kubernetes.io/service-account-token   3         2d
hello-pks-secret      Opaque                                2         2h
hello-pks-tls         kubernetes.io/tls                     2         9s
```

このTLS証明書を使って`hello-pks`アプリケーションのHTTPS対応を行うための設定を行います。

SecretにはPEM形式の証明書が保存されていますが、JavaアプリケーションではPEM形式のままでは読み込めず、
PKCS12形式に変換した後、Keystoreにインポートする必要があります。

`hello-pks.yml`に次の内容を記述して下さい。証明書の変換処理は[Init Containers](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)で行います。

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 50%
  selector:
    matchLabels:
      app: hello-pks
  template:
    metadata:
      labels:
        app: hello-pks
    spec:
      initContainers:
      - image: openjdk:8-jdk-slim
        name: pem-to-keystore
        volumeMounts:
        - name: keystore-volume
          mountPath: /keystores
        - name: hello-pks-tls
          mountPath: /hello-pks-tls
        env:
        - name: SERVER_SSL_KEY_PASSWORD
          valueFrom:
            secretKeyRef:
              name: hello-pks-secret
              key: server.ssl.key-password
        command:          
        - sh
        - -c
        - |
          openssl pkcs12 -export \
                  -name hello-pks \
                  -in /hello-pks-tls/tls.crt \
                  -inkey /hello-pks-tls/tls.key \
                  -out /keystores/hello-pks.p12 \
                  -password pass:foobar
          keytool -importkeystore \
                  -destkeystore /keystores/hello-pks.jks \
                  -srckeystore /keystores/hello-pks.p12 \
                  -deststoretype pkcs12 \
                  -srcstoretype pkcs12 \
                  -alias hello-pks \
                  -deststorepass ${SERVER_SSL_KEY_PASSWORD} \
                  -destkeypass ${SERVER_SSL_KEY_PASSWORD} \
                  -srcstorepass foobar \
                  -srckeypass foobar \
                  -noprompt
      containers:
      - image: making/hello-pks:0.0.4
        name: hello-pks
        ports:
        - containerPort: 8443
        volumeMounts:
        - name: keystore-volume
          mountPath: /keystores
          readOnly: true
        env:
        - name: SERVER_PORT
          value: "8443"
        - name: SERVER_SSL_ENABLED
          value: "true"
        - name: SERVER_SSL_PROTOCOL
          value: TLSv1.2
        - name: SERVER_SSL_KEY_STORE
          value: file:///keystores/hello-pks.jks
        - name: SERVER_SSL_KEY_STORE_TYPE
          value: PKCS12
        - name: SERVER_SSL_KEY_ALIAS
          value: hello-pks
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: NODE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: SPRING_SECURITY_USER_NAME
          valueFrom:
            secretKeyRef:
              name: hello-pks-secret
              key: spring.security.user.name
        - name: SPRING_SECURITY_USER_PASSWORD
          valueFrom:
            secretKeyRef:
              name: hello-pks-secret
              key: spring.security.user.password
        - name: SERVER_SSL_KEY_PASSWORD
          valueFrom:
            secretKeyRef:
              name: hello-pks-secret
              key: server.ssl.key-password
        - name: SERVER_SSL_KEY_STORE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: hello-pks-secret
              key: server.ssl.key-password
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 8443
            scheme: HTTPS
          initialDelaySeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /actuator/info
            port: 8443
            scheme: HTTPS
          initialDelaySeconds: 20
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 1
      volumes:
      - name: keystore-volume
        emptyDir: {}
      - name: hello-pks-tls
        secret:
          secretName: hello-pks-tls
---
apiVersion: v1
kind: Service
metadata:
  name: hello-pks
spec:
  type: LoadBalancer # LoadBalancerに対応していない場合はNodePort
  selector:
    app: hello-pks
  ports:
  - protocol: TCP
    port: 8443 # 8080から変更
```

`spec.template.spec.initContainers`にPod内で初期処理のための設定を記述します。
初期処理に必要な`openssl`と`keytool`コマンドを含む、[`openjdk:8-jdk-slim`](https://hub.docker.com/_/openjdk/)イメージを使用します。
初期処理のスクリプトは`spec.template.spec.initContainers[].command`に記述できます。
`spec.template.spec.volumes[]`にSecretのTLS証明書をマウントするために`hello-pks-tls`というVolumeと、変換したKeystoreファイルをコンテナ間で共有するための
`keystore-volume`というVolumeを定義します。`keystore-volume`の定義に`emptyDir`が設定されていますが、これはPodが生存している間、そのPod内で利用可能な一時的なVolumeです。
Secretに保存されているTLS証明書および秘密鍵はマウントしたディレクトリに`tls.crt`と`tls.key`というファイル名で参照可能になります。Init Containerでは
この証明書を`opensssl`コマンドでPKCS12形式に変換し、`keytool`コマンドでKeystoreにインポートし、Keystoreを`keystore-volume`に保存しています。
あとは`hello-pks`コンテナでもこのVolumeをマウントすればアプリケーションでKeystoreを参照できるようになります。

アプリケーションのポートは慣習的に`8443`にします。`hello-pks`コンテナはポート番号を`8080`から`8443`に変える必要があります。また、ヘルスチェックのプロトコルもHTTPSにする必要があります。
`Service`のポートも8443に変更します。

KeystoreのパスワードをSecretに保存するため、`hello-pks-secret.yml`に次の内容を記述して下さい。

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: hello-pks-secret
type: Opaque
stringData:
  spring.security.user.name: pksuser
  spring.security.user.password: Y4nys7f11
  # ここから追加
  server.ssl.key-password: changeme
```

以上の設定を適用するため、`hello-pks-*.yml`のあるディレクトリで、次のコマンドを実行して下さい。まとめて適用されます。

```
kubectl apply -f hello-pks.yml -f hello-pks-secret.yml -f hello-pks-tls.yml
```
実行結果
```
deployment.apps/hello-pks configured
service/hello-pks configured
secret/hello-pks-secret configured
secret/hello-pks-tls configured
```

Podの`STATUS`が`Running`になったら、アプリケーションにアクセスしましょう。今度はHTTPではなく、HTTPSを使用して下さい。
自己署名証明書を使用しているので、`curl`の引数には`-k`をつけて下さい。

* Serviceの`type`が`NodePort`の場合、Node VMのIPアドレスが`x.y.z.w`であれば、アクセスするURLは`https://hello-pks-x-y-z-w.sslip.io:<Node Port>`です。
* Serviceの`type`が`LoadBalancer`の場合、`EXTERNAL-IP`が`x.y.z.w`であれば、アクセスするURLは`https://hello-pks-x-y-z-w.sslip.io:8443`です。

NodePortの場合、
```
curl -k https://hello-pks-127-0-0-1.sslip.io:31691
```
出力結果(Docker for Mac)
```
{
  "node" : {
    "NODE_IP" : "192.168.65.3",
    "NODE_NAME" : "docker-for-desktop"
  },
  "pod" : {
    "POD_IP" : "10.1.0.52",
    "POD_NAME" : "hello-pks-859d9c7ffb-98vqw",
    "POD_NAMESPACE" : "default"
  },
  "container" : { }
}
```

LoadBalancer(IP)の場合、
```
curl -k https://35-200-1-108.sslip.io:8443
```
出力結果(PKS on GCP)
```
{
  "node" : {
    "NODE_IP" : "192.168.20.11",
    "NODE_NAME" : "vm-ad363daf-92c1-4aaf-52bc-318abc9b59c9"
  },
  "pod" : {
    "POD_IP" : "10.200.11.25",
    "POD_NAME" : "hello-pks-5546489c9c-bn955",
    "POD_NAMESPACE" : "default"
  },
  "container" : { }
}
```

LoadBalancer(Host名)の場合、
```
curl -k https://abcc9a7f0de2211e9812f06c9c16b7d6-2012270132.ap-northeast-1.elb.amazonaws.com:8443
```
出力結果(PKS on AWS)
```
{
  "node" : {
    "NODE_IP" : "10.0.8.8",
    "NODE_NAME" : "ip-10-0-8-8.ap-northeast-1.compute.internal"
  },
  "pod" : {
    "POD_IP" : "10.200.59.36",
    "POD_NAME" : "hello-pks-794f4478f7-4j8w2",
    "POD_NAMESPACE" : "default"
  },
  "container" : { }
}
```


ブラウザでもHTTPSでアクセスできることを確認して下さい。

![image](https://user-images.githubusercontent.com/106908/39065445-c7734d28-450c-11e8-82b2-52b3c3b5acad.png)
