このドキュメントで説明するソフトウェアは、サポートされなくなったか、Extended Support期間中です。
現在サポートされているリリースにアップグレードすることをお薦めします。
第5章 Kubernetesのスタート・ガイド
この章では、Kubernetesの使用を開始して、コンテナ化されたアプリケーションをデプロイ、維持およびスケーリングする方法について説明します。
5.1 kubectlの基本
kubectlユーティリティは、クラスタに対してコマンドを実行するためにAPIサーバーとインタフェースするコマンドライン・ツールです。通常、このツールはクラスタのマスター・ノードで実行されます。これにより、実質的に、クラスタとクラスタ内のすべてのノードに完全な管理権限が付与されます。
kubectlユーティリティについては、次で詳しく説明しています。
https://kubernetes.io/docs/reference/kubectl/overview/
この項では、環境内のポッドとサービスの作成および管理を開始できるように、ツールの基本的な使用方法について説明します。
クラスタ内のノードに関する情報の取得
クラスタ内のすべてのノードおよび各ノードのステータスのリストを取得するには、kubectl getコマンドを使用します。このコマンドを使用して、Kubernetesでサポートされるあらゆる種類のリソースのリストを取得できます。この例では、nodes
リソースは次のようになります。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master.example.com Ready master 1h v1.12.5+2.1.1.el7
worker1.example.com Ready <none> 1h v1.12.5+2.1.1.el7
worker2.example.com Ready <none> 1h v1.12.5+2.1.1.el7
任意のリソースに関する詳細情報を取得するには、kubectl describeコマンドを使用します。リソースの名前を指定した場合、出力は、そのリソースに関する情報のみに制限されます。それ以外の場合は、すべてのリソースの完全な詳細も画面に出力されます。
$ kubectl describe nodes worker1.example.com
Name: worker1.example.com
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/hostname=worker1.example.com
Annotations: flannel.alpha.coreos.com/backend-data: {"VtepMAC":"f2:24:33:ab:be:82"}
flannel.alpha.coreos.com/backend-type: vxlan
flannel.alpha.coreos.com/kube-subnet-manager: true
flannel.alpha.coreos.com/public-ip: 10.147.25.196
kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
...
ポッドでのアプリケーションの実行
実行中の単一のDockerコンテナでポッドを作成するには、kubectl createコマンドを使用できます。
$ kubectl create deployment --image nginx
hello-world
deployment.apps/hello-world created
hello-world
を、ご使用のデプロイメントの名前に置き換えます。ポッドには、接頭辞としてデプロイメント名を使用した名前が付けられます。nginx
を、DockerエンジンによってプルできるDockerイメージに置き換えます。
デプロイメント、ポッドおよびサービスの名前は、DNS-1123ラベルと一致するための要件に従います。これらは、英数字(小文字)または-
で構成され、先頭と末尾が英数字である必要があります。名前の検証に使用される正規表現は、'[a-z0-9]([-a-z0-9]*[a-z0-9])?
'です。デプロイメントで検証されていない名前を使用すると、エラーが返されます。
Kubernetes内で新しいアプリケーションを実行する際に使用できる追加のオプション・パラメータは、数多く存在します。たとえば、起動する必要があるレプリカ・ポッドの数を実行時に指定することも、ポッド・コンポーネントの識別を容易にするためにデプロイメントにラベルを適用することもできます。使用可能なオプションの完全なリストを確認するには、kubectl run -hを実行します。
新しいアプリケーション・デプロイメントによって1つ以上のポッドが作成されたことを確認するには、kubectl get podsコマンドを使用します。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-5f55779987-wd857 1/1 Running 0 1m
kubectl describeを使用して、実行中のコンテナ、基準となったイメージ、現在ポッドをホストしているノードなど、ポッドの詳細ビューを表示します。
$ kubectl describe pods
Name: hello-world-5f55779987-wd857
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: worker1.example.com/192.0.2.11
Start Time: Mon, 10 Dec 2018 08:25:17 -0800
Labels: app=hello-world
pod-template-hash=5f55779987
Annotations: <none>
Status: Running
IP: 10.244.1.3
Controlled By: ReplicaSet/hello-world-5f55779987
Containers:
nginx:
Container ID: docker://417b4b59f7005eb4b1754a1627e01f957e931c0cf24f1780cd94fa9949be1d31
Image: nginx
Image ID: docker-pullable://nginx@sha256:5d32f60db294b5deb55d078cd4feb410ad88e6fe77500c87d3970eca97f54dba
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 10 Dec 2018 08:25:25 -0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-s8wj4 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-s8wj4:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-s8wj4
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
....
ポッド・デプロイメントのスケーリング
実行中のものと同じポッドのインスタンス数を変更するには、kubectl scale deploymentコマンドを使用できます。
$ kubectl scale deployment --replicas=3
hello-world
deployment.apps/hello-world scaled
ポッド・インスタンスの数が適切にスケーリングされていることを確認できます。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-5f55779987-tswmg 1/1 Running 0 18s
hello-world-5f55779987-v8w5h 1/1 Running 0 26m
hello-world-5f55779987-wd857 1/1 Running 0 18s
アプリケーションのサービス・オブジェクトの公開
通常、多くのアプリケーションはポッド内またはポッド間で内部的に通信することのみが必要ですが、Kubernetesクラスタ外のクライアントがアプリケーションとインタフェースできるように、アプリケーションを外部的に公開することが必要になる場合があります。そのためには、そのデプロイメントのサービス定義を作成します。
サービス・オブジェクトを使用してデプロイメントを公開するには、使用する必要があるサービス・タイプを定義する必要があります。クラウドベースのロード・バランシング・サービスを使用しない場合は、サービス・タイプをNodePort
に設定できます。NodePort
サービスにより、クラスタ内のすべてのノードに対するパブリックIPアドレス上の専用ポートで、クラスタ内で実行中のアプリケーションを公開します。新しいサービスを作成するには、kubectl expose deploymentを使用します。
$ kubectl expose deployment hello-world
--port 80
--type=LoadBalancer
service/hello-world exposed
kubectl get servicesを使用して、クラスタで実行中の各種サービスをリストし、そのサービスへのアクセスに必要なポート情報を取得します。
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world LoadBalancer 10.102.42.160 <pending> 80:31847/TCP 3s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h13m
この例の出力では、クラスタ内部のポート80へのトラフィックがNodePort
31847にマップされていることがわかります。サービスにアクセスするために使用できる外部IPは、<pending>としてリストされています。これは、ポート31847でクラスタ内のいずれかのノードの外部IPアドレスに接続すると、そのサービスにアクセスできることを意味します。
このガイドの例として、Webブラウザを開いて、クラスタ内のいずれかのノード(http://worker1.example.com:31847/など)を参照すると、NGINXデモンストレーション・アプリケーションが表示されます。
サービスまたはデプロイメントの削除
オブジェクトはKubernetes内で簡単に削除でき、環境をクリーンアップできます。オブジェクトを削除するには、kubectl deleteコマンドを使用します。
サービスを削除するには、サービス・オブジェクトおよび削除するサービス名を指定します。
$ kubectl delete services hello-world
デプロイメント全体、およびそのデプロイメントで実行中のすべてのポッド・レプリカを削除するには、デプロイメント・オブジェクトとデプロイメントの作成に使用した名前を指定します。
$ kubectl delete deployment hello-world
名前空間の操作
名前空間を使用すると、リソースの使用方法をさらに分割し、特定のユースケースに限定された環境を提供できます。Kubernetesでは、デフォルトで、Kubernetesのシステム・コンポーネント用の名前空間、および名前空間が定義されていない他のすべてのデプロイメント用に使用する標準名前空間が構成されます。
既存の名前空間を表示するには、kubectl get namespacesコマンドとkubectl describe namespacesコマンドを使用します。
kubectlコマンドでは、リクエスト専用の名前空間を設定していない場合、デフォルトの名前空間のリソースのみが表示されます。そのため、Kubernetesシステムに固有のポッドを表示する必要がある場合は、リクエストで--namespace
オプションを使用して、名前空間をkube-system
に設定します。たとえば、単一マスター・ノードのクラスタでは次のようにします。
$ kubectl get pods --namespace=kube-system
NAME READY STATUS RESTARTS AGE
coredns-6c77847dcf-77grm 1/1 Running 2 5h26m
coredns-6c77847dcf-vtk8k 1/1 Running 2 5h26m
etcd-master.example.com 1/1 Running 3 5h25m
kube-apiserver-master.example.com 1/1 Running 4 5h25m
kube-controller-manager-master.example.com 1/1 Running 4 5h25m
kube-flannel-ds-4c285 1/1 Running 0 115m
kube-flannel-ds-ds66r 1/1 Running 0 115m
kube-proxy-5lssw 1/1 Running 0 117m
kube-proxy-tv2mj 1/1 Running 3 5h26m
kube-scheduler-master.example.com 1/1 Running 3 5h25m
kubernetes-dashboard-64458f66b6-q8dzh 1/1 Running 4 5h26m
5.2 YAMLデプロイメントを使用したポッド構成
ポッドの作成とそれに関連する要件を簡略化するために、デプロイメントを構成するすべての要素を定義するデプロイメント・ファイルを作成できます。このデプロイメントでは、ポッド内にコンテナを生成するために使用するイメージとランタイム要件(あれば)、構成するサービス形式でのKubernetesのネットワーキングと記憶域の要件、およびマウントする必要のあるボリュームを定義します。
デプロイメントの詳細は、https://kubernetes.io/docs/concepts/workloads/controllers/deployment/を参照してください。
Kubernetesデプロイメント・ファイルは簡単に共有でき、Kubernetesでは、リモートでホストされたファイルに基づいてデプロイメントを作成することもできます。これにより、誰もが数分でデプロイメントを実行できます。デプロイメントを作成するには、次のコマンドを実行します。
$ kubectl create -f https://example.com/deployment.yaml
次の例では、2つのYAMLデプロイメント・ファイルを作成します。最初のものは、データ・ストア用の永続ボリュームでMySQLサーバーを実行するデプロイメントを作成するために使用されます。また、クラスタ内の他のポッドでこのリソースを消費できるようにするサービスも構成します。
2番目のデプロイメントでは、MySQLサーバーに直接アクセスする別のポッドでphpMyAdminコンテナが実行されます。このデプロイメントでは、Kubernetesクラスタの外部からphpMyAdminインタフェースにアクセスできるように、NodePort
サービスも作成されます。
次の例は、YAMLデプロイメント・ファイルを使用して、完全なアプリケーションを実行するために必要なスコープとリソースを定義する方法を示しています。
ここに示す例は、デモンストレーションのみを目的としています。これらは本番使用を意図したものではなく、望ましいデプロイメントまたは構成の方法を表すものではありません。
MySQLサーバーのデプロイメント
MySQLサーバーのデプロイメントを作成するには、エディタで単一のテキスト・ファイルmysql-db.yaml
を作成します。ここでの説明では、各オブジェクトのブレークダウンをテキスト・ファイルで定義されているとおりに示します。これらの定義はすべて同じファイルで記述できます。
コンテナ内でデータベースを実行する際の問題の1つは、コンテナが永続的ではないことです。つまり、データベースでホストされているデータは、コンテナ自体の外部に格納する必要があります。Kubernetesでは、これらの永続データ・ストアの設定を永続ボリュームの形式で処理します。様々な永続ボリューム・タイプがあります。本番環境では、クラスタ内のすべてのノードからアクセス可能ななんらかの共有ファイル・システムが最適な実装の選択肢となる場合がありますが、この単純な例では、hostPath
タイプを使用します。hostPath
タイプを使用すると、コンテナを実行中のノードでローカル・ディスクを使用できます。
永続ボリューム仕様では、この目的専用にする必要がある記憶域サイズおよびサポートする必要があるアクセス・モードを定義できます。hostPath
タイプの場合、データを格納する必要があるパスも定義されます。この場合、デモンストレーションのためにパス/tmp/data
を使用します。これらのパラメータは、独自の要件に従って変更する必要があります。
永続ボリューム・オブジェクトのYAMLファイルの定義は、次のようになります。
apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv-volume labels: type: local spec: storageClassName: manual capacity: storage:5Gi
accessModes: - ReadWriteOnce hostPath: path: "/tmp/data
"
永続ボリューム・オブジェクトは、Kubernetes内でリソースとして独自のエンティティです。ポッドでこのリソースを使用するには、アクセスをリクエストし、アクセスのためのクレームに適用されるルールに従う必要があります。これは、永続ボリューム・クレームの形式で定義されます。ポッドは永続ボリューム・クレームを実質的に記憶域としてマウントします。
永続ボリューム・クレーム・オブジェクトのYAMLファイルの定義は、次のようになります。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
デプロイメントのサービスを定義することが重要です。これにより、ポッドで実行する予定のアプリケーションで使用されるTCPポートを指定します。この場合、MySQLサーバーはポート3306でリスニングします。最も重要なことは、サービスの名前は、実行中のノードに関係なく、クラスタ内のこのサービスにアクセスするために他のデプロイメントで使用できることです。このサービスでは、クラスタ内部ネットワークで実行中の他のコンポーネントのみがアクセスできるよう、デフォルトのClusterIP
タイプが使用されるため、サービス・タイプは指定されません。このようにして、MySQLサーバーは、リクエストに対してKubernetesクラスタ内のポッドで実行中のコンテナから分離されます。
YAMLファイルのサービス定義は次のようになります。
--- apiVersion: v1 kind: Service metadata: name: mysql-service labels: app: mysql spec: selector: app: mysql ports: - port: 3306 clusterIP: None
MySQLサーバー・インスタンスは、mysql/mysql-server:latest
Dockerイメージを使用して、ポッドで実行中のDockerコンテナとして簡単に作成できます。ポッド定義で、この目的で以前に定義した永続ボリューム・クレームをアタッチするためのボリューム情報を指定します。また、使用する必要のあるイメージ、使用するコンテナ・ポート、ボリューム・マウント・ポイントおよびコンテナの実行に必要なすべての環境変数を含むコンテナ・パラメータも指定します。この場合、永続ボリューム・クレームを実行中の各コンテナ・インスタンスの/var/lib/mysql
にマウントし、イメージでの必要に応じて、環境変数としてMYSQL_ROOT_PASSWORD
値を指定します。
---
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
app: mysql
spec:
volumes:
- name: mysql-pv-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
containers:
- image: mysql:5.6
name: mysql
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- mountPath: /var/lib/mysql
name: mysql-pv-storage
env:
- name: MYSQL_ROOT_PASSWORD
value: "password
"
MYSQL_ROOT_PASSWORD
環境変数に指定されたpassword
値を、セキュリティ要件に適したより適切な代替値に置き換えます。
YAMLデプロイメント・ファイルを作成したら、保存してから次を実行します。
$ kubectl create -f mysql-db.yaml
persistentvolume/mysql-pv-volume created
persistentvolumeclaim/mysql-pv-claim created
service/mysql-service created
pod/mysql created
ファイルで定義されているすべてのリソースおよびコンポーネントは、Kubernetesで作成およびロードされます。kubectlコマンドを使用して、必要に応じて各コンポーネントの詳細を表示できます。
phpMyAdminデプロイメント
デプロイメントで相互に提供されるサービスを相互接続および消費する方法を示すために、この例の最初の部分でデプロイしたバックエンドMySQLサーバーに接続する、phpMyAdmin Dockerインスタンスを設定できます。
phpMyAdminデプロイメントでは、標準のDockerイメージを使用してポッドで実行されるコンテナを作成し、また、クラスタ内の任意のノードからWebインタフェースにアクセスできるようにするNodePort
サービスも定義します。
phpmyadmin.yaml
という新しいファイルを作成してエディタで開き、次のテキストで説明されている2つのコンポーネント定義を追加します。
まず、サービス定義を作成します。このサービスでは、コンテナで使用するポート、および内部Kubernetesクラスタ・ネットワーク内でこのポートをマップするtargetPortを定義します。また、サービス・タイプを指定してNodePort
に設定し、いずれかのクラスタ・ノードおよびNodePort
サービス・タイプにより提供されるポート転送サービスを使用して、クラスタ・ネットワークの外部からサービスにアクセスできるようにします。
宣言は次のようになります。
apiVersion: v1 kind: Service metadata: labels: name: phpmyadmin name: phpmyadmin spec: ports: - port: 80 targetPort: 80 selector: name: phpmyadmin type: NodePort
最後に、phpMyAdminコンテナがロードされるポッドを定義します。ここでは、このコンテナに使用する必要のあるDockerイメージ、およびコンテナで使用するポートを指定できます。このイメージの実行に必要な環境変数を指定することもできます。特に、Dockerイメージでは、環境変数PMA_HOST
を設定して、MySQLサーバーのIPアドレスまたは解決可能なドメイン名を指定する必要があります。ここではどのIPアドレスを使用する必要があるかは推測できないため、ここで値としてmysql-service
名を指定することで、Kubernetesにより自動的に処理できます。Kubernetesでは、このサービス定義を使用して、2つのポッドを自動的にリンクします。
ポッド定義は次のようになります。
--- apiVersion: v1 kind: Pod metadata: name: phpmyadmin labels: name: phpmyadmin spec: containers: - name: phpmyadmin image: phpmyadmin/phpmyadmin env: - name: PMA_HOST value: mysql-service ports: - containerPort: 80 name: phpmyadmin
ファイルを保存してから、kubectl createコマンドを実行して、YAMLファイルをデプロイメントにロードします。
$ kubectl create -f phpmyadmin.yaml
service/phpmyadmin created
pod/phpmyadmin created
これが期待どおりに機能することを確認するには、NodePort
サービスによって提供されるポート転送に使用されるポートを特定する必要があります。
$ kubectl get services phpmyadmin
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
phpmyadmin 10.110.16.56 <nodes> 80:31485/TCP 1d
この出力例では、クラスタ・ネットワークのポート80が各クラスタ・ノードのポート30582にマップされます。ブラウザを開き、指定されたポートマッピング上のいずれかのクラスタ・ノードを指定します。たとえば、http://master.example.com:31485/
です。phpMyAdminログイン・ページが表示され、MySQLサーバーをデプロイしたときにMYSQL_ROOT_PASSWORD
環境変数として指定したパスワードを使用し、rootとしてphpMyAdminにログインできます。
5.3 永続記憶域の使用方法
データベース・デプロイメントに永続記憶域を使用する概念については、前の項第5.2項「YAMLデプロイメントを使用したポッド構成」を参照してください。データベースなどのステートフル・アプリケーションを操作する場合は、永続記憶域が不可欠です。これは、コンテナやさらにはポッド自体のライフサイクルを超えるデータを保持できることが重要であるためです。
Kubernetesでは永続記憶域はPersistentVolumeオブジェクトの形式で処理され、PersistentVolumeClaimを使用してポッドにバインドされます。PersistentVolumeは、ローカルにホストすることも、ネットワーク・ストレージ・デバイスやネットワーク・ストレージ・サービスでホストすることもできます。
デモンストレーションまたは小規模なデプロイメントでは、hostPath
永続ボリューム・タイプによりローカル・ディスクにデータを格納すると便利ですが、一般的なKubernetes環境では複数のホストが必要となり、かつ、通常はなんらかのタイプのネットワーク・ストレージが含まれます。ネットワーク・ストレージを使用すると、レジリエンスの確保に役立ち、クラスタ環境を最大限に活用できます。ポッドを実行中のノードに障害が発生した場合は、代替ノードで新しいポッドを開始でき、ストレージ・アクセスを再開できます。このことは、レプリカ設定が正しく構成されているデータベース環境にとって特に重要です。
この項では、永続記憶域の構成に使用されるKubernetesコンポーネントについて、ネットワーク・ストレージを使用したデータのホストを中心に引き続き説明します。
5.3.1 永続記憶域の概念
Kubernetesでは、永続記憶域はPersistentVolumeサブシステムを使用して提供されます。永続記憶域を構成するには、次の用語を理解しておく必要があります。
-
PersistentVolume。 PersistentVolumeにより、使用される記憶域のタイプ、およびそれに接続するために使用する方法を定義します。これは、データの格納に使用される実際のディスクまたはネットワーク・ストレージ・サービスです。
-
PersistentVolumeClaim。 PersistentVolumeClaimにより、コンシューマ(ポッドなど)でPersistentVolumeのバインドに使用するパラメータを定義します。このクレームでは、コンシューマのリソースに適用する必要のある割当て制限およびアクセス・モードを指定できます。ポッドは、PersistentVolumeClaimを使用してボリュームにアクセスし、このボリュームをマウントできます。
-
StorageClass。 StorageClassは、ボリューム・プラグインを指定するオブジェクトです。これは、ユーザーがPersistentVolumeの記憶域を事前構成しなくてもPersistentVolumeClaimを定義できるようにする、プロビジョナとも呼ばれます。これを使用すると、PersistentVolumeClaimのライフサイクルに対して動的にプロビジョニングできるプール済リソースとして、類似したボリューム・タイプにアクセスできます。
PersistentVolumeは、静的または動的にプロビジョニングできます。
静的PersistentVolumeは手動で作成され、実際の記憶域へのアクセスに必要な詳細を含み、関連するPersistentVolumeClaimを持つ任意のポッドによって直接使用できます。
動的PersistentVolumeは、PersistentVolumeClaimが既存の静的PersistentVolumeと一致せず、既存のStorageClassがクレームでリクエストされた場合に自動的に生成されます。StorageClassは、動的にアクセス可能な記憶域のプールをホストするように定義できます。StorageClassの作成はオプション・ステップとなり、動的プロビジョニングを使用する場合にのみ必要です。
永続記憶域をプロビジョニングするプロセスは、次のとおりです。
-
PersistentVolumeまたはStorageClassを作成します。
-
PersistentVolumeClaimを作成します。
-
PersistentVolumeClaimを使用するようにポッドを構成します。
この例では、記憶域を手動で構成し、静的プロビジョニングを使用していることを前提としています。いずれの場合も、PersistentVolumeが構成され、PersistentVolumeClaimが作成されて、最後にPersistentVolumeClaimを使用するためのポッドが作成されます。
5.3.2 NFSの構成
この例では、クラスタ内のすべてのノードへのアクセスを許可するようにNFSアプライアンスがすでに構成されていることを前提としています。NFSアプライアンスがOracle Cloud Infrastructureでホストされている場合、Kubernetesノードのホストに使用する仮想クラウド・ネットワーク(VCN)サブネットのセキュリティ・リストに、イングレス・ルールを作成する必要があります。NFSアクセスおよびNFSマウント用にポート2049および20049でトラフィックを許可するように、ルールを設定する必要があります。
クラスタ内の各ワーカー・ノードには、nfs-utils
パッケージもインストールされている必要があります。
# yum install nfs-utils
次のステップでは、オブジェクトごとにYAMLファイルを使用したデプロイメントについて説明します。
-
YAMLファイルにPhysicalVolumeオブジェクトを作成します。たとえば、マスター・ノードで、ファイル
pv-nfs.yml
を作成してエディタで開き、次のコンテンツを含めます。apiVersion: v1 kind: PersistentVolume metadata: name: nfs spec: capacity: storage:
1Gi
accessModes: - ReadWriteMany nfs: server:192.0.2.100
path: "/nfsshare
"1Gi
を、使用可能な記憶域のサイズに置き換えます。192.0.2.100
を、ご使用の環境のNFSアプライアンスのIPアドレスに置き換えます。/nfsshare
を、NFSアプライアンス上のエクスポートされた共有名に置き換えます。 -
マスター・ノードで次のコマンドを実行し、作成したYAMLファイルを使用してPersistentVolumeを作成します。
$
kubectl create -f pv-nfs.yml
persistentvolume/nfs created -
YAMLファイルにPhysicalVolumeClaimオブジェクトを作成します。たとえば、マスター・ノードで、ファイル
pvc-nfs.yml
を作成してエディタで開き、次のコンテンツを含めます。apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs spec: accessModes: -
ReadWriteMany
resources: requests: storage:1Gi
accessModes
は、必要に応じてReadWriteMany
値を変更することで変更できます。storage
オプションの値を1Gi
から他の値に変更することにより、このクレームで使用可能な割当て制限を変更することもできます。 -
マスター・ノードで次のコマンドを実行し、作成したYAMLファイルを使用してPersistentVolumeClaimを作成します。
$
kubectl create -f pvc-nfs.yml
persistentvolumeclaim/nfs created -
PersistentVolumeおよびPersistentVolumeClaimが正しく作成され、PersistentVolumeClaimが正しいボリュームにバインドされていることを確認します。
$
kubectl get pv,pvc
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE pv/nfs 1Gi RWX Retain Bound default/nfs 7m NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE pvc/nfs Bound nfs 1Gi RWX 2m -
この時点で、PersistentVolumeClaimを使用してPersistentVolumeにバインドし、そこで使用可能なリソースを使用できるポッドを設定できます。次のステップの例では、ReplicationControllerを使用して、共有リソースを含むマウントパスへのPersistentVolumeのマウントにPersistentVolumeClaimを使用したWebサーバーを実行する、2つのレプリカ・ポッドを設定します。
-
YAMLファイルにReplicationControllerオブジェクトを作成します。たとえば、マスター・ノードで、ファイル
rc-nfs.yml
を作成してエディタで開き、次のコンテンツを含めます。apiVersion: v1 kind: ReplicationController metadata: name: rc-nfs-test spec: replicas: 2 selector: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - name: nginx containerPort: 80 volumeMounts: - name: nfs mountPath: "/usr/share/nginx/html" volumes: - name: nfs persistentVolumeClaim: claimName: nfs
-
マスター・ノードで次のコマンドを実行し、作成したYAMLファイルを使用してReplicationControllerを作成します。
$
kubectl create -f rc-nfs.yml
replicationcontroller/rc-nfs-test created -
ポッドが作成されたことを確認します。
$
kubectl get pods
NAME READY STATUS RESTARTS AGE rc-nfs-test-c5440 1/1 Running 0 54s rc-nfs-test-8997k 1/1 Running 0 54s -
NFSアプライアンスで、
/nfsshare
エクスポートに索引ファイルを作成し、Webサーバー・ポッドがこのリソースにアクセスできることをテストします。次に例を示します。$
echo "This file is available on NFS" > /nfsshare/index.html
-
Webサーバーの出力を確認できるようWebサーバー・ポートを公開するサービスを作成することも、各ポッドの
/usr/share/nginx/html
フォルダのコンテンツを単純に表示することもできます(NFS共有は、各インスタンスでこのディレクトリにマウントする必要があるため)。たとえば、マスター・ノードで次のようにします。$
kubectl exec rc-nfs-test-c5440 cat /usr/share/nginx/html/index.html
This file is available on NFS $kubectl exec rc-nfs-test-8997k cat /usr/share/nginx/html/index.html
This file is available on NFS
-
さらに検証する場合は、ポッドが実行されているノードを停止します。新しいポッドが実行中のノードで生成され、即座にNFS共有のデータにアクセス可能となります。このようにして、ノード障害時のデータの永続性およびレジリエンスを確認できます。
5.3.3 iSCSIの構成
この例では、ブロック・デバイスをiSCSI LUNとしてクラスタ内のすべてのノードに公開するようにiSCSIサービスがすでに構成されていることを前提としています。iSCSIサーバーがOracle Cloud Infrastructureでホストされている場合、Kubernetesノードのホストに使用する仮想クラウド・ネットワーク(VCN)サブネットのセキュリティ・リストに、イングレス・ルールを作成する必要があります。ポート860および3260でトラフィックを許可するように、ルールを設定する必要があります。
クラスタ内の各ワーカー・ノードには、iscsi-initiator-utils
パッケージもインストールされている必要があります。
# yum install iscsi-initiator-utils
デバイスのイニシエータ名(iqn
)を追加するには、クラスタのすべてのノードで/etc/iscsi/initiatorname.iscsi
ファイルを手動で編集する必要があります。このファイルを編集したら、iscsid
サービスを再起動します。
Oracle Linux 7でのiSCSIの構成の詳細は、Oracle® Linux 7: 管理者ガイドを参照してください。
次のステップでは、オブジェクトごとにYAMLファイルを使用したデプロイメントについて説明します。
-
YAMLファイルにPhysicalVolumeオブジェクトを作成します。たとえば、マスター・ノードで、ファイル
pv-iscsi.yml
を作成してエディタで開き、次のコンテンツを含めます。apiVersion: v1 kind: PersistentVolume metadata: name: iscsi-pv spec: capacity: storage:
12Gi
accessModes: - ReadWriteOnce iscsi: targetPortal:192.0.2.100:3260
iqn:iqn.2017-10.local.example.server:disk1
lun: 0 fsType: 'ext4' readOnly: false12Gi
を、使用可能な記憶域のサイズに置き換えます。192.0.2.100:3260
を、ご使用の環境のiSCSIターゲットのIPアドレスとポート番号に置き換えます。iqn.2017-10.local.example.server:disk1
を、iSCSI経由で使用するデバイスのiqn
に置き換えます。 -
マスター・ノードで次のコマンドを実行し、作成したYAMLファイルを使用してPersistentVolumeを作成します。
$
kubectl create -f pv-iscsi.yml
persistentvolume/iscsi-pv created -
YAMLファイルにPhysicalVolumeClaimオブジェクトを作成します。たとえば、マスター・ノードで、ファイル
pvc-iscsi.yml
を作成してエディタで開き、次のコンテンツを含めます。kind: PersistentVolumeClaim apiVersion: v1 metadata: name: iscsi-pvc spec: accessModes: -
ReadWriteOnce
resources: requests: storage:12Gi
accessModes
は、必要に応じてReadWriteOnce
値を変更することで変更できます。iSCSIでサポートされているモードには、ReadWriteOnce
およびReadOnlyMany
があります。storage
オプションの値を12Gi
から他の値に変更することにより、このクレームで使用可能な割当て制限を変更することもできます。iSCSIでは、読取り操作と書込み操作の両方がサポートされるため、すべてのポッドを単一ノード上でホストするよう制限されることに注意してください。スケジューラにより、同じPersistentVolumeClaimを含むポッドは、確実に同じワーカー・ノード上で自動的に実行されます。
-
マスター・ノードで次のコマンドを実行し、作成したYAMLファイルを使用してPersistentVolumeClaimを作成します。
$
kubectl create -f pvc-iscsi.yml
persistentvolumeclaim/iscsi-pvc created -
PersistentVolumeおよびPersistentVolumeClaimが正しく作成され、PersistentVolumeClaimが正しいボリュームにバインドされていることを確認します。
$
kubectl get pv,pvc
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE pv/iscsi-pv 12Gi RWX Retain Bound default/iscsi-pvc 25s NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE pvc/iscsi-pvc Bound iscsi-pv 12Gi RWX 21s -
この時点で、PersistentVolumeClaimを使用してPersistentVolumeにバインドし、そこで使用可能なリソースを使用できるポッドを設定できます。次の例では、ReplicationControllerを使用して、共有リソースを含むマウントパスへのPersistentVolumeのマウントにPersistentVolumeClaimを使用したWebサーバーを実行する、2つのレプリカ・ポッドを設定します。
-
YAMLファイルにReplicationControllerオブジェクトを作成します。たとえば、マスター・ノードで、ファイル
rc-iscsi.yml
を作成してエディタで開き、次のコンテンツを含めます。apiVersion: v1 kind: ReplicationController metadata: name: rc-iscsi-test spec: replicas: 2 selector: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - name: nginx containerPort: 80 volumeMounts: - name: iscsi mountPath: "/usr/share/nginx/html" volumes: - name: iscsi persistentVolumeClaim: claimName: iscsi-pvc
-
マスター・ノードで次のコマンドを実行し、作成したYAMLファイルを使用してReplicationControllerを作成します。
$
kubectl create -f rc-iscsi.yml
replicationcontroller "rc-iscsi-test" created -
ポッドが作成されたことを確認します。
$
kubectl get pods
NAME READY STATUS RESTARTS AGE rc-iscsi-test-05kdr 1/1 Running 0 9m rc-iscsi-test-wv4p5 1/1 Running 0 9m -
iSCSI LUNをマウント可能な任意のホストで、LUNをマウントして索引ファイルを作成し、Webサーバー・ポッドがこのリソースにアクセスできることをテストします。次に例を示します。
#
mount /dev/disk/by-path/
$ip-192.0.2.100\:3260-iscsi-iqn.2017-10.local.example.server\:disk1-lun-0
/mntecho "This file is available on iSCSI" > /mnt/index.html
-
Webサーバーの出力を確認できるようWebサーバー・ポートを公開するサービスを作成することも、各ポッドの
/usr/share/nginx/html
フォルダのコンテンツを単純に表示することもできます(NFS共有は、各インスタンスでこのディレクトリにマウントする必要があるため)。たとえば、マスター・ノードで次のようにします。$
kubectl exec rc-nfs-test-c5440 cat /usr/share/nginx/html/index.html
This file is available on iSCSI $kubectl exec rc-nfs-test-8997k cat /usr/share/nginx/html/index.html
This file is available on iSCSI
-