> For the complete documentation index, see [llms.txt](https://docs.keeper.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keeper.io/keeperpam/jp/secrets-manager/integrations/kubernetes.md).

# Kubernetes

![](/files/3dHNiGH6fyudpc1KO8sQ)

{% hint style="warning" %}
ほとんどのユースケースでは、[Kubernetes外部シークレットオペレータ](/keeperpam/jp/secrets-manager/integrations/kubernetes-external-secrets-operator.md)連携の利用を推奨します。本ドキュメントでは、External Secrets Operatorを使用しない代替の連携方法について取り扱います。
{% endhint %}

## 機能 <a href="#features" id="features"></a>

* Kubernetes内でKeeperボルトからシークレットを取得
* すべてのポッドでKeeperボルトのシークレットにリアルタイムでアクセス
* Keeperボルトからローカルファイルシステムへセキュアなファイル添付をコピー

{% hint style="info" %}
Keeperシークレットマネージャーの機能一覧については、[概要](/keeperpam/jp/secrets-manager/overview.md)をご参照ください。
{% endhint %}

## 要件 <a href="#prerequisites" id="prerequisites"></a>

本ページでは、シークレットマネージャーのKubernetes連携について取り扱います。本連携を利用するには、以下が必要です。

* Keeperシークレットマネージャーへのアクセス（[クイックスタートガイド](/keeperpam/jp/secrets-manager/quick-start-guide.md)をご参照ください）
  * Keeperのサブスクリプションでシークレットマネージャーアドオンが有効になっていること
  * シークレットマネージャーポリシーが有効なロールに所属していること
* シークレットが共有されているKeeper[シークレットマネージャーアプリケーション](/keeperpam/jp/secrets-manager/about/terminology.md#application)
  * アプリケーションの作成手順については、[クイックスタートガイド](https://docs.keeper.io/keeperpam/jp/secrets-manager/integrations/pages/-MeRAVfQmDBzKQBC0f_c#2.-create-an-application)をご参照ください

## 概要 <a href="#about" id="about"></a>

KeeperシークレットマネージャーをK8sクラスタに統合すると、すべてのポッドでKeeperシークレットにリアルタイムでアクセスできます。

## 設定 <a href="#setup" id="setup"></a>

### シークレットマネージャー構成を作成 <a href="#create-a-secrets-manager-configuration" id="create-a-secrets-manager-configuration"></a>

Keeperコマンダーで、Kubernetes用のシークレットマネージャーデバイス構成を作成します。この構成はIPロックされておらず、事前に初期化されている点にご注意ください。

以下のコマンドでKeeperコマンダーに構成を作成します。

`secrets-manager client add --app <APP NAME> --unlock-ip --config-init k8s`

**例:**

{% code lineNumbers="true" %}

```
My Vault> sm client add --app MyAdd --unlock-ip --config-init k8s

Successfully generated Client Device
====================================

Initialized Config:

apiVersion: v1
data:
  config: ewog2N...ICIxMCIKfQ==
metadata:
  name: ksm-config
  namespace: default
type: Opaque

IP Lock: Disabled
Token Expires On: 2021-10-13 12:45:45
App Access Expires on: Never
```

{% endcode %}

上記の例では、8行目から14行目をコピーし、`secret.yaml` というファイルに貼り付けます。次に、`kubectl` がインストールされたマシンでクラスタにアクセスできる場合は、KSM SDK構成をKubernetesシークレットに追加します。

```
$ kubectl apply -f secret.yaml
```

{% hint style="info" %}
シークレットマネージャー構成の作成の詳細については、[構成ドキュメント](/keeperpam/jp/secrets-manager/about/secrets-manager-configuration.md)をご参照ください。
{% endhint %}

### 代替方法: ワンタイムアクセストークンとKSM CLI <a href="#alternate-method-one-time-access-token-and-ksm-cli" id="alternate-method-one-time-access-token-and-ksm-cli"></a>

または、Keeperコマンダー（またはボルトUI）でワンタイムアクセストークンを生成し、[KeeperシークレットマネージャーCLI](/keeperpam/jp/secrets-manager/secrets-manager-command-line-interface.md)で以下のように構成を作成できます（`XX:XXX` はワンタイムアクセストークンに置き換えます）。

```yaml
$ ksm init k8s XX:XXX

apiVersion: v1
data:
  config: ewog2N[...]ICIxMCIKfQ==
kind: Secret
metadata:
  name: ksm-config
  namespace: default
type: Opaque
```

`kubectl` がインストールされたマシンでクラスタにアクセスできる場合は、パラメータ `--apply` を指定して、KSM SDK構成をKubernetesシークレットに自動追加できます。

トークン引き換えの出力をファイルにリダイレクトし、`kubectl` で適用できます。以下に例を示します。

```bash
$ ksm init k8s XX:XXX > secret.yaml
$ kubectl apply -f secret.yaml
secret/ksm-config created
```

## KSM構成の利用 <a href="#using-the-ksm-config" id="using-the-ksm-config"></a>

KSM構成は、[シークレット](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables)を使ってK8sコンテナに取り込めます。

```
apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: mycontainer
    image: my_container:XXXXX
    env:
      - name: KSM_CONFIG
        valueFrom:
          secretKeyRef:
            name: ksm-config
            key: config
  restartPolicy: Never
```

実行時、K8sクラスタで動作するKeeperシークレットマネージャーSDKは、環境変数**KSM\_CONFIG**からデバイス構成を取得し、Keeperボルトと通信します。

## 例 <a href="#examples" id="examples"></a>

### 例1 - SDKを使ったカスタムアプリ <a href="#example-1-custom-app-using-sdk" id="example-1-custom-app-using-sdk"></a>

以下は、ウェブアプリケーションでデータベースシークレットを表示するデプロイメントとサービスを生成する簡単な例です。本例ではウェブアプリケーションにKeeper PythonシークレットマネージャーSDKを使用します。SDKはKubernetesシークレットから構成を取得し、KeeperボルトからPostgreSQLデータベースレコードの情報を取得します。

Keeperボルトで、以下の情報を使って「データベース」レコードタイプを作成します。

![](/files/p0FKQyFkfFNLhGX0ZrdC)

次にウェブアプリケーションを作成します。ウェブページは任意のシークレットマネージャーSDKで作成できます。本例ではPython SDKを使用します。単一エンドポイントを持つシンプルなFlaskアプリケーションが、ボルトレコードのシークレットを含むHTMLを表示します。シークレットは[Keeper表記法](/keeperpam/jp/secrets-manager/about/keeper-notation.md)構文で取得します。

```
from flask import Flask
from keeper_secrets_manager_core import SecretsManager
import os

app = Flask(__name__)

@app.route("/")
def hello_world():
    sm = SecretsManager()
    return """
<h1>Database</h1>
<ul>
    <li>Type: {}</li>
    <li>Host: {}</li>
    <li>Port: {}</li>
    <li>Login: {}</li>
    <li>Password: {}</li>
</ul>
""".format(
       sm.get_notation(os.environ.get("DB_TYPE")),
       sm.get_notation(os.environ.get("DB_HOST")),
       sm.get_notation(os.environ.get("DB_PORT")),
       sm.get_notation(os.environ.get("DB_LOGIN")),
       sm.get_notation(os.environ.get("DB_PASS")))
```

次にDockerfileを作成します。以下のDockerfileはDocker HubのPython Debianイメージをベースにしています。

{% hint style="info" %}
Python SDKは暗号化モジュール `cryptography` を使用します。このモジュールのビルドにはRustが必要です。RustがプリインストールされているDocker Hubイメージもあります。
{% endhint %}

```
FROM python:3.10.0-slim-bullseye
RUN apt-get update \
    && apt-get install -y gcc make libffi-dev curl libssl-dev \
    && apt-get clean
RUN pip3 install --upgrade pip wheel

# cryptographyのビルドにはRustが必要
RUN curl https://sh.rustup.rs -sSf > /tmp/rust.sh \
    && chmod a+x /tmp/rust.sh \
    && /tmp/rust.sh -y
ENV PATH $PATH:/root/.cargo/bin

RUN pip3 install \
    flask \
    keeper-secrets-manager-core

RUN groupadd -g 5000 demo
RUN useradd -g demo demo

# アプリケーションをイメージにコピー
COPY demo.py /demo.py

USER demo

ENV FLASK_APP demo

EXPOSE 5000
CMD ["flask", "run"]
```

次に、`ksm_demo` という名前のDockerイメージをビルドします。

```
$ docker build -t ksm_demo .
```

Kubernetesクラスタにアクセスできる場合、ワンタイムアクセストークンから構成を生成して自動適用できます。

```
$ ksm init k8s --apply XX:XXXXXXXXXXX
secret/ksm-config created
Created secret for KSM config.
```

`kubectl get secret` を実行すると、シークレットエントリを確認できます。

```
$ kubectl get secret ksm-config
NAME         TYPE     DATA   AGE
ksm-config   Opaque   1      55s
```

続いて、**ksm\_demo**Dockerイメージ用のデプロイメントとサービスを作成します。本例ではファイル名を**ksm\_demo.yaml**とします。

必要なシークレットとSDKの構成は、**containers**一覧の**env**セクションで定義します。このセクションでは**KSM\_CONFIG**環境変数に、Kubernetesシークレット**ksm-config**の**config**キーの値を設定します。

その他の環境変数は名前と値のリストです。値にはKeeper表記法を指定し、ウェブアプリケーションがSDKの表記法取得メソッドに渡します。

**ksm\_demo.yaml**の2つ目の定義は**Service**です。Kubernetesクラスタに合わせて変更できます。本例では外部IPアドレスを使用します。例として、KubernetesノードのIPアドレス（10.0.1.18）を使用しても問題ありません。

```
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ksm-demo-deployment
  labels:
    app: ksm-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ksm-demo
  template:
    metadata:
      labels:
        app: ksm-demo
    spec:
      nodeSelector:
        kubernetes.io/hostname: work
      dnsPolicy: "None"
      dnsConfig:
        nameservers:
          - 10.0.1.207
          - 1.1.1.1
      containers:
        - name: ksm-demo
          image: ksm_demo:latest
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 5000
              protocol: TCP
          env:
            - name: KSM_CONFIG
              valueFrom:
                secretKeyRef:
                  name: ksm-config
                  key: config
            - name: DB_TYPE
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/Type"
            - name: DB_HOST
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/host[hostName]"
            - name: DB_PORT
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/host[port]"
            - name: DB_LOGIN
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/login"
            - name: DB_PASS
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/password"
---   
apiVersion: v1
kind: Service
metadata:
  name: ksm-demo-service
spec:
  ports:
    - name: http
      port: 5000
      targetPort: 5000
      protocol: TCP
  selector:
    app: ksm-demo
  externalIPs:
    - 10.0.1.18
```

この時点でデプロイメントとサービスを適用できます。

```
$ kubectl apply -f ksm_demo.yaml
deployment/ksm-demo-deployment created
service/ksm-demo-service created
```

デプロイメントの準備が整うまで待ちます。コマンドラインまたはKubernetesダッシュボードで監視してください。

```
$ kubectl get deployment ksm-demo-deployment
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
ksm-demo-deployment   1/1     1            1           46m

$ kubectl get svc ksm-demo-service
NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
ksm-demo-service   ClusterIP   10.107.91.89   10.0.1.18     5000/TCP   56m
```

最後に、ウェブブラウザで外部IPアドレスのポート5000にアクセスすると、Keeperボルトのデータベースレコードのシークレットが表示されます。

![Keeperシークレットを表示するウェブアプリケーションの例](/files/QvvcYczVGYOzquv1goBq)

### 例2 - NGINX SSL証明書 <a href="#example-2-nginx-ssl-certificates" id="example-2-nginx-ssl-certificates"></a>

本例では、標準のNGINX Dockerイメージと、Keeperボルトから取得したSSL証明書を含むポッドを作成します。

ボルトにログインレコードを作成し、SSL証明書、秘密鍵、証明書パスワードを格納します。

![](/files/zYbG2H4JogEFdVNds31a)

ワンタイムトークンを生成し、Kubernetesシークレットに追加します。

```bash
$ ksm init k8s XX:XXX > secret.yaml
$ kubectl apply -f secret.yaml
secret/ksm-config created
```

例のウェブサイトは単純なインデックスHTMLページです。HTMLはConfigMapに保存し、ドキュメントルートディレクトリにマウントできます。

```yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-html-config
  namespace: default
  labels:
    app: nginx
data:
  index.html: |
    <html>
      <head>
         <title>Nginx Test Page</title>
      </head>
      <body>
        <h1>Hello From Keeper Secrets Manager!</h1>
      </body>
    </html>
```

`default.conf` は本例で上書きします。証明書、鍵、パスワードは `/etc/keys` ディレクトリに配置します。非対話型起動では、NGINXは証明書パスワードをファイルに置き、サーバー構成に `ssl_password_file` を含める必要があります。

```yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  namespace: default
  labels:
    app: nginx
data:
  default.conf: |
    server {
      listen 80 default;
      server_name localhost;
      location / {
        root /var/www/nginx-default;
        index index.html index.htm;
      }
    }
    server {
      listen 443 ssl;
      server_name localhost;
      ssl_certificate /etc/keys/example.com.crt;
      ssl_certificate_key /etc/keys/example.com.key;
      ssl_password_file /etc/keys/global.pass;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_ciphers HIGH:!aNULL:!MD5;
      location / {
        root /var/www/nginx-default;
        index index.html index.htm;
      }
    }
```

本例のデプロイメントは以下のとおりです。

```yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      initContainers:
        - name: ksm
          image: keeper/keeper-secrets-manager-writer:latest
          env:
            - name: KSM_CONFIG
              valueFrom:
                secretKeyRef:
                  name: ksm-config
                  key: config
            - name: SECRETS
              value: |
                5x0v0VFwYj2VvuhamrJhzQ/field/password > file:/etc/keys/global.pass
                5x0v0VFwYj2VvuhamrJhzQ/file/example.com.crt > file:/etc/keys/example.com.crt
                5x0v0VFwYj2VvuhamrJhzQ/file/example.com.key > file:/etc/keys/example.com.key
          volumeMounts:
            - mountPath: "/etc/keys"
              name: keys-volume
      containers:
        - name: nginx
          image: nginx:1.21.4-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
              protocol: TCP
            - containerPort: 443
              protocol: TCP
          volumeMounts:
            - mountPath: "/etc/keys"
              name: keys-volume
            - mountPath: "/etc/nginx/conf.d/default.conf"
              name: nginx-config-file
              subPath: default.conf
            - mountPath: "/var/www/nginx-default/index.html"
              name: nginx-html-file
              subPath: index.html
      volumes:
        - name: keys-volume
          emptyDir: {}
        - name: nginx-config-file
          configMap:
            name: nginx-config
        - name: nginx-html-file
          configMap:
            name: nginx-html-config
      imagePullSecrets:
        - name: my-docker-hub-secrets
```

Dockerイメージ `keeper/keeper-secrets-manager-writer` は初期化コンテナとして使用します。コンテナはシークレットを取得してディスクに書き込み、NGINXで利用できるようにします。シークレットはポッドのemptyDirボリュームに書き込まれ、`/etc/keys` にマウントされます。ポッド削除時にこのディレクトリは削除されます。

{% hint style="info" %}
KeeperシークレットマネージャーWriterのドキュメントは[こちら](/keeperpam/jp/secrets-manager/integrations/docker-writer-image.md)をご参照ください。
{% endhint %}

メインコンテナもポッドのemptyDirボリュームを `/etc/keys` にマウントします。さらに `default.conf` を `/etc/nginx/conf.d` に、 `index.html` をサーバーのドキュメントルートにマウントします。

最後に、以下のとおりNGINXにアクセスするサービスを作成します。

```
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
    - name: http
      port: 80
      targetPort:  80
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
  selector:
    app: nginx
  externalIPs:
    - XXX.XXX.XXX.XX
```

httpsで外部IPにアクセスしてサービスをテストできます（例: <https://XXX.XXX.XXX.XXX）。アドレスバーの鍵アイコンは証明書が有効であることを示します。>

![](/files/1HYtRIf04t1irXUpp3nd)

### 外部シークレット <a href="#external-secrets" id="external-secrets"></a>

External Secretsは、外部APIからシークレットを同期してKubernetesに注入するKubernetesオペレータです。KeeperボルトからKubernetesへシークレットを同期するExternal Secretsのセットアップ方法の詳細は、以下をご参照ください。

{% content-ref url="/pages/1W2jYyeHC58xvrjOXwke" %}
[Kubernetes外部シークレットオペレータ](/keeperpam/jp/secrets-manager/integrations/kubernetes-external-secrets-operator.md)
{% endcontent-ref %}

### 次のステップ <a href="#next-steps" id="next-steps"></a>

この時点で、[シークレットマネージャーSDK](/keeperpam/jp/secrets-manager/developer-sdk-library.md)のいずれかを使って、KeeperシークレットマネージャーをK8sデプロイメントに統合できます。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keeper.io/keeperpam/jp/secrets-manager/integrations/kubernetes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
