KubernetesのWorkloadsリソースって？

Kubernetesの勉強をはじめました。用語がすべて真新しくて、わからなくなるので、自分用にざっくりまとめる。
# Kubernetesのリソース

|リソースの種類| 概要 |
|:----------------|:---------------|
|Workloads|コンテナの実行に関するリソース|
|Discovery & LB|コンテナを外部公開するようなエンドポイントを提供するリソース|
|Config & Storage|設定・機密情報・永続化ボリュームなどに関するリソース|
|Cluster|セキュリティやクォータなどに関するリソース|
|Metadata|リソースを操作する系統のリソース|

# Workloadsリソース
コンテナを起動するために利用するリソースです。よく使われるものは以下。
## Pod
https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/
> Kubernetesの基本的な構成要素であり、ユーザーが作成または配置するKubernetesオブジェクトモデルの中で最小かつ最も単純な単位です。Podは、クラスター上で実行中のプロセスを表します。アプリケーションコンテナ（場合によっては複数のコンテナ）、ストレージリソース、固有のネットワークIP、およびコンテナの実行方法を管理するオプションをカプセル化します。

Dockerのコンテナの集合体（１つ以上）のようなイメージと理解した。後述のReplicaSetやDeploymentで生成するほうが運用上は良さそうだし、Pod単体で生成して使うことはないと思った。

同一Pod内のコンテナはlocalhost通信でアクセス可能。
**本番も開発環境もSTGもアプリケーションはlocalhostでDBやRedisにアクセス責務のコンテナを指定しておけば、環境による違いを踏襲できそう**

``` yaml:マニフェストサンプル
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']
```

## ReplicaSet
https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
> ReplicaSetの目的は、いつでも実行中の安定したレプリカポッドのセットを維持することです。そのため、指定された数の同一のPodの可用性を保証するためによく使用されます。

指定したレプリカ数のPodを維持**し続ける**リソース。
セルフヒーリング機能で自動でPodを生成。レプリカ数を増減してスケーリングも可能。

``` yaml:マニフェストサンプル
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # modify replicas according to your case
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3
```

## Deployments
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
> PodとReplicaSetの宣言型更新を提供します。Deploymentsに目的の状態を記述すると、Deploymetsコントローラは制御された速度で実際の状態を目的の状態に変更します。

ローリングアップデート（すべてのReplicaSetを一度に更新するのではなく、新しいReplicaSetを作成して順次移行させるように影響なくデプロイする）やロールバックの機能を持っている。

基本的にDeploymentsのみを扱い、DeploymentsがReplicaSetを生成し、ReplicaSetがPodを生成するような本番運用がいいとされている。

``` yaml:マニフェストサンプル
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
```

## DeamonSet
https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
> DaemonSetは、すべて（または一部）のノードがPodのコピーを実行することを保証します。

ReplicaSetはノード上にPodを配置するが、ノードのリソース状況で配置は自動化されている（全ノードに均等にPodが配置されない）。
DeamonSetはReplicaSetと違い、すべてのノードに１Podを確実に配置してくれる（２Pod配置することもできない）。
Pod上のログ収集や監視などの全ノード上で必ず動作させたいもの向け。

``` yaml:マニフェストサンプル
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: sample-ds
spec:
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.12
          ports:
            - containerPort: 80
```

## StatefulSet
https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
> 一連のPodのDeploymentsとスケーリングを管理し、これらのPodの順序と一意性について保証します。デプロイメントと同様に、StatefulSetは同一のコンテナ仕様に基づいたPodを管理します。配置とは異なり、StatefulSetはそれぞれのPodに対してスティッキーなIDを保持します。

Deploymentと違い、作成されたPod名にサフィックスの数字の連番が付与される。
Pod名が変わらないため、永続化領域に向けのリソースとして利用できる。
スケーリングの順番も明示的で、サフィックスの数字の０から順にスケールアウトし、スケールインの場合は、逆順となる。

``` yaml:マニフェストサンプル
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sample-statefulset
spec:
  serviceName: sample-statefulset
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.12
          ports:
            - containerPort: 80
          volumeMounts:
          - name: www
            mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1G
```

## Job
https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
> ジョブは1つ以上のポッドを作成し、指定された数のポッドが正常に終了するようにします。ポッドが正常に完了すると、ジョブは正常に完了したことを追跡します。指定された数の成功した完了に達すると、タスク（すなわちJob）は完了します。ジョブを削除すると、作成したポッドがクリーンアップされます。

ReplicaSetとの違いは、「Podが停止前提であるかどうか」。
「特定のサーバとのrsync」や「S3などのObjecStrageへアップロード」などのバッチ的な処理に向いている。
並列Jobやワークキュー型の実行も可能。

``` yaml:マニフェストサンプル
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4
```

## CronJob
https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/
> 時間ベースのスケジュールでジョブを作成します。1つのCronJobオブジェクトは、crontab（cronテーブル）ファイルの1行に似ています。 Cron形式で書かれた、指定されたスケジュールで定期的にジョブを実行します。

時間はジョブが開始されたマスターのタイムゾーンに依存することに注意。
同時実行の挙動の指定や、Jobの履歴管理、実行開始期限（開始時間のズレの猶予）なども可能。

``` yaml:マニフェストサンプル
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: sample-cronjob
spec:
  schedule: "*/1 * * * *"
  concurrencyPolicy: Allow
  startingDeadlineSeconds: 30
  successfulJobsHistoryLimit: 5
  failedJobsHistoryLimit: 3
  suspend: false
  jobTemplate:
    spec:
      completions: 1
      parallelism: 1
      backoffLimit: 1
      template:
        spec:
          containers:
          - name: sleep-container
            image: centos:6
            command:
            - "sh"
            - "-c"
            args:
            # 約50%の確率で成功するコマンド
            - "sleep 40; date +'%N' | cut -c 9 | egrep '[1|3|5|7|9]'"
          restartPolicy: Never
```

# 参考
+ [kubernetes.io](https://kubernetes.io/docs/concepts/)
+ [Kubernetes完全ガイド](https://github.com/MasayaAoyama/kubernetes-perfect-guide)