ローカル環境のKubernetesでとにかく動くものを作ってみる

## ローカル環境のKubernetesでとにかく動くものを作る
Dockerに触れる機会があったので、ついでにKubernetesについても理解を深めるためにとにかく動くものを作るまでをまとめてみました。

- ローカルKubernetesの環境構築
- Kubernetes用Dashboradのインストール
- Kubernetes上でJenkinsの構築
    - Podの作成
    - Serviceの作成

## 環境
- OS: Mac OS 10.13.6（High Sierra）
- Docker for Mac: stable版 2.0.0.3
- docker: 18.09.2
- Kubernetes: v1.10.11

## Docker for Windows/MacでローカルKubernetesを構築する
参考リンク
https://qiita.com/nakayamam/items/a9855444cdc4310e0231

**Docker for Mac** を[公式](https://www.docker.com/)からダウンロード。ダウンロードにはアカウントの登録必須です。
ダウンロードした後はアプリメニューからKubernetesメニューを選択し、「Enable Kubernetes」をクリックするだけでKubernetesのインストールが実行されます。

## kubectlのダウンロード
参考リンク（公式）
https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-using-curl

以下のコマンドを実行します。

- kubectlのバイナリをダウンロード

```shell
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
```
- 実行権限を付与

```shell
$ chmod +x ./kubectl
```

- バイナリをbin以下に移動

```shell
$ sudo mv ./kubectl /usr/local/bin/kubectl
```
これでkubecltコマンドが実行可能になります。

## ダッシュボードのインストール
ダッシュボードはKubernetesをWeb上で操作できる管理ツールです。Kubernetes全体のイメージが掴みやすくなるので入れて操作してみるのがいいと思います。ソースはGithubに上がっているので、READMEを参考にデプロイを行います。

URL：https://github.com/kubernetes/dashboard

- 下記のコマンドをターミナルにて実行

```
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
```

- 下記コマンドでダッシュボードの起動

```
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
```

任意のブラウザ上から localhost:8001で管理ツールを表示することができます。最初は以下のような画面が表示されます。
![dashborad.png](https://qiita-image-store.s3.amazonaws.com/0/366054/72a18938-db2e-c29a-474d-e55ef8eee634.png)

サインインを行いましょう。

## Bearerトークンによるサインイン
とりあえず簡単に作成できそうなBearerトークンを作成してサインインをしてみます。トークンの発行方法は、KubernetesのGithubに記述されていたのでそちらを参考することで生成できました。

URL：https://github.com/kubernetes/dashboard/wiki/Creating-sample-user#bearer-token

- コマンドをターミナルにて実行

```shell
https://github.com/kubernetes/dashboard/wiki/Creating-sample-user#bearer-token
```

最後の方に表示されるadmin-user-tokenのtokenをコピーして、管理ツールのサインイン画面でラジオボタン「トークン」を選択し、フォームに貼り付けてサインインできます。以下公式のサンプルです。

```plaintext
Name:         admin-user-token-6gl6l
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name=admin-user
              kubernetes.io/service-account.uid=b16afba9-dfec-11e7-bbb9-901b0e532516

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTZnbDZsIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJiMTZhZmJhOS1kZmVjLTExZTctYmJiOS05MDFiMGU1MzI1MTYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.M70CU3lbu3PP4OjhFms8PVL5pQKj-jj4RNSLA4YmQfTXpPUuxqXjiTf094_Rzr0fgN_IVX6gC4fiNUL5ynx9KU-lkPfk0HnX8scxfJNzypL039mpGt0bbe1IXKSIRaq_9VW59Xz-yBUhycYcKPO9RM2Qa1Ax29nqNVko4vLn1_1wPqJ6XSq3GYI8anTzV8Fku4jasUwjrws6Cn6_sPEGmL54sq5R4Z5afUtv-mItTmqZZdxnkRqcJLlg2Y8WbCPogErbsaCDJoABQ7ppaqHetwfM_0yMun6ABOQbIwwl8pspJhpplKwyo700OSpvTT9zlBsu-b35lzXGBRHzv5g_RA
```
ログインすると以下のような画面が表示されます。

![dashboard2.png](https://qiita-image-store.s3.amazonaws.com/0/366054/a7c62aa3-71ca-206f-0fac-ca0fdac8c84a.png)

## Kubernetesで何か動かしてみる
Jenkinsを構築してみることにしました。ローカルKuberntes上で以下のことを実行します。

- Podの作成
- Serviceの作成

## Kubernetesでできること
公式サイト：https://kubernetes.io/ja/docs/concepts/
公式サイトは一部しか日本語になっていない模様（2019/03/25 現在）

管理ツール上に表示されるサイドメニューがKubernetesの機能に該当するかもしれません。私はKubernetesについて「コンテナを管理する何か」程度しか把握していませんでしたが、サーバに対して行えるあらゆること（冗長化、負荷分散、権限管理、バックアップ、運用監視など）を、コンテナーレベルで可能にするためのツールというふうに大雑把な理解にとどめておくことにしました。まるでコンテナレベルの小さなAWSを扱うかのよう。これからも機能等がどんどん増えていくことでしょう。

**Docker/Kubernetes 実践コンテナ開発入門 5.3 Kubernetesの概念**にKubernetesの概念が一覧で掲載されているので、読んでみると理解が進みやすくなると思います。

以下同本の5.3Kubernetesの概念の引用して掲載しています。

| リソース名       |用途|
|:----------------------|:------------------------------------|
| Node|Kubernetesクラスタで実行するコンテンを配置するためのサーバ|
| Namespace|Kubernetesクラスタ内で作る仮想的なクラスタ|
| Pod|コンテナの集合体の単位でコンテンを実行する方法を定義する|
| ReplicaSet|同じ仕様のPodを複数生成・管理する|
| Deployment|ReplicaSetの世代管理をする|
| Ingress|ServiceをKubernetesクラスタの外に公開する|
| ConfigMap |設定情報を定義しPodに供給する|
| PersistentVolume|Podが利用するストレージのサイズや種別を定義する|
| PersistentVolumeClaim | PersistentVolumeを動的に確保する | 
| StrageClass| PersistentVolumeが確保するストレージの種類を定義する| 
| StatefulSet|同じ仕様で一意性のあるPodを複数生成・管理する|
| Job |常駐目的ではない複数のPodを作成し、正常終了することを保証する|
| CronJob |cron記法でスケジューリングして実行されるJob|
| Sercret |認証情報等の機密データを定義する|
| Role |Namespace内で操作可能なKubernetesリソースのルールを定義する|
| RoleBinding | RoleとKubernetesリソースを利用するユーザーを紐づける|
| ClusterRole |Cluster全体で操作可能なKubernetesリソースを定義づける|
| ServiceAccount |PodにKubernetesリソースを操作させる前に利用するユーザー|

今回はこの中の**（Node）・Pod・Service**を利用して、ローカル環境上にJenkinsを構築してみようと思います。

## Nodeとは
Kubernetesがインストールされたサーバのことです。Nodeを増やすことで、冗長化等が可能になると思います。
Nodeの上位概念がClusterになります。

管理ツール上でも確認することができます。
![node.png](https://qiita-image-store.s3.amazonaws.com/0/366054/c63ed741-9267-e724-bff9-38184042b9ba.png)

今回は特にいじるものはありません。

## Podとは
コンテナの集合体の単位のことです。少なくとも一つのコンテナを持ちます。

## JenkinsのPodを作成

```yml:jebkins-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: jenkins_pod
  labels:
    app: jenkins
spec:
  containers:
  - name: jenkins
    image: jenkins:latest
    ports:
    - containerPort: 8080
```

- ymlからPodを生成

```shell
$ kubectl apply -f jenkins-pod.yml
```

管理ツールで作成したPodを確認してみましょう。

![pod.png](https://qiita-image-store.s3.amazonaws.com/0/366054/b001e973-ab1d-cf11-bd89-44e8a1b6a6a1.png)

Podのみ生成した状態ではjenkinsへアクセスすることができません。localhost:8080にアクセスしようとしても失敗してしまいます。接続をするにはServiceの作成が必要になります。

## Serviceとは
Podの集合に対する経路を提供するためのリソースのことです。イメージとしてはコンテナ間L3スイッチのようなものと理解するととっつきやすいかもしれません。

## Jenkins用のServiceを作成

```yml:jenkins-service.yml
apiVersion: v1
kind: Service
metadata:
  name: jenkins
spec:
  type: NodePort
  selector:
    app: jenkins
  ports:
  - name: http
    port: 8080
```

selectorで先ほど作成したPodのラベルを記述していることで、ServiceとPodの関連付けを行っています。
portsについてもPodで記述したportと同じもの指定しています。

- serviceを作成

```shell
$ kubectl apply -f jenkins-service.yml
```

管理ツールにてServiceが生成されていることを確認
![service.png](https://qiita-image-store.s3.amazonaws.com/0/366054/98ae873f-cd5a-b829-d466-3850975f458c.png)
内部エンドポイントに二行の記述がある。

```
jenkins:8080 TCP
jenkins:30143 TCP
```

localhost:30143 でブラウザからアクセスするとJenkinsの初期設定画面が表示されています。
![jenkins.png](https://qiita-image-store.s3.amazonaws.com/0/366054/647f2769-9d60-9a67-e0ee-f8adf5c44e94.png)

## 終わりに
Kubernetesでコンテナ一つですが何か動くものを作ることができました。
もっとじっくり触ってRailsの環境構築等を作成したり、AWSのEKS等クラウドサービス上に構築も後ほど行ってみたいと思います。

## 参考
[**Docker/Kubernetes 実践コンテナ開発入門**](https://www.amazon.co.jp/Docker-Kubernetes-%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E6%98%8E%E6%86%B2/dp/4297100339/ref=sr_1_2?ie=UTF8&qid=1553449383&sr=8-2&keywords=kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89)
DockerとKuberntesの全体像を掴むのに非常によかったです。

[**Kubernetes完全ガイド**](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear-%E9%9D%92%E5%B1%B1/dp/4295004804/ref=sr_1_1?ie=UTF8&qid=1553449383&sr=8-1&keywords=kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89)
1章と2章を読むだけでも、DockerとKubernetesの概要を掴むことができるので、目を通しておくといいと思います。
 
著者は異なりますがどちらもサイバーエージェントの方が書かれた本です。