rancherをdocker-composeでhttpsでたてた

Rancherをたててそれで社内の色々を勉強がてら移行してみてねとタスクをふられ、とりあえずdocker runでたてたもののhttpだとアクセスコントロールの設定をAzureAD連携できねえな(そもそも認証が平文て危ないよね！)と思ってせっかくだからdocker-composeでnginx-proxyとletsencryptでhttpsにしてみた話です。
別にhttpsにするとこはコンテナでやらなくても良かったんですがまあそこはやってみたかっただけっすね（楽しかったです）。

なんかコンテナとか普段使ってなくてよく知らなかったので調べたりマニュアル読むのに超時間がかかりました(そしてまだ理解度は低めです)がやってみると短時間でできるのでファー！ってなりました。

インスタンスの準備は[AzureのCloudShellとTerraform](https://qiita.com/smallpalace/private/8a2d6046f1892c5797c0)でやりました(サービスプリンシパル不要らしいCloudShell使ってみたかっただけ)。
[画面からポチポチやる方法はここに書いてあった](https://qiita.com/dz_/items/e8a96acd532a97ee0868)ので参考にどうぞ。

で、dockerいれるとこはAnsibleをつかいました。なんかdocker-ceだと17が入るんだけど[rancherがk8sサポートしてるらしいのがdocker-engine1.12らしく](https://rancher.com/docs/rancher/v1.6/en/hosts/#supported-docker-versions)バージョン下げるときにdockerのデータディレクトリ(/var/lib/docker)を消し去らないとストレージドライバのエラーが出ててdocker.ioを入れて消したらデータディレクトリが消えてくれました。この辺のdockerの種類の相関関係~~もちょっとよくわかっていません。~~ 書いてる人がいた→[docker-engine、docker-ce、docker.ioの違い - よくある日記](http://kenoha.hatenablog.com/entry/2017/03/31/114418)

#####**Rancherとは**
[カタログを作っとく](https://www.slideshare.net/m-daichang/rancher-compose)か既存のカタログを使うと手軽にコンテナの構成を作れるGUIのコンテナ管理(オーケストレーション)ツール
という理解でうれしいことについては使い倒してなくて腑に落ちきってないのですが以下のあたりが参考になりました。
[Rancher と GitLab を使う3つの理由](https://www.slideshare.net/ttyno/rancher-gitlab-3)
[Rancherとは – WebARENA backstage](https://blog.arena.ne.jp/vps/602)
[rancherでコンテナベースのサーバ運用を始めた話 - Aqutras Members' Blog](http://blog.aqutras.com/entry/2017/04/22/140037)

#####**ホストの構成やRancherの推奨スペックなど**

とりあえずVM一台の上にコンテナたてただけでmysqlはマウントしただけで外部接続にしてないのでHAでないです。
（[HAには外部のMySQLクラスタへの接続、外部LBのセットアップ、クラスタ間での必要ポートの解放などが要る模様](http://rancher.com/docs/rancher/v1.6/en/installing-rancher/installing-server/#launching-rancher-server---full-activeactive-ha)）

推奨要件

```
Ubuntu 16.04
64-bit
kernel of 3.10+
1GB Memory
Docker 1.10.3+
```

letsencryptでhttpsにするにあたり気にするところとしては、事前にドメインレコード登録して名前解決できるようにしておくということと、クラウドプロバイダがデフォルトで提供するようなドメインだとDDoS扱いというか[週に1つのドメイン20個までしか登録できない的な制限に引っかかる](https://qiita.com/sawanoboly/items/8e3c57aa2e30fc58c4e3)ので独自のを用意する必要がある、など。（あとAzureAD連携的にはテナントに許可されてるドメインじゃないと通らないとかはあるかと思いますが今のところそっちはうまくいってない(テナント管理者アカウント設定してMFA無効とアクセス権の変更あたりが要るっぽいあたりがアレで)）

[HA構築方法はこちらに書いてくださっている](https://qiita.com/cyberblack28/items/40a7a9f21082f95790a1)のがありました。（2台のホストにそれぞれマスタとスレーブのコンテナ立てておりGTIDは有効っぽくてCHANGE_MASTERにバイナリログのポジション指定要らない感じで[mysqlfailover](https://www.s-style.co.jp/blog/2017/10/1147/)とかはしてないので手動切り替え）

[こちらにもHA記事](https://blog.1q77.com/2017/01/rancher-on-digitalocean-part2/)あったので追記。これは[DBはコンテナじゃなくてpacemaker](https://blog.1q77.com/2017/06/mariadb-on-centos7-ha-using-drbd/)ですね。
(SSHがコンテナでは使えないのでコンテナ上でMHAやpacemakerはなんか無理ぽい)

サービスレベル的に夜間休日に自動切り替わりしてほしい等でないなら手動でいいかも。
呼び出される可能性があるなら自動にしたほうが幸せかも。



#####**Docker入れるAnsibleタスク**

dockerengine_versionは`'docker-engine=1.12.6-0~ubuntu-xenial'`と指定しました

```yaml:role/docker/tasks/main.yml
# install docker
- name: Check kernel version.
  fail: msg="Kernel {{ ansible_kernel }} is not supported."
  when: "ansible_kernel | version_compare('3.10', '<')"
- block:
  - name: apt-get install packages
    apt: pkg={{ item }} state=present update_cache=yes
    with_items:
      - apt-transport-https
      - ca-certificates
      - curl
      - linux-image-extra-virtual
      - linux-image-extra-{{ ansible_kernel }}
      - software-properties-common
  - name: Check docker gpg key.
    shell: apt-key fingerprint 0EBFCD88 | grep 0EBFCD88
    register: docker_gpg
    ignore_errors: True
    changed_when: False
  - name: Add Docker’s official GPG key
    shell: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    when: docker_gpg | failed
  - name: set up the stable repository
    shell: add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
  - name: Install docker-ce.
    apt: 
      name: "{{ item }}"
      state: present
      update_cache: yes
    with_items:
      - docker-ce=1.12*
      - docker-compose
    notify:
      - docker-restart
    when:
      - kind_of_docker == "docker-ce"
  - name: Install docker-engine
    apt:
      name: "{{ item }}"
      state: present
      update_cache: yes
    with_items:
      - "{{ dockerengine_version }}"
      - docker-compose
    when:
      - kind_of_docker == "docker-engine" 
  when:
    - ansible_distribution == "Ubuntu"
    - ansible_lsb.major_release > 14
```


#####**docker-compose.ymlの内容と解説**

```yaml:docker-compose.yml
# cat docker-compose.yml 
version: '2'
services:
  rancher-server:
    image: rancher/server:stable
    container_name: "rancher"
    environment:
      VIRTUAL_PORT: 8080
      VIRTUAL_HOST: <server-name>
      LETSENCRYPT_HOST: <server-name>
      LETSENCRYPT_EMAIL: <my-email>
    volumes:
      - '/home/docker/rancher-server/mysql:/var/lib/mysql:rw'
  nginx-proxy:
    image: jwilder/nginx-proxy:latest
    container_name: "nginx-proxy"
    depends_on:
      - rancher-server
    ports:
     - "80:80"
     - "443:443"
    volumes:
      - '/home/docker/nginx-proxy/ssl:/etc/nginx/certs:ro'
      - '/etc/nginx/vhost.d'
      - '/usr/share/nginx/html'
      - '/var/run/docker.sock:/tmp/docker.sock:ro'
    logging:
      driver: syslog
  letsencrypt-nginx-proxy-companion:
    image: jrcs/letsencrypt-nginx-proxy-companion:latest
    container_name: "letsencrypt"
    depends_on:
      - rancher-server
      - nginx-proxy
    volumes_from:
      - nginx-proxy
    volumes:
      - '/home/docker/nginx-proxy/ssl:/etc/nginx/certs:rw'
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
networks:
  default:
    external:
      name: common_link
```

[ググったら出てきたもの](https://gist.github.com/KrustyHack/9dfeb491304b77a4930b)を参考に若干変えただけです。

`services`でそれぞれのコンテナのサービスを定義、
~~（上から順にコンテナが起動するため`rancher`を上にしないと`letsencrypt`でエラー出る）~~ →depens_onで後から起動するサービス側に先に起動させたいサービスを定義するとよさそうでversion2ではlinksは自動的に行われるので不要
`image`で利用するイメージを指定(rancherはstableをpreviewにすると2.0が入る模様)、
`container_name`でコンテナの名前を定義（atattchとかコンテナ間で名前で接続するのにつかう）
`environment`はどうやら指定しておくと勝手に検知してnginx-proxyがリバースプロキシ設定してくれたりletsencryptが証明書作ってくれたりするものらしい（スゲー）
`ports`でホストポート:コンテナポートのフォワーディング指定でホストポートは自動的に公開
`volumes`でhost_volume:container_volumeという感じにマウントしてる
　host_volumeの指定がないのはvolumes_fromでnginx-proxyからletsencryptにコンテナ間で連携する用ぽい
　`rw`は読み書きする、`ro`は読むだけ
　`docker`のソケットはホストの`docker`の終了をコンテナ側で検知するためのもの
　`mysql`は`rancher`が内部的に利用してるらしくデータディレクトリをホストにマウントすることでデータの消失を免れるようにしてる
　クラウドならRDBMSはマネージドのやつに外だしするのが正しいかもしれない（[外部指定オプションが存在する](http://rancher.com/docs/rancher/v1.6/en/installing-rancher/installing-server/#launching-rancher-server---single-container---external-database)）
`logging`でコンテナのサービスのログをドライバ`syslog`でホストの`syslog`に転送
　これやるとrancher側で表示できなくなるのでrancherで確認したい場合は他のやり方考えたほうがよさげ
　改ざん防止他かBlueGreenで入れ替えるのに備えてどっかに飛ばしたい場合は[fluentdで飛ばす](http://blog.takanabe.tokyo/2015/12/24/2021/)とかもできるぽい
`networks`でブリッジネットワークを作成してコンテナ間はコンテナ名で自在に行き来できる用にした

`docker-compose up`だけだとctrl+cで抜けるとdockerコンテナが勝手にstopするので`-d`つける必要がある

rancherに限っては--helpオプションでどんなオプションが使えるか出る感じになってたのでだいぶ親切だなあと思いました

`docker run rancher/server --help`


#####**実施したコマンドなど**

```bash
## 必要そうなディレクトリとymlを準備
 mkdir -p /home/docker/{rancher-server,nginx-proxy}
 cd /home/docker/rancher-server/
 mkdir mysql
 vi docker-compose.yml 
 mkdir ../nginx-proxy/ssl
 mkdir -p /etc/nginx/vhost.d
 mkdir -p /usr/share/nginx/html

## dockerあがってるよな確認
 ls /var/run/docker.sock

## networkを作っておく
 docker network create --driver bridge common_link

## コンテナを起動して確認
 docker-compose up -d
 docker ps
 docker images
 docker run rancher/server --help

## 起動したコンテナが紐づけられてるネットワーク情報を確認
 docker network ls
 docker network inspect common_link

## データディレクトリがマウントされてて証明書が作成されてることを確認
 ll mysql
 ll /home/docker/nginx-proxy/ssl
```

少し待つとhttpsでサイトにアクセスできるようになりました。

docker-composeの上げ下げ方法は--helpうつと出てくる感じでした。
よく考えずにうっかりdown打つと跡形もなく消えるので注意が必要なことがわかりました。

#####**rancher/agentを入れてrancherにホスト登録する**

とりあえずrancher/server入れたホスト本体にrancher/agent入れてホストをrancherに認識さしたところ上がってるコンテナ情報を勝手に取ってきてくれてました。
（1.6だとCattleがデフォだけど[DockerがKubernetesネイティブサポート](http://www.publickey1.jp/blog/17/dockerkubernetesdockercon_eu_2017.html)とかの関係でEnvironment追加してtemplateをKubernetesにしてからホストにagent追加したほうがいいのかもしれないなーとおもったのですが2.0からの話な模様）
[Investigating of kubernetes Platform](https://qiita.com/cyberblack28/items/e4836b4ff06156f69588)
[Kubernetes etc.. & rancher 2.0 technical preview “Let’s import GKE/Bluemix/AKS K8S Clusters !!” Multi Containers “K8S”](https://www.slideshare.net/cyberblackvoom/kubernetes-etc-rancher-20-technical-preview-lets-import-gkebluemixaks-k8s-clusters-multi-containers-k8s)

INFRASTRUCTURE＞Hosts＞AddHost＞Custom＞5のコピペ＞ホスト上で実行しrancher/agentのコンテナ起動さす
すると1分くらいでホスト情報が画面に表示されます

```bash:５のコピペ参考コマンド
sudo docker run -e CATTLE_AGENT_IP="＜ホストのGlobalIP＞"  -e CATTLE_HOST_LABELS='Name=＜ホスト名＞' \
 --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock \
 -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.2.6 https://＜ホストのURL＞/v1/scripts/...
```
ホスト内に表示されたコンテナそれぞれポインタするとそこからrestartとか停止とかログ見たりなど自在にできる感じでした。これだけでもだいぶ便利かもしれないですねー。cattleのSTACKSと[CATALOG](https://www.slideshare.net/m-daichang/rancher-compose)も便利らしいのであとで。。

![rancher-container-mng.png](https://qiita-image-store.s3.amazonaws.com/0/25031/d88ca24f-15a9-b4d7-8893-017ea0fef447.png)


INFRASTRUCTURE＞Containersからコンテナのイメージ名とか打ったコマンドとか全部見られる感じでした。
(docker psでみれるやつかなー）
間違って打ったdockerコマンドが停止状態で表示されててそういうのは消せばよさげでしたね。

![rancher-containers.png](https://qiita-image-store.s3.amazonaws.com/0/25031/2430e280-0553-7513-1ac4-f6a9cbf01212.png)

とりあえずこんなところで失礼します。

他に要りそうだなと思っているのは
・ホストを何台か追加（載ってるクラウド的に可用性のゾーン分ける）
・HA化（要、外部のMySQLクラスタへの接続、外部LBのセットアップ、クラスタ間での必要ポートの解放）
・ホストとコンテナ間で連携するための外部ストレージの用意
・kubernetesとDockerとrancherとdocker-composeそのものに対する仕組みと操作の理解を深める
　コンテナ内の設定ファイル操作して更新する方法とかあんまりわかってないので調べる
　etcdとか分散システムについて全く知らないのをもうちょっと理解する
・Gitlab、Gitlab-runner（CI)、コンテナレジストリを準備する（runnerは、複数コンテナ相乗りだとリソースを食い合いそうかなー）
・ログを飛ばして一括管理することについて検討する
・バックアップとレストアをどこまでどうやればよさそうか調べてやってみる
・アラート監視とグラフ監視についてどうやってやんのかを調べてやってみる
ってところですかね。。

#####**参考サイト**

[クイックスタートガイド](https://rancher.com/docs/rancher/v1.6/en/quick-start-guide/)
[Installing Rancher Server with SSL](http://rancher.com/docs/rancher/latest/en/installing-rancher/installing-server/basic-ssl-config/)
[Docker × Nginx × Let'sEncrypt | 俺の考えた最強のサーバー構築方法！ | Hackers Log](https://hackerslog.net/post/labs/docker-letsencrypt-on-docker-and-nginx/)
[Docker-compose for rancher, nginx and let's encrypt](https://gist.github.com/KrustyHack/9dfeb491304b77a4930b)
[network コマンドを使う — Docker-docs-ja 17.06.Beta ドキュメント](http://docs.docker.jp/engine/userguide/networking/work-with-networks.html)
[Compose を始めましょう — Docker-docs-ja 17.06.Beta ドキュメント](http://docs.docker.jp/compose/gettingstarted.html)
[サービスの拡張と Compose ファイル — Docker-docs-ja 17.06.Beta ドキュメント](http://docs.docker.jp/compose/extends.html)
[Compose の起動順番を制御 — Docker-docs-ja 17.06.Beta ドキュメント](http://docs.docker.jp/compose/startup-order.html)
[DockerコンテナにNginxリバースプロキシを導入](https://gtrt7.com/blog/nginx/reverseproxy)
[【Docker】RancherOSで本格的な自宅サーバーを構築しよう(2) ~ rancher-serverをインストール ~ - Qiita](https://qiita.com/okamu_/items/305e0af4545901d44a94)
[nginxを使ったリバースプロキシ on Docker - Qiita](https://qiita.com/ka2asd/items/372d30be64c57a8a81b1)
[Setting up Rancher to authenticate with AzureAD | Marius Sandbu](http://msandbu.org/setting-up-rancher-to-authenticate-with-azuread/)
[Check! Rancher のホストとして Azure を登録してみよう！ - Qiita](https://qiita.com/dz_/items/24ade6fe0d06c14bbfe4)
[How to Run GitLab in Rancher](http://rancher.com/how-to-run-gitlab-in-rancher-1/)
[Rancher/Kubernetes入門ハンズオン資料～第2回さくらとコンテナの夕べ #さくらの夕べ 番外編](https://www.slideshare.net/zembutsu/rancher-kubernetes-hands-on-sakura-container-evening)
[Rancher プライベートカタログとCompose](https://www.slideshare.net/m-daichang/rancher-compose)
[Investigating of kubernetes Platform](https://qiita.com/cyberblack28/items/e4836b4ff06156f69588)
[Kubernetes etc.. & rancher 2.0 technical preview “Let’s import GKE/Bluemix/AKS K8S Clusters !!” Multi Containers “K8S”](https://www.slideshare.net/cyberblackvoom/kubernetes-etc-rancher-20-technical-preview-lets-import-gkebluemixaks-k8s-clusters-multi-containers-k8s)

余談ですがdockerのドキュメントサイトは英語の方が情報が多い気がしました。（気のせいかもしれない）
日本語サイトみてても.jpを.comに変えて.htmlを/にすると英語ページが出てくる感じでした。