知識0からKubernetesで本番環境までひと月でデプロイした話

自己紹介

初めまして。21新卒で入社しました、AI/IoTサービス開発部のIoTサービス開発ユニットの濱村です。
昨年3月に初めてVue x Laravelでアプリケーションを開発してOPTiMに入社した初心者フロントエンドエンジニアです。
配属されてひと月経った5月の下旬にプロダクトのインフラ担当に任命されてひと月で本番環境までリリースした話をお伝えしていきます。
初めての記事になりますので読みにくい部分伝わりにくい部分がありましたら申し訳ございません。

はじめに

背景

配属されてひと月でチームの中のインフラ担当に任命され、Dockerもわからないような知識0の状態からKubernetesを使ってWEBアプリケーションを本番環境までデプロイしました。 その際に獲得した知識やKubernetes初学者に向けて情報を発信できればと思い、記事を書きました。

また、本記事ではイメージをKubernetesでPodとして立ち上げて通信させるまでについて記述しております。詳しい内容はあまり扱っておりませんのでご注意ください。

目次

Kubernetesとは?

Kubernetesとは、複数のコンテナを立てて連携させるようなコンテナオーケストレーションシステムとよく目にします。確かにその通りなのですが、2か月前の自分からすると複数個のコンテナを立てることすらなかったため、あまりイメージがつきませんでした。当時の自分に説明するとしたら、コンテナ同士を簡単につなげて、常に動かしてくれるものですよ。くらいの説明です。

Kubernetesの読み方・略称

主な読み方

  • くーばねてぃす
  • くーべねてぃす

略称

  • くべ
  • k8s(けーえいつ)

ローカルでPodを動かす

まず、Kubernetesを使用するための1stステップとして取り組んだこととしてローカルでKubernetesを動かしてみることでした。

Kubernetesのインストール

私の場合は普段からDocker Desktopを使用しており、Docker DesktopにKubernetesを追加する項目がありましたため、そちらを使用してKubernetesをインストールいたしました。GUIでボタンをポチポチするだけでしたので簡単にインストールすることができました。具体的な手順は以下のようになります。

  1. Docker-Desktop右上の設定
  2. 左メニューのKubernetesをクリック
  3. Enable Kubernetesにチェックを入れる
  4. 画面右下のApply & Restartをクリック

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20210831/20210831145956.png

マニフェストの作成

Kubernetesを扱ううえで最も重要な部分です。Kubernetesのマニフェストはyaml形式で記述されるもので、宣言的なものです。宣言的とはPodがこうあるべきという理想を記述する形式で、宣言的の反対に命令的なものもあり、Dockerfileは命令的なものでコマンドを記述してcontainerを構築するものとなっております。

具体的なマニフェストのサンプル

こちらがOPTiM IoTをローカルで動かすために使用したマニフェストになります。

/front-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: front
spec:
  selector:
    matchLabels:
      app: front
  replicas: 1
  template:
    metadata:
      labels:
        app: front
    spec:
      containers:
      - name: front
        image: front:v0.1.2a
        imagePullPolicy: Never
        resources:
          limits:
            cpu: 1000m
            memory: 1024Mi
          requests:
            cpu: 10m
            memory: 1024Mi
        ports:
        - containerPort: 8000
        volumeMounts:
          - name: config-volume
            mountPath: /opt/app/config/config.json
            subPath: config.json
      volumes:
        - name: config-volume
          configMap:
            name: front
            items:
              - key: config.json
                path: config.json
---
apiVersion: v1
kind: Service
metadata:
  name: front
  labels:
    app: front
spec:
  type: NodePort
  selector:
    app: front
  ports:
    - name: http
      port: 8000
      targetPort: 8000
      nodePort: 30180
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: front
data:
  config.json: |
    {"cookie": {
      "name": "_session",

/redis-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:6.0.8-alpine
        imagePullPolicy: Always
        resources:
          limits:
            cpu: 1000m
            memory: 1024Mi
          requests:
            cpu: 10m
            memory: 1024Mi
        ports:
        - containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  type: NodePort
  selector:
    app: redis
  ports:
    - name: http
      port: 6379
      targetPort: 6379

Kubernetesコマンド

kubectlというコマンドラインツールを使用しますが、私の場合はKubernetesのインストール時に一緒にインストールされていましたので特にインストールの必要はないと思います。インストールをする場合は以下のリンクを参考にしていただけますと幸いです。

kubectlのインストールおよびセットアップ | Kubernetes

使用したコマンド

kubectl apply -f redis-deployment.yaml
kubectl apply -f front-deployment.yaml

これだけです。これで先ほど作成したマニフェストからPodを起動することができます。

マニフェストのサンプルでアプリケーションのDeploymentと、RedisのDeploymentの2つのマニフェストからPodを起動し、 ServiceというマニフェストによってアプリケーションとRedisの接続が可能になっております。

また、アプリケーションへのアクセスの方法ですが、http://localhost:30180でアクセスできるようになっております。

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20210831/20210831161951.png

開発環境・本番環境にデプロイするためにしたこと

kustomizeの導入

環境ごとにマニフェストを分けたいと考え、他のプロダクトで使用していた実績がありましたので導入してみました。 インストールの方法は以下のリンクを見ていただければと思います。

Kustomize | SIG CLI

ファイル構成の変更

├── bases
│   ├── kustomization.yaml
│   ├── optim-iot-front.yaml
│   └── optim-iot-redis.yaml
└── overlays
     ├── dev
     │   ├── kustomization.yaml
     │   └── patch.yaml
     └── prod
          ├── kustomization.yaml
          └── patch.yaml

このような構成にすることで、kustomizeの機能が使用できる状態になります。 特徴としては、basesにマニフェストの共通部分を置いておき、overlaysの中で環境ごとに分けて、環境変数を定義したり、マニフェストを上書きすることができます。 basesの中のマニフェストファイルは変更ありませんが、kustomizeを使用するために追加でkustomization.yamlを用意する必要があります。

/bases/kustomization.yaml

resources:
  - optim-iot-front.yaml
  - optim-iot-redis.yaml

commonLabels:
  pjt: optim-iot

namespace: optim-iot

内容的には、環境共通で使用するファイルやラベル、ネームスペースの定義が書いてあります。

続いて、overlays内のkustomization.yamlとpatch.yamlになります。

overlays/dev/kustomization.yaml

bases:
  - ../../bases

commonLabels:
  env: development

patchesStrategicMerge:
  - patch.yaml

images:
  - name: front:v0.1.2a
    newTag: v0.1.2a

overlays/dev/patch.yaml

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-front
  namespace: optim-iot
data:
  config.json: |
    {"cookie": {
      "name": "_session",

デプロイコマンド

kustomizeを使用するために-kオプションを付けます。

kubectl apply -k overlays/dev

ディレクトリごと指定することで、ローカルでデプロイしたredisとアプリケーションの両方を一緒にデプロイすることができます。

まとめ

Kubernetesを使ってみて、敷居が高いものだと思っておりましたが、コンテナのイメージさえあればどんなものでも簡単に動かせることを知りました。

また、コマンドもPodを動かすまでに必要な手数が少なく、使いやすいものに感じました。

皆様も常時動かしておきたいものがある方は、イメージ化してKubernetesで動かしてみましょう!


OPTiMでは随時エンジニアを募集しております。部署によりますが、新卒でも新しいことを経験できる職場になっております!

www.optim.co.jp