目次
前回の振り返り
FSSを作成する
OKEを設定する
kubectlを設定する
Deploymentマニュフェストを作成する
Serviceマニュフェストを作成する
FSS用のマニュフェストを作成する
OKEクラスターの稼働状況を確認する
さいごに
前回の振り返り
今回が3回目ということで、Oracle CloudのOKEとFSSでファイルをアップロードするWebアプリケーションの構築をしてきましたが、ついに今回で完成します。
前回まではASP.NET Core MVCでWebアプリケーションを作成しdocker buildで作成したイメージをOCIRにPushしました。また、作業用のコンピュートインスタンスにkubectlをインストールしOKEを操作できるように準備、OKE用にアイデンティティ(ポリシー/ユーザー)の設定をしました。
いよいよ大詰めですね。
今回の主な内容はOKEのマニュフェストファイルを作成していきます。
OKEにFSSをマウントできるようにしないといけないのですが、Oralceの公式ブログの記事を参考にして設定をしていきます。
- Webアプリケーションを開発する(完了)
- アイデンティティユーザーを作成しポリシーを設定する (完了)
- OCIレジストリにDockerイメージを登録する (完了)
- File Storage Serviceを設定する ←今回
- OKEを設定する ←今回
- 稼働!完成! ←今回!!
FSSを作成する
各コンテナがデータを格納する場所を用意します。OCIコンソールよりファイル・ストレージ・サービスでファイルシステムとマウントターゲットを作成します。
作成後はマウントターゲットのIPアドレスを確認しておきます。
マウントターゲットにアクセスできるように適宜、セキュリティリスト、もしくはネットワークセキュリティグループで通信を許可をしておきます。
OKEを設定する
OKEクラスターを作成していきます。まずはOCIコンソールでクラスターを作成するところからです。
OCIコンソールからサクサク作っていきますが、注意点が3つあります。
- インスタンスのリソース制限状況を事前に確認しておく(制限された数以上のnodeは作れないので注意が必要です)
- プライベートサブネットにはOCIのサービスゲートウェイを設定しておくこと
- プライベートサブネットにはNATゲートウェイを設定しておくこと
この3つで実際にすごくハマりました。何度やってもノードプールのインスタンスが途中でコケてしまい、どうしようかと途方に暮れそうでした。OKEクラスターにsshをしてシスログを確認すると、オブジェクトストレージにアクセスが出来ないといったエラーが出ていることに気づきました。
また、NATゲートウェイに関しては、OCIR以外のリポジトリからイメージを取得する際に必要です。
上記点を事前に設定した上でクラスターの作成をします。「カスタム作成」で進めていきます。
名前やコンパートメントは適宜設定をしましょう。
ノードプールのノードの数は実際にComputeで作成されるインスタンス数になります。
検証なので、1つだけにしておきます。
OKEクラスターが作成できました。
あとはOKEのノードがしっかり「Ready」になっていれば、クラスターの作成自体は成功です。
Kubectlを設定する
作成したOKEクラスターを操作するために、「kubectl」を使用します。OCIコンソール上に「Access Cluster」というボタンから、コマンドを確認できますので、作業インスタンスに設定します。
ただし、OCI CLIを事前にインストールしておく必要があります。
設定が完了したら kubectlが利用可能な状態になります。
次にDocker Registry Secret を登録します。これでOKEがOCIRを使用することが出来るようになります。
<docker-registry-secret>には、任意の名前を入力します。
kubectl create secret docker-registry <docker-registry-secret> \ --docker-server=nrt.ocir.io \ --docker-username='<tenancy-namespace>/<username>' \ --docker-password='<auth-token>' \ --docker-email=<Email>'
Deploymentマニュフェストを作成する
今回は1つのPodにWebアプリコンテナとNginxコンテナが稼働するように設定します。
Nginxは「ConfigMap」で設定を記述しています。
また「/UploadFiles」ディレクトリに対してFSSをマウントするようにマニュフェストに定義します。「persistentVolumeClaim」は後述のFSS用のマニュフェストで定義します。
deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: fileupload-app spec: selector: matchLabels: app: fileupload-app replicas: 1 template: metadata: labels: app: fileupload-app spec: containers: - name: fileupload-app image: nrt.ocir.io/<tenancy-namespace>/file_upload_web_app:v03 imagePullPolicy: Always ports: - containerPort: 5000 volumeMounts: - mountPath: /UploadFiles name: nfs - name: nginx image: nginx:latest ports: - containerPort: 8080 volumeMounts: - mountPath: /etc/nginx readOnly: true name: nginx-conf - mountPath: /var/log/nginx name: log volumes: - name: nfs persistentVolumeClaim: claimName: oke-fsspvc readOnly: false - name: nginx-conf configMap: name: nginx-conf items: - key: nginx.conf path: nginx.conf - key: virtualhost.conf path: virtualhost/virtualhost.conf - name: log emptyDir: {} imagePullSecrets: - name: <docker-registry-secret> --- apiVersion: v1 kind: ConfigMap metadata: name: nginx-conf data: nginx.conf: | user nginx; worker_processes 3; error_log /dev/stderr warn; events { worker_connections 10240; } http { log_format main 'remote_addr:$remote_addr\t' 'time_local:$time_local\t' 'method:$request_method\t' 'uri:$request_uri\t' 'host:$host\t' 'status:$status\t' 'bytes_sent:$body_bytes_sent\t' 'referer:$http_referer\t' 'useragent:$http_user_agent\t' 'forwardedfor:$http_x_forwarded_for\t' 'request_time:$request_time'; access_log /dev/stdout main; include /etc/nginx/virtualhost/virtualhost.conf; } virtualhost.conf: | upstream app { server localhost; keepalive 1024; } server { listen 8080 default_server; server_name _; root /usr/local/app; access_log /dev/stdout main; error_log /dev/stderr warn; location / { proxy_pass http://app; proxy_http_version 1.1; } }
kubectl apply -f deployment.yaml
Serviceマニュフェストを作成する
OKEのServiceではOracle Cloud のロードバランサが利用できます。
yamlを作成してこちらもapplyをします。
service.yaml
apiVersion: v1 kind: Service metadata: name: loadbalancer spec: type: LoadBalancer selector: app: fileupload-app ports: - name: http port: 80 targetPort: 8080
kubectl apply -f service.yaml
これでOracle Cloudのロードバランサが作成されています。OCIコンソールからも確認が出来ました。
FSS用のマニュフェストを作成する
これで最後のマニュフェストです。
「mntTargetId」は、ファイル・ストレージ・サービスのマウントターゲットOCIDを入力します。「nfs」の「server」に記載するIPアドレスはマウントターゲットのIPアドレスを入力します。OCIコンソールより確認し入力しましょう。
storage.yaml
apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: oci-fss provisioner: oracle.com/oci-fss parameters: mntTargetId: ocid1.mounttarget.oc1.ap_tokyo_1.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --- apiVersion: v1 kind: PersistentVolume metadata: name: oke-fsspv spec: storageClassName: oci-fss capacity: storage: 10Gi accessModes: - ReadWriteMany mountOptions: - nosuid nfs: server: 10.0.1.12 path: /UploadFiles readOnly: false --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: oke-fsspvc spec: storageClassName: oci-fss accessModes: - ReadWriteMany resources: requests: storage: 10Gi volumeName: oke-fsspv
kubectl apply -f storage.yaml
3つyamlファイルを作成しましたが、インデントをしっかりしてないと怒られます。インデントの付け方はkubernetesのドキュメントで書き方を確認しておくのが良いかと思います。
OKEクラスターの稼働状況を確認する
これで、podが既に稼働しているはずですので、上手く稼働ができているか確認をしてみたいと思います。
podの状態が「Ready」となっていれば成功です。
kubectl get all
NAME READY STATUS RESTARTS AGE pod/fileupload-app-7b8786bd5b-2rg58 2/2 Running 0 34m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 33h service/loadbalancer LoadBalancer 10.96.236.164 x.x.x.x 80:30957/TCP 6h41m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/fileupload-app 1/1 1 1 3h57m NAME DESIRED CURRENT READY AGE replicaset.apps/fileupload-app-6df694d58d 0 0 0 3h57m replicaset.apps/fileupload-app-78fbbd9544 0 0 0 3h47m replicaset.apps/fileupload-app-7b8786bd5b 1 1 1 34m
Readyになってますね!ただ、実際には上手くいかなくて何回もトライ&エラーでした。…笑
podが上手く動作しない場合や詳細を確認する際には、以下のコマンドでイベントを確認できます。
# Podの情報やイベントを確認する kubectl describe pods <pod名> (例: kubectl describe pods fileupload-app-78fbbd9544-snjmt )
# ログを確認する kubectl logs <pod名> <コンテナ名> (例: kubectl logs fileupload-app-78fbbd9544-snjmt nginx )
※ 1つのPodに複数のコンテナがある場合は、コンテナ名の指定が必須です。
ということでk8sでWebアプリが稼働している状態になりましたので、ブラウザからも確認ができました。
ブラウザからアップロードしたファイルが実際にファイルストレージサービスにも入っているか作業用コンピュートインスタンスに同じFSSをマウントして確認してみます。
[opc@itport-work ~]$ ls -l /UploadFiles/ total 64 -rw-r--r--. 1 root root 41089 Apr 7 14:12 itport.png
ブラウザからアップロードしたファイルがストレージに入ってます。OKですね!これで今回の目標は全て達成しました!
さいごに
これで今回の検証はすべて終わりとなります。いかがでしたでしょうか。
長い道のりに感じましたが、k8sは一度マニュフェストを作れば、似た構成の場合は、次回から参考にできるので便利だと思いました。
今まではコンピュートインスタンスを立てて、Webアプリケーションを構築する事が多かったのですが、OCIのマネージドサービスだけでWebアプリケーションの構築が出来たことは非常に良い勉強となりました。
今回、Nginxをあえて利用したのは、アクセスログなどは運用上必要だろうと思い利用するようにしてみました。まだまだk8sのことは未熟ですので、セキュリティ対策やロギングなどについては勉強が必要です。
データベースエンジンを利用する場合でも、Autonomous Transaction Processing を選択すれば、OKEとATPでマネージドサービスだけの環境が整いますね!
謝辞
NginxのConfigMapを作成する際に Qiita より @petiviolet さんの記事を参考にさせていただきました。
この場を借りて謝辞を申し上げます。