「おじいちゃん kubernetesってなに?」「...それはコスモスじゃよ」(2) -構築編-


おはこんばんにちは
zerobillbank株式会社のインフラエンジニアtomatoことtomatoです。

前回に引き続き、kubernetesの第2回目になります。
前回はkubernetesとはなんぞやという概要の部分をお伝えしたので、
今回はより具体的に、kubernetesの環境をどう構築していくのかについてお話ししていきマウス

ちなみに前回の記事はこちらです
「おじいちゃん kubernetesってなに?」「...それはコスモスじゃよ」(1) -概要編-

すごい図

まずいきなりですがこの図をご覧ください..デン!

kubernetesの構築を理解する上で、大事であろうポイントをあえて3つに絞ってみました。

  • Deployment
    • Podを定義するもの
  • Service
    • 内部IP
  • Ingress
    • 外部IP

まずはこの3つを基本の軸に考えることで、kubernetesの沼に
引きずり込まれることを防げるのではと思います!

不死身のDeployment

「や、やつは不死身なのかッ..!?」「いや、コアを狙うんだ!!」
倒しても復活しちゃう系のボスっているじゃないですか
あれの身体がPodで、コア部分がDeployment...まあそんな感じです。

DeploymentにはPodの定義を記載します。
Podには実際に動くアプリケーションが入ります(例えばnginxとか自分で作ったアプリとか)
Podの自己増減や自己修復などの機能については、第一回でお伝えしていますが
それを実現するのがこのDeploymentです。

例として、Deployment側で「AというイメージのPodを常に2つ起動しておく」
という定義を記載しておくと、常にAのPodが2つ起動されるようになります。
そのため、AのPodを手動で1つ削除しても、AのPodが新しく作られ
常に2つがPodが起動している状態を保つようになります。

補足ですが、似たようなものにReplicaSetDaemonSetなどがあります。
ただ、可能な限りシンプルに説明したいため、あえて今回は触れません。
Podを作成できるのは必ずしもDeploymentだけではありませんが、
やはりDeploymentが最もよく使用する基本のリソースになります。

引きこもりのService

Serviceで内部IPを定義します。
逆を言えば、DeploymentによってPodが作成されても
Serviceが定義されていなければ、どこからもアクセスできないわけです。
つまり最強の引きこもりです。

内部IPはPrivate IPとも呼ばれ、
同じkubernetesクラスタ内でのアクセスを可能にするものです。
ただしインターネットからのアクセスはできません。
例えるなら、マンションの部屋番号とか内線番号とかが近いですかね。

パリぴのIngress

Ingressは外部IPを定義します。

上記のServiceを定義した段階では、同じkubernetesクラスタ内でのみアクセスが可能で
外部(インターネット)からのアクセスはできない状態です。
外部からのアクセスを可能にするにはIngressが必要です。

IngressはパブリックIPとkubernetes側の入り口の紐付けを行い
kubernetesを外界へと解き放ちます。
インターネット越しのアクセスはIngress->Service->Podという風に伝わっていきます。

外部IPはまさに住所みたいなもので、その外部IP(普通はそれに紐づくドメイン)を知っていれば
誰でもインターネットでアクセスすることができます。
エブリワンカムオン、ミンナトモダチ。まさにパリピです(偏見)

構築しちゃうzoy

超最小ですが、上記の3つのリソースを使用していよいよKubernetesを使用した構築をしちゃいたいと思います!!!
..が、その前にちょっとした下準備が必要になります。

クラスタの作成

Kubernetesでの構築を行う際にはまずクラスタを作成する必要があります。
クラスタとは第一回で説明したnodeの定義などを行います。
復習がてら説明しますとnodeは物理的なコンピュータの単位であり、
このKubernetesでどのコンピュータをいくつ使いますねんっていう定義です

実際の作成方法はここでつらつら説明するより、使用するクラウド側の
リファレンスを参照してもらった方がすんなりすんすんできると思います。
そんなに難しいものでなく、今のご時世ポータルからホイホイできちゃいます。

例えばAzureだと下記になります。

yamlってなんやねん

で、もう一つ用意するのがyamlと呼ばれるファイルになります。
これに上記のDeploymentやらServiceやらの定義を書き込むわけです。

yamlとは...

  • ファイル形式の一種だよ
  • データ構造を表現できるよ

まあそんな感じものですが、難しいものではなく
実際に具体例を見れば理解しやすいものかと思います。

Deploymentのyaml例

下記のyamlは、Webサーバの代名詞でもあるnginxのリソースを定義したものです。
予備知識がなくても、なんとなく何を書いてあるのかがわかるんじゃないかなーと思います。

ポイントはimage: nginxの部分で、ここで何のDockerイメージを読み込むかを記載します。
Dockerのオフィシャルイメージにあるものなら、イメージ名を書くだけで呼び出してくれます。

オリジナルのDockerイメージを使用したい場合は、
Dockerファイルの作成 -> Dockerファイルをコンテナレジストリに登録という手順を踏み
そのコンテナレジストリのURLをimageタグに記載します。

nginx/deplyment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: sample
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 80

Serviceのyaml例

nginx/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: sample
  labels:
    app: nginx
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - port: 80 # Default port for image
      targetPort: 80

Ingressのyaml例

ドメインについてはレジストラから事前に取得しておく必要があります。
クラウドサービスからも割り当てることができますが、例えばAzureの場合xxx.japaneast.cloudapp.azure.comみたいなアドレスになります。

xxx.comやらxxx.jpやらが良いという場合は、レジストラから希望のドメインを購入する必要があります。

nginx/ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: sample
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'

spec:
  tls:
  - hosts:
    - xxx.com
    secretName: tls-secret
  rules:
  - host: xxx.com
    http:
      paths:
        - backend:
            serviceName: nginx
            servicePort: 80
          path: /

yamlの適用

ではいよいよyamlを適用してkubernetesを構築していきます!!

kubectl

kubernetesの操作はkubectlというコマンドで行います。
インストールについてはOSごとに異なりますので、下記を参照してください。

適用コマンド

kubectlのインストールが成功したらyamlの適用を行います。

今回はsampleというnamespaceを作成し、そこに適用したいと思います。
namespaceというのはkubernetesにおける論理的な境界になります。

ターミナルを起動し、下記のコマンドを打ち込みます。

$ kubectl create namespace sample

上記で作成したyamlを適用します。

$ kubectl apply -f nginx/deplyment.yaml
$ kubectl apply -f nginx/service.yaml
$ kubectl apply -f nginx/ingress.yaml

applyした各リソースの確認は下記のコマンドで行います。
今回はnginxというリソースができていることを確認します。

$ kubectl -n sample get deplyment
$ kubectl -n sample get service
$ kubectl -n sample get ingress

そしてDeploymentからPodが作成されていることを確認します。

$ kubectl -n sample get pod
NAME                      READY   STATUS        RESTARTS   AGE
nginx-546d5b6b48-r64gr    1/1     Running       0          10s

問題なければIngressで設定したドメインに
nginxの初期設定ページが表示されているはずです。

おわり

今回はこんな感じです。
駆け足で構築までしましたが、次回はうまく構築できなかった時のトラブルシューティングや
実際の運用とか監視とかについてお話できればと思います。

ではまた🙋‍♂️

さいごに

ZEROBILLBANKでは一緒に働く仲間を募集中です。
なんとかjsとか、ブロックチェーンとか、kubernetesとかでいろんなAPIを作るお仕事。
今のところエンジニアは5人くらい。スタートアップだけど、結構ホワイトで働きやすいです。

ZEROBILLBANK JAPAN Inc.