7/25 勉強会スライド
本日の勉強会で発表したスライドです。
最近はスライド共有にも様々なサービスがあって便利ですね。
内容について突っ込まれた時に、回答に困ることがあったことが反省点です。
もう少し深堀しなきゃなーと思いました。
Infra Study 2nd #3「いまさら聞けないIPv6ネットワーク」に参加した
7/14に開催された、Infra Study 2nd #3「いまさら聞けないIPv6ネットワーク」に参加したのでログを残す。
2回目ですが、この勉強会は雰囲気がとても良いですね。
「いまさら聞けないIPv6ネットワーク」
講師は小川 晃通 氏。
※は自分のコメント。
IPv6の利用は増えている
IPv6の利用は昨今で急激に増加している
企業LANだとIPv4 onlyが多い。
IPv6とは
企業のIPv6対応について
一般的な企業では社内ネットワークをIPv4のプライベートIPアドレスで構成し、インターネットに出る際にはNATを使用するパターンが多い。
しかし、IPv6ではプライベートIPアドレスに相当するものがないため、同様の構成をとることが難しい。IPv6にはULA(Unique Local Address)と呼ばれる、インターネットでは使用できないが、内部で使用できるアドレスが存在する。
しかし、これはNATを介した通信を想定しているものではないため、インターネットに繋ぐのであれば、結局はグローバルIPアドレスを割り振る必要がある。- 普通に抵抗感があるが、IFTFとしては「ファイアウォールの設定すればええやん」のスタンス。
現在ではIaaSクラウドが主流となっており、クラウドサービスがネットワーク設定も請け負っているため、IPv6への以降も意外とスムーズに進むかもしれない。
- ULAは必要か?という質問については、GUA(Global Unicast Address)はIPアドレスが変わる可能性があるため、静的に設定しておきたいIPアドレス(プリンタ等)についてはULAを使用した方が良い。
ただし、その場合GUAとULAの2つのIPアドレスが存在することになるので、管理者にとっては悩みどころ。
感想
IPv6はテキストで読んだ程度であったが、インターネット利用者の半分近くまで使用されているという事実に衝撃を受けた。
今後もインターネット上においてIPv4→IPv6への移行は進むと思う。
しかし、社内ネットワークについてはベストプラクティスが確立されていないことから、移行まではまだまだ時間がかかると考える。
IPv6はIPv4とは考え方が異なるため、移行が完了した未来においては、企業におけるNWアーキテクチャも大幅に変わっているはずだ。 そこで採用されている技術や方法論がどのようなものとなっているのか、楽しみではある。
HDDドライブのIOPSを求めてみる
HDDドライブのIOPSを求めてみる。
IOPSとは、1秒間にディスクが処理可能なI/O数のこと。
IOPSを求めるためには、ディスクのサービス時間(1I/Oにかかる時間)を計算する必要がある。
なぜなら、ディスクのサービス時間の逆数がIOPSとなるため。
ディスクのサービス時間は以下の要素で構成される。
Ts = T + L + X
Ts:ディスクのサービス時間、T:シークタイム、L:回転遅延、X:内部転送レート
各要素について説明していく。
シークタイム
HDDのR/Wヘッド(データを読み書きする部品)が、目的の位置まで移動するのにかかる時間。
以下写真の赤枠がR/Wヘッド。
回転遅延
プラッタと呼ばれるデータを含む円盤が回転する時間。ミリ秒単位で表される。
回転遅延は回転速度から求める。
回転速度はrpmで表され、これは「1分間に何回転するか」を示す。
例えば、5400rpmであれば「1分間に5400回転する」ということ。
また、回転遅延は平均回転時間が使用される。
平均回転時間は完全な回転にかかる時間を2で割ったものとなる。
試しに5400rpmの回転遅延を求めてみる。
5400rpm = 90rps ※rpsは「1秒間に何回転するか」を示す。
1/90 × 1/2 = 0.0055… ≒ 5.5ミリ秒
よって、5400rpmのディスクの回転遅延は約5.5ミリ秒となる。
内部転送レート
内部転送レートは、プラッタからデータを読み込み~ディスク内のバッファに読み込まれるまでの時間のこと。
IOPSを求めてみる
平均シークタイム5ミリ秒、7200rpm、転送レート40MB/sのディスクについて、I/O平均サイズ64KBのアプリケーションでアクセスする。
この状況におけるディスクの最大IOPSを計算していく。
まず、ディスクのサービス時間を求める式をおさらい。
Ts = T + L + X
Ts:ディスクのサービス時間、T:シークタイム、L:回転遅延、X:内部転送レート
シークタイムはT=5ms。
次に、回転遅延を求める。
7200rpm = 120rps
L = 1/120 × 1/2 = 0.00416… ≒ 4.2ms。
最後に、内部転送レートを求める。
アプリケーションのI/O平均サイズは64KBであるため、1I/Oあたりの時間を求める。
X = 64KB/40MB = 0.0016秒 = 1.6ミリ秒。
よって、サービス時間Tsは、
Ts = 5 + 4.2 + 1.6 = 10.8ms。
IOPSはサービス時間の逆数なので、
IOPS = 1/Ts = 0.0925 × 1000*1 = 93IOPS
以上より、IOPSは93となる。
また、この値はディスク使用率が100%時のものであるため、例えば常時80%程度にしたいといった場合には0.8をかけた値がIOPSとなる。
この場合では93×0.8 = 74IOPS。
*1:サービス時間の単位はミリ秒であるが、IOPSは1秒間のI/O数であるため。
Fluentdを触ってみた(1)
※以下はfluentd v1.0(td-agent-4.1.1)をベースに書いてます。
Fluentdとは
ログの収集・転送・加工を行うツール。
syslogやファイルからログを収集し、ファイルやMongoDB、S3等に転送することができる。
Fluentdは、Inputプラグイン、Outputプラグイン、Bufferプラグインといったように
機能をプラグインの形で実装している。
各プラグインはFluentd製品が提供しているものや(Inputのtailとか)、
サードパーティ製のプラグインも存在する。
例えば、以下はsyslogからイベントを受信するInput設定。
- Input設定サンプル
<source> @type syslog port 5140 bind 0.0.0.0 tag test <parse> @type none </parse> </source>
- Output設定サンプル
<match test.**> @type file path /var/log/td-agent/output.txt </match>
こちらは、testタグがついたログを/var/log/td-agent/output.txtに出力する設定。
※fluentdではログにタグを付けることができ、付けたタグで出力先や転送先の挙動を変えることが可能。
イベントの受信
fluentdでイベントの受信を行うには、sourceディレクティブを使用する。
基本的な書き方は以下の通り。
<source> @type <プラグイン名> # 以下は各設定項目 port 5140 bind 0.0.0.0 tag test <parse> @type none </parse> </source>
@typeで指定するプラグインを指定する。
現在、公式で提供しているinputプラグインは以下の通り。
プラグイン名 | 説明 |
---|---|
in_tail | テキストファイルの末尾からイベントを読み取る(tail -f) |
in_forward | 別のfluentdから送られたデータを受信 |
in_udp | UDPプロトコルでイベントを受け取る |
in_tcp | TCPプロトコルでイベントを受け取る |
in_unix | UNIXドメインソケットからレコードを取得 |
in_http | HTTPリクエストを通してイベントを取得 |
in_syslog | syslogを通してイベントを取得 |
in_exec | 外部プログラムからイベントを取得(形式は標準出力、TSV、JSON等) |
in_sample | サンプルイベントを受信(デバッグ向け) |
in_windows_eventlog | Windowsイベントログからイベントを取得 |
以下の例では、syslogからイベントを取得するため、@typeにsyslogを指定している。
具体的な設定項目については、プラグインごとに異なるため、公式ドキュメントを参照。
<source> @type syslog port 5140 bind 0.0.0.0 tag test <parse> @type none </parse> </source>
また、fluentdの特徴として取得したイベントに“タグ”を付けることができる。
このタグは後述するmatchディレクティブの条件式として使用することができ、特定のタグのみをファイルに出力する、といったことが可能となる。(ログのルーティング)
上記の例ではタグとして「test」を指定している。
イベントの送信
fluentdでイベントの送信を行うには、matchディレクティブを使用する。
基本的な書き方は以下の通り。
<match 条件式> @type <プラグイン名> # 以下は各設定項目 path /var/log/td-agent/output.txt </match>
inputプラグインと同様、@typeで指定するプラグインを指定する。
現在、公式で提供しているoutputプラグインは以下の通り。
プラグイン名 | 説明 |
---|---|
out_copy | 複数ファイルへのコピー出力 |
out_null | イベントを破棄 |
out_roundrobin | 複数の出力にラウンドロビンでイベントを転送 |
out_stdout | 標準出力にイベントを転送 |
out_exec_filter | イベントを入力として、外部プログラムを実行し、実行結果を出力とする |
out_forward | 他のfluentdノードにイベントを転送 |
out_mongo / out_mongo_replset | MongoDBにレコード出力 |
out_exec | 外部プログラムにイベントを転送 |
out_file | ファイルにイベントを出力 |
out_s3 | AWS S3にファイル出力 |
out_webhdfs | HDFSにレコード出力 |
以下の例では、testタグの付いたログをファイルに出力するため、@typeにfileを指定している。
fileプラグインの設定項目であるpathに出力パスを指定することで、指定のパスにファイルとして出力させることが可能。
<match test.**> @type file path /var/log/td-agent/output.txt </match>
条件式内では“*”、“**”といったワイルドカードを使用することができる。
記号 | 説明 |
---|---|
* | 単一のタグにマッチ(a.*はa.bにマッチするが、a、a.b.cにはマッチしない) |
** | 0個以上のタグにマッチ(a.**はa.b、a.b.cにもマッチ) |
Q&A
Q. ファイルに出力したログのローテーションは可能?
A. できる。ただし、日時ローテのみ。
出力ログの形式は、fileプラグインのpathにて設定する。
デフォルトは“%Y%m%d”であるため、日付でログ名が変わる(=日付ローテーション)。
“%Y%m%d%H%M%S”まで指定可能であるため、必要に応じて変更する。
実際に、pathを“%Y%m%d%H%M”としてみる。
- 設定ファイル抜粋
<match test.**> @type file format single_value path output_%Y%m%d%H%M <buffer time> @type file path buffer timekey 1m timekey_wait 1m </buffer> </match>
出力間隔やバッファファイルの出力先はbufferディレクティブで設定する。
ここでは、timekey(出力間隔)を1分、ログが遅れて届いた場合のため、1分間のtimekey_wait(予備時間)を設定している。
拡張子はデフォルトで.logとなる。
- 実行結果
[root@fluentd1 ~]# ll total 123536 -rw-r--r--. 1 root root 165 Jul 3 12:22 output_202107031220_0.log -rw-r--r--. 1 root root 165 Jul 3 12:27 output_202107031225_0.log
このように、分刻みでのログ出力となる。
ファイル名末尾の_0について、fluentdは内部にバッファを持っており、バッファが一杯になった際に強制的にファイルに書き出す仕様となっている。
短時間でバッファが一杯になってしまった場合、同時刻に出力されたファイルと区別をつけるため、末尾に連番を付与している。
なお、appendをtrueにすると末尾の連番は付与されず、そのまま追記される。
オプションappendを有効にした場合の出力は以下。
-rw-r--r--. 1 root root 110 Jul 3 12:32 output_202107031230.log -rw-r--r--. 1 root root 213 Jul 3 12:34 output_202107031232.log
また、サイズローテーションについてはfluentdの機能では不可能。
Linuxであれば、logrotateを使用すること。
(参考) github.com
物理ディスク、LVM、ファイルシステムにおける管理の最小単位
Linuxに物理ディスクを接続した際、パーティションに直接ファイルシステムを作成するのでなく、
今後の拡張を見据えてLVMの設定をすることは多い。
今回、LVM・ファイルシステムにて、データをどの単位で管理しているかを学習したのでまとめる。
物理ディスク
物理ディスクでは、アクセスの最小単位はセクタである。
基本的に1セクタ=512バイトであるが、最近は4K(4096)バイトのディスクも多い。
物理ボリューム(PV)
LVMではPV作成時に物理領域をPEの単位に分割する。RHELにおけるPEはデフォルトで4MiB。
最終的に切り出すLVサイズはPEの倍数となるため、この場合だと4MiBの倍数となる。
pvdisplayコマンドの実行結果においては、「PE Size」が該当する。
[root@localhost tmp]# pvdisplay --- Physical volume --- PV Name /dev/sda3 VG Name centos PV Size <38.00 GiB / not usable 3.00 MiB Allocatable yes ★PE Size 4.00 MiB Total PE 9727 Free PE 1946 Allocated PE 7781 PV UUID b2lToF-X3y0-1XM5-S1aC-qLzC-2hzl-DzlvT4
LV(論理ボリューム)
VGをLVに切り分ける際にはLE(論理エクステント)の単位で切り分ける。
通常、PEとLEは同じ大きさとなる。
この VG のうち、いくつかのまたはすべての PE は、論理エクステント (Logical Extent、LE) という単位で論理ボリューム (Logical Volume、LV) にアロケートすることができます。 各 LE は対応する PE にマップされます。 LE と PE は同じサイズになります。
http://linuxjf.osdn.jp/JFdocs/kernel-docs-2.4/LVM-HOWTO.html
したがって、今回はPEと同じ4MiBとなる。
lvdisplayコマンドの実行結果においては、「Current LE」が該当する。
つまり、以下の例では/dev/centos/rootはPE×7771となり、PEは4MiBなので30.36GBと「LV Size」に一致する。
--- Logical volume --- LV Path /dev/centos/root LV Name root VG Name centos LV UUID uri6ss-33Vi-5MgX-Ss0e-q91j-c00D-Pt8CEm LV Write Access read/write LV Creation host, time localhost, 2021-06-10 18:02:32 +0900 LV Pool name pool00 LV Status available # open 1 LV Size <30.36 GiB Mapped size 7.52% ★Current LE 7771 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:3
ファイルシステム
ファイルシステムはブロックサイズの単位で管理を行う。
ext4ではデフォルトのサイズは4096バイトと設定されている。
以下の実行結果においては、「Block size」で確認できる。
[root@localhost tmp]# tune2fs -l /dev/centos/root tune2fs 1.42.9 (28-Dec-2013) Filesystem volume name: <none> Last mounted on: / Filesystem UUID: 5e28f3c2-ab89-4dc1-afb9-35b1003287db Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize Filesystem flags: signed_directory_hash Default mount options: user_xattr acl Filesystem state: clean Errors behavior: Continue Filesystem OS type: Linux Inode count: 1990656 Block count: 7957504 Reserved block count: 397875 Free blocks: 7473161 Free inodes: 1963218 First block: 0 ★Block size: 4096 ※単位はbyte Fragment size: 4096 Group descriptor size: 64 Reserved GDT blocks: 1024 Blocks per group: 32768 Fragments per group: 32768 Inodes per group: 8192 Inode blocks per group: 512 RAID stride: 16 RAID stripe width: 16 Flex block group size: 16 Filesystem created: Thu Jun 10 18:02:32 2021 Last mount time: Thu Jun 10 18:09:09 2021 Last write time: Thu Jun 10 18:09:08 2021 Mount count: 2 Maximum mount count: -1 Last checked: Thu Jun 10 18:02:32 2021 Check interval: 0 (<none>) Lifetime writes: 2798 MB Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 256 Required extra isize: 28 Desired extra isize: 28 Journal inode: 8 First orphan inode: 1835023 Default directory hash: half_md4 Directory Hash Seed: afa9cd9d-9b2a-4277-9a06-0ce63f9c092d Journal backup: inode blocks
以上のことから、ファイルシステムが作成されるまでに、
物理ディスク(セクタ) → 物理ボリューム(PE) → 論理ボリューム(LE) → ファイルシステム(ファイルシステムブロック)
の順でマッピングされていることが分かった。
逆にいうと、ユーザがファイルにアクセスするまでには以下の経路を辿ることとなる。
(図中、オレンジがデータの格納場所)
「Kubernetes Meetup Tokyo #42」に参加した
6/24に開催された、「Kubernetes Meetup Tokyo #42」に参加したのでログを残す。
自分がKubernetesを触り始めということもあるだろうが、全体的にレベルが高い気がしたため、
理解できていないところも多々ある。
「KubeVirtによるIaaS基盤構築」
講師はヤフー株式会社の相良 幸範氏。
www.slideshare.net
KubeVirtとは?
- Kubernetes上で動くクラスタアドオンであり、Podと同じWorkerノードで仮想マシンを起動できる仕組み。
- コンテナ移行が困難なシステムであるが、Kubernetesで管理したいといった場合に利用できる。
- 利用状況としては、Akamai/Apple/Cisco等の大企業で使用されているが、まだまだ数えるほどである。
- Kubernetes上で動くクラスタアドオンであり、Podと同じWorkerノードで仮想マシンを起動できる仕組み。
VirtualMachineInstanceのマニフェスト(KubeVirtで仮想マシンを作成する際のマニフェスト)は、Podと比べると複雑になってしまう
KubernetesでIaaS基盤を設計する際、テナンシーの確保方法が課題となる。
テナント単位にKubernetesクラスタを払い出す
- テナンシーの考慮が不要となり、障害時の影響範囲を最小化できる
- 運用負荷が高い、サーバの利用率が低くなる
テナント単位でNamespaceを払い出す
- 運用負荷を大幅に削減可能、サーバの利用率が高い
- Kubernetes内のリソース隔離を検討する必要がある、コントロールプレーンへの負荷集中、仮想マシンの性能問題
CNIプラグインについて
- KubernetesのNWはCNIとServiceリソース等で構成されるが、CNIによって機能が異なるため、要件を基に慎重に選定する
KubeVirtに対する印象
- KubeVirtでもOpenStackのようにIaaS基盤は提供可能であるが、OpenStackのようにきめ細かな機能はない
- 機能や実績も含め、まだまだ発展途上といった印象
感想
KubernetesでもOpenShiftのようにIaaS基盤が提供できると聞いて驚いた。
まだまだ発展途上ではあるものの、成熟すればKubernetesの他機能と連携することで用途がより広まるのではないかと思う。
今後の動向が楽しみだ。
「KubernetesとGatlingを使って、負荷試験に秒間10kユーザーをシミュレーションする方法」
講師はTenkan Inc.のZhaoqiang Wang氏。
Gatlingはオープンソースの負荷テストツールであり、レポート機能が存在
Gatlingは10kユーザ以上のアクセスのシミュレーションができない
※エラーメッセージを見た限りでは、ファイルディスクリプタとポート範囲が不足しているように見えたが、このクラスになるとチューニングでも対処できないのかなOSS版のGatlingはJMeterのようにクラスタ機能をサポートしていないため、 複数のインスタンスで同じディレクトリにレポートを作成し、マージすることで解決させる
- 「複数のインスタンス」については、KubernetesでGatlingクラスターを構築することで、単一インスタンスの上限を突破
感想
Gatlingは使用したことはあるが、このクラスの高負荷試験の経験はないため、このような解決方法もあるだなと思った。
単一インスタンスからの使用しかなかったため、レポートをマージできることは知らなかった。
「How to setup Production Ready Istio?」
講師は株式会社ZOZOテクノロジーズのAkito Kobayashi氏。
Istioとは?
Istioのリソース消費量見積もり
- DataPlaneとControlPlaneに分けて考える
- 負荷試験の結果ベースで見積もりを行う
監視
- インフラメトリクスを監視するのではなく、Istioが上手く動作しているかのメトリクスを監視
- 分散トレーシングを行うことで、複数サービスを跨いだ調査を行いやすくなる
可観測性
- DataDogのDashboardを使用し、問題の切り分けがしやすいグラフを作成
感想
Istioだけでなく、サービスメッシュを構築する上での試験方法や監視について参考になる講演だった。
試験については、過去案件にて一気にサービスを通貫して試験を行い、切り分けが難しくなった経験があるため、身につまされる話だった。
【LT枠】「Pod を force delete しないで」
講師は株式会社Preferred Networksの坂田氏。
- ForceDeleteはkubernetes上で、Podの強制削除に使用されるコマンド
実際のプロセスの終了を待たずにPodを削除する
ForceDeleteの仕様が問題になるケース
- Pod内のプロセスが「D state」のままノードに残っていた場合
- 「D state」は割り込み不可であるため、killでも消すことが不可能(SIGKILLも不可)
- プロセスがリソースを掴みっぱなしで、リソースの確保が出来なくなる場合がある
- 対処はOS再起動
- Pod内のプロセスが「D state」のままノードに残っていた場合
Pod内のプロセス状態がよく分からない理由でForceDeleteはNG
感想
Pod削除時にForceDeleteを行いたくなる気持ちはあるが、改めて気軽にやるものではないなと認識した。
sftpのログ出力設定
sftpのログ出力設定について
sftpを利用するにあたり、アクセス・操作ログを出力したい場合がある。
出力先のログファイルに応じて、以下の3種類の設定が存在する。
- /var/log/secureに出力する方法
- /var/log/messagesに出力する方法
- 任意のファイルに出力する方法
前提条件
OSはRHEL7。
sftp設定ファイルはssh設定に影響を与えないように、/etc/ssh/sftpd_configとしている。
また、セキュリティを考慮し、chrootを有効にした環境とする。
実装1 /var/log/secureに出力する方法
最も簡単な方法であり、設定ファイルの該当行に-lオプションを付与するだけ。
- /etc/ssh/sftpd_config
# override default of no subsystems Subsystem sftp internal-sftp -l VERBOSE
実装2 /var/log/messagesに出力する方法
この方法を実装するにあたって、理解しておくべき前提知識がある。
前提として、Linuxの各デーモンは/dev/logと呼ばれるソケットファイルにログを出力している。
ソケットファイルとは、プロセス間通信にて使われるファイルのこと。
chrootを有効にした環境では、sftpログインを行うと本来の/devディレクトリが見えなくなってしまう。
そのため、chroot先のディレクトリに/dev/logを作成してあげる必要がある。
/dev/logは以下の設定後、rsyslogの再起動を行うことで自動的に作成される。
- /etc/rsyslog.conf
input(type="imuxsock" Socket="/<OSから見たchroot先のパス>/dev/log" CreatePath="on") //例(ログイン後、/sftptestをchroot先とする場合) input(type="imuxsock" Socket="/sftptest/dev/log" CreatePath="on")
- /etc/ssh/sftpd_config
# override default of no subsystems Subsystem sftp internal-sftp -l VERBOSE
実装3 任意のファイルに出力する方法
最も設定項目が多い方法ではあるが、基本的には実装2と同様。
今回は出力先を/var/log/sftp.logとする。
まずは、sftpd_config側にて、出力ログをファシリティlocal3に向ける。
※local0~7の範囲かつ、他アプリケーションで使用していなければどこでも可。
- /etc/ssh/sftpd_config
# override default of no subsystems Subsystem sftp internal-sftp -l VERBOSE -f local3
次に、chroot先のディレクトリに/dev/logを作成する。
- /etc/rsyslog.conf
input(type="imuxsock" Socket="/<OSから見たchroot先のパス>/dev/log" CreatePath="on") //例(ログイン後、/sftptestをchroot先とする場合) input(type="imuxsock" Socket="/sftptest/dev/log" CreatePath="on")
最後に、local3で受信したログを/var/log/sftp.logに出力する設定を追加する。
/var/log/messagesに出力されないように、local3.noneを追記しておく。
- /etc/rsyslog.conf
local3.* /var/log/sftp.log # Log anything (except mail) of level info or higher. # Don't log private authentication messages! *.info;mail.none;authpriv.none;cron.none;local3.none /var/log/messages