前回、最後にちらっと予告していた「OpenResty」をDockerでたてて、Luaスクリプトを使って動的リバースプロキシを構築したいと思います。
まずはDockerfileを作成していきます。ベースとなるイメージは公式で出している「buster-fat」のフレーバーを使います。
FROM openresty/openresty:buster-fat
次に「LuaRocks」というLua用のパッケージマネージャを入れます。公式の説明では alpine-fat
, centos
, bionic
のフレーバーには内包されているということですが、buster-fat
には入っていないので独自に入れます。公式にサンプルがあるので、それを流用しちゃいます。
ARG RESTY_LUAROCKS_VERSION="3.7.0"
# install LuaRocks
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
make \
unzip \
git \
logrotate \
&& cd /tmp \
&& curl -fSL https://luarocks.github.io/luarocks/releases/luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz -o luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz \
&& tar xzf luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz \
&& cd luarocks-${RESTY_LUAROCKS_VERSION} \
&& ./configure \
--prefix=/usr/local/openresty/luajit \
--with-lua=/usr/local/openresty/luajit \
--lua-suffix=jit-2.1.0-beta3 \
--with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1 \
&& make build \
&& make install \
&& cd /tmp \
&& rm -rf luarocks-${RESTY_LUAROCKS_VERSION} luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz
# Add LuaRocks paths
# If OpenResty changes, these may need updating:
# /usr/local/openresty/bin/resty -e 'print(package.path)'
# /usr/local/openresty/bin/resty -e 'print(package.cpath)'
ENV LUA_PATH="/usr/local/openresty/site/lualib/?.ljbc;/usr/local/openresty/site/lualib/?/init.ljbc;/usr/local/openresty/lualib/?.ljbc;/usr/local/openresty/lualib/?/init.ljbc;/usr/local/openresty/site/lualib/?.lua;/usr/local/openresty/site/lualib/?/init.lua;/usr/local/openresty/lualib/?.lua;/usr/local/openresty/lualib/?/init.lua;./?.lua;/usr/local/openresty/luajit/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/openresty/luajit/share/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/?/init.lua"
ENV LUA_CPATH="/usr/local/openresty/site/lualib/?.so;/usr/local/openresty/lualib/?.so;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so"
# install a rock
RUN /usr/local/openresty/luajit/bin/luarocks install ljsyscall \
&& /usr/local/openresty/luajit/bin/luarocks install lua-resty-ipmatcher
一部追加しているものを説明します。
&& /usr/local/openresty/luajit/bin/luarocks install lua-resty-ipmatcher
まずはこの部分ですが、独自に実装したLuaスクリプトでIPアドレスをCIDRで判定したいので、「lua-resty-ipmatcher」というモジュールを追加します。
このモジュールですがIPアドレスを下記のようにCIDR形式で判定することができるようになります。
local ipmatcher = require("resty.ipmatcher")
local ip = ipmatcher.new({
"127.0.0.1",
"192.168.0.0/16",
"::1",
"fe80::/32",
})
ngx.say(ip:match("127.0.0.1"))
ngx.say(ip:match("192.168.1.100"))
ngx.say(ip:match("::1"))
上記のモジュールをインストールするには「git」が必要になるので「apt-get」 しているところに追加します。あとNGINXのログをホストにバインドしてローテしたいので「logrotate」もついでにいれます。logrotateはインストールしただけだと実行されないので以下の設定ファイルを /etc/logrotate.d
に格納してサービスを有効にします。
/usr/local/openresty/nginx/logs/*.log {
daily
rotate 10
missingok
notifempty
sharedscripts
compress
delaycompress
postrotate
/usr/local/openresty/nginx/sbin/nginx -s reopen >/dev/null 2>&1 || true
endscript
}
サービス有効化はENTRYPOINTにシェルスクリプトをかまして service cron start
を実行します。
#!/bin/sh
echo "Starting cron service"
service cron start
echo "Starting openresty"
/usr/bin/openresty -g 'daemon off;'
exec "$@"
Luaスクリプトはコンパイルしてバイトコード化することができるのでその処理を追加します。スクリプトの置き場とバイナリの出力先は呼び出しやすいようにLUA_PATHで定義してるところにしましょう。
# Compile script
RUN cd /usr/local/openresty/nginx/lua/ \
&& ls *.lua | sed -e s/\.lua// | xargs -I{} luajit -b {}.lua {}.luac
あとはいつもの如く、実行ユーザーとドキュメントルートの作成、各種ファイルのコピー、ヘルスチェック等を追加します。最終的に以下のDockerfileになります。
FROM openresty/openresty:buster-fat
ARG RESTY_LUAROCKS_VERSION="3.7.0"
ARG PUID=300
ARG PGID=300
# install LuaRocks & Others
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
make \
unzip \
git \
logrotate \
&& cd /tmp \
&& curl -fSL https://luarocks.github.io/luarocks/releases/luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz -o luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz \
&& tar xzf luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz \
&& cd luarocks-${RESTY_LUAROCKS_VERSION} \
&& ./configure \
--prefix=/usr/local/openresty/luajit \
--with-lua=/usr/local/openresty/luajit \
--lua-suffix=jit-2.1.0-beta3 \
--with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1 \
&& make build \
&& make install \
&& cd /tmp \
&& rm -rf luarocks-${RESTY_LUAROCKS_VERSION} luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz
# Add LuaRocks paths
# If OpenResty changes, these may need updating:
# /usr/local/openresty/bin/resty -e 'print(package.path)'
# /usr/local/openresty/bin/resty -e 'print(package.cpath)'
ENV LUA_PATH="/usr/local/openresty/site/lualib/?.ljbc;/usr/local/openresty/site/lualib/?/init.ljbc;/usr/local/openresty/lualib/?.ljbc;/usr/local/openresty/lualib/?/init.ljbc;/usr/local/openresty/site/lualib/?.lua;/usr/local/openresty/site/lualib/?/init.lua;/usr/local/openresty/lualib/?.lua;/usr/local/openresty/lualib/?/init.lua;./?.lua;/usr/local/openresty/luajit/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/openresty/luajit/share/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/?/init.lua"
ENV LUA_CPATH="/usr/local/openresty/site/lualib/?.so;/usr/local/openresty/lualib/?.so;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so"
# install a rock
RUN /usr/local/openresty/luajit/bin/luarocks install ljsyscall \
&& /usr/local/openresty/luajit/bin/luarocks install lua-resty-ipmatcher
# create webservd user
RUN groupadd -g ${PGID} webservd \
&& useradd -u ${PUID} -g webservd -d /home/webservd -m webservd \
&& mkdir -p /home/webservd/WebContent/ROOT
# Copy nginx configuration files
COPY ./conf/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
COPY ./conf/ssl.conf /etc/nginx/ssl.conf
COPY ./conf/dhparam /etc/nginx/dhparam
COPY ./conf/conf.d/*.conf /etc/nginx/conf.d/
COPY ./conf/logrotate.d/* /etc/logrotate.d/
COPY ./lua /usr/local/openresty/nginx/lua
COPY entrypoint.sh /
# Compile script
RUN cd /usr/local/openresty/nginx/lua/ \
&& ls *.lua | sed -e s/\.lua// | xargs -I{} luajit -b {}.lua {}.luac
# Healthcheck to make sure container is ready
HEALTHCHECK CMD curl --fail http://localhost:80 || exit 1
ENTRYPOINT ["sh", "/entrypoint.sh"]
EXPOSE 80 443
# Declare volumes for mount point directories
VOLUME ["/usr/local/openresty/nginx/logs", "/etc/ssl", "/home/webservd/WebContent/ROOT"]
ひとまず、Dockerfileはこれで完成したのであとは肝心のLuaスクリプトとNGINXの設定ですが長くなったので次回に回します。
コメント