CLOVER🍀

That was when it all began.

Varnish 6.0をUbuntu Linux 18.04 LTSにインストールする

これは、なにをしたくて書いたもの?

キャッシュサーバーで有名な、Varnishをちょっと試してみようかな、と。

対象はLTSであるVarnish 6.0で、Ubuntu Linuxにインストールします。

Varnish

Varnishとは、キャッシュサーバーの1種です。

Varnish HTTP Cache — Varnish HTTP Cache

HTTPを対象としたキャッシュサーバーであり、バックエンドのサーバーの代わりにコンテンツを配信するリバースプロキシとして
動作します。比較対象としては、SquidやApacheのmod_proxy、nginxのキャッシュ機能などが挙がります。

非常に高速で、設定はVCLという独自言語で柔軟に設定できることが利点として謳われています。

Introduction to Varnish — Varnish HTTP Cache

サポートしているプラットフォームは、こちら。

Varnish is written to run on modern versions of Linux and FreeBSD and the best experience is had on those platforms. Thanks to our contributors it also runs on NetBSD, OpenBSD, OS X and various Solaris-descendants like Oracle Solaris, OmniOS and SmartOS.

基本的には、Linux、FreeBSDが対象ですね。

Supported platforms

なお、Squidとの違いは以下に書かれています。

What is the difference in caching architectures between Varnish and Squid?

Squidはフォワードプロキシにもリバースプロキシにもなれますが、Varnishはリバースプロキシのみです。

こちらも参考に。

Varnish入門と仕組み - Qiita

インストール

今回の環境は、こちら。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:    18.04
Codename:   bionic

Ubuntu Linux 18.04 LTSにインストールします。ドキュメントを読むと、aptでインストールが可能なようです。

Installing on Debian/Ubuntu — Varnish version 6.3.0 documentation

インストール。

$ sudo apt install varnish

すると、ちょっと古いVarnishが入りました。

$ varnishd -V
varnishd (varnish-5.2.1 revision 67e562482)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2015 Varnish Software AS

もうちょっと新しいのがいいですね。6.0のインストール手順があったので、こちらで試してみましょう。

Varnish 6.0 LTS Install / Manual deb

パッケージのインストール。

$ sudo apt install curl gnupg apt-transport-https

鍵の取り込み。

$ curl -sL https://packagecloud.io/varnishcache/varnish60lts/gpgkey | sudo apt-key add -
OK

aptリポジトリの追加。

$ sudo add-apt-repository 'deb https://packagecloud.io/varnishcache/varnish60lts/ubuntu/ bionic main'

1度更新して

$ sudo apt update

Varnishをインストール。

$ sudo apt install varnish

今度は、6.0が入りました。

$ varnishd -V
varnishd (varnish-6.0.4 revision 14d4eee6f0afc3020a044341235f54f3bd1449f1)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2019 Varnish Software AS

どうやら、Varnish 6.0がLTSのようです。最新版は6.3ですが、今回はLTSを使うことにしましょう。

2018-11-12 - Varnish 6.0.2 released, official Long Term Support

At the same time we bring you the news that that 6.0 will maintained much longer than other Varnish Cache Releases, and that new repositories, Varnish 6.0 LTS, are introduced.
If you are currently using official packages, you need to change to the new LTS repositories to get 6.0.2. Please follow the instructions on the release page to set up the new repository for your platform.

少し調べていると、起動時にvarnishdに与えている引数が重要みたいなことを見たので、ちょっとsystemdの設定を確認。

$ grep -v '#' /etc/systemd/system/multi-user.target.wants/varnish.service 
[Unit]
Description=Varnish Cache, a high-performance HTTP accelerator
After=network-online.target

[Service]
Type=forking
KillMode=process

LimitNOFILE=131072

LimitMEMLOCK=85983232

TasksMax=infinity

LimitCORE=infinity

ExecStart=/usr/sbin/varnishd -a :6081 -f /etc/varnish/default.vcl -s malloc,256m
ExecReload=/usr/sbin/varnishreload

[Install]
WantedBy=multi-user.target

オプションの意味を確認。

$ varnishd -?

「-a」がバインドするアドレス、ポートのようです。

  -a address[:port][,proto]    # HTTP listen address and port
     [,user=<u>][,group=<g>]   # Can be specified multiple times.
     [,mode=<m>]               #   default: ":80,HTTP"
                               # Proto can be "PROXY" or "HTTP" (default)
                               # user, group and mode set permissions for
                               #   a Unix domain socket.

「-f」が設定ファイルの指定。

  -f vclfile                   # VCL program
                               # Can be specified multiple times.

「-s」がストレージオプション。

  -s [name=]kind[,options]     # Storage specification
                               # Can be specified multiple times.
                               #   -s default (=malloc)
                               #   -s malloc
                               #   -s file

とすると、6081ポートでバインドし、設定ファイルは「/etc/varnish/default.vcl」で、ストレージにはmalloc(メモリ)で256Mバイト、
と読めそうですね。

ExecStart=/usr/sbin/varnishd -a :6081 -f /etc/varnish/default.vcl -s malloc,256m

はい。

$ sudo ss -tnlp | grep varnish
LISTEN   0         128                 0.0.0.0:6081             0.0.0.0:*        users:(("cache-main",pid=8314,fd=3),("varnishd",pid=8297,fd=3))                
LISTEN   0         10                127.0.0.1:45539            0.0.0.0:*        users:(("varnishd",pid=8297,fd=8))                                             
LISTEN   0         128                    [::]:6081                [::]:*        users:(("cache-main",pid=8314,fd=5),("varnishd",pid=8297,fd=5))

起動停止は、systemdで。

$ sudo systemctl start varnish
$ sudo systemctl stop varnish

デフォルトの設定ファイルを確認して、バックエンドサーバーを置いてみる

デフォルトの設定ファイルを見てみましょう。

$ grep -v '#' /etc/varnish/default.vcl 

vcl 4.0;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_recv {
}

sub vcl_backend_response {
}

sub vcl_deliver {
}

デフォルトのバックエンドサーバー定義と、いくつかサブルーチンの定義があります。

とりあえず、バックエンドに簡単なサーバーを立ててみましょう。

$ echo 'Hello Varnish!!' > hello.txt
$ python3 -m http.server 8080

確認。

$ curl localhost:6081/hello.txt
Hello Varnish!!

バックエンドのサーバーにもリクエストが到達しました。

127.0.0.1 - - [29/Sep/2019 02:58:48] "GET /hello.txt HTTP/1.1" 200 -

この後、何回かcurlを実行しても、バックエンドまでリクエストが届きません。この状態で、キャッシュされているようです。

デフォルトのTTLは、どうなっているのでしょう?varnishadmというコマンドで、確認できるようです。

varnishadm — Varnish version 6.0.4 documentation

varnish-cli — Varnish version 6.0.4 documentation

確認すると、120秒です、と。

$ sudo varnishadm param.show default_ttl
default_ttl
        Value is: 120.000 [seconds] (default)
        Minimum is: 0.000

        The TTL assigned to objects if neither the backend nor the VCL
        code assigns one.

        NB: This parameter is evaluated only when objects are created.
        To change it for all objects, restart or ban everything.

ちょっと、有効期限を変えてみましょう。

sub vcl_backend_response {
    set beresp.ttl = 5s;
}

5秒にしてみました。こうすると、5秒でキャッシュが切れ、バックエンドのサーバーにアクセスが行くようになります。

「beresp」というのは、VCLにおけるリクエスト、レスポンスを表すオブジェクトのひとつで、バックエンドからのレスポンスを
表すオブジェクトのようです。

Request and response VCL objects — Varnish version 6.0.4 documentation

「resp」だと、Varnishからクライアントに返すレスポンスを指すようですね。

また、オブジェクトの属性の意味は、こちらで確認できます。

VCL — Varnish version 6.0.4 documentation

ログを見たい

デフォルトでは、Varnishはログをファイルとしては出力しません。共有メモリに持っています。

Logging in Varnish — Varnish version 6.0.4 documentation

これは、速度優先だからみたいですね。

とはいえ、ログを見る方法がまったくないわけではなく、varnishlog、またはvarnishncsaコマンドを使うことでログを見ることが
できます。

$ sudo varnishlog -g raw
$ sudo varnishlog -b
$ sudo varnishlog -c

指定するオプションによって動作が変わり、割と詳細な情報を見ることができます。

varnishlog — Varnish version 6.0.4 documentation

続いて、varnishncsa。

$ sudo varnishncsa

こちらでは、Apacheのアクセスログのようなフォーマットでログを見ることができます。

127.0.0.1 - - [29/Sep/2019:03:39:42 +0000] "GET http://localhost:6081/hello.txt HTTP/1.1" 200 16 "-" "curl/7.58.0"

varnishncsa — Varnish version 6.0.4 documentation

このコマンドを利用すると、ログをファイルに書き出すこともできるみたいです。

デフォルトのログフォーマットは以下のようなので、ドキュメントを見て少し変えてみましょう。

%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-agent}i"

「%{Varnish:hitmiss}」を加えて、キャッシュヒットまたはキャッシュミスをログ出力するようにしてみました。

$ sudo varnishncsa -F '%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-agent}i" %{Varnish:hitmiss}x'
127.0.0.1 - - [29/Sep/2019:03:43:42 +0000] "GET http://localhost:6081/hello.txt HTTP/1.1" 200 16 "-" "curl/7.58.0" miss
127.0.0.1 - - [29/Sep/2019:03:43:44 +0000] "GET http://localhost:6081/hello.txt HTTP/1.1" 200 16 "-" "curl/7.58.0" hit

設定ファイルとVCL

あとは、設定ファイルを変えつつ、いろいろ試していこうと思ったのですが、今回はここでいったん区切りにします。

次は、以下あたりを見ることになるでしょう。

ビルトインのサブルーチンと、遷移。

Built in subroutines — Varnish version 6.0.4 documentation

Varnish Processing States — Varnish version 6.0.4 documentation

デフォルトで組み込まれているVCL。

https://github.com/varnishcache/varnish-cache/blob/varnish-6.0.4/bin/varnishd/builtin.vcl