nginxとdocker-genとその他を使って良い感じにする(2)~gitlab構築~
前回の続きです.今回はgitlabの構築をしたいと思います.
環境
前回と同じ
構築したい環境
gitlab.hoge.com
という感じのサブドメイン,かつhttpsでgitlabにアクセスできるようにする.
前準備
前回で構築した環境が動いていれば問題ないです.
gitlabのコンテナを建てる
Gitlabのdockerコンテナ構築にはsameersbn/docker-gitlabがよく用いられているように思いますが,公式のコンテナがあるのでそっちを使っていきたいと思います.
ディレクトリ構成は以下の様にします.
. ├── config ├── data ├── docker-compose.yml └── logs
設定
version: "2" services: gitlab: image: gitlab/gitlab-ce:latest container_name: gitlab volumes: - ./data:/var/opt/gitlab - ./config:/etc/gitlab - ./logs:/var/log/gitlab restart: always environment: VIRTUAL_HOST: gitlab.hoge.com VIRTUAL_NETWORK: shared VIRTUAL_PORT: 80 LETSENCRYPT_HOST: gitlab.hoge.com LETSENCRYPT_EMAIL: hoge@mail.hoge.com GITLAB_OMNIBUS_CONFIG: | external_url "https://gitlab.hoge.com" nginx['listen_port'] = 80 nginx['listen_https'] = false nginx['proxy_set_headers'] = { "X-Forwarded-Proto" => "https", "X-Forwarded-Ssl" => "on" } gitlab_rails['time_zone'] = 'Asia/Tokyo' networks: - shared networks: shared: external: name: internal_shared
gitlabのhttps化には色々手段が考えられると思いますし,直接gitlabを外部に晒す方法であれば直接gitlabに対してletsencryptで取得した証明書を食わせるべきですが,今回はそれらを全てフロントエンドのnginxに任せてしまいます*1.
通常external_url "https://gitlab.hoge.com"
を指定すると証明書が要求されますが,以降のnginxに関する設定をすることでリバースプロキシにそれらの処理をゆだねることが出来ます.
起動
$ docker-compose up
gitlabはかなりメモリを食うようです.実験のためにMac上のVagrantで起動しようとしたときはひたすらエラーでなんともなりませんでしたが,サーバ上ではうまく動いてくれました.
初回起動時には様々な設定を行うようでそこそこの時間がかかり,それまではアクセスしてもエラーが帰ってくるだけになります.
httpsでアクセスできるようになったら成功です.初回ログインに成功したらアカウントの登録を止めておきましょう.
うまくいってないこと
メールの設定もしたのですが確認メールが送られてきません.ルータのログも確認しましたが特にそこでフィルタリングしているわけではなく,どうもgitlabの内部のエラーで送れていないようです.何度か設定をいじくり回したのでそこで何かおかしくなったような気もするのですが…
まとめ
ずっとgithubに頼っていましたがどうしてもgitlabのCI/CDをためしてみたかったのでインストールしました.簡単に起動できて最高な時代になったなぁ…
nginxとdocker-genとその他を使って良い感じにする(1)
jwilder/nginx-proxyという超便利コンテナがあるのですが,こいつは/var/run/docker.sock
をReadOnlyとはいえ外側に晒すコンテナにマウントすることになり怖いので,推奨されているようにjwilder/docker-genとnginxを分けて同様の環境を構築します.
環境
- Ubuntu Server 16.04LTS
- Docker version 1.13.0
- docker-compose version 1.8.0
構築したい環境
macvlanドライバを用いたフロントのnginxへの静的IPアドレスの割り当て,及びdocker-genとJrCs/docker-letsencrypt-nginx-proxy-companionの機能を用いた各コンテナへのサブドメインの割り当てとSSL対応.(2)でgitlabを立ち上げて完成とします.
前準備
静的アドレス割り当て
まず,うちの環境ではこれまでYAMAHA RTX1200を使って,LXCで構築した外側に晒すコンテナ群のセグメントを分けて運用していました.つまり,それぞれのコンテナに対してブリッジを用いて静的なIPアドレスを割り当てていました.そしてルータのIPマスカレードでそれぞれのコンテナへとパケットを通していました.
しかしDockerで静的なIPを割り当てる方法を検索しても,直接NICの下にぶら下げる方法はあまり出てきませんでした.
そこで先輩に教えていただいたのがdocker networkのmacvlanドライバです.
これを用いてdocker networkを作り,それぞれのコンテナへとホストに割り当てられているものと同じ空間の静的なipv4アドレスを割り当てることが出来ました.
まず,ホストのNIC(何も使われていない余っているもの.以下hoge)をプロミスキャスモードにし,network create
します.
$ docker network create --driver macvlan \ --subnet=xxx.xxx.x.x/24 \ --gateway=xxx.xxx.x.y \ -o parent=hoge dmz_nw
docker-composeでのipの割り当て方は以下の様にします.
version: "2" services: front_test: image: nginx container_name: front_test networks: dmz_nw: ipv4_address: xxx.xxx.x.z networks: dmz_nw: external: name: dmz_nw
ブラウザからxxx.xxx.x.z
にアクセスしてWelcome to Nginx
が出てこれば成功です.
各コンテナを繋ぐネットワークの作製
macvlanドライバを用いると,gateway(ルータ)に直接問い合わせをするためdockerの名前解決は使えない*1ため,docker-genの機能を活用するために別のbridgeドライバを用いたnetworkを作製します*2.
$ docker network create --driver bridge \ -o "com.docker.network.bridge.name"="shared" \ shared
nginxとdocker-genを組み合わせる
ディレクトリ構造は以下の様にして進めます.
. ├── docker-compose.yml ├──proxy │ ├── certs │ ├── conf │ │ └── default.conf │ ├── html │ ├── templates │ │ └── nginx.tmpl │ └── vhost │ └── default └── web └── Dockerfile
nginxの設定
docker-compose.ymlに記述していきます.
version: "2" services: proxy: image: nginx container_name: proxy # そのままではコンテナ名が面倒なことになるので指定 volumes: - ./proxy/html:/usr/share/nginx/html:rw - ./proxy/conf:/etc/nginx/conf.d - ./proxy/vhost:/etc/nginx/vhost.d - ./proxy/certs:/etc/nginx/certs:ro # ReadOnlyでマウント restart: always networks: shared: aliases: - proxy dmz_nw: ipv4_address: xxx.xxx.x.N networks: shared: external: name: shared dmz_nw: external: name: dmz_nw
/usr/share/nginx/html
をrw
でマウントしないとなぜかJrCs/docker-letsencrypt-nginx-proxy-companionがエラーを吐きました.
docker-genの設定
本来はnginx-proxyに含まれているnginx.tmplファイルが必要となるので落としてきます.
$ curl https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl > ./proxy/templates/nginx.tmpl
nginxの設定に追記していきます.
version: "2" services: proxy: # 省略 nginx-gen: image: jwilder/docker-gen:latest container_name: nginx-gen volumes: - /var/run/docker.sock:/tmp/docker.sock:ro # ReadOnlyでマウント - ./proxy/templates/nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro # tmplファイルをマウント volumes_from: - proxy restart: always entrypoint: /usr/local/bin/docker-gen -notify-sighup proxy -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf networks: - shared networks: # 省略
letsencryptの設定
version: "2" services: proxy: # 省略 nginx-gen: # 省略 letsencrypt: image: jrcs/letsencrypt-nginx-proxy-companion container_name: nginx-letsencrypt volumes_from: - proxy volumes: - /var/run/docker.sock:/var/run/docker.sock:ro # ReadOnlyでマウント - ./proxy/certs:/etc/nginx/certs:rw environment: NGINX_DOCKER_GEN_CONTAINER: nginx-gen depends_on: - nginx-gen restart: always networks: - shared networks: # 省略
webサーバをぶら下げてみる
以下,webサーバをぶら下げるアドレスをwww.hoge.com
として進めます.
設定
version: "2" services: proxy: # 省略 nginx-gen: # 省略 letsencrypt: # 省略 web: build: ./web container_name: web environment: VIRTUAL_HOST: www.hoge.com VIRTUAL_NETWORK: shared LETSENCRYPT_HOST: www.hoge.com LETSENCRYPT_EMAIL: hoge@mail.hoge.com depends_on: - nginx-gen - proxy restart: always networks: - shared networks: # 省略
web
ディレクトリ以下のDockerfileを編集しますが,これはgithubリポジトリに自分のwebサーバの静的ファイルを置いているためで必須ではないです.
FROM nginx:latest RUN apt update && \ apt install -y git && \ rm -r /usr/share/nginx/html && \ git clone https://github.com/pddg/poyo_web.git /usr/share/nginx/html
立ち上げてみる
$ docker-compose up --build
最初letsencryptでの証明書の取得に時間がかかります.うまく立ち上がったっぽい雰囲気を感じたらwww.hoge.com
にアクセスしてみて,うまく表示されれば完了です.
まとめ
RTX1200でフィルターを使ってアクセスに制限をかけているとはいえ,macvlan以下にぶら下げたコンテナは何の防御もしていないため,もう少し何かするべきかもしれませんがとりあえずはここまで.
かなり身構えてやり始めましたが,2~3時間で思っていたものが出来上がったので良かったです.
今回は全て同じdocker-compose.ymlに記述しましたが,上記で使用したshared
ネットワークにさえ接続すれば,docker run
でも,他のdocker-compose.ymlでも,VIRTUAL_HOST
など各種の環境変数を与えることでサブドメインの割り当てが出来ます.
もう少ししたらgitlabを立ち上げてgitlab.hoge.com
へとhttpsでアクセスできるようにした記事を書きたいと思います.
続き書きました
MacのTwitterクライアントが一切繋がらなくなったのを解決した話
TweetDeckが繋がらなくなったのが最初で,以降夜フクロウもダメになり,最近は公式クライアントでなんとかしていたのですが,ついにそれすらも全く繋がらない状態になってしまったため,さすがに本腰を入れようかと思い色々やったら思ったよりもハマってしまったという話です.
環境
症状
- Twitterクライアントを起動しても全く読み込まない
- ブラウザ等は正常にTwitterに接続できる
- コンソール等からpingしたりtracerouteしてもちゃんとtwitter.comに到達できる
- プロキシ環境下でもなんでもない自宅のWi-Fi環境下で起きる
- そのWi-Fiに繋がっている他の端末でも正常にTwitterが使える
原因究明
まずWireshark*1でパケット解析をしてみることに.とりあえずブラウザ等を閉じて,http || ssl
でフィルタリングしてみると,Twitterクライアントを起動しても一切パケットが飛んでいない(!)ことが分かりました.
名前解決が上手くいっていないのではということで,dns
でフィルタリングしてみましたが,正常に解決している模様.
しかし,フィルタを取っ払って見てみると,どうも大学のdnsサーバらしきアドレスに対してひたすら"TCP Retransmission"*2している模様.おそらくDNS周りのゴミが残っていて正常に通信できていないのではという仮説を立て色々やってみました.
試行錯誤
試行1: 再起動
何か困ったら再起動.しかし効果無し.
試行2: DHCPリース更新
効果無し.
試行3: ローカルのDNSキャッシュをクリア
通常ネットワークの切断時に行われるはずですが,一応
$ sudo killall -HUP mDNSResponder
効果無し.
試行4: ネットワーク設定からDNSに8.8.8.8を追記
効果無し.
解決: ネットワーク設定から「自動プロキシ検出」をオフに
正直半ば諦めていたのですが,たまたま気付いて切ってみたら上手くいったので心底驚きました…
検出だけなら問題ないだろうと思っていたのですが,もう一度オンにするとまた接続できなくなっていたので,おそらくこれが原因と思われます.
ブラウザ等他のものが正常動作していたせいで何が原因なのかの切り分けが難しく,かなりハマりました.とはいえ,プロキシ検出を切ってしまうとまた大学に行くたびにこれをオンにしないといけなくなって面倒なので何かしら対策はしたいところ…
まとめ
「Twitterクライアントがつながらないときはプロキシ検出を切れ. 」
今までのOS Xでは特に問題がなかったのでmacOS Sierraから…?それとも僕の環境に特異的な何かなのでしょうか…とはいえ治って良かったです.
*2:パケットの再送.通常ネットワークの状態が悪いときとかに起こるものらしい.