Rancher 構築メモ

## 0.用語

Rancher:実環境でコンテナを稼働させるには、ライフサイクル全体にわたって統合され、管理されなければならない多種多様な技術が必要です。Kubernetesのような強力なツールは、インストールと管理に多くの専門知識を必要とします。Rancherは、生産におけるコンテナの管理と使用を非常に簡単にする完全なコンテナ管理プラットフォームです。（公式より）

カタログ：Rancherは、複雑なスタックを容易に展開できるアプリケーションテンプレートのカタログを提供しています。 ライブラリカタログにはRancher認定カタログのテンプレートが含まれており、コミュニティカタログにはコミュニティカタログのテンプレートが含まれています。 Rancherは、ライブラリ内の認定テンプレートのサポートのみを維持しています。（公式より）

プライベートカタログ：自作のカタログ

スタック：複数コンテナをまとめたもの


## 1.目的
Rancherを使ってみたので自分用のメモ。
Dockerすら始めて2週間なのであんまり実運用を考慮したところまではわかってない。
Proxy環境でのDockerとDocker-compose、Rancherのインストールと、簡単な使い方、RancherでのPostgreSQL+pgAdmin4を入れたプライベートカタログの作成を行う。

## 2.環境

  **ホスト（物理サーバ）**
  - OS：CentOS Linux 7 (Core)
  - proxyあり。proxyない人は適宜proxy部分を読み飛ばしてください。
  - rootで実行。root以外は適宜sudoをつけたりしてください。
  - ファイアウォール、SElinuxは無効

## 3.Dockerインストール

既に物理サーバへのCentOSのインストール、OSアップデートなどは完了している状態として説明する。
環境変数やyum.confへのproxy設定も出来ている前提。

Docker公式のインストール手順：
https://docs.docker.com/engine/installation/linux/docker-ce/centos/#set-up-the-repository

公式の手順に従ってインストールする。


```bash
$ sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

# stableのレポジトリセットアップ
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

# testとedgeリポジトリの有効・無効設定は公式ページを見ること。
# 上記コマンドではtestとedgeリポジトリは有効ではない。

$ yum list docker-ce --showduplicates | sort -r

docker-ce.x86_64            17.09.ce-1.el7.centos             docker-ce-stable

# versionを正確に指定してもいい
$ sudo yum -y install docker-ce

$ sudo systemctl start docker

# proxy環境だと以下のようなエラーがでてhello-world出来なかった。
# docker pullが出来ないみたい。
$ sudo docker run hello-world
Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on <環境のIPアドレス:ポート>: no such host

```

公式のProxyに関する説明通りに設定する。
https://docs.docker.com/engine/admin/systemd/#runtime-directory-and-storage-driver

```bash:
# ディレクトリ作成
$ sudo mkdir -p /etc/systemd/system/docker.service.d

# http-proxy.conf と https-proxy.confファイルを作る
$ touch /etc/systemd/system/docker.service.d/http{,s}-proxy.conf

# めんどいので両方のファイルを同じ内容にして大丈夫。以下のような内容を書き込んで保存する。
$ cat  /etc/systemd/system/docker.service.d/http-proxy.conf 
[Service]
Environment="HTTP_PROXY=http://<ユーザ名>:<パスワード>@<proxyサーバ>:<ポート>/" "HTTPS_PROXY=http://<ユーザ名>:<パスワード>@<proxyサーバ>:<ポート>/" "NO_PROXY=localhost,127.0.0.1(,他にもあれば追加する)"

# デーモン再起動
$ sudo systemctl daemon-reload

# docker再起動
$ sudo systemctl restart docker

# 2018/07/29追加 docker自動起動設定
$ systemctl enable docker.service

# 設定確認
$ systemctl show --property=Environment docker
# もしくは、
$ docker info |grep Proxy

# あまり覚えてないけどIPv6設定はホストで無効化した気がする。
# この設定が必要かどうかは不明。設定しても私の環境では特に問題は起きてない。
$ sysctl -w net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.all.disable_ipv6 = 1
$ sysctl -w net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6 = 1

$ cat /proc/sys/net/ipv6/conf/all/disable_ipv6
1
$ cat /proc/sys/net/ipv6/conf/default/disable_ipv6
1


```

## 4.docker-composeインストール

公式の手順通りインストールする。
https://docs.docker.com/compose/install/#install-compose

```bash:
# proxy環境の場合、curlのproxy設定をすること。
$ sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

$ sudo chmod +x /usr/local/bin/docker-compose

# インストール確認
$ docker-compose --version
```

必要な人はCommand-line completionの設定をする。
公式：https://docs.docker.com/compose/completion/

root以外で環境構築した場合に以下のようなエラーが出たので対処する。

以下に書かれている方法でやっても良いらしい。（未確認）
http://docs.docker.jp/compose/install.html

```bash:
$ docker-compose up -d
ERROR: Couldn't connect to Docker daemon at http://127.0.0.1:8082 - is it running?

If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.

$ sudo docker-compose up -d
sudo: docker-compose: コマンドが見つかりません

# 以下のようにsecure_pathを変更しておく。
$ sudo visudo

...
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/local/bin:/usr/bin
...

# うまくいった
$ sudo docker-compose up -d
Creating network "rancher_default" with the default driver
Pulling rancher-server (rancher/server:latest)...
...

```


## 5.Dockerを動かしてみる

httpdを起動するDockerfileを作成してみた。
Dockerfile内でもENVとして`HTTP_PROXY=${HTTP_PROXY}`、`HTTPS_PROXY-${HTTPS_PORXY}`を指定する。
Dockerfile内でリポジトリを見つけられないエラーが出る場合はyum clean allを書くらしいが、
nginxはうまく行かなくて泣いて諦めた。(proxyのせいか。。)

ファイルが出来たら以下のコマンドを実行。(docker-compose.ymlで書いても良い)
test100の部分は任意の名前。

```bash:
# 適宜好きなディレクトリに変更してください。
$ mkdir -p /root/testweb/html

$ cd /root/testweb

# 以下のDockerfileを作成。
# /etc/yum.confを./にコピーしておく。
$ cat Dockerfile
FROM             centos:centos7.4.1708
MAINTAINER       TestUser
ENV              container docker
ENV              HTTP_PROXY=${HTTP_PROXY}
ENV              HTTPS_PROXY=${HTTPS_PROXY}
ADD              yum.conf /etc/
RUN              yum update -y && yum clean all
RUN              yum swap -y fakesystemd systemd && yum clean all
RUN              yum install -y httpd && yum clean all
RUN              yum install -y iproute
RUN              systemctl enable httpd
EXPOSE           80

# test100は任意の名称
$ docker build -f Dockerfile -t centos:test100 --no-cache=true .
...

# imageの確認
$ docker images
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
centos                                   test100             6973673f976e        19 seconds ago      578MB
...

# docker-compose.ymlでコンテナ起動(docker runでやってもいい)
# 適宜、自分の環境にあうように書き換えてください。
# volumesでホストのボリューム/root/testweb/htmlを/var/www/htmlに見せる。
# 権限がおかしくpermission deniedになる場合は、ホスト側でchownしてやること。
# ★.envファイルでproxyの設定を書いている。ベタでenvironment:でproxy設定を書いても良い。
# ホストのポートを8040に指定。
# docker runの場合はproxy設定を--envで行う。以下に docker runの場合を示す（未確認）。
# docker run -d --privileged --name test -it -p 8040:80 centos:test100 /sbin/init \
#   --env HTTP_PROXY=${HTTP_PROXY} --env HTTPS_PROXY=${HTTPS_PROXY} --restart=unless-stopped こんな感じ？
$ cat docker-compose.yml 
version: '3'
services:
  testweb:
    image: cenots:test100
    container_name: test
    ports:
      - "8040:80"
    privileged: true
    hostname: testweb
    volumes:
      - /root/testweb/html:/var/www/html
    env_file: .env
    restart: unless-stopped
    command: /sbin/init

# 適宜、自分の環境のproxy情報に書き換えてください。
$ cat .env 
http_proxy=http://xxxx
https_proxy=http://xxxx
HTTPS_PROXY=http://xxxx
HTTP_PROXY=http://xxxx
NO_PROXY="localhost,127.0.0.1"

# コンテナ起動
$ docker-compose up -d

# ちゃんと起動している。
$ docker ps -a
CONTAINER ID        IMAGE                             COMMAND                  CREATED             STATUS                       PORTS                                                   NAMES
b5a7ccd8147c        cenots:test100                    "/sbin/init"             17 minutes ago      Up 17 minutes                0.0.0.0:8040->80/tcp                                    test

# コンテナに入ってみる
docker exec -it test /bin/bash

# ホストで (./ = /root/testweb/)
echo "hello" > ./html/index.html

# ブラウザで"ホストIP:8040"を開くとhelloと表示される。

```

## 6.Rancherをインストールする

docker-composeの動作確認できたので、docker-composeでRancherを入れる。
HA構成、ACLなどを考えて書いてないので適宜公式を見て書き換えてください。
https://rancher.com/docs/rancher/latest/en/

```bash:

# v1.6を入れる。rancher2.0が使いたい場合は、 imageで rancher/server:v2.0.0-alpha10を指定する（未確認）
# https://github.com/rancher/rancher

$ mdkir -p /root/rancher/

$ cd /root/rancher/

# 以下のファイルを作成。
# データボリュームをホストに作成して、Rancherを削除してもデータが消えないようにする。
# .evnは先程と同じ
$ cat docker-compose.yml 
version: '3'
services:
  rancher-server:
    image: rancher/server:latest
    container_name: rancher-server
    ports:
      - "8000:8080"
    environment:
      - CATTLE_DB_CATTLE_USERNAME=rancher
      - CATTLE_DB_CATTLE_PASSWORD=rancher
    volumes:
      - /root/rancher/rancher-server/mysql:/var/lib/mysql
      - /root/rancher/rancher-server/mysql-log:/var/log/mysql
      - /root/rancher/rancher-server/cattle:/var/log/cattle
    env_file: .env
    restart: unless-stopped

# 実行
$ docker-compose up -d

# ログを監視。立ち上がりを待つ。
$ docker-compose logs -f rancher-server

```

ブラウザから"ホストIP:8000"でアクセス。右下の方に言語設定があるので日本語にしたい人はする。
管理者→設定でホスト登録URLが正しいか確認する。
ここからの設定はググれば他にも出てくるし簡単なので雑です。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/152194/d179d0a7-08a6-a16b-9d49-1bd30a3eb049.png)

ホストサーバ入れる。5.コマンドをコピーしてホスト上で実行する。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/152194/8752a68d-76cc-e7af-4615-4d456a5516dc.png)

インフラストラクチャ→ホストで以下のように、ホストが追加されていることがわかる。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/152194/852bf6d6-3cc9-6e8d-a6c0-b405645ce2ea.png)

## 7.プライベートカタログ追加

以下の公式の通り作成する。Git、リポジトリの説明は省略。
PostgreSQLとpgAdmin4が動くプライベートカタログを作る。
https://rancher.com/docs/rancher/v1.3/en/catalog/private-catalog/

以下のようなディレクトリ構造を作成した。これをgithubのリポジトリに追加した。

```bash:
$ pwd;find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/|  /g'
/root/rancher_catalog/templates/postgres_pgadmin
|--0
|  |--docker-compose.yml
|  |--rancher-compose.yml
|--catalogIcon-cloudflare.png
|--config.yml

$ cat config.yml 
name: postgres_pgadmin
description: "available postgreSQL&pgAdmin4"
version: v0.1
category: "Web Apps"

$ cat docker-compose.yml 
version: '2'

services:
  postgres:
    image: postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: changeme
      PGDATA: /data/postgres
    volumes:
       - /data/postgres:/data/postgres
    ports:
      - "5434:5432"
    networks:
      - postgres
    restart: unless-stopped
  
  pgadmin:
    links:
      - postgres:postgres
    image: fenglc/pgadmin4
    volumes:
       - /data/pgadmin:/root/.pgadmin
    ports:
      - "5052:5050"
    networks:
      - postgres
    restart: unless-stopped

networks:
  postgres:
    driver: bridge

$ cat rancher-compose.yml 
version: '2'
catalog:
  name: "PostgreSQL & pgAdmin4"
  version: "v1.0"
  description: "PostgreSQL & pgAdmin4"
services:
  postgres:
    scale: 1

```

カタログを追加に、名前、URL、ブランチを入れて保存をする。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/152194/956468c1-6f7b-85fc-c3a2-1639cd03997a.png)

自作のカタログが追加される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152194/d2747e54-ea01-21f8-2e81-d8522e8824da.png)

## Docker、Rancherについてのメモ
- ホストreboot時のコンテナの起動  
  `systemctl enable docker`でdockerを自動起動させている場合は、rancherとその管理対象は自動起動するっぽい。restartの設定？
  ただし、rancherで管理していない独立型コンテナに関してはrancherが起動してくれないので個別に自動起動を仕掛ける必要がある。
- データ永続化  
  volumeでホストかデータ用コンテナにデータを保存するようにしないとコンテナ削除でデータが消える。
- rancherのアップデート  
  何故かrancher2.0はうまく入れられなかった。時間無いので後回し。  
  s6-svscanctl: fatal: unable to control /service: supervisor not listening。こんなのが出てうまくいかない。  
  データ永続化をすれば毎回ホスト追加などしなくても問題なく情報を残してアップデート出来た。  
  ranchersvrを削除してもスタックが消えることはない。（当たり前か）  
  アップデートの時にagentや他のrancherのネットワーク用のコンテナは特に削除などしなくてもアップデート出来た。
- クラスタ  
  scaleを増やすだけでコンテナを増やしてスケールしてくれる。
  ホストが複数ある場合は、分散してコンテナが割り当てられる。  
  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/152194/e6bf747b-10a4-9a8f-5fe5-87470272bf0c.png)    
  あるホストが死んだ場合、死んだホスト上のコンテナを生きているホスト上で立て直してくれる。  
  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/152194/6a5af2c2-b218-f68e-1f08-341c91adf821.png)


## コマンドメモ

- docker-compose build --no-cache #cacheせずにbuild



## 今後調べたいこと
- rancher CLI
- postgreSQLのクラスタとrancherの関連（pgpool-IIの構築）
- cattle→k8s
- Rancher ACL設定

## おわり
まだわかってない部分が沢山あるので、公式ドキュメントを読みたい。
勉強中なので変なこと言ってたら教えてください。
プライベートカタログは今のままだとスケール出来ないのでその設定も今後行う。

## 参考
- IT技術者のための現場ノウハウ Docker 実践ガイド (古賀 政純=著)
- [Docker公式サイト][docker_formal]


[docker_formal]: https://docs.docker.com/engine/installation/linux/docker-ce/centos/#install-docker-ce-1

[misc]: https://www.slideshare.net/recruitcojp/rancherrancher