RancherでKubernetesでHelmでDockerでJenkinsを動かす方法

# RancherでKubernetesでHelmでDockerでJenkinsを動かす方法
Rancherを使ってKubernetesクラスタを構築し、HelmでJenkinsをインストールする手順を紹介します。
Dockerをオーケストレーションツールで管理し、既存のアプリケーション（JenkinsとかWordPressとか）を実行したい、というとき、それぞれをインストールしていこうとすると、ドキュメントが散在していて困ることがあります。
今回はRancher→Kubernetes→Helm→Jenkinsまで構築する一連の手順をまとめます。

全体像はこうなります。

![0.png](https://qiita-image-store.s3.amazonaws.com/0/55384/24c1f06b-37df-ea86-1696-67c1407f2071.png)


## サーバ
サーバは3台使います。
2台がKubernetesクラスタとなり、1台はNFSサーバになります。

|  サーバ  |  役割   |  IPアドレス  |  RancherOS |  Kubectl  |  Helm  |
|:--:|:---:|:---:|:---:|:--:|:--:|
|  マスター  |   Kubernetes Master  |   10.249.20.100  |   ○   |   ○   |  ○  |
|  ワーカー  |  Kubernetes Minion  |  10.249.20.102  |  x  |  x  |  x  |
|  NFS  |  NFSサーバ  |  10.249.20.11   |  x  |  x  |   x   |

OSはCentOS7.4を使います。

## Rancher, Kubernetes, Helm, Docker, Jenkins
Rancher, Kubernetes, Helm, Docker, Jenkinsについては以下をご参考ください。

- Rancher:
https://rancher.com/
http://rancher.com/docs/rancher/v1.5/en/

- Kubernetes:
https://kubernetes.io/
https://qiita.com/mihirat/items/ebb0833d50c882398b0f
https://qiita.com/MahoTakara/items/85096f8b2632c802ab22

- Helm:
https://github.com/kubernetes/helm
https://github.com/kubernetes/charts
https://qiita.com/tkusumi/items/12857780d8c8463f9b9c

- Docker:
https://www.docker.com/
https://qiita.com/tigberd/items/b94ae2bf7d78685cd6f5

- Jenkins:
https://jenkins.io/
https://qiita.com/ko8@github/items/e6e058976d48d3fc3424


## 事前作業
事前作業として、まずはOSの設定や更新、Dockerのインストールを行います。
これは全サーバで実行します。
なお、この辺の設定はOSの初期状態次第です。
目的はOSの更新、Dockerのインストール、selinuxやiptables, firewalldの無効化、ホスト名の設定、サーバ間接続の確認です。
特にselinux、iptables, firewalldの無効化はセキュリティ設定ですので、自分の環境、方針に合わせて設定してください。


```bash
## all servers
# update Linux and install docker
sudo su -
yum -y update && yum -y upgrade
rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install epel-release
yum -y install yum-utils git wget vim
yum -y install docker

# start docker
systemctl start docker && systemctl enable docker

# stop selinux and firewalld
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
getenforce
cat /etc/selinux/config
systemctl disable iptables-services firewalld
systemctl stop iptables-services firewalld

# set hostname
ipad=$(ip addr show eth0 | sed -nEe 's/^[ \t]*inet[ \t]*([0-9.]+)\/.*$/\1/p')
hostnamectl set-hostname $(cat /etc/hostname)
echo "HOSTNAME=$(cat /etc/hostname)" >> /etc/sysconfig/network
echo "${ipad}  $(hostname)"  >> /etc/hosts
echo "preserve_hostname: true" >> /etc/cloud/cloud.cfg
hostname && hostname -i && hostname -f

# set ntp
yum -y install chrony
systemctl start chronyd.service
chronyc sources
yum -y install ntp
systemctl start ntpd
systemctl enable ntpd

# set network
cat << EOF > /tmp/hosts
localhost
10.249.20.11
10.249.20.100
10.249.20.102
EOF
for i in $(cat /tmp/hosts); do ssh-keyscan -H $i >> ~/.ssh/known_hosts ; done

# delete yum pkg
yum -y clean all
```

## NFSサーバとクライアントの設定
続いてNFSサーバを構築し、NFSクライアントを設定します。
NFSサーバは10.249.20.11のサーバのみ実行します。

```bash
## nfs server
yum -y install nfs-utils rpcbind
mkdir /opt/nfs
## change network address to your env
echo "/opt/nfs 10.249.20.0/16(rw,no_root_squash)" >> /etc/exports
echo "Domain = $(hostname -d)" >> /etc/idmapd.conf
systemctl start rpcbind nfs-server
systemctl enable rpcbind nfs-server

touch /opt/nfs/test
echo "test nfs" >> /opt/nfs/test
```

これでNFSサーバが起動します。
`/opt/nfs`をNFS共有ストレージにしています。
NFSクライアントからの接続テスト用に、`/opt/nfs/test`というファイルを作り、"test nfs"と書き込んであります。
続いてNFSクライアントです。

```bash
## nfs client
yum -y install nfs-utils
mkdir /opt/nfs
## change ip address to your env
echo "10.249.20.11:/opt/nfs   /opt/nfs        nfs defaults 0  0" >> /etc/fstab
mount /opt/nfs
nfsstat -m

cat /opt/nfs/test
```

NFSサーバ　10.249.20.11の`/opt/nfs`をマウントし、`/opt/nfs/test`の中身を見ています。
以下のように表示されればOKです。

![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/a2081b90-469c-c379-f8f8-7f713e34043d.png)


## Rancherの起動
Rancherを起動します。
RancherはRancherOSとして、Dockerコンテナ専用のOSが提供されています。
以下のコマンドでRancherOSをDocker runし、起動することができます。
このコマンドはKubernetesマスター(10.249.20.100)で実行します。

```bash
## rancher master
# start rancher
docker run -d --restart=unless-stopped -p 8080:8080 rancher/server
```

![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/3c1898f4-6a89-b1fe-9a2c-fdf9c000e2ea.png)


Rancherが起動すると http://10.249.20.100:8080 で公開されます。
ブラウザで　http://10.249.20.100:8080　を開きます。
以下のような画面が表示されていればOKです。

![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/b46e8160-303a-cc22-f6a3-1aa064a6a7d9.png)


## Kubernetesクラスタの構築
Rancherを使ってKubernetesクラスタを構築します。
KubernetesクラスタはRancherで構築、管理されます。
そのため、Rancherの画面上だけでKubernetesクラスタを構築することができます。

左上メニューのDefaults配下のManage Environmentsを選択します。

![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/31e99552-ed6d-6092-bb08-899e9e97d8b6.png)

Add Environmentします。

![4.2.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/f809d83c-5152-91b5-1c2c-922dc03bdcee.png)

環境としてKubernetesを選択して作成します。

![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/f25e54fa-0593-24b8-b755-46725df584b2.png)

これでRancher上にKubernetesの環境は作れます。

![6.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/87a476c2-b100-b32e-e2e4-dd2e524c68d0.png)


続いてKubernetesクラスタにホストを追加します。
Kubernetesクラスタにはマスター(10.249.20.100)とミニオン(10.249.20.102)を参加させます。

Defaults配下のKubernetesを選択します。
![7.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/171590f3-0ecb-3788-3e52-bb3b9e653960.png)

ホスト追加待ち状態になっているので、Add Hostsします。
![8.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/fabc39ea-46e5-88c9-1814-d6b634480dc3.png)

まずはホストの追加先アドレスを設定します。
基本的にここはデフォルトでOKです。
![9.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/4e5976b1-f94c-4b29-c82d-8d88374217ba.png)

まずはKubernetesマスターを追加します。
IPアドレスにKubernetesマスターのIPアドレス（10.249.20.100）を書き込みます。
![10.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/37dede7a-9526-a697-be63-386410790a73.png)

コマンドが生成されるので、このコマンドをコピーしてKubernetesマスターのコンソールで実行します。
![11.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/4a22eecc-0f20-6bcb-022c-b2d4ee53dd87.png)

ホストが追加されると、Rancher上ではこのように見えます。
![12.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/8480eb32-1f3d-b8be-57c7-6a71d5fe04d6.png)

同じ手順でKubernetesミニオンも追加します。
![15.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/3c15ac88-675a-3562-a732-71e605f1ac26.png)

Kubernetesクラスタが起動すると、以下のように[Kubernetesダッシュボード](https://github.com/kubernetes/dashboard)も起動します。
![13.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/cd1b8bf4-1faa-4b20-8355-a7b0ae921c21.png)


### Kubectlのインストール
Kubernetesクラスタの設定が済んだら、kubectlをマスターにインストールします。
KubectlやhelmコマンドはRancherのCLIで操作することもできますが、どうも不安定なようなので、OSにも入れておきます。

![16.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/6e04d087-f7ef-3789-3ec0-df64f4bae0ec.png)


公式なkubectlのインストール方法は以下をご参考ください。
https://kubernetes.io/docs/tasks/tools/install-kubectl/

```bash
# install kubectl
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl
```

kubectlのconfigはRancherの画面上で確認することができます。

![17.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/1fc375b8-fac9-7f01-7064-eabd2b71826f.png)

これをコピーし、`~/.kube/config`に書き込みます。

```bash
cat <<- EOF > ~/.kube/config
apiVersion: v1
kind: Config
clusters:
- cluster:
    api-version: v1
    insecure-skip-tls-verify: true
    server: "https://10.249.20.100:8080/r/projects/1a7/kubernetes:6443"
  name: "KubeEnv"
contexts:
- context:
    cluster: "KubeEnv"
    user: "KubeEnv"
  name: "KubeEnv"
current-context: "KubeEnv"
users:
- name: "KubeEnv"
  user:
    token: "QmFzaWMgTURWQlJURXdOemxHTlRaRVJUTkROa1pCTlRNNlYySmpUa2RaVnpaeGIxcHhhRTFoTlRoMFVYVjZkMVZTV1dwS1MwdHJOV3RVTkhVNWRuVkhZZz09"
EOF

kubectl cluster-info
```

最後にkubectlが使えるか、試してみます。
成功していたら以下のように表示されます。

![18.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/a667373a-8247-dd25-9606-d02a9a1a205a.png)


## Helmのインストール
Helm自体はRancherでKubernetesをインストールしたときに自動的に導入されています。
ここではKubernetesマスターにHelmコマンドをインストールし、Helmクライアントとして使えるようにします。

公式のHelmのインストール方法は以下をご参考ください。
https://docs.helm.sh/using_helm/#installing-helm

```bash
# install helm commands
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh
helm init
helm init --upgrade
helm version
```

Helmクライアントをインストールし、マスターからHelmコマンドが使えるようになりました。
上記の`helm init upgrade`でHelmサーバをアップデートしていますが、少し時間がかかることがあるので気長に待ちましょう。

![20.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/f15fa7dd-e7a4-92df-9faf-6cd27058c47d.png)



## Kubernetes PersistentVolumeの設定
KubernetesにPersistentVolumeを設定します。
PersistentVolumeはKubernetesで永続ストレージとなります。
Dockerコンテナで作ったファイルはDockerコンテナの外に保存しないかぎり、Dockerコンテナが削除されるとファイルも消えます。
Kubernetesの場合、複数サーバでDockerコンテナが起動するため、永続性のある共有ストレージにファイルやデータを保存します。
詳しくは以下をご参考ください。
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
https://qiita.com/kaishuu0123/items/4c4336851d06ba906bab

PersistentVolumeをつくり、ためしにnginxを使ってNFSにデータが書き込めるか、試します。
以下はKubernetesマスターで実行します。

```bash
# setup persistent volume
cat <<- EOF > /opt/pv-nfs.yml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.249.20.11
    path: "/opt/nfs"
EOF
kubectl create -f /opt/pv-nfs.yml

cat <<- EOF > /opt/pvc-nfs.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
EOF
kubectl create -f /opt/pvc-nfs.yml

kubectl get pv,pvc
```

まずはPersistentVolumeとPersistentVolumeClaimを作り、NFSを設定しました。

```bash
# try run nginx with persistent volume
cat <<- EOF > /opt/rc-nfs.yml
apiVersion: v1
kind: ReplicationController
metadata:
  name: rc-nfs-test
spec:
  replicas: 1
  selector:
    app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
          - name: nginx
            containerPort: 80
        volumeMounts:
            - name: nfs
              mountPath: "/usr/share/nginx/html"
      volumes:
      - name: nfs
        persistentVolumeClaim:
          claimName: nfs
EOF
kubectl create -f /opt/rc-nfs.yml
kubectl get pods

echo "NFS Works" > /opt/nfs/index.html
```

![23.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/75e624ef-39b4-933a-f2f4-05de19afd032.png)


Kubernetesクラスタにnginxをデプロイします。
VolumeMountsにNFSを設定し、`/opt/nfs/index.html`に"NFS Works"と書き込みました。


```bash
kubectl exec rc-nfs-test-sqkzn  cat /usr/share/nginx/html/index.html

cat /opt/nfs/index.html
```

`/opt/nfs/index.html`に書き込めていることを確認します。

![24.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/a716571a-7085-94c0-83da-b13e6fdf6b50.png)

![33.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/d0834c41-fe94-75de-063d-30caf7fc9cc7.png)


OKであれば、不要なnginxは削除します。

```bash
kubectl delete pods,rc --all
```


## HelmでJenkins起動
最後に、Helmを使ってJenkinsを起動します。
HelmでJenkinsをインストールするだけであれば、`helm install stable/jenkins`で済むのですが、これだとPersistentVolume不在で正常起動できないことがあります。
HelmでPersistentVolumeを設定するため、以下のオプション付きで起動します。

なお、HelmのJenkins起動方法や使えるオプションは以下をご参考ください。
https://github.com/kubernetes/charts/tree/master/stable/jenkins

```bash
# helm install jenkins
helm install --name my-jenkins --set persistence.enabled=true,persistence.size=10Gi,Persistence.ExistingClaim=nfs stable/jenkins
```

これでJenkinsが起動すると、以下のNotesが表示されます。
![25.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/6d939bd2-abaa-d8f2-0210-41e42306d3b9.png)

Notesに従って、Jenkins adminユーザのパスコードを取得し、URLを入手します。
![26.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/ab5e1d03-23a1-ffd9-2609-d668ec1c0a26.png)

![27.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/711af05a-f843-4b51-fa22-eaac97703ee8.png)

このURLをブラウザで開きます。
起動に時間がかかることもありますが、成功するログイン画面が表示されます。

![31.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/760a5112-b671-437e-4cf4-945247b78e25.png)

adminユーザでさきほどのパスコードを入力し、ログインします。
![32.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/ac7bed1d-b5d0-88f5-6fea-f671d400b2b9.png)

成功です！

なお、Jenkinsの起動はKubernetesダッシュボードから確認することもできます。
![30.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/9953b1ba-0909-1ca4-d128-d695b08d6731.png)


## 以上です。良いRancherでKubernetesでHelmでDockerでJenkinsライフを！