Kubernetesをだいたい理解するまで
インフラ初心者がいきなり実務でKubernetesを使うことになったので、その学習記録✎
流れとしては、
- 概念的なところを抑える
- 実際に手元で動かしてみる
 です!
また、すでにKubernetesについて書かれたわかりやすい記事がたくさんあるので、本記事はそれらをもとに自分の理解をまとめたものになります。
概念的なこと
まずはこれで概要把握
まずは👇を読もう。(ありがたやありがたや...)
- Kubernetesというものが出てきた背景を、オンプレの時代からどういうふうに変わっていったかわかる
- KUbernetesの概要がわかる
- メリデメがわかる
- Argo CDの例などを用いてどういうふうに使われているのかイメージが付く
Kubernetesとは
ざっくりいうと、
サービスをコンテナ上で動かすようになったことで起こった、
- 複数のサーバ上で複数のコンテナを動かしたい
- コンテナに割り当てるリソースを制御したい
- コンテナの稼働状況を監視したい
- webアプリコンテナをリクエスト量に応じてスケールするようにしたい
- cron的にコンテナを起動して処理したい
- 複数のコンテナで1つのストレージを共有したい。
のような問題を解決するために生まれた、コンテナオーケストレーション技術のこと。
どうやらKubernetesを用いたら、いい感じにコンテナを扱うことができるらしい...
以下、公式ドキュメントを参照すると詳しくわかる。
全体の流れ
- Manifesetと呼ばれるKubernetesの設定ファイルをapplyする
- controllerと呼ばれる内部の実装によって差分を監視
- 差分があったら、Manifestをもとに各リソース(後で説明)が立ち上がる

ここで特徴的なのは、各リソースは宣言的な仕組みであること。
Kubernetesではユーザーが宣言したマニフェストをもとに複数のプログラムが連携し、システムがあるべき状態になるように調整していきます。
リソース
ここでは、Kubernetesクラスタを構成する、リソースを理解していきます!
KubernetesのリソースはManifestというyamlファイルで管理されています。
リソースの中でも、元々用意されている標準リソースと、独自でリソースを作成するCRD(Custom Resource Definition)があります。
今回は標準リソースの方をみていきたいと思います。
まずはこれ
👇神ブログでインプット(ありがたやありがたや...)
Kubernetes道場
- 各リソースごとにコード付きで理解ができる
- ハンズオンでできる
- 割と初心者目線な記事で、初めてでも結構細かいところまで理解できる
標準リソースとしては
- Pod
- Replicaset
- Deployment
- Job
- Cronjob
- Service
- Ingress
などがあります。
一旦この辺りの理解ができれば、全体は理解できそうです😁
Pod
コンテナとかストレージとかを1セットにした最小単位のユニットのこと。
Kubernetesクラスター内のPodは、主に次の2種類の方法で使われます。
- 
単一のコンテナを稼働させるPod 
 「1Pod1コンテナ」構成が一般的なユースケース。
- 
複数のコンテナを稼働させるPod 
 単一のPodは、密に結合してリソースを共有する必要があるような、同じ場所で稼働する複数のコンテナからなるアプリケーションをカプセル化することもできます。
 たとえば、アプリケーションのPodのサイドカーコンテナとしてログコレクタを配置してログを収集するようなパターンとか。
Manifestはこんな感じ
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
- kind...リソースの名前
- apiVersion...kindで指定したリソースが属するapigroupの名前を指定
- metadata...clusterのnamespaceを指定したり、オブジェクトのnameを指定したりする
- spec...作成したいコンテナの情報を書く
Deployment
- Pod単位でapplyする事もできるが、Podがちゃんと立ち上がったかどうかはわからないのでちゃんと管理したい(Rolling Update)
- Podのレプリカもつくりたい(ReplicaSet)
 で、それらを管理するためにDeploymentを使います。
Manifestはこんな感じ
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 0%
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:alpine
        name: nginx
specの中を見ていくと
- spec.replicas...いくつPodを作成するか指定
- spec.selector...どのラベルが付いたPodをtemplateとするか指定
- spec.strategy...rollingUpdateするのかrollingOutするのかの指定
Service
Serviceリソースは、クラスター内で起動するPodに対するL4負荷分散と名前解決をします。
Serviceは4つの種類に分けられます。
- 
ClusterIP - クラスター内のPodから、Podグループにアクセスする時に使用
   
 
- クラスター内のPodから、Podグループにアクセスする時に使用
- 
NodePort - KubernetesのNodeのランダムなポートを使用して外部のサーバーからの疎通性を取ってくれる。
   
 
- KubernetesのNodeのランダムなポートを使用して外部のサーバーからの疎通性を取ってくれる。
- 
LoadBalancer - LoadBalancerはNodePortのServiceを作成した上で、さらに外部のLoadBalanerを作成し、LoadBalancerのUpstreamとしてNodePortで疎通性を取っているポートへ転送するよう設定してくれる。
   
 
- LoadBalancerはNodePortのServiceを作成した上で、さらに外部のLoadBalanerを作成し、LoadBalancerのUpstreamとしてNodePortで疎通性を取っているポートへ転送するよう設定してくれる。
- 
ExternalName - 外部のサービスに対してのエイリアス(別名)を作成できる。
   
 
- 外部のサービスに対してのエイリアス(別名)を作成できる。
Manifestはこんな感じ
apiVersion: v1
kind: Service
metadata:
  name: service-my-api
spec:
  type: NodePort # typeにNodePortを指定する
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    name: http
  selector:
    app: my-api # Deploymentと同じappを指定する
    version: v1 # Deploymentと同じversionを指定する
Ingress
- 
クラスター内のServiceに対する外部からのアクセス(主にHTTP)を管理するAPIオブジェクト 
- 
Ingressリソースは、クラスター内で起動するPodに対するL7負荷分散を提供します。Ingressに登録される負荷分散対象は前述のServiceが利用されます。 
- 
IngressではL7レベルのロードバランシング、ServiceではL4レベルのロードバランシングをしています 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-wildcard-host
spec:
  rules:
  - host: "foo.bar.com"
    http:
      paths:
      - pathType: Prefix
        path: "/bar"
        backend:
          service:
            name: service1
            port:
              number: 80
  - host: "*.foo.com"
    http:
      paths:
      - pathType: Prefix
        path: "/foo"
        backend:
          service:
            name: service2
            port:
              number: 80
Tools
- 
kubectl - Kubernetesのコマンドラインツールkubectlを使用すると、Kubernetesクラスターに対してコマンドを実行できるようになります。kubectlは、アプリケーションのデプロイ、クラスターリソースの調査と管理、ログの表示などに使用できます。
 
- 
kubectx - kubernetesのコンテキストを切り替える
- 便利なコマンドtipsのところで紹介
 
- 
Kubernetesをローカルで実行するツール - minikube
- kind
- microk8s
 
- 
kuebval - Manifestのフォーマットチェックツール
- 使うときは--strictをつけて使う
 
- 
kustomize - manifestで共通部分を切り分けて一つのmanifestで共通化できるようにするツール
 
もっと深ぼっていきたいこと
- コントローラー周りのこと
- 内部的な仕組み
- カスタムコントローラー
 
- GKE
- サービスメッシュの導入
- Istio、Envoy...
- Envoy Proxyを始めてみよう
- サービスメッシュについて調査してみた件
 
実際に動かしてみよう
- 
全体的に詳しくハンズオンしたい方 
 👉Kubernetes道場
- 
一旦軽く動かしたい方 
 👉ingress-tutorial
上の資料を参考に手元で動かしてみると、さらにイメージがつきやすくなります!
(ここの詳しい説明は割愛します)
Tips
- kubectlのcontextとnamespace周りの操作をkubectxとkubensでちょっと楽する
- k9s
- k9sとは、kubernetesクラスタをリッチなターミナルUIで操作するためのソフトウェア
- https://github.com/derailed/k9s
 


Discussion
良記事ありがとうございます!