4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

⑰1日10分で理解するコンテナ技術入門 - OKEを使ったサービス公開 -

Last updated at Posted at 2024-07-01

前回までで以下のようなリソースについて紹介しました。

今回はこれらの知識を使って、簡単なウェブサービスをパブリッククラウドで公開してみたいと思います。

Kubernetesをパブリッククラウドで利用する場合、各社のマネージドサービスを利用することができます。代表的なKubernetesのマネージドサービスは、

  • GKE (Google)
  • EKS (AWS)
  • AKS (Azure)
  • OKE (OCI)

などがあります。
今回はOracleのOKEを使って、自作のサービスをインターネットに公開してみます。なお、前回までで紹介した知識だけで公開するので、本番想定ではない点については注意してください。あくまで各コンポーネントの動きを理解する目的です。

今回使用するコード

OKEクラスターを作成する

OKEのクラスターを作成して、ターミナルからkubectlコマンドが利用できるようにします。

OKEクラスターのプロビジョニング

OCIのホーム画面に移動したら、右上のハンバーガーメニューから、「開発者サービス」->「 Kubernetesクラスタ(OKE)」を選択します。
image.png

「クラスタの作成」を選択します。
image.png

「クイック作成」が選択されていることを確認して、「送信」を選択します。
image.png

ここ以降は、すべてデフォルトのまま次に進みます(もしサービス制限の関係でインスタンスが3つ用意できない場合、ノード数を減らしてください)。

下のような画面になったら「閉じる」を選択します。
image.png

下のような画面になるので、マークが緑色になるのを待ちます。
image.png

以下のようにマークが緑色になったらプロビジョニング完了です。
image.png

アクセス確認

kubectlをインストールしている端末から、アクセス確認を行います。

下の画面から、「クラスタのアクセス」を選択します。
image.png

「ローカル・アクセス」を選択し、表示される手順に従います。なお、エンドポイントは「パブリックエンドポイント」の方で操作を行います。
image.png

kubectl get nodesコマンドを実行して、正しくノードの情報がとれていれば成功です。

$ kubectl get nodes
NAME          STATUS   ROLES   AGE   VERSION
10.0.10.122   Ready    node    19m   v1.29.1-6+b511b8ca8a18c5
10.0.10.42    Ready    node    19m   v1.29.1-6+b511b8ca8a18c5
10.0.10.55    Ready    node    19m   v1.29.1-6+b511b8ca8a18c5

コンテナイメージのリモートレポジトリを作成する

自作のアプリケーションをKubernetesクラスターで動かす場合、以下のようなイメージでコンテナイメージをやり取りします。
image.png

  1. 作成したアプリケーションのコンテナイメージをリモートレポジトリ(この場合はOCIR)にプッシュ
  2. アプリケーションをデプロイするためのマニフェストファイルをクラスターに適用(マニフェストファイルにはイメージをプッシュしたレポジトリの情報が記載されている)
  3. クラスターは、マニフェストファイルを適用するうえで、レポジトリからイメージをプルしてくる

このような動作になるため、リモートレポジトリを作成する必要があります。OCIでは、OCIRというサービスがあるのでそれを利用します。

レポジトリを作成

OCIのコンソールに移動し、左上のハンバーガーメニューから、「開発者サービス」、「コンテナ・レジストリ」を選択します。
image.png

まず、ウェブサーバのイメージをプッシュするリポジトリを作成します。

「リポジトリの作成」を選択します。
image.png

ご自身のコンパートメントが選択されているかを確認します。アクセスは「パブリック」にし、リポジトリ名はお好きな値を入力します。私は4qiita_sample/webとしました。入力が完了したら「作成」を選択します。
image.png

次に、DBのイメージをプッシュするリポジトリを作成します。
同様の手順で、名前を4qiita_sample/dbとして作成します。
image.png

以上でコンテナイメージのリモートレポジトリの作成は完了です。

OCIRについて
OCIRは一般的なコンテナレジストリと少し仕様が異なるのでここで説明しておきたいと思います。
一般的なコンテナレジストリでは、レポジトリを作成し、その中で複数目的のイメージを配置することができると思います(例えば以下のような構成)。

└── 4qiita-sample
    ├── db
    │   ├── 1.1
    │   ├── 1.2
    │   └── latest
    └── web
        ├── 1.1
        ├── 1.2
        └── latest

OCIRでは、このように同一レポジトリ内に複数の目的のイメージを配置することができません。もう少し正確に言うと、リポジトリ内はディレクトリのような構造を取ることができません(同一リポジトリ内のイメージはタグでしか区別することができない)。
そのため、OCIRで複数イメージを使ったサービスを管理する場合、以下のように構成する必要があります。

├── 4qiita-sample/db (リポジトリ1)
|   ├── 1.1
|   ├── 1.2
|   └── latest
└── 4qiita-sample/web(リポジトリ2)
    ├── 1.1
    ├── 1.2
    └── latest

このような仕様のため、上記手順では2つのリポジトリ(web用とdb用)を作成しました。

レポジトリアクセスのために認証トークンを取得

以前の記事でも説明しましたが、レポジトリアクセスにはOCIのユーザー名と認証トークンを利用しますので、取得してメモなどに控えておいてください。

レポジトリにログイン

docker loginコマンドでログインしてください。詳細は以前の記事で確認してください。

アプリケーションのイメージをOCIRにプッシュ

それでは、アプリケーションイメージをOCIRにプッシュしたいと思います。
まず、今回使用するアプリケーションのソースコードをダウンロードします。

$ git clone git@github.com:sogawa-yk/simple-knowledge-sharing-platform.git
$ cd simple-knowledge-sharing-platform
$ git checkout tags/9-article -b 17-article-branch

webサーバのイメージをプッシュ

以下の手順でビルド・プッシュを行います。
なお、<region-code>はご自身が作成したOCIRのリージョンコードをここのリージョンキーをみて調べてください。また、リージョンキーは小文字で入力します。
<tenancy-namespace>は、OCIコンソール画面の右上のプロファイルアイコンをクリックし、「テナンシ」を選択、遷移した画面にある「オブジェクト・ストレージ・ネームスペース」の値を入力します。

$ cd web # webサーバ用のディレクトリに移動
$ docker build -t simple-knowledge-sharing-platform/web .
$ docker tag simple-knowledge-sharing-platform/web:latest <region-code>.ocir.io/<tenancy-namespace>/4qiita-sample/web:latest
$ docker push <region-code>.ocir.io/<tenancy-namespace>/4qiita-sample/web:latest

dbのイメージをプッシュ

以下の手順でビルド・プッシュを行います。

$ cd ../db # db用のディレクトリに移動
$ docker build -t simple-knowledge-sharing-platform/db .
$ docker tag simple-knowledge-sharing-platform/db:latest <region-code>.ocir.io/<tenancy-namespace>/4qiita-sample/db:latest
$ docker push <region-code>.ocir.io/<tenancy-namespace>4qiita-sample/db:latset

以上でリモートレポジトリへのプッシュは完了です。

マニフェストファイルの作成

次に、クラスターにデプロイするために各リソースのマニフェストファイルを作成します。今回作成するリソースは、

  • WebサーバのDeployment
  • DBのDeployment
  • Webサーバアクセス用のService
  • WebサーバがDBにアクセスするためのService

の4つです。

WebサーバのDeployment

適当なディレクトリに移動して、以下のコマンドでまずマニフェストファイルのひな型を作成します。

$ kubectl create deploy 4qiita-sample-web --image=<region-code>.ocir.io/<tenancy-namespace>/4qiita-sample/web:latest --replicas=3 --dry-run=client -o yaml >> deploy_web.yaml

以下のようなyamlが出力されるはずです。

deploy_web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: 4qiita-sample-web
  name: 4qiita-sample-web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: 4qiita-sample-web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: 4qiita-sample-web
    spec:
      containers:
      - image: <imageで指定した値>
        name: web
        resources: {}
status: {}

このままでも問題ありませんが、不要な部分を削除にしてシンプルにします。

編集後のdeploy_web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: 4qiita-sample-web
  name: 4qiita-sample-web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: 4qiita-sample-web
  template:
    metadata:
      labels:
        app: 4qiita-sample-web
    spec:
      containers:
      - image: <imageで指定した値>
        name: web

DBのDeployment

同様に、DBもまずひな型を作成します。

$ kubectl create deploy 4qiita-sample-db --image=<region-code>.ocir.io/<tenancy-namespace>/4qiita-sample/db:latest --replicas=1 --dry-run=client -o yaml >> deploy_db.yaml

修正すると以下のようになります。

deploy_db.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: 4qiita-sample-db
  name: 4qiita-sample-db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: 4qiita-sample-db
  template:
    metadata:
      labels:
        app: 4qiita-sample-db
    spec:
      containers:
        - image: <imageで指定した値>
          name: db

Webサーバアクセス用のService

同様に、以下のコマンドでひな型を作成します。

$  kubectl create svc loadbalancer qiita-sample-web --tcp=8080:5000 --dry-run=client -o yaml >> deploy_web_svc.yaml

以下のようなマニフェストファイルが出力されます。

deploy_web_svc.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: qiita-sample-web
  name: qiita-sample-web
spec:
  ports:
  - name: 8080-5000
    port: 8080
    protocol: TCP
    targetPort: 5000
  selector:
    app: 4qiita-sample-svc
  type: LoadBalancer
status:
  loadBalancer: {}

不要な部分を削除します。

不要な部分削除後のdeploy_web_svc.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: qiita-sample-web
  name: qiita-sample-web
spec:
  ports:
  - name: 8080-5000
    port: 8080
    protocol: TCP
    targetPort: 5000
  selector:
    app: 4qiita-sample-svc
  type: LoadBalancer

WebサーバのPodにルーティングするので、selectorをapp: 4qiita-sample-webに変更します。

セレクター変更後のdeploy_web_svc.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: qiita-sample-web
  name: qiita-sample-web
spec:
  ports:
    - name: 8080-5000
      port: 8080
      protocol: TCP
      targetPort: 5000
  selector:
    app: 4qiita-sample-web
  type: LoadBalancer

今回、ServiceのタイプとしてLoadBalancerを指定しています。このタイプでデプロイすると、OCIのロードバランサ―を自動的にプロビジョニングしてくれるのですが、少しだけ追加で設定を書く必要があります。追加の設定はmetadata.annotationsに記述します。

annotation追加後のdeploy_web_svc.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: qiita-sample-web
  name: qiita-sample-web
  annotations:
    oci.oraclecloud.com/load-balancer-type: "lb"
    service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
    service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10"
    service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "30"
spec:
  ports:
    - name: 8080-5000
      port: 8080
      protocol: TCP
      targetPort: 5000
  selector:
    app: 4qiita-sample-web
  type: LoadBalancer

DBアクセス用のService

同様に以下のコマンドでひな型を作成します。

$ kubectl create svc clusterip --tcp=3306:3306 --dry-run=clinet -o yaml >> deploy_db_svc.yaml

不要な部分を削除すると以下のようになります。

deploy_db_svc.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: qiita-sample-db
  name: qiita-sample-db
spec:
  ports:
  - name: 3306-3306
    port: 3306
    protocol: TCP
    targetPort: 3306
  selector:
    app: qiita-sample-db
  type: ClusterIP

selectorをDBのDeploymentのラベルに変更します。

セレクタ変更後のdeploy_db_svc.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: qiita-sample-db
  name: qiita-sample-db
spec:
  ports:
    - name: 3306-3306
      port: 3306
      protocol: TCP
      targetPort: 3306
  selector:
    app: 4qiita-sample-db
  type: ClusterIP

以上で作成完了です。
なお、WebのPodからはこのService名でDB用のPodにアクセスできます。ですので、qiita-sample-dbという名前でアクセス可能です。

クラスターにデプロイ

作成したマニフェストファイルを適用して、クラスターにアプリケーションをデプロイします。以下のコマンドで適用できます。

$ kubectl apply -f deploy_db.yaml
$ kubectl apply -f deploy_web.yaml
$ kubectl apply -f deploy_web_svc.yaml
$ kubectl apply -f deploy_db_svc.yaml

正しく作成されたかどうか、確認します。

$ kubectl get deploy
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
4qiita-sample-db    1/1     1            1           2m9s
4qiita-sample-web   3/3     3            3           111s

すべてREADYになっています。

$ kubectl get svc
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)             AGE
kubernetes         ClusterIP      10.96.0.1      <none>          443/TCP,12250/TCP   3h32m
qiita-sample-db    ClusterIP      10.96.157.65   <none>          3306/TCP            5m49s
qiita-sample-web   LoadBalancer   10.96.71.82    146.56.42.208   8080:32154/TCP      89s

作成した二つのService(qiita-sample-db, qiita-sample-web)があることがわかります。

アクセスしてみる

作成したロードバランサ―の<EXTERNAL-IP>:<PORT>でアクセスします。以下のように無事に画面が表示されれば成功です。
image.png

記事の更新が可能か確かめてみます。
image.png
無事に記事の追加ができることが確認できました。

まとめ

少し長くなりましたが、今回はパブリッククラウドのマネージドKubernetesサービスを利用して、自作のウェブアプリを公開するまでの流れを説明しました。最低限のKubernetesの機能しか使っていないので、まだまだ改善するべき点は多々ありますが、とりあえずデプロイするだけなら比較的簡単に可能であることが分かっていただけたかと思います。

今回はDockerfileの中に環境変数の値を埋め込んでいるため、環境変数の値を変更しようとすると毎回コンテナイメージをビルドする必要があり、不便です。Kubernetes側で環境変数を扱えるようにするため、次回はConfigMapについて説明したいと思います。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?