CLOVER🍀

That was when it all began.

Logstashで独自のGrokパターンを定義する際に、ファイルにまとめて読み込む

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

LogstashのGrok filter pluginで使えるGrokパターンは、自分で定義することもできるようなのですが、これをファイルにまとめることが
できるようなので試してみようかなと。

こちらですね。

Grok Filter Configuration Options / patterns_dir

指定のディレクトリ配下にパターンファイルを置くことで、Logstashが認識するようです。
※一応、最後にLogstashのパイプライン定義に直接パターンを書く方法も試しておこうと思います

環境

今回の環境は、こちら。

$ uname -srvmpio
Linux 4.15.0-70-generic #79-Ubuntu SMP Tue Nov 12 10:36:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux


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


$ java --version
openjdk 11.0.5 2019-10-15
OpenJDK Runtime Environment (build 11.0.5+10-post-Ubuntu-0ubuntu1.118.04)
OpenJDK 64-Bit Server VM (build 11.0.5+10-post-Ubuntu-0ubuntu1.118.04, mixed mode, sharing)

Filebeat、Logstashのバージョンは、いずれも7.5.1。それぞれ、aptでインストールしたものです。

## Filebeat
$ filebeat version
filebeat version 7.5.1 (amd64), libbeat 7.5.1 [60dd883ca29e1fdd5b8b075bd5f3698948b1d44d built 2019-12-16 21:56:14 +0000 UTC]


## Logstash
Jan 03 15:45:03 ubuntu1804.localdomain logstash[6755]: [2020-01-03T07:45:03,577][INFO ][logstash.runner          ] Starting Logstash {"logstash.version"=>"7.5.1"}

定義したGrokのパターンが確認できればよいので、Elasticsearchは付けていません。

それぞれのミドルウェアが動作しているサーバーは、以下のとおりとします。

  • Filebeat … 192.168.33.11
  • Logstash … 192.168.33.12

お題とサンプルアプリケーション

アプリケーションが出力した、Multilineなメッセージを含むログを、Filebeatで読み込みLogstashでパースします。

以前やったこちらのエントリで使ったGrok filter pluginの設定を、パターンファイルに切り出して、構成要素からElasticsearchを削ったもの
という感じですね。

Filebeatで読み込んだログを、LogstashでパースしてElasticsearchに放り込む - CLOVER🍀

アプリケーションは、こちらで作成したものと同じものを使います。

Filebeatで、複数行のログをElasticsearchに取り込んでみる - CLOVER🍀

pom.xmlの設定。

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.2.2.RELEASE</version>
                <executions>
                  <execution>
                    <goals>
                      <goal>repackage</goal>
                    </goals>
                  </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

ソースコード。
src/main/java/org/littlewings/spring/example/App.java

package org.littlewings.spring.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@RequestMapping("app")
public class App {
    Logger logger = LoggerFactory.getLogger(App.class);

    public static void main(String... args) {
        SpringApplication.run(App.class, args);
    }

    @GetMapping("info")
    public String info() {
        logger.info("{}, info logging", "hello");

        return "info logging";
    }

    @GetMapping("warn")
    public String warn() {
        logger.warn("{}, warn logging", "world");

        return "warn logging";
    }

    @GetMapping("error")
    public String error() {
        logger.error("{}, error logging", "oops!!");

        return "error logging";
    }

    @GetMapping("exception")
    public String exception() {
        Exception e = new RuntimeException("Oops!!");

        logger.error("exception occurred, {}", "why?", e);

        return "exception logging";
    }
}

こちらをパッケージングして、以下のようにしてFilebeatが動作しているサーバーで起動させます。

$ mvn package
$ java -Dlogging.file.path=/tmp -jar target/simple-logging-web-app.jar

これで、アプリケーション側の準備は完了です。ログファイルは、「/tmp/spring.log」という名前で出力されます。

Filebeatの設定

Filebeat側は、以下のように設定します。

$ sudo grep -vE '^ *#|^$' /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /tmp/spring.log
  multiline.pattern: '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}'
  multiline.negate: true
  multiline.match: after
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false
setup.template.settings:
  index.number_of_shards: 1
setup.kibana:
  host: "192.168.33.14:5601"
output.logstash:
  hosts: ["192.168.33.12:5044"]
processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~

出力先はLogstashで、Multililne messageを読めるようにしておきます。

設定したら、Filebeatは再起動しておきます。

$ sudo systemctl restart filebeat

Logstashの設定をする

では、Logstashの設定を行っていきます。

自分で作るGrokパターンは、以下のディレクトリに配置することにしました。

$ sudo mkdir /etc/logstash/conf.d/patterns

パターンファイルは、拡張子なしで作るみたいですね。

https://github.com/logstash-plugins/logstash-patterns-core/tree/v4.1.2/patterns

Spring Bootのデフォルトのログフォーマットを使っているので、そんな感じの名前でパターンファイルを作成。
/etc/logstash/conf.d/patterns/spring-app-log

LOG_TIME \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d.\d\d\d
PID %{POSINT:pid}
THREAD_NAME \S+
LOGGER_NAME %{NOTSPACE:logger}
LOG_MESSAGE %{GREEDYDATA:logmessage}

SPRING_APP_LOG_MESSAGE (?m)^%{LOG_TIME:logtime} *%{LOGLEVEL:loglevel} %{PID} --- \[%{THREAD_NAME:thread}\] %{LOGGER_NAME} *: *%{LOG_MESSAGE}

※THREAD_NAMEは%{NOTSPACE:logger}をそのまま使ってもいいのですが、今回は定義しなおすサンプルにしています

Grokのパターンは、Onigurumaの正規表現で定義します。

https://github.com/kkos/oniguruma/blob/master/doc/RE

「名前 パターン」な感じですね。

LOG_TIME \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d.\d\d\d

既存のパターンに別名を付けたり、その時にパース後の名前を付与したりもできます。

PID %{POSINT:pid}

最後に全部まとめて、こんな感じで定義。

SPRING_APP_LOG_MESSAGE (?m)^%{LOG_TIME:logtime} *%{LOGLEVEL:loglevel} %{PID} --- \[%{THREAD_NAME:thread}\] %{LOGGER_NAME} *: *%{LOG_MESSAGE}

パース後は、マッチした各要素に名前が付けられます。

で、Logstashのパイプラインは、以下のように定義。
/etc/logstash/conf.d/logstash-app-log.conf

input {
  beats {
    port => 5044
  }
}

filter {
  grok {
    patterns_dir => ["/etc/logstash/conf.d/patterns"]
    match => { "message" => "%{SPRING_APP_LOG_MESSAGE}" }
  }

  mutate {
    rename => [ "@timestamp", "event_time" ]
  }

  date {
    match => [ "logtime", "yyyy-MM-dd HH:mm:ss.SSS" ]
    target => "@timestamp"
  }

  mutate {
    remove_field => [ "logtime", "message" ]
  }
}

output {
  stdout { }
}

patterns_dirで自分が定義したパターンファイルを置いたディレクトリを指定し、matchからは自分で定義したパターンが使えるように
なります。

  grok {
    patterns_dir => ["/etc/logstash/conf.d/patterns"]
    match => { "message" => "%{SPRING_APP_LOG_MESSAGE}" }
  }

patterns_dirはリストで指定するので、複数のディレクトリを指定することができます。

ディレクトリ内で読み込むファイルを絞り込む場合は、patterns_files_globで指定するようです。デフォルトは「*」となっています。

patterns_files_glob

ここまでできたらLogstashを再起動。

$ sudo systemctl restart logstash

確認。

Logstash側では、Logstash自身のログを見ておきましょう。

$ sudo journalctl -u logstash -f

では、Filebeat側のサーバーで、アプリケーションログを出力させてみます。

$ curl localhost:8080/app/info
info logging

$ curl localhost:8080/app/exception
exception logging

$ curl localhost:8080/app/warn
warn logging

少し待っていると、Logstashのログ側にパースされた結果が出力されます。

Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]: {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:          "agent" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:             "hostname" => "ubuntu1804.localdomain",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                 "type" => "filebeat",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "ephemeral_id" => "b5ad0ed3-4216-4b6d-b886-77721edb667d",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:              "version" => "7.5.1",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                   "id" => "9610f5f5-8fea-4a42-b8f4-2c8dee0ded55"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     "logmessage" => "hello, info logging",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:       "@version" => "1",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:       "loglevel" => "INFO",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     "event_time" => 2020-01-03T16:37:38.985Z,
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:          "input" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "type" => "log"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:            "ecs" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "version" => "1.1.0"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:           "host" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:              "hostname" => "ubuntu1804.localdomain",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                    "os" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:              "version" => "18.04.3 LTS (Bionic Beaver)",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:             "platform" => "ubuntu",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:               "family" => "debian",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:               "kernel" => "4.15.0-70-generic",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:             "codename" => "bionic",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                 "name" => "Ubuntu"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                    "id" => "7d9a31c8858d4e5a90285fafc05126ba",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "containerized" => false,
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:          "architecture" => "x86_64",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                  "name" => "ubuntu1804.localdomain"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:            "log" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:           "file" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:             "path" => "/tmp/spring.log"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "offset" => 30735
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "thread" => "http-nio-8080-exec-7",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "logger" => "org.littlewings.spring.example.App",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     "@timestamp" => 2020-01-03T16:37:30.782Z,
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:           "tags" => [
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         [0] "beats_input_codec_plain_applied"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     ],
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:            "pid" => "19574"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]: }
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]: {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:          "agent" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:             "hostname" => "ubuntu1804.localdomain",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                 "type" => "filebeat",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "ephemeral_id" => "b5ad0ed3-4216-4b6d-b886-77721edb667d",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:              "version" => "7.5.1",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                   "id" => "9610f5f5-8fea-4a42-b8f4-2c8dee0ded55"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     "logmessage" => "exception occurred, why?\n\njava.lang.RuntimeException: Oops!!\n\tat org.littlewings.spring.example.App.exception(App.java:44) ~[classes!/:na]\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]\n",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:       "@version" => "1",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:       "loglevel" => "ERROR",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     "event_time" => 2020-01-03T16:37:38.985Z,
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:          "input" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "type" => "log"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:            "ecs" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "version" => "1.1.0"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:           "host" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:              "hostname" => "ubuntu1804.localdomain",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "containerized" => false,
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                    "id" => "7d9a31c8858d4e5a90285fafc05126ba",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                    "os" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:              "version" => "18.04.3 LTS (Bionic Beaver)",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:             "platform" => "ubuntu",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:               "family" => "debian",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:               "kernel" => "4.15.0-70-generic",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:             "codename" => "bionic",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                 "name" => "Ubuntu"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:          "architecture" => "x86_64",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:                  "name" => "ubuntu1804.localdomain"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:            "log" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:           "file" => {
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:             "path" => "/tmp/spring.log"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:          "flags" => [
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:             [0] "multiline"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         ],
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "offset" => 30861
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "thread" => "http-nio-8080-exec-8",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         "logger" => "org.littlewings.spring.example.App",
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     "@timestamp" => 2020-01-03T16:37:32.265Z,
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:           "tags" => [
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:         [0] "beats_input_codec_plain_applied"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:     ],
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]:            "pid" => "19574"
Jan 03 16:37:41 ubuntu1804.localdomain logstash[7354]: }
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]: {
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:          "agent" => {
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:             "hostname" => "ubuntu1804.localdomain",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:                 "type" => "filebeat",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         "ephemeral_id" => "b5ad0ed3-4216-4b6d-b886-77721edb667d",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:              "version" => "7.5.1",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:                   "id" => "9610f5f5-8fea-4a42-b8f4-2c8dee0ded55"
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:     "logmessage" => "world, warn logging",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:       "@version" => "1",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:       "loglevel" => "WARN",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:     "event_time" => 2020-01-03T16:37:38.987Z,
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:          "input" => {
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         "type" => "log"
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:           "host" => {
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:              "hostname" => "ubuntu1804.localdomain",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         "containerized" => false,
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:                    "os" => {
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:              "version" => "18.04.3 LTS (Bionic Beaver)",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:             "platform" => "ubuntu",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:               "family" => "debian",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:               "kernel" => "4.15.0-70-generic",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:             "codename" => "bionic",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:                 "name" => "Ubuntu"
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         },
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:                    "id" => "7d9a31c8858d4e5a90285fafc05126ba",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:          "architecture" => "x86_64",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:                  "name" => "ubuntu1804.localdomain"
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:            "ecs" => {
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         "version" => "1.1.0"
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:            "log" => {
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:           "file" => {
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:             "path" => "/tmp/spring.log"
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         },
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         "offset" => 37805
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:     },
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         "thread" => "http-nio-8080-exec-10",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         "logger" => "org.littlewings.spring.example.App",
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:     "@timestamp" => 2020-01-03T16:37:33.575Z,
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:           "tags" => [
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:         [0] "beats_input_codec_plain_applied"
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:     ],
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]:            "pid" => "19574"
Jan 03 16:37:45 ubuntu1804.localdomain logstash[7354]: }

OKそうですね。

これで、自分で作るGrokパターンをファイルとして用意できることを確認できました、と。

オマケ: Logstashのパイプライン定義の中に、カスタムパターンを用意する

オマケで、Logstashのパイプライン定義の中にカスタムパターンを書く…要するに、インラインで書く例も載せておきます。

この場合、patten_definitionsを使います。

[Grok Filter Configuration Options / pattern_definitions

ひとつのGrok filterの中でのみ有効なので、他の箇所でも使いたい場合はファイルとして切り出した方が良いです。

こんな感じで使います。

  grok {
    pattern_definitions => {
      "SPRING_APP_LOG_MESSAGE" => "(?m)^(?<logtime>\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d.\d\d\d) *%{LOGLEVEL:loglevel} %{POSINT:pid} --- \[%{NOTSPACE:thread}\] %{NOTSPACE:logger} *: *%{GREEDYDATA:logmessage}"
    }
    match => { "message" => "%{SPRING_APP_LOG_MESSAGE}" }
  }

pattern_definitionsの引数がハッシュなので、複数パターンを書こうと思ったら全然うまくいきませんでした…。

Canonicalが開発したパッケージ管理システムSnappy(Snap)を使う

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

以前MicroK8sを試す時に、よくわからないままsnapコマンドでMicroK8sをインストールしたのですが、またsnapを見る機会が
できたので、1度ちゃんと調べてみようかなと思いまして。

Snappy?

Snappyとは、Ubuntu Linuxの開発元であるCanonicalが開発したパッケージ管理システムです。

Snappy - Wikipedia

Snappyで管理されるパッケージのことをSnapと呼ばれ、操作には「snap」というコマンドを使用します。

Linuxのパッケージ管理システムといえば、特にUbuntu Linuxであればaptやdebパッケージを思い浮かべますが、こちらは様々な
Linuxディストリビューションで使えることと、パッケージが自己完結型であることが特徴です。

サポートされているLinuxディストリビューションは、こちら。

Installing snapd | Snapcraft documentation

Ubuntu Linuxではプリインストールされていますが、他のLinuxディストリビューションにインストールすることも可能です。
例えば、CentOSではyumでインストールすることができます。

オフィシャルサイトは、こちら。

Snapcraft - Snaps are universal Linux packages

ドキュメント。

Snap documentation | Snapcraft documentation

利用できるパッケージは、ストアから探します。

Install Linux apps using the Snap Store | Snapcraft

f:id:Kazuhira:20200103025115p:plain

たとえば、Visual Studio Codeを探してみます。

f:id:Kazuhira:20200103025315p:plain

snapコマンドで探すこともできます。このあたりは、後で。

では、ちょっと試していってみましょう。

環境

今回の環境は、こちら。

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

snapはすでにインストールされています。

$ snap version
snap    2.42.1+18.04
snapd   2.42.1+18.04
series  16
ubuntu  18.04
kernel  4.15.0-72-generic

もしもsnapが入っていない場合は、インストールするにはaptを使います。

$ sudo apt install snapd

ここからは、MicroK8sを例に試していってみましょう。

ヘルプを見る

まずは、ヘルプ。

「snap」または「snap help」コマンドで、ざっくりとは見れます。

$ snap
# または
$ snap help
The snap command lets you install, configure, refresh and remove snaps.
Snaps are packages that work across many different Linux distributions,
enabling secure delivery and operation of the latest apps and utilities.

Usage: snap <command> [<options>...]

Commands can be classified as follows:

         Basics: find, info, install, list, remove
        ...more: refresh, revert, switch, disable, enable
        History: changes, tasks, abort, watch
        Daemons: services, start, stop, restart, logs
       Commands: alias, aliases, unalias, prefer
  Configuration: get, set, unset, wait
        Account: login, logout, whoami
    Permissions: connections, interface, connect, disconnect
      Snapshots: saved, save, check-snapshot, restore, forget
          Other: version, warnings, okay, ack, known, model, create-cohort
    Development: run, pack, try, download, prepare-image

For more information about a command, run 'snap help <command>'.
For a short summary of all commands, run 'snap help --all'.

詳細に見たい場合は、「snap help --all」と実行します。

$ snap help --all

snapはコマンドを指定して実行するのですが、コマンドごとに「--help」オプションを付けることでコマンドのヘルプも見ることが
できます。

$ snap install --help

パッケージをインストールする

「snap install」で行います。

$ sudo snap install microk8s
error: This revision of snap "microk8s" was published using classic confinement and thus may
       perform arbitrary system changes outside of the security sandbox that snaps are usually
       confined to, which may put your system at risk.

       If you understand and want to proceed repeat the command including --classic.

怒られました。

パッケージによっては、「--classic」オプションが必要です。

$ sudo snap install microk8s --classic

今度はインストールできます。

この「--classic」オプションの意味ですが、Snapの持つセキュリティ機能を無効にするものになります。

$ snap install --help | grep classic
      --classic                       Put snap in classic mode and disable security confinement

Snapでは環境の分離レベルが定義されており、「--classic」は従来のaptなどのパッケージと同じものになります。

Snap confinement | Snapcraft documentation

通常の「Strict」では、ファイル、ネットワーク、プロセスなど、特別なインターフェースを経由しない限り、他のリソースへは
アクセスできない分離レベルとなります。

どういうパッケージが「--classic」オプションを必要とするかは、検索やパッケージの情報を見た時にわかりますが、そもそも付けない
場合はパッケージのインストールに失敗するので、そこで気づきます。

バージョンを指定したり、開発中のものをインストールしたりする場合は、「--channel」で指定します。

$ sudo snap install microk8s --classic --channel=1.17/stable

どんなchannelがあるかは、パッケージの情報で確認することができます。

インストールされているパッケージを確認する

「snap list」を使います。

$ snap list
Name      Version    Rev   Tracking  Publisher   Notes
core      16-2.42.5  8268  stable    canonical✓  core
microk8s  v1.17.0    1107  stable    canonical✓  classic

「--all」を付与すると、無効になっているパッケージも表示することができます。

$ snap list --all

パッケージを検索する

「snap find」または「snap search」で行います。

$ snap find kubernetes
Name                     Version                Publisher              Notes    Summary
microk8s                 v1.17.0                canonical✓             classic  Kubernetes for workstations and appliances
kata-containers          1.9.3                  katacontainers✓        classic  Lightweight virtual machines that seamlessly plug into the containers ecosystem
kubectl                  1.17.0                 canonical✓             classic  Command line client for controlling a Kubernetes cluster.
conjure-up               2.6.10-20191109.1611   canonical✓             classic  Package runtime for conjure-up spells
juju                     2.7.0                  canonical✓             classic  Simple, secure and stable devops. Juju keeps complexity low and productivity high. Manage applications wherever they are run.
helm                     3.0.2                  snapcrafters           classic  The Kubernetes package manager
kubelet                  1.17.0                 canonical✓             classic  Kubernetes “node agent” that runs on each node in Kubernetes.
kube-proxy               1.17.0                 canonical✓             classic  Kubernetes network proxy that runs on each node.
kube-scheduler           1.17.0                 canonical✓             -        Kubernetes master component that assigns each newly created pod to a node.
kube-controller-manager  1.17.0                 canonical✓             -        Kubernetes master component that runs controllers.
cdk-addons               1.17.0                 canonical✓             -        Addons for Canonical Kubernetes
kube-apiserver           1.17.0                 canonical✓             -        Kubernetes master component that exposes the Kubernetes API.
kubernetes-worker        0.0.1                  canonical✓             -        A complete Kubernetes worker
kubeadm                  1.17.0                 canonical✓             classic  Tool for bootstrapping Kubernetes clusters.

〜省略〜

Notesに「classic」と書かれているものは、インストール時に「--classic」オプションが必要になります。

パッケージの情報を見る

「snap info」を使います。channelの情報は、ここで確認できます。

$ snap info microk8s 
name:      microk8s
summary:   Kubernetes for workstations and appliances
publisher: Canonical✓
contact:   https://github.com/ubuntu/microk8s
license:   unset
description: |
  MicroK8s is a small, fast, secure, single node Kubernetes that installs on just about any Linux
  box. Use it for offline development, prototyping, testing, or use it on a VM as a small, cheap,
  reliable k8s for CI/CD. It's also a great k8s for appliances - develop your IoT apps for k8s and
  deploy them to MicroK8s on your boxes.
commands:
  - microk8s.add-node
  - microk8s.cilium
  - microk8s.config
  - microk8s.ctr
  - microk8s.disable
  - microk8s.enable
  - microk8s.helm
  - microk8s.inspect
  - microk8s.istioctl
  - microk8s.join
  - microk8s.juju
  - microk8s.kubectl
  - microk8s.leave
  - microk8s.linkerd
  - microk8s.remove-node
  - microk8s.reset
  - microk8s.start
  - microk8s.status
  - microk8s.stop
services:
  microk8s.daemon-apiserver:          simple, enabled, active
  microk8s.daemon-apiserver-kicker:   simple, enabled, active
  microk8s.daemon-cluster-agent:      simple, enabled, active
  microk8s.daemon-containerd:         simple, enabled, active
  microk8s.daemon-controller-manager: simple, enabled, active
  microk8s.daemon-etcd:               simple, enabled, active
  microk8s.daemon-flanneld:           simple, enabled, active
  microk8s.daemon-kubelet:            simple, enabled, active
  microk8s.daemon-proxy:              simple, enabled, active
  microk8s.daemon-scheduler:          simple, enabled, active
snap-id:      EaXqgt1lyCaxKaQCU349mlodBkDCXRcg
tracking:     stable
refresh-date: today at 17:59 UTC
channels:
  stable:           v1.17.0  2019-12-13 (1107) 179MB classic
  candidate:        v1.17.0  2019-12-10 (1107) 179MB classic
  beta:             v1.17.0  2019-12-10 (1107) 179MB classic
  edge:             v1.17.0  2019-12-14 (1130) 179MB classic
  dqlite/stable:    –                                
  dqlite/candidate: –                                
  dqlite/beta:      –                                
  dqlite/edge:      v1.16.2  2019-11-07 (1038) 189MB classic
  1.17/stable:      v1.17.0  2019-12-10 (1109) 179MB classic

〜省略〜

Channels | Snapcraft documentation

パッケージをアップデートする

「snap refresh」を使います。

パッケージ単位にアップデートする場合。

$ sudo snap refresh microk8s

インストールされているすべてのパッケージをアップデートする場合。

$ sudo snap refresh

なお、自動アップデートも行われており、デフォルトでは4時間おきに行われます。

$ sudo snap refresh --time
timer: 00:00~24:00/4
last: today at 17:57 UTC
next: today at 19:03 UTC

設定を変える場合は、こちらを参照。

Managing updates | Snapcraft documentation

サービスの管理

Snapでインストールされるものには、Daemonとなるものもあります。MicroK8sもDaemonになりますね。

Service management | Snapcraft documentation

現在稼働しているサービスを確認するには、「snap services」を使います。

$ snap services
Service                             Startup  Current  Notes
microk8s.daemon-apiserver           enabled  active   -
microk8s.daemon-apiserver-kicker    enabled  active   -
microk8s.daemon-cluster-agent       enabled  active   -
microk8s.daemon-containerd          enabled  active   -
microk8s.daemon-controller-manager  enabled  active   -
microk8s.daemon-etcd                enabled  active   -
microk8s.daemon-flanneld            enabled  active   -
microk8s.daemon-kubelet             enabled  active   -
microk8s.daemon-proxy               enabled  active   -
microk8s.daemon-scheduler           enabled  active   -

特定のパッケージに絞って見ることもできます。

$ snap services microk8s
Service                             Startup  Current  Notes
microk8s.daemon-apiserver           enabled  active   -
microk8s.daemon-apiserver-kicker    enabled  active   -
microk8s.daemon-cluster-agent       enabled  active   -
microk8s.daemon-containerd          enabled  active   -
microk8s.daemon-controller-manager  enabled  active   -
microk8s.daemon-etcd                enabled  active   -
microk8s.daemon-flanneld            enabled  active   -
microk8s.daemon-kubelet             enabled  active   -
microk8s.daemon-proxy               enabled  active   -
microk8s.daemon-scheduler           enabled  active   -

サービスの停止。

$ sudo snap stop microk8s

サービスの起動。

$ sudo snap start microk8s

サービスの再起動。

$ sudo snap restart microk8s

ちなみに、MicroK8sに関していえば、「microk8s.start」、「microk8s.stop」でも起動、停止が行なえます。

$ microk8s.stop
$ microk8s.start

サービスの自動起動を有効化するには、「snap start」に「--enable」オプションを付けます。

$ sudo snap start --enable microk8s

自動起動を無効にするには、「snap stop」に「--disable」オプションを付与します。

$ sudo snap stop --disable microk8s

現在の自動起動の設定は、「snap services」で「Startup」を見ればOKみたいですね。

$ snap services microk8s
Service                             Startup   Current   Notes
microk8s.daemon-apiserver           disabled  inactive  -
microk8s.daemon-apiserver-kicker    disabled  inactive  -
microk8s.daemon-cluster-agent       disabled  inactive  -
microk8s.daemon-containerd          disabled  inactive  -
microk8s.daemon-controller-manager  disabled  inactive  -
microk8s.daemon-etcd                disabled  inactive  -
microk8s.daemon-flanneld            disabled  inactive  -
microk8s.daemon-kubelet             disabled  inactive  -
microk8s.daemon-proxy               disabled  inactive  -
microk8s.daemon-scheduler           disabled  inactive  -

ログを見るには、「snap logs」コマンドを使用します。

$ sudo snap logs microk8s

「-f」オプションを使うと、「tail -f」オプションのようにログを読み続けます。

$ sudo snap logs microk8s -f

まるで、systemdを使っているかのようです…。

エイリアスを作成する

ところで、MicroK8sを使う場合「kubectl」コマンドを実行するには以下のような感じになります。

$ microk8s.kubectl create deployment nginx --image nginx:latest

ちょっと長いですね。

こういう時は、「snap alias」でエイリアスを作成することができます。

$ sudo snap alias microk8s.kubectl kubectl
Added:
  - microk8s.kubectl as kubectl

こんな感じになります。

$ kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-75b7bfdb6b-9k8sn   1/1     Running   0          91s

エイリアスの一覧を確認。

$ snap aliases
Command           Alias    Notes
microk8s.kubectl  kubectl  manual

エイリアスの解除。

$ sudo snap unalias kubectl
Removed:
  - microk8s.kubectl as kubectl

ちなみに、元の名前がやたら長いのは、「"snap name"」または「"snap name"."application name"」というような名前空間を
使うことで名前の競合を回避しようとしているからみたいです。

Commands and aliases | Snapcraft documentation

パッケージを有効/無効にする

パッケージを無効にするには、「snap disable」を使います。

$ sudo snap disable microk8s

有効にするには、「snap enable」を使います。

$ sudo snap enable microk8s

パッケージをアンインストールする

「snap remove」を使います。

$ sudo snap remove microk8s

データのスナップショットを残さずに削除する場合は、「--purge」オプションを付けます。

$ sudo snap remove microk8s --purge

Snapshots | Snapcraft documentation

Snap自体の設定

プロキシの設定などは、こちらを参照。

System options | Snapcraft documentation

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

「/snap」ディレクトリになります。

$ ll /snap
total 24
drwxr-xr-x  5 root root 4096 Jan  2 18:33 ./
drwxr-xr-x 23 root root 4096 Jan  2 17:45 ../
drwxr-xr-x  2 root root 4096 Jan  2 18:41 bin/
drwxr-xr-x  3 root root 4096 Jan  2 17:58 core/
drwxr-xr-x  3 root root 4096 Jan  2 18:41 microk8s/
-r--r--r--  1 root root  548 Nov 21 21:45 README

The system /snap directory | Snapcraft documentation

ちょっと見てみると面白いですが、パッケージの中身がまるで隔離空間のように独立したディレクトリ構造になっているように見えます。

$ find /snap/microk8s -type d
/snap/microk8s
/snap/microk8s/1107
/snap/microk8s/1107/actions
/snap/microk8s/1107/actions/common
/snap/microk8s/1107/actions/fluentd
/snap/microk8s/1107/actions/jaeger
/snap/microk8s/1107/actions/jaeger/crds
/snap/microk8s/1107/actions/knative
/snap/microk8s/1107/actions/prometheus
/snap/microk8s/1107/actions/prometheus/setup
/snap/microk8s/1107/bin
/snap/microk8s/1107/certs
/snap/microk8s/1107/certs-beta
/snap/microk8s/1107/configs
/snap/microk8s/1107/default-args
/snap/microk8s/1107/default-args/cni-network
/snap/microk8s/1107/etc
/snap/microk8s/1107/etc/ca-certificates
/snap/microk8s/1107/etc/ca-certificates/update.d
/snap/microk8s/1107/etc/cron.d
/snap/microk8s/1107/etc/cron.weekly
/snap/microk8s/1107/etc/default
/snap/microk8s/1107/etc/dpkg
/snap/microk8s/1107/etc/dpkg/dpkg.cfg.d
/snap/microk8s/1107/etc/gss
/snap/microk8s/1107/etc/gss/mech.d
/snap/microk8s/1107/etc/init
/snap/microk8s/1107/etc/init.d
/snap/microk8s/1107/etc/iproute2
/snap/microk8s/1107/etc/ldap
/snap/microk8s/1107/etc/nvidia-container-runtime
/snap/microk8s/1107/etc/pam.d
/snap/microk8s/1107/etc/python3.5
/snap/microk8s/1107/etc/ssl
/snap/microk8s/1107/etc/ssl/certs
/snap/microk8s/1107/etc/ssl/private
/snap/microk8s/1107/etc/sudoers.d
/snap/microk8s/1107/etc/systemd
/snap/microk8s/1107/etc/systemd/system
/snap/microk8s/1107/etc/zfs
/snap/microk8s/1107/include
/snap/microk8s/1107/include/libiptc
/snap/microk8s/1107/include/libnftnl
/snap/microk8s/1107/lib
/snap/microk8s/1107/lib/pkgconfig
/snap/microk8s/1107/lib/python3.5
/snap/microk8s/1107/lib/python3.5/site-packages

〜省略〜

/snap/microk8s/1107/usr/share/perl5
/snap/microk8s/1107/usr/share/perl5/Debian
/snap/microk8s/1107/usr/share/perl5/Debian/Debhelper
/snap/microk8s/1107/usr/share/perl5/Debian/Debhelper/Buildsystem
/snap/microk8s/1107/usr/share/perl5/Debian/Debhelper/Sequence
/snap/microk8s/1107/usr/share/pixmaps
/snap/microk8s/1107/usr/share/python3
/snap/microk8s/1107/usr/share/python3/debpython
/snap/microk8s/1107/usr/share/python3/dist
/snap/microk8s/1107/usr/share/python3/runtime.d
/snap/microk8s/1107/usr/share/zsh
/snap/microk8s/1107/usr/share/zsh/vendor-completions
/snap/microk8s/1107/var
/snap/microk8s/1107/var/lib
/snap/microk8s/1107/var/lib/systemd

「/usr/share」とか「/var/lib」とかありますからね。

つまり、環境がまるっとインストールされます。パッケージが「自己完結型」であるとか、分離度が高いとかはこのあたりからも
伺い知れます。

なお、このインストール形態な分だけ、ディスクの消費はaptなどよりも大きいようです。

aptかSnapか

さて、こうなるとaptとSnapのどちらのパッケージ管理システムを使うのか?という気になりますが…個人的にはaptでもSnapでも
インストールできるパッケージの場合はapt…というように、aptを基本に考えようかなぁと思っています。

Snapにしかないパッケージをインストールする場合にのみ、Snapを使う感じですね。
※aptとSnapの共存自体は可能です

まだまだapt(やyum/DNF)のようなものが主流な気はするので、当面はこんな感じで。

参考

Snap(Snappy) コマンドの使い方 | Linux Magazine

Ubuntu 18.04 LTS Desktopでsnapパッケージを管理 – LAB4ICT

第582回 いろいろなディストリビューションでsnapとLXDを利用する:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社

【連載】にわか管理者のためのLinux運用入門 [141] パッケージ管理システム「Snap」(その3)|サーバ/ストレージ|IT製品の事例・解説記事