オペレータは、アドバンスト・ユーザー用のオプションのREST APIを提供します。 APIは、WebLogicドメインおよびクラスタのリストを取得するための代替メソッド(たとえば、kubectl get domains
をコールするかわりに)、またはドメインのステータスの特定の側面を取得するために使用できます(たとえば、kubectl get domain MYDOMAIN -o yaml
をコールするかわりに)。 また、REST APIまたはコマンドラインを使用してドメイン・リソースのreplicas
値を変更するのではなく、スケーリング操作を開始するための代替アプローチとしてREST APIを使用することもできます。
オペレータ・バージョン4.0.5以降、オペレータのRESTエンドポイントはデフォルトで無効になっています。 Helmインストール・オプション--set "enableRest=true"
を指定してオペレータをインストールし、RESTエンドポイントを有効にします。
オペレータは、Kubernetesクラスタの外部からアクセスできる外部REST HTTPSインタフェースを公開できます。 オペレータの内部RESTインタフェースと同様に、外部RESTインタフェースには、外部RESTインタフェースのアイデンティティとして使用されるSSL/TLS証明書および秘密キーが必要です。
外部RESTインタフェースを有効にするには、カスタム構成ファイルまたはHelmコマンドラインでこれらの値を構成します:
externalRestEnabled
をtrue
に設定します。externalRestIdentitySecret
を、証明書および秘密キーを含むKubernetes tls secret
の名前に設定します。 RESTアイデンティティ・シークレットの詳細は、「オペレータの外部証明書の更新」を参照してください。 externalRestHttpsPort
をオペレータRESTインタフェースの外部ポート番号に設定します(デフォルトは31001
)。ノート: ノード・ポートは、一部の環境でパブリックにインターネットにさらされる可能性があるため、セキュリティ上のリスクです。 RESTポートへの外部アクセスが必要な場合は、ロード・バランサを介したアクセスの提供、またはKubernetesポート転送の使用などの代替方法を検討してください。
オペレータが現在使用中または外部REST API SSL/TLSアイデンティティなしでインストールされている外部証明書およびキーを更新する必要がある場合は、helm upgrade
コマンドを使用して、必要な証明書を含む新規または更新されたKubernetes tls secret
でオペレータを再起動します。
オペレータは、新規または更新された外部証明書の使用を開始するために再起動が「必要」です。 Helm --recreate-pods
フラグを使用して、既存のKubernetesポッドを終了し、更新された構成で新しいポッドを開始します。
たとえば、オペレータがネームスペースweblogic-operator-ns
でHelmリリース名weblogic-operator
とともにインストールされ、Kubernetes tls secret
の名前がweblogic-operator-cert
の場合、次のコマンドを使用すると、オペレータ証明書およびキーを更新できます:
$ kubectl create secret tls weblogic-operator-cert -n weblogic-operator-ns \
--cert=<path-to-certificate> --key=<path-to-private-key>
$ helm get values weblogic-operator -n weblogic-operator-ns
$ helm -n weblogic-operator-ns upgrade weblogic-operator weblogic-operator/weblogic-operator \
--wait --recreate-pods --reuse-values \
--set externalRestEnabled=true \
--set externalRestIdentitySecret=weblogic-operator-cert
その他のリソース:
GET
を使用して、ほとんどのRESTサービスにアクセスできます。次に例を示します:
GET
リクエストをURL /operator/latest/domains
に送信GET
リクエストをURL /operator/latest/domains/<domainUID>/clusters
に送信すべてのRESTサービスに認証が必要です。 コール元は有効なトークン・ヘッダーを渡す必要があり、サーバーによって提示されるX.509証明書がクライアントによって信頼されるように、トラスト・ストアに適切に構成されたCA証明書が必要です(「オペレーティング・システムのトラスト・ストアに証明書を追加する方法」を参照)。 以前のオペレータ・バージョンでは、オペレータはKubernetesトークン・レビューおよびサブジェクト・アクセス・レビューAPIを使用してチェックを実行した後、オペレータの権限を使用してドメイン・リソースを更新しました。 デフォルトでは、オペレータはコール元のベアラー・トークンを使用して、コール元の権限を使用してドメイン・リソースに対する基礎となる更新を実行するため、認証および認可チェックをKubernetes APIサーバーに直接委任します(「RESTインタフェース構成」を参照)。 Kubernetesクラスタ認証および認可構成に応じて、有効なトークンを取得する方法が複数あります。 Kubernetesサービス・アカウントの使用例については、「サンプルのオペレータRESTクライアント・スクリプト」を参照してください。
オペレータのRESTサービスを使用してWebLogicクラスタをスケール・アップまたはスケール・ダウンする場合、コール元のベアラー・トークンに関連付けられたユーザーまたはサービス・アカウントにpatch
アクセス権を付与する必要がある場合があります。 これは、ユーザーまたはサービス・アカウントと、WebLogic domains
リソースのアクセス権を定義するClusterRoleの間のRBAC ClusterRoleBindingを使用して実行できます。 詳細は、Kubernetesドキュメントの「RBAC認可の使用」を参照してください。
コール元は、Accept:/application/json
ヘッダーを渡す必要があります。
クロス・サイト・リクエスト・フォージェリ(CSRF)攻撃から保護するために、オペレータREST APIでは、変更を行うRESTエンドポイントを起動するとき(たとえば、/scale
エンドポイントにPOSTするとき)にX-Requested-By
ヘッダーで送信する必要があります。 値は、MyClient
などの任意の名前です。 たとえば、curl
を使用する場合は、次のようにします:
$ curl ... -H X-Requested-By:MyClient ... -X POST .../scaling
X-Requested-By
ヘッダーを渡さない場合、リクエストが不正である理由を説明する詳細なしで400 (不正なリクエスト)レスポンスが返されます。 X-Requested-By
ヘッダーは、オペレータのRESTエンドポイントのいずれかをGETする場合など、読取り専用のリクエストには必要ありません。
「サンプルのオペレータRESTクライアント・スクリプト」を使用する前に、次を実行する必要があります:
values.yaml
ファイルを指します(証明書を取得できるようにします)。curl
のバージョンを更新する必要がある場合があります(新しいバージョンのmacOSには新しいバージョンのcurl
が付属しています)。 Oracleでは、curl 7.63.0 (x86_64-apple-darwin17.7.0) libcurl/7.63.0 SecureTransport zlib/1.2.11
以降をお薦めします。 不明な場合は、curl --version
を参照してください。 macOSの場合は、ファインダで証明書を見つけてダブルクリックします。 これにより、キーストアに追加され、Keychain Accessが開きます。 Keychain Accessで証明書を見つけ、ダブルクリックして詳細を開きます。 「信頼」ドロップダウン・メニューを開き、「この証明書を使用する場合」の値を「常に信頼」に設定し、詳細ウィンドウを閉じます。 要求されたら、パスワードを入力します。
Oracle Linuxの場合、次のスクリプトを1回実行して証明書を/tmp/operator.cert.pem
にコピーし、次のコマンドを実行して証明書をトラスト・ストアに追加します:
$ sudo cp /tmp/operator.cert.pem /etc/pki/ca-trust/source/anchors/
$ sudo update-ca-trust enable; sudo update-ca-trust extract
$ openssl x509 -noout -hash -in /tmp/operator.cert.pem
$ sudo ln -s /etc/pki/ca-trust/source/anchors/operator.cert.pem /etc/pki/tls/certs/e242d2da.0
最後のコマンドで、ファイル名e242d2da.0
は、前のコマンドの出力にサフィクス.0
を追加したものになります。
その他のオペレーティング・システムについては、オペレーティング・システムのドキュメント(またはGoogle)を参照してください。
テストのために、WebLogic Kubernetes Operatorプロジェクトには、オペレータ外部RESTインタフェース用に自己署名証明書および秘密キーを生成する「サンプル・スクリプト」が用意されています。 生成された証明書とキーはKubernetes tls secret
に格納され、サンプル・スクリプトは対応する構成値をYAML形式で出力します。 これらの値は、オペレータのHelmチャートのインストール時に使用するために、カスタムYAML構成ファイルに追加できます。 サンプル・スクリプトとその実行方法の詳細は、「証明書およびキーを作成するためのサンプル」を参照してください。
通常、外部通信用の自己署名証明書は安全とみなされないため、本番環境ではサンプル・スクリプトを使用「しないで」ください。 商用認証局によって署名された証明書は、より広く受け入れられ、有効なホスト名、有効期限およびキー制約が含まれている必要があります。
オペレータのRESTサービスをコールするために必要なトークン、証明書などの準備に役立つ小さいサンプルBASHスクリプトを次に示します:
#!/bin/bash
KUBERNETES_SERVER=$1
URL_TAIL=$2
REST_PORT=`kubectl get services -n weblogic-operator -o jsonpath='{.items[?(@.metadata.name == "external-weblogic-operator-svc")].spec.ports[?(@.name == "rest")].nodePort}'`
REST_ADDR="https://${KUBERNETES_SERVER}:${REST_PORT}"
SECRET=`kubectl get serviceaccount weblogic-operator -n weblogic-operator -o jsonpath='{.secrets[0].name}'`
ENCODED_TOKEN=`kubectl get secret ${SECRET} -n weblogic-operator -o jsonpath='{.data.token}'`
TOKEN=`echo ${ENCODED_TOKEN} | base64 --decode`
OPERATOR_CERT_DATA=`kubectl get secret -n weblogic-operator weblogic-operator-external-rest-identity -o jsonpath='{.data.tls\.crt}'`
OPERATOR_CERT_FILE="/tmp/operator.cert.pem"
echo ${OPERATOR_CERT_DATA} | base64 --decode > ${OPERATOR_CERT_FILE}
cat ${OPERATOR_CERT_FILE}
echo "Ready to call operator REST APIs"
STATUS_CODE=`curl \
-v \
--cacert ${OPERATOR_CERT_FILE} \
-H "Authorization: Bearer ${TOKEN}" \
-H Accept:application/json \
-X GET ${REST_ADDR}/${URL_TAIL} \
-o curl.out \
--stderr curl.err \
-w "%{http_code}"`
cat curl.err
cat curl.out | jq .
-k
オプションを使用してチェックを無視し、オペレータの証明書が(curl --cacert
ではなく)信頼できるものであることを確認できますが、これはセキュアではありません。
このスクリプトを使用するには、Kubernetesサーバー・アドレスを渡してから、コールするURLを渡します。 このスクリプトは、jq
がインストールされていることを前提とし、それを使用してレスポンスをフォーマットします。 これは必要に応じて削除できます。 スクリプトは、レスポンスに加えて、かなりの有用なデバッグ情報も出力します。 このスクリプトの出力例を次に示します:
$ ./rest.sh kubernetes001 operator/latest/domains/domain1/clusters
Ready to call operator REST APIs
Note: Unnecessary use of -X or --request, GET is already inferred.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 10.139.151.214...
* TCP_NODELAY set
* Connected to kubernetes001 (10.1.2.3) port 31001 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* error setting certificate verify locations, continuing anyway:
* CAfile: /tmp/operator.cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [81 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [799 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [413 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [150 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=weblogic-operator
* start date: Jan 18 16:30:01 2018 GMT
* expire date: Jan 16 16:30:01 2028 GMT
* issuer: CN=weblogic-operator
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
> GET /operator/latest/domains/domain1/clusters HTTP/1.1
> Host: kubernetes001:31001
> User-Agent: curl/7.54.0
> Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJ3ZWJsb2dpYy1vcGVyYXRvciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQ (truncated) 1vcGVyYXRvcjp3ZWJsb2dpYy1vcGVyYXRvciJ9.NgaGR0NbzbJpVXguQDjRKyDBnNTqwgwPEXv3NjWwMcaf0OlN54apHubdrIx6KYz9ONGz-QeTLnoMChFY7oWA6CBfbvjt-GQX6JvdoJYxsQo1pt-E6sO2YvqTFE4EG-gpEDaiCE_OjZ_bBpJydhIiFReToA3-mxpDAUK2_rUfkWe5YEaLGMWoYQfXPAykzFiH4vqIi_tzzyzNnGxI2tUcBxNh3tzWFPGXKhzG18HswiwlFU5pe7XEYv4gJbvtV5tlGz7YdmH74Rc0dveV-54qHD_VDC5M7JZVh0ZDlyJMAmWe4YcdwNQQNGs91jqo1-JEM0Wj8iQSDE3cZj6MB0wrdg
> Accept:application/json
>
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 463
<
{ [463 bytes data]
100 463 100 463 0 0 205 0 0:00:02 0:00:02 --:--:-- 205
* Connection #0 to host kubernetes001 left intact
{
"links": [
{
"rel": "self",
"title": "",
"href": "/operator/latest/domains/domain1/clusters"
},
{
"rel": "canonical",
"title": "",
"href": "/operator/latest/domains/domain1/clusters"
},
{
"rel": "parent",
"title": "",
"href": "/operator/latest/domains/domain1"
}
],
"items": [
{
"links": [
{
"rel": "self",
"title": "",
"href": "/operator/latest/domains/domain1/clusters/cluster-1"
},
{
"rel": "canonical",
"title": "",
"href": "/operator/latest/domains/domain1/clusters/cluster-1"
}
],
"cluster": "cluster-1"
}
]
}