ノート:
- このチュートリアルは、Oracle提供の無料ラボ環境で提供されています。
- Oracle Cloud Infrastructureの資格証明、テナンシおよびコンパートメントの値の例を使用します。演習を完了するときは、これらの値をクラウド環境に固有の値に置き換えます。
Oracle LinuxでKubernetesを実行
イントロダクション
Kubernetesは、パイロットやヘルムスマンのためにギリシャ語です。つまり、コマンドにたどり着いて船を究極の目標(注文船長ではなく)に向けて送る人です。そのため、Kubernetesは、コンテナ化されたアプリケーションをデプロイ、管理およびスケーリングするためのオープンソースの拡張可能なプラットフォームです。これは、いくつかのコマンドライン・ツールを使用して実現します。このラボでは、kubectl
と呼ばれる属性の1つをYAMLファイルとともに使用して、アプリケーションをデプロイする組織に必要な属性を定義し、アプリケーションのデプロイ後にアプリケーションを設定および保守する方法を理解します。
Kubernetesクラスタへのすべてのデプロイメントは、オブジェクトとして表されます。これらのデプロイ済オブジェクトは、テキストベースのYAMLファイルを使用して、クラスタにデプロイされたアプリケーションの必要な状態の詳細を提供します。これらのYAMLファイルでは、次のことが説明されます。
- どのコンテナ化されたアプリケーションでどのノードで実行するか
- アプリケーションに必要なリソースの詳細
- 再起動ポリシー、アップグレード・ポリシーなど、これらのアプリケーションの状態を詳細に示すポリシー。
この3番目のポイントは、基本を理解せずに複雑です。したがって、このトピックは、今後のチュートリアルで取り扱います。
このチュートリアルは、Oracle LinuxのコンパクトなOracle Cloud Native Environment内で実行されるKubernetesと連携します。目的は、本番デプロイメントの管理に必要なすべてのものにとって「ワン・ストップ・ショップ」ではありません。かわりに、サンプル・アプリケーションをデプロイするために必要なスキルを紹介します。
目的
- ポッド、デプロイメント、サービスなどの様々なKubernetesコンポーネントを確認します
- 様々なKubernetesオブジェクトの確認
- サンプル・プロジェクトのデプロイおよびテスト
前提条件
次の構成を持つ Oracle Linux 8以降のシステム:
sudo
権限を持つroot以外のユーザー- Oracle Cloud Native Environmentをインストールして構成
演習環境の設定
ノート: 無料ラボ環境を使用する場合、接続およびその他の使用手順については、Oracle Linux Labの基本を参照してください。
情報: 無料ラボ環境では、環境を作成する準備ができて、提供されたノードにOracle Cloud Native Environmentをデプロイします。このデプロイメントは、起動後に終了するまでに約8分から10分かかります。したがって、この実行中にステップ・アウトし、演習を完了するために戻ります。
-
まだ接続されていない場合は、端末を開き、sshを使用して ocne-node01システムに接続します。
ssh oracle@<ip_address_of_ol_node>
-
環境の準備ができていることを確認します。
kubectl get pods -A
出力例:
[oracle@ocne-node01 ~]$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE externalip-validation-system externalip-validation-webhook-7988bff847-8ws2v 1/1 Running 0 3m18s kube-system coredns-7cbc77dbc7-qxqth 1/1 Running 0 3m18s kube-system coredns-7cbc77dbc7-r9bgj 1/1 Running 0 3m18s kube-system etcd-ocne-node01 1/1 Running 0 3m37s kube-system kube-apiserver-ocne-node01 1/1 Running 0 3m37s kube-system kube-controller-manager-ocne-node01 1/1 Running 0 3m37s kube-system kube-flannel-ds-vcwzn 1/1 Running 0 3m18s kube-system kube-proxy-7lx59 1/1 Running 0 3m18s kube-system kube-scheduler-ocne-node01 1/1 Running 0 3m37s kubernetes-dashboard kubernetes-dashboard-5d5d4947b5-7pffh 1/1 Running 0 3m18s
ポッドおよびリクエストの詳細でのデプロイメントの作成
Kubernetesでは、deploymentは、ポッドの動作と特性を制御するファイルを参照する技術用語です。管理者はデプロイメントを使用してアプリケーションに何をするかを指示し、Kubernetesはその状態に達するためにタスクを実行します。
この例では、HTTPヘッダーを介して受信したリクエストのソースIPをエコー・バックする小さなnginx Webサーバーを含むイメージを使用しています。
-
echoserverの配備を作成します。
kubectl create deployment test --image=k8s.gcr.io/echoserver:1.4
-
クラスタ内のすべてのポッドをリストします。
kubectl get pods
出力例:
[oracle@ocne-node01 ~]$ kubectl get pods NAME READY STATUS RESTARTS AGE test-6c486b6d76-467p7 1/1 Running 0 53s
ノート: ポッド名には、ポッドをデプロイするたびに変化する接尾辞値が含まれます。
-
JSONPathを使用して、ポッド名を変数に割り当てます。
TESTPOD=$(kubectl get pods -o jsonpath='{ $.items[*].metadata.name }')
-
変数の割当てをテストします。
kubectl get pods
コマンドでは、ポッド名をパラメータとして渡して、そのポッドの情報のみを表示することもできます。kubectl get pods $TESTPOD
-
ポッドに関する選択した情報を要求します。
kubectl get pod $TESTPOD --output custom-columns=NAME:metadata.name,NODE_IP:status.hostIP,POD_IP:status.podIP
出力例:
[oracle@ocne-node01 ~]$ kubectl get pod $TESTPOD --output custom-columns=NAME:metadata.name,NODE_IP:status.hostIP,POD_IP:status.podIP NAME NODE_IP POD_IP test-6c486b6d76-467p7 10.0.0.140 10.244.0.7
-
ポッドの詳細を取得します。
kubectl describe pod $TESTPOD
出力例:
[oracle@ocne-node01 ~]$ kubectl describe pod test-6c486b6d76-467p7 Name: test-6c486b6d76-467p7 Namespace: default Priority: 0 Node: ocne-node01/10.0.0.140 Start Time: Tue, 28 Jun 2022 19:21:27 +0000 Labels: app=test pod-template-hash=6c486b6d76 Annotations: <none> Status: Running IP: 10.244.0.7 IPs: IP: 10.244.0.7 Controlled By: ReplicaSet/test-6c486b6d76 Containers: echoserver: Container ID: cri-o://5b7866a27722ec0998cd9fe74945fb82b4dd9ed4c5c80671d9e8aa239c7008a4 Image: k8s.gcr.io/echoserver:1.4 Image ID: k8s.gcr.io/echoserver@sha256:5d99aa1120524c801bc8c1a7077e8f5ec122ba16b6dda1a5d3826057f67b9bcb Port: <none> Host Port: <none> State: Running Started: Tue, 28 Jun 2022 19:21:30 +0000 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-d67ph (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-d67ph: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 21m default-scheduler Successfully assigned default/test-6c486b6d76-467p7 to ocne-node01 Normal Pulling 21m kubelet Pulling image "k8s.gcr.io/echoserver:1.4" Normal Pulled 21m kubelet Successfully pulled image "k8s.gcr.io/echoserver:1.4" in 3.102843235s Normal Created 21m kubelet Created container echoserver Normal Started 21m kubelet Started container echoserver
YAMLファイルを使用したデプロイメントの作成
Kubernetesのデプロイメント・マニフェストを使用して、アプリケーションをKubernetesクラスタにデプロイする方法を定義し、自己修復、スケーラビリティ、バージョニングおよびローリング更新などの他のKubernetes機能へのアクセスを提供します。このラボでは、Kubernetes内で提供されるこのより複雑な機能に対処しません。かわりに、非常に基本的なマニフェスト・ファイルを使用してアプリケーションをデプロイする方法を説明します。
デプロイメント・マニフェスト・ファイルは、JSONまたはYAMLで書き込まれます。JSONを使用できますが、YAMLは柔軟性、可読性、最終的なデプロイメントの側面を明確にする説明コメントを含める機能により、非常に人気があります。
デプロイメントを実行すると、ポッドは一連の宣言的更新によって更新され、実行中のアプリケーションの目的の状態に到達します。
deployment.yamlのすべての詳細は、Kubernetesがデプロイメント・リクエストを実施できるようにするには不可欠ですが、次の点がより重要な部分を示しています。
- apiVersionフィールドは、使用するKubernetes APIバージョンを指定します。Kubernetesの最新バージョンを使用している場合は、これをapps/v1に設定します。
- この場合、「親切」フィールドは、「デプロイメント」というオブジェクトのタイプを参照するようにKubernetesに通知します。
- metadataセクションは、配備名と関連するラベルの詳細を概説するために使用されます
- .specセクションは、デプロイメントマニフェストファイルのもっとも重要なセクションである可能性があります。ここから下方にあるものは、ポッドの配備に関連しています。.spec.templateセクションの下には、Kubernetesがデプロイメントの管理に使用するポッド・テンプレート(この例では、単一のコンテナ)について説明します。
- この例で使用されていないその他のフィールドは、.spec.replicasフィールド(デプロイするポッド・レプリカの数をKubernetesに通知する)および.spec.strategyフィールド(デプロイメントの更新の実行方法をKubernetesに通知する)です。
これらの他のフィールドの詳細は、上流のデプロイメントのドキュメントを参照してください。
-
デプロイメント・ファイルを作成します。
cat << 'EOF' | tee mydeployment.yaml > /dev/null apiVersion: apps/v1 kind: Deployment metadata: name: echo1 spec: selector: matchLabels: app: echo1 template: metadata: labels: app: echo1 spec: containers: - name: echoserver image: k8s.gcr.io/echoserver:1.4 EOF
-
デプロイメント・マニフェスト・ファイルを使用して、アプリケーションをポッドにデプロイします。
kubectl apply -f mydeployment.yaml
出力例:
[[oracle@ocne-node01 ~]$ kubectl apply -f mydeployment.yaml deployment.apps/echo1 created
-
デプロイメントによって管理されるポッドをリストします。
kubectl get pods -l app=echo1
出力例:
[oracle@ocne-node01 ~]$ kubectl get pods -l app=echo1 NAME READY STATUS RESTARTS AGE echo1-7cbf6dfb96-4cgq7 1/1 Running 0 24s
-l
または--selector=
オプションは、フィルタ対象のセレクタ(ラベル問合せ)を提供します。このオプションでは、'= '、'= = 'および'!= 'がサポートされます。(例:-l key1=value1,key2=value2
)
ノート: ポッド名には、ポッドをデプロイするたびに変化する接尾辞値が含まれていることに注意してください。
-
デプロイメントが成功したことを確認します。
kubectl get deploy echo1
出力例:
[oracle@ocne-node01 ~]$ kubectl get deploy echo1 NAME READY UP-TO-DATE AVAILABLE AGE echo1 1/1 1 1 16m
deploy
オプションは、deployments
では短くなっています。kubectl
コマンドでは、そのオプションの多くに省略された構文を使用できます。詳細は、kubectl --help
を実行して入手できます。
-
デプロイメントの詳細情報を返します。
kubectl describe deploy echo1
出力例:
[oracle@ocne-node01 ~]$ kubectl describe deploy echo1 Name: echo1 Namespace: default CreationTimestamp: Tue, 28 Jun 2022 20:20:40 +0000 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=echo1 Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=echo1 Containers: echoserver: Image: k8s.gcr.io/echoserver:1.4 Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: echo1-7cbf6dfb96 (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set echo1-7cbf6dfb96 to 1
ClusterIPサービスの使用
echo1 Deploymentをポッドに正常にデプロイしても、エンドユーザーが内部またはネットワーク上でアクセスできない場合、あまり使用されません。そのアクセスでは、サービスがネットワークにデプロイメントを公開する際に便利です。
デフォルトのKubernetesサービス・タイプはClusterIPです。ただし、インターネットからClusterIPサービスにアクセスすることはできませんが、Kubernetesプロキシを使用できます。プロキシの詳細は、アップストリームのドキュメントを参照してください。
この項では、echo1を公開し、Oracle Linuxポッドを使用してクラスタ内でサービス間通信を作成し、アプリケーションのフロントエンド・コンポーネントとバックエンド・コンポーネント間の通信を示します。
-
ノードのリストを取得します。
kubectl get nodes
出力例:
[oracle@ocne-node01 ~]$ kubectl get nodes NAME STATUS ROLES AGE VERSION ocne-node01 Ready <none> 4h27m v1.22.8+1.el8
ノードは、ポッドをデプロイするための物理システムまたは仮想マシンです。
-
kube- proxyモードをクエリーします。
kube- proxyを iptablesモードで実行すると、ClusterIPサービスに送信されるパケットはソースNAT'dになりません。
curl -w "\n" http://localhost:10249/proxyMode
- kube- proxyは、ポート10249が動作しているノードで待機します。
-
ClusterIPサービスを作成します。
kubectl expose deployment echo1 --name=clusterip-service --port=80 --target-port=8080
-
クラスタに割り当てられたIPアドレスを取得します。
kubectl get svc clusterip-service
出力例:
[oracle@ocne-node01 ~]$ kubectl get svc clusterip-service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE clusterip-service ClusterIP 10.108.107.54 <none> 80/TCP 13s
出力の
CLUSTER-IP
アドレスをノートにとります。 -
ClusterIPサービスにアクセスするためのポッドを同じクラスタに作成します。
kubectl run ol -it --image=oraclelinux:8 --restart=Never --rm
このコマンドは、対話型モードでOracle Linux 8コンテナを実行しているポッドを作成し、コマンド・プロンプトを表示します。
出力例:
[oracle@ocne-node01 ~]$ kubectl run ol -it --image=oraclelinux:8 --restart=Never --rm If you don't see a command prompt, try pressing enter. [root@ol /]#
-
Oracle LinuxコンテナのIPアドレスを取得します。
ip -br a
出力例:
[root@ol /]# ip -br a lo UNKNOWN 127.0.0.1/8 ::1/128 eth0@if12 UP 10.244.0.9/24 fe80::146f:2cff:fe73:b528/64
-
echo1内でnginx Webサーバーをテストします。
curl -w "\n" <CLUSTER-IP_ADDRESS>
前の出力の
CLUSTER-IP
アドレスを使用します。出力例:
[root@ol /]# curl -w "\n" 10.108.107.54 CLIENT VALUES: client_address=10.244.0.9 command=GET real path=/ query=nil request_version=1.1 request_uri=http://10.108.107.54:8080/ SERVER VALUES: server_version=nginx: 1.10.0 - lua: 10001 HEADERS RECEIVED: accept=*/* host=10.108.107.54 user-agent=curl/7.61.1 BODY: -no body in request-
出力には、Oracle Linuxからのリクエストが表示され、echo1デプロイメントを使用したClusterIPサービスによって処理されます。
-
コンテナを終了します。
exit
出力例:
[root@ol /]# exit exit pod "ol" deleted
YAMLファイルでのNodePortサービスの使用
以前は、echo1デプロイメントはkubectl expose
コマンドを使用して公開され、ClusterIPを使用して内部的にアクセスされました。ここで、NodePortサービスを使用します。これは、echo1にネットワーク経由で外部からアクセスできるようにするための開発者のアプローチです。
NodePortサービスは、すべてのノードで特定のポートを開き、トラフィックをそのポートにサービスに転送します。
ノート Standardの演習では、主に次の理由から、本番システムにNodePortを使用することはお薦めしません。
- デプロイされた各サービスには異なるポートが必要です
- ノードはパブリックに使用可能である必要があります。これは確実に推奨されません。
- ノード間でロード・バランシングが発生しない(マルチノードのKubernetesクラスタ内)
-
サービス・ファイルを定義します。
cat << 'EOF' | tee myservice.yaml > /dev/null apiVersion: v1 kind: Service metadata: name: echo1-nodeport namespace: default spec: ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - nodePort: 32387 port: 80 protocol: TCP targetPort: 8080 selector: app: echo1 sessionAffinity: None type: NodePort status: loadBalancer: {} EOF
- type: サービスを外部クライアントからのネットワーク要求で使用できるようにします。有効な値は、nodePort、LooadBalancerです。
- nodePort: サービスへのアクセスに使用される外部ポート。
- port: - クラスタ内で公開されているポート番号。
- targetPort: コンテナがリスニングしているポート。
-
サービスを作成します。
kubectl apply -f myservice.yaml
出力例:
[oracle@ocne-node01 ~]$ kubectl apply -f myservice.yaml service/echo1 created
ノート: アプリケーションの管理を簡素化するために、デプロイメントおよびサービス定義を同じYAMLファイルに含めることが一般的です。これらのステップで個別のファイルを使用することは、トレーニングのみを目的としています。1つのファイルに結合する場合は、
---
YAML構文を使用してそれらを区切ります。 -
新しく作成されたサービスをKubernetesがどのように保存するかを表示します。
kubectl get service echo1-nodeport -o yaml
出力例:
[oracle@ocne-node01 ~]$ kubectl get service echo1-nodeport -o yaml apiVersion: v1 kind: Service metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"echo1-nodeport","namespace":"default"},"spec":{"ipFamilies":["IPv4"],"ipFamilyPolicy":"SingleStack","ports":[{"nodePort":32387,"port":80,"protocol":"TCP","targetPort":8080}],"selector":{"app":"echo1"},"sessionAffinity":"None","type":"NodePort"},"status":{"loadBalancer":{}}} creationTimestamp: "2022-06-29T00:14:30Z" name: echo1-nodeport namespace: default resourceVersion: "6242" uid: 3171dda6-05b8-45b8-a0ba-457eab6e4f71 spec: clusterIP: 10.100.17.53 clusterIPs: - 10.100.17.53 externalTrafficPolicy: Cluster internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - nodePort: 32387 port: 80 protocol: TCP targetPort: 8080 selector: app: echo1 sessionAffinity: None type: NodePort status: loadBalancer: {}
-
Podsサービスの説明
kubectl describe svc echo1-nodeport
出力例:
[oracle@ocne-node01 ~]$ kubectl describe svc echo1-nodeport Name: echo1-nodeport Namespace: default Labels: <none> Annotations: <none> Selector: app=echo1 Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.100.17.53 IPs: 10.100.17.53 Port: <unset> 80/TCP TargetPort: 8080/TCP NodePort: <unset> 32387/TCP Endpoints: 10.244.0.7:8080 Session Affinity: None External Traffic Policy: Cluster Events: <none>
-
オブジェクト・エンドポイントを取得します。
エンドポイントは、サービスがトラフィックを送信するポッドのIPアドレスを追跡します。
kubectl get endpoints echo1-nodeport
出力例:
[oracle@ocne-node01 ~]$ kubectl get endpoints echo1-nodeport NAME ENDPOINTS AGE echo1-nodeport 10.244.0.7:8080 8m39s
-
アプリケーションを実行しているポッドをリストします。
kubectl get pods --output=wide
出力例:
[oracle@ocne-node01 ~]$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES echo1-7cbf6dfb96-mlds4 1/1 Running 0 80m 10.244.0.7 ocne-node01 <none> <none> test-6c486b6d76-v4htj 1/1 Running 0 83m 10.244.0.6 ocne-node01 <none> <none>
echo1のこのリストの IPアドレスは、指定したノードで実行されているポッドのIPアドレスであるエンドポイントの前の手順に示されている値と一致する必要があります。
-
サービスをリストします。
kubectl get svc -o wide
出力例:
[oracle@ocne-node01 ~]$ kubectl get svc -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR clusterip-service ClusterIP 10.107.31.75 <none> 80/TCP 78m app=echo1 echo1-nodeport NodePort 10.100.17.53 <none> 80:32387/TCP 10m app=echo1 kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 88m <none>
このコマンドは、
--output=wide
ではなく-o wide
の代替オプションを使用しました。echo1-nodeportサービスの 32387に設定されている NodePortをノートにとります。
-
ノードのIPアドレスを取得します。
フリー・ラボ環境は、単一のノードocne-node01で実行されます。
ip -br a
無料ラボ環境では、IPアドレスは、インタフェースens3に割り当てられたインスタンスのプライベートIPアドレス10.0.0.140を返す必要があります。
-
JSONPathを使用して、NodePortに変数を割り当てます。
NODEPORT=$(kubectl get -o jsonpath="{.spec.ports[0].nodePort}" services echo1-nodeport)
-
JSONPathを使用して、ノードIPを変数に割り当てます。
NODES=$(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="InternalIP")].address }')
-
ファイアウォール・ルールを作成します。
このルールにより、
node:nodeport
のトラフィックが許可されます。node
は、Podが実行されているシステムまたは仮想マシンのホストIPアドレスです。sudo firewall-cmd --permanent --add-port=$NODEPORT/tcp sudo firewall-cmd --reload
--reload
の後、firewalldデーモンは、iptables
を含む構成を再ロードします。kube- proxyはiptables
に依存するため、サービスからのレスポンスに遅延が発生します。 -
ノード・アドレスとノード・ポートを使用して、アプリケーションを確認します。
curl -s $NODES:$NODEPORT
出力例:
[oracle@ocne-node01 ~]$ curl -s $NODES:NODEPORT CLIENT VALUES: client_address=10.244.0.1 command=GET real path=/ query=nil request_version=1.1 request_uri=http://10.0.0.140:8080/ SERVER VALUES: server_version=nginx: 1.10.0 - lua: 10001 HEADERS RECEIVED: accept=*/* host=10.0.0.140:32387 user-agent=curl/7.61.1 BODY:
この出力は、NodePortサービス、kube- proxy、および echo1デプロイメントを実行しているポッドを介したローカルノードルーティングからのリクエストを示しています。
ノート: 出力がハングアップしたように見える場合、これはファイアウォールの以前のリロードによるものです。
Ctrl-C
と入力して再試行してください。
デプロイメントとサービスの削除
サービスまたはデプロイメントが完了したら、それらをKubernetesから削除します。
-
サービスを削除します。
kubectl delete svc clusterip-service echo1-nodeport
-
デプロイメントを削除します。
kubectl delete deployments echo1 kubectl delete deploy test
オブジェクトの削除は、個別にまたはグループで実行できます。詳細は、Kubernetesリファレンス・マニュアルを参照してください。
概要
このラボでは、Kubernetesのようなクラウドネイティブ・オーケストレータを使用する機能が、Kubernetesを使用してコンテナ・デプロイメントを管理するすべての組織に提供する最も簡単な概要を示します。これらの演習は、Kubernetesを使用して提供できる柔軟性を実現する長い旅になる可能性が最も高いものの最初のステップを提供します。
詳細情報
その他の学習リソース
他のラボをdocs.oracle.com/learnで探すか、Oracle Learning YouTubeチャネルでより無料の学習コンテンツにアクセスします。また、education.oracle.com/learning-explorerにアクセスしてOracle Learning Explorerになります。
製品のドキュメントは、Oracle Help Centerを参照してください。