それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

xargsでリダイレクト> を使う方法

xargs やfind exec でリダイレクトを使うには

sh を挟むのが覚えやすくて楽

sh -c ' cmd "{}"> out.txt '

find と xargs の例

find . | xargs -I@ sh -c ' echo "@" >> names.txt '
find . -exec  sh -c ' echo "{}" >> names.txt '

参考資料

https://stackoverflow.com/questions/845863/how-to-use-in-an-xargs-command

nginxで unix ドメイン socket をlisten してバックエンド専用に設定する。

nginx 使いまくり問題

docker やCDNとか使ってると、いくつのプロキシが挟まるんだよ。管理面倒くさいんだよ。って問題にぶち当たる。特にphp 関連。

browser → 企業・学校内プロキシ → CDN → docker ホスト nginx → dockerコンテナnginx → php-fpm

コレ全部が、SSLのデクリプトとエンクリプションや、TCPコネクションでsyn/ack してると思うとゾッとしない話ではない。そりゃhttp2でTCP節約が必要になるよねって感じる。

リバースプロキシから裏側はTCPを減らせるのでは。

docker ホスト nginx → dockerコンテナnginx → php-fpm

この部分がlocalhost:9000とかで待ち受けてるけど、全部unix ドメインソケットにしてしまえば、接続も管理も楽になるんじゃないかと。

nginx が unix sock で待ち受ける

ポートの管理とかTCPのコネクションが面倒くさいので、unix ソケットでnginx を動かしてみたらどうだろうか。 と思ったので試してみた。

nginx で設定してみる。

/etc/nginx/sites-enabled/default

server {
  #listen 80 default_server;
  #listen [::]:80 default_server;
  listen unix:/var/lib/nginx/backend.sock;
  access_log off;

  # SSL configuration
  #
  ##略
}

接続してみる

echo  'GET /' | nc -U /var/lib/nginx/backend.sock

nginx のunix:sock に応答する プロキシを 構成する。

リバースプロキシからバックエンドのnginxにunixソケットで接続できるようにする。

nginx:80 → nginx:sock に対応するものを作る。

upstream nginx-internal-sock {
    server unix:/usr/local/var/run/nginx-internal.sock;
}
server{

    listen 80;
    server_name 'www';
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Accept-Encoding "";
        proxy_pass http://nginx-internal-sock;
    }

}

または次のように書く

server{

  listen 80;
  server_name 'www';
  
  location / {
    proxy_pass http://unix:/usr/local/var/run/nginx-internal.sock; 
    ## ↑ http://unix:/ は記述ミスじゃなくて本当にこう書きます
  }

}

パスが違うのは、docker の起動時にボリュームでマッピングしてるから

-v /usr/local/var/run/:/var/lib/nginx/

socket ファイルを直接ボリュームマッピングすると socket がすでに存在しますと言われて起動できないので注意

何に使うの?

ポートの管理が面倒くさい。

docker で localhost:8001 / localhost:8002 / localhost:8003 と次々とnginxが占拠していくので何がなんだかわからなくなる。

とくに、nginx→(nginx+phpfpm) 間のリバースプロキシをすると管理が面倒くさいし、docker-composeのYAMLもだんだん増えてしまうので、ファイル名で扱うほうが楽かなかって思ったりしてる。ポート被らないし、ファイル名で識別できるし。ドメインソケットのほうがちょっとだけ速いし。

nginx-fpm をワンペアで扱う

apache+mod_php を使うのであれば、Apacheインスタンスを見ておけばいいが、 fastcgi+apachefastcgi+nginx にすると管理が面倒くさいのでソケットを volumeで外に出そうかなと。

アプリ側の設定 sites-enabled/myapp-php.nginx

upstream my-app-php-fpm {
   server unix:/usr/local/var/run/php-fpm/php-fpm.sock;
}
server{

    listen unix:/usr/local/var/run/my-app-nginx-internal.sock;
    root /var/www/html;

    location ~* \.php$ {
    fastcgi_pass  my-app-php-fpm;
    }

}

フロント側の設定。 sites-enabled/www.myapp.example.com.nginx

upstream nginx-internal-sock {
    server unix:/usr/local/var/run/my-app-nginx-internal.sock;
}
server{

    listen 80;
    server_name www.myapp.example.com;
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Accept-Encoding "";
        proxy_pass http://nginx-internal-sock;

    }

}

こうしておけば、unix socket でバックエンドにつながるので、マシン上に大量にのっけてもポート管理が煩雑にならない。

pull して実行したらcomposer.yaml でポート被った!あああぅっ。ってならなくて済むんじゃないかなと。

apt-cacherで docker buildを速くする

docker build おそい。。。

Dockerfileを書くのが苦痛。ちょっと変えたらすぐに再構築が行われて、上手くキャッシュが効かないことが在る。

apt-update で待たされる。

apt-get update && apt upgrade && apt install がもう無理。1度や2度なら我慢するけど、10回実行する可能性があるならもう我慢できない。

キャッシュしようキャッシュ。

apt-cacher-ngでキャッシュしよう。

---
version: '2'
services:
  apt-cacher:
    container_name: proxies-apt-cacher
    image: sameersbn/apt-cacher-ng
    ports:
    - 3142:3142

docker-composer

docker-composer up -d

クライアント側にキャッシュ設定書こう。

dockerfile作ってるときだけつかう、APT設定ファイル書きましょう

Dockerfile

APT の設定をdocker ファイル作ってるときだけ cacher に向けて、build を考える速度で実行できるようにしておきたい。

apt-cacher-ng は debian でも ubuntu でもどちらでも受け付けてくれる万能選手なので優秀だ。

ubuntu の例。

FROM ubuntu:artful

MAINTAINER takuya_1st

## docker file 作成時の用途
RUN echo 'Acquire::HTTP::Proxy "http://172.17.0.1:3142";' >> /etc/apt/apt.conf.d/01proxy \
 && echo 'Acquire::HTTPS::Proxy "false";' >> /etc/apt/apt.conf.d/01proxy
RUN echo 'APT::Install-Recommends 0;' >> /etc/apt/apt.conf.d/01norecommends \
 && echo 'APT::Install-Suggests 0;' >> /etc/apt/apt.conf.d/01norecommends

## jaist にお願いする。
RUN sed -i.bak  -s 's%http://archive.ubuntu.com/ubuntu/%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g'  /etc/apt/sources.list
# RUN sed -i.bak  -s 's%http://security.ubuntu.com/ubuntu/%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g'  /etc/apt/sources.list

docker registry mirror と組み合わせる

ボトルネックを解消する。 docker 作ってて困るボトルネックは大きく4つ

  • apt install
  • docker pull
  • git clone
  • composer.phar install

これらをまとめて対策したいが、git clone と composer はちょっとめんどくさいので後回しにした。

docker pull を速くする、docker レジストリのミラー機能と組み合わせてまとめて起動しちゃう。

併せた。

---
version: '2'
services:
  apt-cacher:
    container_name: proxies-apt-cacher
    image: sameersbn/apt-cacher-ng
    ports:
    - 3142:3142
  docker-registry-proxy:
    container_name: proxies-docker-registry
    image: my.reg.example.com/docker-registry-proxy
    ports:
    - 5000:5000

これでだいぶ楽になった。

Dockerfile 書いたら負けって解ってるんだけど、docker pull で持ってきたイメージの中でapt update されてたりするのでだいぶ楽になった。思考を止めず、思考の速度でdockerfile 記述に一歩近づいた

関連資料

dockerのプロキシ(docker mirror registry)を設置してdocker hubからのpullを早くする - それマグで!