CentOS 7.6上のMicrok8s環境でEFKスタック(Elasticsearch,Fluentd,Kibana)を利用してコンテナログを取得・可視化【1】
首題の通り。シングルノード構成。
fluentd周りで大変苦労した。
このブログポストで紹介する内容は以下。
====ここから====
ステップ⓪コンポーネント紹介
ステップ①dockerを導入する
ステップ②microk8sをCentOSに導入する
ステップ③dockerイメージを取得してmicrok8sのプライベートイメージリポジトリにプッシュする
ステップ④microk8sでビルドしたイメージを動かす。
====ここまで====
※以下は次回のブログポストを参照
ステップ⑤elasticsearchをデプロイする
ステップ⑥kibanaをデプロイする
ステップ⑦fluentdをデプロイする
ステップ⓪コンポーネント紹介
まず登場する各コンポーネントの簡単な説明。
・CentOS
OS。バージョン7.6を使用。
(ちなみにインスタンスのCPUは1コアでメモリは4GB。これでも動くんですね。)
・Microk8s
軽量なKubernetes実行環境。バージョンv1.14.1を使用。
・fluentd
データ収集・転送コンポーネント。Elasticsearchにログを転送する役を担う。
今回はhelmで導入し、DaemonSetとして稼動させる。dockerイメージ名とタグ:gcr.io/fluentd-elasticsearch/fluentd:v2.5.2
(Microk8sに組み込まれたfluentdも利用可能だが、今回そちらは利用せず、別途導入する。helmで導入したのは、試行錯誤の結果、helmでの導入が唯一うまくいったためです。。)
・Elasticserach
分散型RESTful検索/分析エンジン。Kibanaからのログ検索の役割を担う。
Podとして稼動させる。dockerイメージ名とタグ:docker.elastic.co/elasticsearch/elasticsearch:6.5.4
Kibana
可視化ツール。今回はElasticsearchがfluentdから収集したログを可視化する役割を担う。
Podとして稼動させる。dockreイメージ名とタグ:docker.elastic.co/kibana/kibana:6.5.4
helm
kubernetes構成ツール。fluentdのために利用。
クライアント、サーバーともにバージョンは2.14.0。
(手動でデプロイメント作っても良いと思いますが、私はうまくいかず、上述の通り試行錯誤の結果、helmでの導入が唯一うまくいきました)
docker
docker imageの管理のために利用。バージョンは1.13.1
ステップ①dockerを導入する
イメージ管理のためにdockerを導入。
[nakanishi@elastic01 ~]$ sudo yum install docker Loaded plugins: copr, fastestmirror … Complete!
dockerプロセスを開始。
[nakanishi@elastic01 ~]$ [nakanishi@elastic01 ~]$ systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Active: inactive (dead) Docs: http://docs.docker.com [nakanishi@elastic01 ~]$ sudo systemctl start docker [nakanishi@elastic01 ~]$ [nakanishi@elastic01 ~]$ systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Active: active (running) since Fri 2019-05-24 03:33:54 CDT; 17s ago Docs: http://docs.docker.com …. [nakanishi@elastic01 ~]$
nakanishiユーザーでdockerコマンドを利用しようとしたらpermission deniedだった。
https://qiita.com/tubone/items/9c1b3d807197b7162fd9
Centos7ではユーザーをdockerrootグループに追加して、/var/run/docker.sockのグループをrootからdockcerrootに変更することが必要なようだ。
[akanishi@elastic01 ~]$ sudo usermod -aG dockerroot ${USER} [nakanishi@elastic01 ~]$ groups ${USER} nakanishi : nakanishi wheel dockerroot [nakanishi@elastic01 ~]$ [nakanishi@elastic01 ~]$ sudo chown root:dockerroot /var/run/docker.sock [nakanishi@elastic01 ~]$ ls -l /var/run/docker.sock srw-rw----. 1 root dockerroot 0 May 24 03:33 /var/run/docker.sock [nakanishi@elastic01 ~]$
これでdockerコマンドを利用できるはずだったが、まだpermission denied。
一度シェルを終了し、再度ログインしたところ、無事dockerコマンドが利用できた。
また、以下を参照。
https://qiita.com/ir-shin1/items/37d606144566387996eb
“ただ、/var/run/docker.sock は起動のたびに作成されるファイル(ソケット)だからどこかでグループを定義してやる必要がある。”
↑なるほど。
以下の通りdockerを構成。
[nakanishi@elastic01 ~]$ sudo cp /etc/sysconfig/docker /etc/sysconfig/docker.org [nakanishi@elastic01 ~]$ sudo vi /etc/sysconfig/docker [nakanishi@elastic01 ~]$ sudo diff /etc/sysconfig/docker /etc/sysconfig/docker.org 4c4 < OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false -G dockerroot' --- > OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false' [nakanishi@elastic01 ~]$ 起動時にdockerrootグループで起動するように構成した。
dockerプロセスを再起動。
[nakanishi@elastic01 ~]$ sudo systemctl restart docker [nakanishi@elastic01 ~]$ systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Active: active (running) since Fri 2019-05-24 03:45:05 CDT; 6s ago Docs: http://docs.docker.com [nakanishi@elastic01 ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [nakanishi@elastic01 ~]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE [nakanishi@elastic01 ~]$
ステップ②microk8sをCentOSに導入する
microk8sをCentOS7に導入する。
参考:https://computingforgeeks.com/install-snapd-snap-applications-centos-7/
[nakanishi@elastic01 ~]$ sudo yum install -y epel-release [sudo] password for nakanishi: [nakanishi@elastic01 ~]$ sudo yum install -y yum-plugin-copr [sudo] password for nakanishi: ......(略) Complete! [nakanishi@elastic01 ~]$ sudo yum copr enable ngompa/snapcore-el7 ......(略) Do you want to continue? [y/N]: y copr done [nakanishi@elastic01 ~]$ sudo yum -y install snapd Loaded plugins: copr, fastestmirror ......(略) Complete! [nakanishi@elastic01 ~]$ sudo systemctl enable --now snapd.socket Created symlink from /etc/systemd/system/sockets.target.wants/snapd.socket to /usr/lib/systemd/system/snapd.socket. [nakanishi@elastic01 ~]$ sudo ln -s /var/lib/snapd/snap /snap [nakanishi@elastic01 ~]$ which snap /usr/bin/snap //snapコマンドを確認。 sudo snap install microk8s --classic 2019-05-24T03:18:25-05:00 INFO Waiting for restart... Warning: /var/lib/snapd/snap/bin was not found in your $PATH. If you've not restarted your session since you installed snapd, try doing that. Please see https://forum.snapcraft.io/t/9469 for more details. microk8s v1.14.1 from Canonical✓ installed [nakanishi@elastic01 ~]$
これで導入自体は完了。
この状態だと必要なパスが通っておらずmicrok8sを操作するコマンド群microk8s.*コマンドが見つからないので、“/var/lib/snapd/snap/bin”のパスを通す。
[nakanishi@elastic01 ~]$ export PATH=$PATH:/var/lib/snapd/snap/bin
これでmicrok8sの操作コマンドのパスを通すことができた。
[nakanishi@elastic01 ~]$ microk8s.config 2019/05/24 03:23:09.833961 cmd_run.go:367: restoring default SELinux context of /home/nakanishi/snap apiVersion: v1 clusters: - cluster: certificate-authority-data: xxxxx...(SSL証明書をbase64で難読化した値) server: https://XX.XXX.XXX.XX:XXXXX name: microk8s-cluster contexts: - context: cluster: microk8s-cluster user: admin name: microk8s current-context: microk8s kind: Config preferences: {} users: - name: admin user: username: admin password: xxxxxxxxxxxxxxxxxxx [nakanishi@elastic01 ~]$
以下のステータス確認コマンドを実行すると、microk8sには色々とアドオンがあることがうかがえる。(fluentdも)
[nakanishi@elastic01 ~]$ microk8s.status microk8s is running addons: ingress: disabled dns: disabled metrics-server: disabled prometheus: disabled istio: disabled jaeger: disabled fluentd: disabled gpu: disabled storage: disabled dashboard: disabled registry: disabled [nakanishi@elastic01 ~]$
DNSを有効化させる。
[nakanishi@elastic03 curl]$ microk8s.enable dns Enabling DNS Applying manifest service/kube-dns created serviceaccount/kube-dns created configmap/kube-dns created deployment.extensions/kube-dns created Restarting kubelet [sudo] password for nakanishi: DNS is enabled [nakanishi@elastic03 curl]$
kubectlコマンド相当のコマンドはmicrok8s.kubectlであるようだ。
[nakanishi@elastic01 ~]$ microk8s.kubectl config current-context microk8s
kubectlコマンドを実行できるように、エイリアス設定。
[nakanishi@elastic01 ~]$ sudo snap alias microk8s.kubectl kubectl [sudo] password for nakanishi: Added: - microk8s.kubectl as kubectl [nakanishi@elastic01 ~]$
ステップ③dockerイメージを取得してmicrok8sのプライベートイメージリポジトリにプッシュする
fluentdがログを収集するサンプルアプリのdocker imageを作成して、プッシュする。
#ディレクトリを作成して移動
[nakanishi@elastic03 ~]$ mkdir -p k8s/testapp/sample-app [nakanishi@elastic03 ~]$ cd ~/k8s/testapp/sample-app [nakanishi@elastic03 sample-app]$
#Dockerimageの作成
Dockerfile
[nakanishi@elastic03 sample-app]$ cat Dockerfile FROM node:10.11.0-alpine WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY index.js ./ EXPOSE 3000 CMD [ "node", "index.js" ] [nakanishi@elastic03 sample-app]$
#Dockerfileで利用するpackage.jsonとcat package-lock.json、index.jsファイルを作成。
[nakanishi@elastic03 sample-app]$ vim package.json [nakanishi@elastic03 sample-app]$ cat package.json { "dependencies": { "simple-node-logger": "^18.12.21" } }
[nakanishi@elastic03 sample-app]$ vim package.json [nakanishi@elastic03 sample-app]$ cat package-lock.json { "requires": true, "lockfileVersion": 1, "dependencies": { "event-lite": { "version": "0.1.2", "resolved": "http://jam.clickfox.net:80/artifactory/api/npm/npm/event-lite/-/event-lite-0.1.2.tgz", "integrity": "sha1-g4o+D93e+MyQ8SgAbI5VpOTkwRs=" }, "fluent-logger": { "version": "3.2.3", "resolved": "http://jam.clickfox.net:80/artifactory/api/npm/npm/fluent-logger/-/fluent-logger-3.2.3.tgz", "integrity": "sha1-PjG0fWPz6f/ueSnR9n5XorrlZIY=", "requires": { "msgpack-lite": "*" } }, "ieee754": { "version": "1.1.12", "resolved": "http://jam.clickfox.net:80/artifactory/api/npm/npm/ieee754/-/ieee754-1.1.12.tgz", "integrity": "sha1-UL8k5bnIu5ivSWTJQc2wkY2ntgs=" }, "int64-buffer": { "version": "0.1.10", "resolved": "http://jam.clickfox.net:80/artifactory/api/npm/npm/int64-buffer/-/int64-buffer-0.1.10.tgz", "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" }, "isarray": { "version": "1.0.0", "resolved": "http://jam.clickfox.net:80/artifactory/api/npm/npm/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "lodash": { "version": "4.17.11", "resolved": "http://jam.clickfox.net:80/artifactory/api/npm/npm/lodash/-/lodash-4.17.11.tgz", "integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40=" }, "moment": { "version": "2.23.0", "resolved": "http://jam.clickfox.net:80/artifactory/api/npm/npm/moment/-/moment-2.23.0.tgz", "integrity": "sha1-dZ6kkayX1UusWtd2mW4qWMwbwiU=" }, "msgpack-lite": { "version": "0.1.26", "resolved": "http://jam.clickfox.net:80/artifactory/api/npm/npm/msgpack-lite/-/msgpack-lite-0.1.26.tgz", "integrity": "sha1-3TxQsm8FnyXn7e42REGDWOKprYk=", "requires": { "event-lite": "^0.1.1", "ieee754": "^1.1.8", "int64-buffer": "^0.1.9", "isarray": "^1.0.0" } }, "simple-node-logger": { "version": "18.12.21", "resolved": "http://jam.clickfox.net:80/artifactory/api/npm/npm/simple-node-logger/-/simple-node-logger-18.12.21.tgz", "integrity": "sha1-nv0ITxis/erSfK0SVNevP3R2gkY=", "requires": { "lodash": "^4.17.10", "moment": "^2.20.1" } } } } [nakanishi@elastic03 sample-app]$
index.js
[nakanishi@elastic03 sample-app]$ cat index.js const SimpleNodeLogger = require('simple-node-logger'); const opts = { timestampFormat:'YYYY-MM-DD HH:mm:ss.SSS' }; const log = SimpleNodeLogger.createSimpleLogger(opts); (function repeatMe() { setTimeout(() => { log.info('it works'); repeatMe(); }, 1000) })(); [nakanishi@elastic03 sample-app]$
合計4つのファイルを用意した。
[nakanishi@elastic03 sample-app]$ ls -la total 24 drwx------. 2 nakanishi nakanishi 4096 May 26 23:28 . drwx------. 3 nakanishi nakanishi 4096 May 26 23:33 .. -rw-------. 1 nakanishi nakanishi 145 May 26 23:24 Dockerfile -rw-------. 1 nakanishi nakanishi 277 May 26 23:25 index.js -rw-------. 1 nakanishi nakanishi 66 May 26 23:26 package.json -rw-------. 1 nakanishi nakanishi 2314 May 26 23:25 package-lock.json [nakanishi@elastic03 sample-app]$
イメージをビルドする。
[nakanishi@elastic03 sample-app]$ docker build -t fluentd-node-sample:latest ./ Sending build context to Docker daemon 7.168 kB Step 1/7 : FROM node:10.11.0-alpine ......(略) Successfully built 7d1c9aabd8f8 [nakanishi@elastic03 sample-app]$
ビルドしたイメージを確認する。
[nakanishi@elastic03 sample-app]$ docker images fluentd-node-sample REPOSITORY TAG IMAGE ID CREATED SIZE fluentd-node-sample latest 7d1c9aabd8f8 2 days ago 75 MB [nakanishi@elastic03 sample-app]$
イメージをtarファイル化する
[nakanishi@elastic03 sample-app]$ docker save fluentd-node-sample:latest > fluentd-node-sample.tar [nakanishi@elastic03 sample-app]$ ls -la total 78260 drwx------. 2 nakanishi nakanishi 4096 May 29 02:19 . drwx------. 3 nakanishi nakanishi 4096 May 26 23:33 .. -rw-------. 1 nakanishi nakanishi 145 May 26 23:24 Dockerfile -rw-------. 1 nakanishi nakanishi 80024576 May 29 02:20 fluentd-node-sample.tar -rw-------. 1 nakanishi nakanishi 277 May 26 23:25 index.js -rw-------. 1 nakanishi nakanishi 66 May 26 23:26 package.json -rw-------. 1 nakanishi nakanishi 2314 May 26 23:25 package-lock.json [nakanishi@elastic03 sample-app]$
イメージをmicrok8sのリポジトリにインポートする。
[nakanishi@elastic03 sample-app]$ microk8s.ctr -n k8s.io image import ./fluentd-node-sample.tar [sudo] password for nakanishi: unpacking docker.io/library/fluentd-node-sample:latest (sha256:eea68fd106755a230c9f681ab1e96ea17f9dff2f79ca650199645b913650341c)...done [nakanishi@elastic03 sample-app]$
インポートしたイメージを確認する。
[nakanishi@elastic03 sample-app]$ microk8s.ctr -n k8s.io images ls | grep sample docker.io/library/fluentd-node-sample:latest application/vnd.oci.image.manifest.v1+json sha256:eea68fd106755a230c9f681ab1e96ea17f9dff2f79ca650199645b913650341c 76.3 MiB linux/amd64 io.cri-containerd.image=managed [nakanishi@elastic03 sample-app]$
ステップ④microk8sでビルドしたイメージを動かす。
デプロイメントを作成する
[nakanishi@elastic03 sample-app]$ cd ../ [nakanishi@elastic03 testapp]$ pwd /home/nakanishi/k8s/testapp [nakanishi@elastic03 testapp]$ ls sample-app //sampleappディレクトリにはアプリのファイル群がある。 [nakanishi@elastic03 testapp]$ [nakanishi@elastic03 testapp]$ vim node-deployment.yaml [nakanishi@elastic03 testapp]$ cat node-deployment.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: node labels: name: node spec: replicas: 1 template: metadata: labels: app: node spec: containers: - name: node image: fluentd-node-sample:latest imagePullPolicy: IfNotPresent [nakanishi@elastic03 testapp]$
今回はサービスリソースは作成しない。(fluentdに転送するログを取得できれば良いため)
デプロイメントをデプロイする。
#デプロイ [nakanishi@elastic03 testapp]$ kubectl apply -f node-deployment.yaml deployment.extensions/node created #確認 [nakanishi@elastic03 testapp]$ kubectl get pod --all-namespaces -w NAMESPACE NAME READY STATUS RESTARTS AGE default node-8684bdfccf-fnmps 1/1 Running 0 3s kube-system kube-dns-6bfbdd666c-qrwlg 3/3 Running 0 3d ^C[nakanishi@elastic03 testapp]$
以上。