-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathc90.tex
More file actions
684 lines (481 loc) · 63.2 KB
/
Copy pathc90.tex
File metadata and controls
684 lines (481 loc) · 63.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
\documentclass[9pt,b5paper,tombo,openany]{jsbook}
\usepackage[dvipdfmx]{graphicx}
\usepackage{listings}
\usepackage{inconsolata}
\usepackage{url}
\usepackage{titlesec}
\usepackage[dvipdfmx]{color}
\usepackage{setspace}
\usepackage{wrapfig}
\lstset{basicstyle={\small\ttfamily}}
\lstset{frame=single}
\lstset{breaklines=true}
\lstset{lineskip=-1.5pt}
\lstset{framesep=6pt}
\renewcommand{\kanjifamilydefault}{\gtdefault}
\renewcommand{\familydefault}{\sfdefault}
\renewcommand{\contentsname}{}
\renewcommand{\baselinestretch}{1.1}
\definecolor{gray75}{gray}{0.75}
\titleformat{\chapter}[hang]{\Huge\bfseries}{\thechapter\textcolor{gray75}{|}}{0pt}{\Huge\bfseries}
\begin{document}
\noindent
{\Huge OpenStackの本 上級編}
\vspace*{-1in}
\begin{minipage}{0.4\paperwidth}
\tableofcontents
\end{minipage}
\vspace*{1in}
\begin{minipage}{0.4\paperwidth}
\begin{spacing}{0.75}
{\small 入門編・中級編と出してきて、あいだに番外編をはさみ、今回は上級編ということになった。内容としては、アップグレードしてみたら大変でした、という話と、一問一答型式でいままで書いてこなかった小ネタを書き連ねてみるという企画の2つになる。最近のOpenStackはコアコンポーネントが安定して(しまって)いるので、サブプロジェクトがどんどんと発生している。正直何がなにやら分からなくなってきているし、情況を追っていくのも大変になってきた。活気があると考えることにしよう。\\ OpenStackは半年に一回メジャーバージョンアップがリリースされる。ところが\verb|yum update|とすればバージョンアップ、というわけにはいかない。一部の設定値が非推奨になっていたり、デフォルト値が変わっていたりする。メタデータストアのスキーマも変更されるため、ダウングレード作業も難しい。本来OpenStackの各コンポーネントは疎結合で、主にAPIでの通信しかしない。従って、APIのバージョンが変わらないのなら、違うバージョンのコンポーネントが混在できるので、ローリングアップデートのような方法をとれる。と、思っていたがそんなことは全然なくて、という話だ。\\ 一問一答は割と苦し紛れの企画で、構成を考えずに紙面を稼げそうという感じである。最初に思いついた質問を書き連ねてみたら、ほとんどが具体的なコンポーネントに関係する話題ではなくなってしまったが、何かの役に立てば幸いである。}
\end{spacing}
\end{minipage}
\thispagestyle{empty}
\chapter{OpenStackアップグレード超入門}
\setcounter{page}{1}
\marginpar{\includegraphics[width=30mm]{mini1.png}}本章は、 Qiita に投稿した OpenStack Advent Calendar 2015 の 12 月 3 日の記事である「 OpenStack をアップグレードしたら心臓止まりかけた話」という物語を改めて書き記した章である(ただし、改訂版というわけではない)。
本章で行ったアップグレード作業は実話なのだが、作業自体は 2015 年 11 月時点での出来事である。その後、 Liberty リリースは幾度かのポイントリリースを経ているので、その中で今回遭遇した事象はもしかしたら解消されているかもしれない。が、我々には同じことをもう一度行う体力は残っていない。よって、 Liberty リリースを使ってこれからアップグレードを検討するという奇特なエンジニアの皆々様は、是非元記事であるQiita記事のコメント欄にその結果をご報告いただきたい。
\section{はじめに}
先日、 OpenStack 環境を Juno から Liberty に一気にアップグレードしてみた。なんでそんなことしたのかっていうと、先日の OpenStack Summit Tokyo で PayPal が Folsom から Kilo までアップグレードしたっていうセッション見たら、自分にもできるって思ったからだ。
いや、結果、アップグレードできたんだけどさ。まぁそんなわけで、見事に人柱になれたと思うので、ここではその時のことを記すことにした。\\[1ex]
\noindent
なお、そんな PayPal 様のセッションはこちら。
\begin{quote}
PayPal's Cloud Journey From Folsom to Kilo - What We Learned in the Upgrade
\end{quote}
アップグレード前の構成は、 OS が Ubuntu 14.04 、 OpenStack のバージョンが Juno 、 Hypervisor が KVM 、 Neutron Driver が VLAN + OVS で L3 Agent は稼働させていない構成となる。
\section{アップグレード}
Keystone、 Glance、 Nova、 Neutron の順番でやるのが一般的なんじゃないだろうか。 Design Summit では、各コンポーネントでバージョンがバラバラだって言う企業もいたから、順番は参考程度なんだが、全コンポーネントをアップグレードするならこの順番がいいと思う。\\[1ex]
ちなみに、無停止アップグレードは絶対無理だからアキラメロン。って、 Design Summit に居たハッカーのおっちゃんたちが言っとりました。\\[1ex]
\noindent
おっしゃる通りでございます。\\[1ex]
\noindent
\textbf{. . . 閑話休題 . . .}
\subsection{ロードバランサの紐付け解除}
Keystoneのフロントにあるロードバランサの5000番ポートに対する紐付けを解除し、完全に外部からの通信を止める。35357番ポートはそのままで問題ないと思われる。
\subsection{Liberty リポジトリ導入}
\noindent
まずは、全てのサーバにLibertyリリースのリポジトリを入れよう。
\begin{lstlisting}
$ sudo echo "deb http://ubuntu-cloud.archive.canonical.com/ubuntu \
trusty-updates/liberty main" \
> /etc/apt/sources.list.d/cloudarchive-liberty.list
$ sudo apt-get update
\end{lstlisting}
\subsection{Keystone 前準備}
KeystoneのDBに溜まっているtokenを削除する。LibertyからはデフォルトでMemcachedをtoken用途で利用するようになっているので、そちらを使うことにした。つまり、事前にMemcached用サーバを用意する必要がある。
\begin{lstlisting}
$ sudo su -s /bin/sh -c "keystone-manage token_flush" keystone
\end{lstlisting}
\noindent
DBのTokenを綺麗に消したら次は定期実行していたCronを停止する。
\begin{lstlisting}
$ sudo crontab -e -u keystone
\end{lstlisting}
\noindent
以下の行を削除する。
\begin{lstlisting}
@hourly /usr/bin/keystone-manage token_flush > \
/var/log/keystone/keystone-tokenflush.log 2>&1
\end{lstlisting}
\noindent
潔く、Keystoneを止めましょう。
\begin{lstlisting}
$ sudo service keystone stop
\end{lstlisting}
\subsection{データベースのバックアップ}
\noindent
DBサーバにログインして以下のコマンドでDBのバックアップを取得する。
\begin{lstlisting}
$ sudo mysqldump -uroot -p --opt --add-drop-database \
--single-transaction --master-data=2 keystone > \
liberty-keytone-db-backup.sql
$ sudo mysqldump -uroot -p --opt --add-drop-database \
--single-transaction --master-data=2 glance > \
liberty-glance-db-backup.sql
$ sudo mysqldump -uroot -p --opt --add-drop-database \
--single-transaction --master-data=2 nova > \
liberty-nova-db-backup.sql
$ sudo mysqldump -uroot -p --opt --add-drop-database \
--single-transaction --master-data=2 neutron > \
liberty-neutron-db-backup.sql
\end{lstlisting}
\subsection{Keystone アップグレード}
ここでKeystoneのアップグレードを行う。いろんなパラメータが新規に追加されたり廃止予定になったりしているが、それについては書ききれないのでConfiguration Referenceを参照してほしい。アップグレード自体は、apt-get install XXXXして、その後、keystone.confを書き換えて、プロセスを起動するだけである。基本的にはインストール手順のとおりに行えば問題ない(はず)。
ちなみに、confにDEBUGオプションを入れていると、プロセス起動直後のログに、confの各項目に何の値が設定されているのかが全て出力される。親切なことに、廃止予定の項目も指摘してくれる。これは全コンポーネント共通の仕組みなので、覚えておいて損はない。そういえば、Novaのusernameという項目で、usernameは廃止予定だから使うのやめてuser-nameを使えってログに出ていたから、使うのやめてuser-name使ったらエラー吐きまくってNovaが動かなくなった。ツンデレか。\\[1ex]
話が逸れた。\\[1ex]
keystone.confを配置したら以下のコマンドでLibertyリリースまでDBのスキーマのマイグレーションを行う。Kilo以降、KeystoneはApacheで稼働するようになったので、事前にKeystoneプロセスが止まっていることを確認してApacheを起動しておこう。
\begin{lstlisting}
$ sudo service keystone stop
$ sudo service apache2 restart
$ sudo su -s /bin/sh -c "keystone-manage db_sync" keystone
\end{lstlisting}
エラーが出なければKeystoneのアップグレードは完了である。一応、openstackコマンドが実行可能かどうかを確認しておこう。
\begin{lstlisting}
$ ADMIN_TOKEN=${keystone.confに記載されているadmin_tokenの文字列}
$ export OS_TOKEN=${ADMIN_TOKEN}
$ export OS_URL=http://${Keystoneが稼働しているどれかのサーバのIPアドレス}:35357/v3
$ export OS_IDENTITY_API_VERSION=3
$ openstack service list
\end{lstlisting}
\subsection{Glance アップグレード}
Keystone同様にConfiguration Referenceや公式のインストールガイドを確認しながら、環境にあったglance-api.conf、glance-registry.confを配置しよう。\\[1ex]
\noindent
その後、Glanceのdb syncを行う。
\begin{lstlisting}
$ sudo service glance-api restart
$ sudo service glance-registry restart
$ sudo su -s /bin/sh -c "glance-manage db_sync" glance
\end{lstlisting}
\noindent
エラーが出なければGlanceのアップグレードは完了である。
\subsection{nova-api アップグレード (Nova db sync 失敗編)}
最大の難関である。NovaのDBを上手くLibertyまでマイグレーション出来ればアップグレードできたも同然である。がしかし、現実はそうそう上手くはいかなかった。\\[1ex]
\noindent
なので、この項ではアップグレードが上手くいかなかった時の状況をそのまま記すことにした。
\subsubsection{まずは一気に Liberty までアップグレードしてみる}
\noindent
まず、nova-apiが稼働しているサーバ上で、nova-apiをLibertyまでアップグレードした。
\begin{lstlisting}
$ sudo apt-get install nova-api python-novaclient
\end{lstlisting}
その後db syncを行って、問題なければそのまま他のコンポーネントもアップグレードして完了となる(\textbf{はずだった})。\\[1ex]
\noindent
で、以下のコマンドを叩くのだが、
\begin{lstlisting}
$ sudo su -s /bin/sh -c "nova-manage db sync" nova
\end{lstlisting}
\noindent
エラー発生:(
\subsubsection{奇妙な nova-manage のオプション}
\noindent
エラーの内容はこうだ。
\begin{itemize}
\item db sync する前にnova-manage db migrate\_flavor\_dataというコマンドを実行しろ
\end{itemize}
だがしかし、\textbf{実はLibertyリリースのnova-manageコマンドにはこのオプションが入ってないのである。} ソースコードまで読んで調べたが本当になかった。んなアホなと思ったんだが、この時点でDBのスキーマ自体はかなり中途半端に変更されてしまっていた。
\noindent
この状態で以下のことを行った。
\begin{itemize}
\item DBをドロップ(1度目)してリストア
\item リポジトリをJunoリリースまで戻してパッケージを再インストール
\end{itemize}
\noindent
次に疑ったのが、Kiloリリースである。なので、以下のことを行った。
\begin{itemize}
\item Kiloリリースのnova-apiインストール
\item nova-manage db migrate\_flavor\_data実行
\item nova-manage db sync実行
\end{itemize}
Kiloリリースのリポジトリを追加してインストールしたnova-apiにはnova-manageのオプションにmigrate\_flavor\_dataがあった。キタコレ!と思って、さっそくnova-manage db migrate\_flavor\_dataを実行した。そしたら成功したもんだから、そのまま一旦Kiloリリースまで上げてからLibertyリリースにしようと思って、Kiloリリース時点までdb syncした。\\[1ex]
\noindent
そしたら、またエラーが出た:(\\[1ex]
flavor のテーブルのスキーマがおかしいという旨のエラーだった。嘘だろって思ったがマジだった。エラーの内容と状況を整理すると、\textbf{Kiloリリースのdb syncの後で、かつLibertyリリースのdb syncの前に、nova-manage db migrate\_flavor\_dataを実行しろ}、ということである。\\[1ex]
\noindent
つまり、正解はこうだ。
\begin{itemize}
\item Kiloリリースのnova-apiインストール
\item nova-manage db sync実行
\item nova-manage db migrate\_flavor\_data実行
\item Libertyリリースのnova-apiインストール
\item nova-manage db sync実行
\end{itemize}
\subsubsection{apt 壊れた}
この時点でまたもやDBのスキーマは中途半端に変更されてしまっていたため、Junoリリース時点まで戻して、またDBのドロップ(2度目)とリストアを行った。その後、Junoリリース時点のnova-apiに戻そうとしたのだが、\textbf{今度はaptが壊れた....}。\\[1ex]
JunoとKiloとLibertyを何度も行き来していたせいで、依存パッケージがおかしなことになりインストールも削除もできなくなってしまった。しょうがないので、dpkgコマンドで全3バージョン(Juno, Kilo, Liberty)のNovaに依存が貼られている依存パッケージ全てを削除した。そしたらaptが動くようになったので、またJunoリリースまで戻して再チャレンジすることとなる。\\[1ex]
実はこれやってる最中に、この前テレビでやっていた「学校へ行こう!」の軟式globeの曲が脳内でループしていた。\\[1ex]
\noindent
「アホだなぁー」「そうだよアホだよ」\\[1ex]
\noindent
名曲である。\\[1ex]
\noindent
\textbf{. . . 閑話休題 . . .}
\subsection{nova-api アップグレード (Nova db sync 成功編)}
\noindent
ここまでを踏まえて、成功した手順を記す。\\[1ex]
\noindent
Kiloリリースをインストールする。
\begin{lstlisting}
$ sudo echo "deb http://ubuntu-cloud.archive.canonical.com/ubuntu trusty-updates/kilo main" \
> /etc/apt/sources.list.d/cloudarchive-kilo.list
$ sudo apt-get update
$ sudo apt-get install nova-api python-novaclient
\end{lstlisting}
\noindent
Kiloリリース時点のスキーマまでマイグレーションする。
\begin{lstlisting}
$ sudo service nova-api restart
$ sudo su -s /bin/sh -c "nova-manage db sync" nova
$ sudo su -s /bin/sh -c "nova-manage db migrate_flavor_data" nova
\end{lstlisting}
\noindent
その後、Libertyリリースに上げる。
\begin{lstlisting}
$ sudo echo "deb http://ubuntu-cloud.archive.canonical.com/ubuntu trusty-updates/liberty main" \
> /etc/apt/sources.list.d/cloudarchive-liberty.list
$ sudo apt-get update
$ sudo apt-get install nova-api python-novaclient
\end{lstlisting}
\noindent
Libertyリリース時点のスキーマまでマイグレーションする。
\begin{lstlisting}
$ sudo service nova-api restart
$ sudo su -s /bin/sh -c "nova-manage db sync" nova
\end{lstlisting}
これで、nova-apiのアップグレードとNovaのDBのマイグレーションが完了となる。ちなみに、このDBマイグレーション手順については、実はKiloのリリースノートに1行だけ記載があった。が、それでもあまり親切な書き方ではないから、事前に確認していてもハマってたと思う。
\subsection{neutron-server アップグレード}
nova-apiがアップグレードできたら、次にneutron-serverをアップグレードする。
Keystone同様にConfiguration Referenceや公式のインストールガイドを確認しながら環境にあったneutron.confや、その他諸々を配置しよう。なお、Open vSwitchはml2の設定ファイルが分割されているので注意が必要である。
\noindent
その後、Neutronのdb syncを行う。
\begin{lstlisting}
$ sudo service neutron-server restart
$ sudo su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf \
--config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron
\end{lstlisting}
\noindent
エラーが出なければNeutronのDBはLibertyリリース時点のスキーマまでマイグレーションされている。
\subsection{Nova / Neutron の残りのパッケージのアップグレード}
ここまで完了すれば後は残っているパッケージを全てアップグレードしよう。ここから先は、特に問題は起こらない(はず)である。何をどうやってアップグレードするのかについては各環境に依存するので、ここでは記さないこととする。
\subsection{ロードバランサの紐付け}
Keystoneのフロントにあるロードバランサの5000番ポートに対してリアルサーバを紐付ける。
\subsection{Horizon アップグレード}
Horizonは、ぶっちゃけると、他のコンポーネントとバージョンが食い違っていても全く問題ないので、OpenStackがリリースされるたびにアップグレードしても何も問題ない。
が、Libertyリリースに限って言うと、\textbf{というか、Libertyリリースのdebパッケージに限って言うと}、アップグレードが失敗する。
なぜうまくいかなかったのかについて詳しい事象は判明していない。とりあえず、起こった事象を書き記すことにした。申し訳ない。
\subsubsection{deb パッケージの謎}
自分は今回deb パッケージが新規インストール時とアップグレード時で挙動が違うという事象に遭遇した。普通は(きっと)そんなことはない(はず)なのだが、LibertyリリースのHorizonのdebパッケージに限って言えば、挙動が違った。
Junoリリースで稼働していたHorizonのサーバで、apt-get upgrade、もしくはapt-get install openstack-dashboardでHorizonのバージョンを上げた場合、CSSが読み込まれず、Horizonが2000年あたりの何とも簡素なWebページのようなデザインになる。
Horizonもコンポーネントが増えてごちゃごちゃしてきたから、ここで一つ Simple is Best ってことでデザイン変更したのかなって一瞬だけ思ったが、そんなことは全く無かった。いくらなんでも時代に逆行しすぎである。\\[1ex]
\noindent
\textbf{. . . 閑話休題 . . .}
ひとまずアップグレードプロセスに問題があるのだろうと踏んだので、調べるためにLibertyリリースのdeb-src行をリポジトリに追記して、openstack-dashboardのdebパッケージを落としてくる。
\begin{lstlisting}
$ sudo echo "deb-src http://ubuntu-cloud.archive.canonical.com/ubuntu trusty-updates/liberty main" \
>> /etc/apt/sources.list.d/cloudarchive-liberty.list
$ sudo apt-get update
$ sudo apt-get source openstack-dashboard
$ tar zxvf horizon_8.0.0-0ubuntu2~cloud0.debian.tar.gz
$ cd debian
\end{lstlisting}
\noindent
README.sourceを開くと早速以下の様なことが書いてあった。
\begin{lstlisting}
During the Juno/14.10 development cycle, use of xstatic packages was introduced
so that CSS, JS and other static assets did not have to be embedded in the
horizon source tree.
\end{lstlisting}
\noindent
怪しい、すごく怪しい。
ついでに、Icehouseリリースに遡ってソースを落としてくると、今度はREADME.compressionというファイルに以下のことが書いてある。
\begin{lstlisting}
Until this can be scripted and integrated into package build, updating the
pre-compressed static CSS and JS requires a some manual steps:
sudo apt-get install python-lesscpy python-openstack-auth python-compressor
quilt pop top
./debian/rules refresh-static-assets
\end{lstlisting}
\noindent
ふむ。\\[1ex]
rulesファイルとかちゃんと読めば、きちんとした原因が判明するだろう。が、僕はこの時点で完全に力尽きていた。
唯一分かっていることは、一度JunoリリースのHorizon(Django含む)のパッケージを全て削除してLibertyリリースのパッケージを入れなおせば、問題なく動くということである。なお、この事象は、JunoからKiloに上げた際には発生しない。JunoからLiberty、もしくはKiloからLibertyにアップグレードした場合にのみ発生するのである。\\[1ex]
\noindent
というわけで、詳細知ってる人がいたら教えて下さい、お願いします。\\[1ex]
\noindent
あと、Canonicalの中の人はこのdebパッケージどうにかして下さい。\\[1ex]
\subsection{アップグレードの終わり}
ここまででOpenStack環境のアップグレードが完了となる。当然だが、こんな作業をマニュアルでやっていたら、いつか腱鞘炎になる。それが嫌なら、ChefとかPuppetとかAnsibleとかそういうの使ってやったほうがいい。たぶん。\\[1ex]
\noindent
お疲れ様でした
\section{アップグレード作業から得た教訓}
\noindent
\textbf{1. 事前の検証は絶対必要}
本番環境でのアップグレードを実施するまでに、本番と同等構成による新規でLiberty構築を1回と、事前にJunoの同等構成の検証環境を作っておき、そこからのアップグレードテストを1回やった。ちなみに今回の話は検証環境で起こった話です。おかげで本番環境ではすんなりアップグレードが出来ました。\\
\noindent
\textbf{2. どうしてもアップグレードが必要というわけでないのならやらないに越したことはない}
OpenStackの各バージョンはリリースから約14ヶ月でEOLを迎える。つまり、リリースから約14ヶ月はBugfixがバックポートされるので、それでお茶を濁すというのもあり。もしくは、リリースタイイングごとにKeystoneだけアップグレードして、その他のコンポーネントはRegionをきちんと定義して小さくOpenStackクラスターを作っていくという手もある。当然、構築したOpenStackクラスターそのもののEOLを定義していく必要がある。\\
\noindent
\textbf{3. 問題はアップグレード後にも起こる}
アップグレード後に初めて気付く問題もたくさんある。事前にLaunchpadからバグやKnown Issueは確認して、アップグレードをするかどうかの判断基準にするとよい。とはいえ、リリース直後にアップグレードするとなると、それはただの人柱であり、バグがそもそもLaunchpadに登録されてない、なんてこともある。
\chapter{OpenStack一問一答}
\marginpar{\includegraphics[width=35mm]{mini2.png}}OpenStackをしばらく運用してみて、ちょっとした疑問がいろいろ浮かんできたと思うので、OpenStackに関するよくある質問をQ\&A型式でずらずらと並べてみることにしました。割とよくある質問だけれど、ネットにはちゃんと書かれていないようなものもあるかと思いますので、何かのお役に立てば幸いです。
\section{構築}
\subsection*{{\bfseries Q.} Ubuntuじゃないとだめなんですか?CentOSは?}
\subsection*{{\bfseries A.} どっちでもいいです}
初めの頃はUbuntuが多かったのですが、最近はCentOSと市場を二分しています。どちらもリポジトリにパッケージがありますし、公式のドキュメントにも両方の手順が公開されています。Ubuntuもsystemdになりましたし、まぁほんとにどっちでもいいでしょう。でも、なんとなくUbuntuの方がちゃんとパッケージが管理されているような感はありますが、気のせいかもしれないです。
\subsection*{{\bfseries Q.} どうやってインストールするんですか}
\subsection*{{\bfseries A.} ひとまずは公式ドキュメント通りにやってみましょう}
OpenStackコミュニティーが公式に提供しているインストールドキュメントがありますので、ひとまずはそれに則って構築をしてみましょう。その後、少しずつ勉強して設定を要求に合わせて変えていくのがよいでしょう。まずは手元でdevstackなどを用いて構築、次に倉庫に眠っているサーバーを数台かき集めて構築、という感じで何回か構築してみると勘やスケール感がつかめてくると思います。最初から要求通りに設定をしていくのはほぼ不可能でしょう。
\subsection*{{\bfseries Q.} サーバー何買えばいいですか}
\subsection*{{\bfseries A.} SSDと10GBのNICがあれば何でも}
コンポーネントによってはあまりスペックは必要ありません。ネットワークノードはディスクアクセスはあまりありませんが、ネットワークを酷使しますのでNICやCPUの性能は上げておくのが良いでしょう。KeystoneやHorizonは水平スケール可能なため、小さなマシンやコンテナなんかで横に並べてロードバランサ配下にするのが良い手です。もちろん、コンピュートホストは高いスペックが必要になります。特にディスクはボトルネックになりがちなので、SSDなどで高速化する必要があります。盲点はGlanceで、これはディスクイメージの転送が走るため、ネットワーク帯域は広めにしておくとVM起動の体感速度が上がります。
コンピュートホストは、「ホスト1台あたり」・「どのくらいのスペックのVMを」・「何台入れると」・「費用対効果が高いか」を考えてスペックを選ぶことになるでしょう。メモリをばかでかくしても、ディスクが足りなければVMは動かせませんし、逆もまたしかりです。
\subsection*{{\bfseries Q.} いいドキュメントないですか?}
\subsection*{{\bfseries A.} ないです}
公式がOpenStackセットアップ手順として提供されているものは非常にベーシックなセットアップのみです。特にneutronに関しては、その機能の豊富さに比べて資料がとても少ないと言えます。ひとまずはこのベーシックな構成で作ってみて、必要に応じて設定を変更していくのがいいかと思います。
\section{運用}
\subsection*{{\bfseries Q.} No more available hostみたいなエラーが出たんですが}
\subsection*{{\bfseries A.} 汎用エラーです}
汎用エラーって何やねん、ってことですね、分かります。このエラーはavailableなホストが無い、という意味ではなく、「仮想マシンを起動できなかった」という意味としてとらえるべきです。なお、このエラーは現象を示すもので、原因を示すものではありません。ありとあらゆる原因の末、要するにVMが起動できなかったよ、と言っているに過ぎません。
というわけで、これが出ちゃうと、さまざまなコンポーネントのログを見ていくことになります。まずは、nova-schedulerのログを見るとよいでしょう。コンピュートホストのリソースが足りないなどの理由で「availableなホストが本当に無い」ということも十分考えられます。次にコンピュートノードのログを見ると、何かしらのエラーが出力されている可能性があります。
\subsection*{{\bfseries Q.} 入れたはいいけど監視したいです}
\subsection*{{\bfseries A.} 何を監視するか決めましょう}
まずは仮想マシンの監視ですが、これは普通のOS監視と同じ考え方で大丈夫です。ZabbixでもInfluxDBでも好きな物を使えますので、運用スタイルにあったものを選択しましょう。仮想環境ではマシンが頻繁に作成されては消えていく性質があるため、それに対応できるような監視ソリューションがいいと思います。
コンピュートホストやネットワークノードなど、OpenStackで使われる物理サーバーの監視は普通のログやシステムメトリクスの監視に加えて、OpenStack専用の監視項目を追加する必要があるかもしれません。メモリは実使用メモリと仮想マシン割り当て量が大きく違ってきますので注意が必要です。また、ディスクもThinプロビジョニングですと、あるとき急にディスクがあふれる、なんていうこともあり得ます。libvirtのAPIなどを使用して(\verb|virsh|コマンドなど)仮想マシンホスト専用のメトリクスを取得することを考えるとよいと思います。
OpenStack自体の監視となると、これはインスタンスを作成できるか定期的にチェックする、というような形になるでしょう。真面目にTempestなどを使ってテストするのがベストではありますが、そこまでは必要無いような気もします。
\subsection*{{\bfseries Q.} トラブったら誰に聞けばいいんですか}
\subsection*{{\bfseries A.} サポートしてくれるSIerでも契約しましょう}
ってかオープンソースのもの導入しておいて、トラブルを誰のせいにするかなんて話をするような人達なんて、お金もらっても相手したくないですね。まぁでもお金くれればやってもいいと思っている人達はいるので、そういう人達と契約すればいいと思います。最近はOpenStackの流行を受けて、大手ベンダーやSIerがサポート体制を組んでいます。中にはOpenStack専業にしている企業もあるくらいです。
オープンソースコミュニティがありますので、そのメーリングリストやIRCなどで助けを求めることもできます。ですが、こちらは慈善事業ですので、無視は当然と思うべきでしょう。エチケットや適切な情況の報告が必要不可欠です。OpenStackのwikiにメーリングリストでのエチケットやルールが書かれたページがありますので、一読しておくことをオススメします。
要は、コミュニティーは慈善団体であるということです。返事が返ってこなくてもそんなに凹むことはないですし、どうしても返答が必要な場合は、週1で4回ほどならば自己レスの形で聞き直しても問題ありません。IRCも広く使われていますし、主要な開発者はIRCにいることが多いため、そちらで聞くとより早く返答が得られるかもしれません。
とはいえ、やはり問題は英語です。ですが、日本人でも活躍している方は多いですし、メーリングリストなどをよく見ると、まったくデタラメな英語の人も意外と多いものです。むしろ日本人のほうがきちんと文法を気にして書いている印象です。エチケットさえ守れていれば、英語の善し悪しはあまり大きな問題ではありません。Wordの文法チェックぐらいかけておけばよいでしょう。
\subsection*{{\bfseries Q.} 仮想マシンが重いです}
\subsection*{{\bfseries A.} どこが重いのか調べましょう}
恐らくCPUが遅いということはあまりないと思うので、ディスクとかネットワークあたりが体感速度を下げている要因である可能性が高いでしょう。ディスクでしたらホストがSSDじゃないと厳しいでしょう。ネットワークに関しては、高速化のための開発がKVMとQEMU双方で目下行われています。MMIOやVFIO、パススルーなど、ハードウェアとの距離を縮めるような技術を使うのも手です。個人的にはdpdkもおもしろそうです。ただ、ハードウェアとの距離を縮めると、仮想化ならではの良さ(ポータビリティーなど)を失うことにもなります。パフォーマンスや可用性を高めたい場合は、分散アーキテクチャやクラスタ化を検討するべきと言えます。
\subsection*{{\bfseries Q.} ネットワークが遅いです}
\subsection*{{\bfseries A.} そうなんですよね}
これは昔からの問題です。根本的な問題としては、もともとパケット処理はコンテキストスイッチが多いので、古いLinuxカーネルではあまりパフォーマンスが出ない、ということになります。これはLinuxをネットワーク機器として使用するNFVのようなプロジェクトで大いに議論と開発が活発に続いていますので、要チェックな状態です。それでも最近は通常用とであれば十分なスピードが出るようです。
\subsection*{{\bfseries Q.} ディスクに制限をつけたいです}
\subsection*{{\bfseries A.} できます}
いわゆるディスクのIO制限ですね。EphemeralディスクはFlavorで、Cinderの場合はドライバによってやりかたが違うでしょうが、基本的にはドライバータイプごとに帯域が制限できます。
\subsection*{{\bfseries Q.} 帯域制限したいです}
\subsection*{{\bfseries A.} できます}
これもFlavorでできます。Neutron側で設定できるようにする話もあるみたいですね。\\
\section{一般}
\subsection*{{\bfseries Q.} これだけ覚えておけばOKみたいなのありますか}
\subsection*{{\bfseries A.} 甘え}
そんなものはありません。知らないことはすべて知る必要があります。強いて言えば、OpenStackのことだけ知っておけばOKです。KVMの事はあまり知る必要はありませんが、QEMUについては少し勉強しておくと良いでしょう。あとは、OpenStackではとにかくネットワークの構築でハマります。ネットワークの知識が必要になるでしょう。息をするようにtcpdumpをとりましょう。
\subsection*{{\bfseries Q.} 何か本とかないですか}
\subsection*{{\bfseries A.} あります}
最近は日本語の本も登場しています。Amazonとかで探すと結構出てくると思います。本家OpenStack Foundation公認の「日本OpenStackユーザー会」で書かれた本もあります。構築、または運用に関する本が多いです。
\subsection*{{\bfseries Q.} コマンド覚えられないんですが}
\subsection*{{\bfseries A.} --help}
ちゃんとメンテナンスされているコマンドリストのようなものはありませんので、もうこれは\verb|--help|するしかありません。単に\verb|help|だけのサブコマンド型式になっているコマンドもあります。引数を忘れた、ということも往々にしてありますので、ヘルプを見るのを癖にしておくとよいでしょう。
\subsection*{{\bfseries Q.} Horizon使いにくいんですが}
\subsection*{{\bfseries A.} 使わなくていいです}
まず、OpenStackの第一の存在意義は、インフラをAPIで操作できることであって、画面で操作できることではありません。OpenStackはAPIでできることがすべてであり、それ以上でもそれ以下でもありませんし、それ以外のことはできません。HorizonはそれらAPIの一部をブラウザで操作できるようにしているだけです。OpenStackを使うのに、Horizonを使う必要はありません。
\subsection*{{\bfseries Q.} なのでHorizon改造したいです}
\subsection*{{\bfseries A.} 大抵の場合はやめたほうがいいでしょう}
もっと使いやすくしよう、これは良い考えです。良い物を作ってどんどんコミュニティーに還元していって欲しいです。
もしその改造がパッチを送るには出来が悪すぎるとか、特定の用途に特化しすぎているとかだったら、その改造はメンテナンスできなくてすぐに破綻するでしょうから、やめておくのが無難でしょう。そんな汎用性の無い改造をすることに時間を使うくらいだったら、そんな改造が必要になってしまうようなワークフローを変えることのほうが世のため人のためです。
\subsection*{{\bfseries Q.} 本番で使ってるひといるんですか?}
\subsection*{{\bfseries A.} それ聞いてどうするんですか}
いますけどね。でもだからって自分のところで上手くいくとは限りません。OpenStackは非常にさまざまな環境や用途にそれなりに対応できるので、他人の例はほぼ役に立たないでしょう。
\subsection*{{\bfseries Q.} OpenStackって大丈夫なんですか?}
\subsection*{{\bfseries A.} それ聞いてどうするんですか}
まぁ大丈夫なんですけどね。でも大丈夫と言われたから大丈夫なんだろうという判断はしないほうがいいでしょう。
\subsection*{{\bfseries Q.} 誰が作ってるんですか?}
\subsection*{{\bfseries A.} いろんな人たちです いやほんとに}
コミュニティーをベースにした開発が行われています。コミュニティーからの選挙で選ばれたボードメンバーによるファウンデーションが主導しています。企業で仕事としてOpenStack開発をやっている人もいれば、個人の趣味でやっている人もいます。
給料もらいながら開発に参加している人のほうが、どうしても貢献の量が多くなるので、ボードメンバーにはクラウドシステム開発系の人達が多いです。とはいえ、そのような人達はパッチのレビューに多くの時間を割かれてしまう現実があるので、実際に手を動かしてパッチを書いている人は個人だったり企業の人だったり様々です。
\subsection*{{\bfseries Q.} さくっとためしたいんですが}
\subsection*{{\bfseries A.} devstackが便利です}
devstackというのはOpenStack開発者向けのテスト環境作成ツールです。設定ファイルを少し書いてスクリプトを実行すると、ソースコードの取得から設定・プロセスの起動まで、一通りの構築をしてくれるものです。パブリッククラウドでもvmware Playerでも、環境は適当な仮想マシンで問題ありません。
が、OpenStackの全てのコンポーネントが起動するので、メモリが4GBくらいは少なくとも必要になります。また、設定ファイルの書き方がOpenStackのことを知っていないと書けないほど難解なので、「鶏と卵」の関係になるかもしれません……。
\subsection*{{\bfseries Q.} なんか変な仕様なんですが、これ誰が決めてるんですか?}
\subsection*{{\bfseries A.} 開発者です}
OpenStackの仕様は主に以下の方法で決定されます。
\begin{itemize}
\item OpenStackデザインサミット
\item LaunchpadのBlueprint
\item メーリングリスト
\end{itemize}
これらすべてに、すべての人が参加可能です。なので、誰か特定の偉い人や企業が独占的に決めているのではありません。
\subsection*{{\bfseries Q.} どうやって開発してるんですか}
\subsection*{{\bfseries A.} 基本的に話し合いです}
バグの修正も新規機能の開発も、基本的にはパッチを書き、コードをレビューしてもらい、テストが通り、良さそうならマージされます。すべての工程が公開されていますので、誰でも参加できます。
\subsection*{{\bfseries Q.} でもプルリク投げたら怒られたんですが}
\subsection*{{\bfseries A.} すみません}
コードはGitHubにあるんですが、実はこれはミラーリポジトリです。本当は\url{http://git.openstack.org}がオリジナルです。なので、GitHubのインフラを使った開発は行われていません。従って、プルリクエストによるコードレビューは行っていません。また、Linuxカーネルのようなメーリングリストにパッチを投げる型式でも取り合ってくれません。コードレビューはGerritで、バグ管理はLaunchpadで行われているのですが、始める前のお作法がちょっとあります。昔はこの辺のドキュメントはほとんどなかったのですが、最近は日本語でも検索でけっこうひっかかるようになってきました。ぜひ調べてやってみてください。コントリビューションはハマるととっても楽しいものですよ。
\subsection*{{\bfseries Q.} とりあえず勉強しておくといいことありますか}
\subsection*{{\bfseries A.} 端から全部です}
まぁなんとなく概要を掴んでおくことぐらいは必要ですが、インストールしてセットアップしつつ、分からないことを調べていくのがよいでしょう。知らないまま構築はできません。
\subsection*{{\bfseries Q.} novaが何でneutronが何でとか覚えられません}
\subsection*{{\bfseries A.} しかもたまに名前変えますからね}
昔neutronはqurntamだったし、割ところころ変わりますよね。
\section{インスタンス}
\subsection*{{\bfseries Q.} 起動途中で変な状態で止まっちゃいました}
\subsection*{{\bfseries A.} リセットできます}
\verb|nova reset-state|コマンドでインスタンスの状態をリセットできます。
\subsection*{{\bfseries Q.} マイグレーションってすごくないですか}
\subsection*{{\bfseries A.} そう思います}
マイグレーションには2種類あります。1つは普通のマイグレーションで、共有ストレージを使うものです。面白いのは二つ目のブロックマイグレーションです。これは共有ストレージ無しでディスクイメージを同期させながらマイグレーションする方法で、技術的にはなかなか興味深いところです。
\subsection*{{\bfseries Q.} KVMってなんですか}
\subsection*{{\bfseries A.} 仮想マシンのアクセラレーターです}
割と勘違いされていることが多いのですが、KVMは「アクセラレーター」です。仮想マシンアクセラレーターの機能を持つカーネルモジュールです。いや、LinuxでやるVMのことでしょ、と思うかもしれませんが、いわゆる「仮想マシン」と言った時のイメージは、KVMではなく、正確にはQEMUが担っています。QEMUがそのままではあまりに遅いので、KVMというアクセラレーターを使って速くしているのです。つまり、QEMUさえあればKVMはなくてもOpenStackは(動くには)動きます。
とはいえ、KVMとQEMUがごっちゃになって巷では認識されているは事実です。大抵の場合、KVMと言ったらQEMUのことを意図していると考えて差し支えない感もあります。
\subsection*{{\bfseries Q.} そのQEMUってなんですか}
\subsection*{{\bfseries A.} 仮想マシンです}
位置付けとしては、VirtualBoxとかvmware Playerと同じです。仮想マシンが起動しているコンピュートホスト上でpsコマンドなどでプロセスを見てみると、仮想マシンごとにqemuのプロセスが起動していることが確認できると思います。いわゆる仮想マシン構成の「設定ファイル」のようなものは無いので、構成に関する情報を起動時の引数ですべて指定するため、コマンドがとんでもなく長くなる傾向があります。
\subsection*{{\bfseries Q.} libvirtってなんですか}
\subsection*{{\bfseries A.} 仮想マシン操作API群です}
QEMU/KVM、ESXi, behyve, VirtualBoxなどなど、世の中には沢山の仮想化環境がありますよね。これらの違いを意識せず、ラッパーAPIのような形で統一的に操作できたらいいですよね。と、いうわけでできたのがlibvirtです。もとはC言語のライブラリとして開発が続いており、多言語のラッパーも多く存在します。特にpythonはオリジナルのC言語版とほぼ同等の地位をもってメンテナンスされています。
OpenStackでは、novaがlibvirtが提供するAPIを使用することにより、仮想マシンのライフサイクルが管理されます。novaはlibvirtのラッパー、という見方でも問題ない位でしょう。。ただ、QEMU独自の機能やQEMUにはあるけどlibvirtからはまだ使えない機能なんかもありますので、そういう機能を使うときにはQEMUのプロセス間通信を使ってQEMUの動作を直接変更し、libvirtをパスすることもあります。
\subsection*{{\bfseries Q.} インスタンスにSSHできません}
\subsection*{{\bfseries A.} でしょうね}
誤解の無いように言っておきますが、普通SSHはできます。SSHができないのは、設定がちゃんとできてないからです。手順が違うからです。問題は、その手順が非常に複雑である、ということです。パッと数分でできるようなシロモノではないです。インスタンスにSSHできるまで3週間は見積もっておくべきでしょう。セットアップ百戦錬磨の玄人もOpenStack一式を動かすまでは1日2日は見積もるところです。
インスタンスは起動している(ように見える)のに、SSHができない要因は実にさまざまですが、代表的な要因として考えるのは以下でしょう。
\begin{itemize}
\item SecurityGroupで22番がDenyされている
\item DHCP Discoverパケットがネットワークノードに届いていない
\item インスタンスOSのファイヤーウォールで22番がDenyされている
\end{itemize}
デフォルトのSecurityGroupは外部からの通信をすべてDenyしていますので注意して下さい。また、コンピュートホストやネットワークノードのインターフェースのtcpdumpをとってみるのも良いでしょう。DHCP Discoverが届かない、あるいはDHCP Offerが返ってこないなどの場合は、物理マシンが接続しているスイッチなどの設定を見直す必要があるかもしれません。やはりtcpdumpなどで、どこまでパケットが来ているかを確認していくことになるでしょう。
\subsection*{{\bfseries Q.} インスタンスに(から)pingできません}
\subsection*{{\bfseries A.} でしょうね}
誤解のないように言っておきm(以下略)
考えられる原因はSSHの時とほぼ同じです。インスタンスから外部に接続できない場合は、Open vSwitchのbr-exブリッジにホストの物理インターフェースがちゃんと接続されているか確認してみましょう。tcpdumpを見て、ちゃんとインスタンスからのパケットが出ているかを確認すると良いでしょう。
\subsection*{{\bfseries Q.} HorizonのWebコンソールが出ません}
\subsection*{{\bfseries A.} でしょうね}
誤解のn(以下略)
たいていの場合は6080番ポートが開いてないことが原因だと思います。
\section{ネットワーク}
\subsection*{{\bfseries Q.} 2つのネットワークに同じVLAN付けたいんですが}
\subsection*{{\bfseries A.} ルーター使わないとできません}
Neutronのルーター機能を使ってテナントネットワークを有効にすれば可能ですが、使わない場合はできません。ルーター機能を使わない場合、テナントネットワークを新規作成時に、Neutronが指定されたVLANが他のテナントネットワークで使用されていないかチェックするようになっているからです。
\subsection*{{\bfseries Q.} DHCP使わないとダメなんですか?}
\subsection*{{\bfseries A.} ダメではないです}
DHCPを使わないとなると、cloud-initなどを使うことになるでしょう。Neutronにより仮想マシンに割り当てられたインターフェースに特定のIPが振られていますので、そのIPを何らかの方法で取得する必要があります。ネットワークノードのmetadataサーバーやconfig\_driveなどから取得するのが定石でしょう。
OpenStackで振られたIP以外を使用するとどうなるのかっていうと、OpenStackはそのIPが使用されているとは思っていないため、別のVMにそのIPが振られる可能性があります。となると、IPが重複する可能性があります。とはいえ、最近のOSは同じネットワーク内で既に同じIPが存在していないかを確認し、存在している場合はインターフェースを上げないようになっているようですので、水際で大事故は防げそうではあります。
\subsection*{{\bfseries Q.} VLANとかよくわかんないんですがflatにしとけばとりあえずはしのげます?}
\subsection*{{\bfseries A.} しのげないです}
個人の趣味でやるならともかく、もしそれがどこかのデータセンターで動かす、とかいう状態なら、絶対にやめた方がいいです。ネットワーク内にDHCPが作成されるため、安易にネットワーク設定を試すのはよしたほうがいいでしょう。IPもNeutronの都合で割り振っていきますので、IPが重複する、なんていう事態にもなりかねません。
とはいえ、OpenStackはネットワークの構築がとにかく難しいので気持ちは分からなくはないですね……。なんとなくflat構成が一番簡単そうではあるんですが、実はVLAN構成が一番情報も多くて簡単なのではないかという気もします。
\subsection*{{\bfseries Q.} ミラーポートとか作りたいです}
\subsection*{{\bfseries A.} Open vSwitchとかだと簡単にできます}
Open vSwitchのミラーポートとかで検索するとヒットします。これをサービス化して、neutronのサブモジュール(Tap as a Service)としてコンポーネント化する計画もあります。セキュリティー対策・トラブルシュートの観点からも、ミラーリングポートの作成は調べてマニュアルにしておくのがよいと思います。
\subsection*{{\bfseries Q.} IPってどういう順番で振られるんですか}
\subsection*{{\bfseries A.} 前から順番で、最後まで行ったら最初に戻ります}
サブネットの前から順番に割り当てられていきます。サブネットが.0/24なら、.1から始まり、.254まで来ると最初に戻ります。途中インスタンスが消えた場合、そのIPは.254まで行って、戻った時にようやく再利用されます。NeutronにPAM機能を追加しようとする動きもありますので、今後は変わっていく可能性があります。
\chapter{あとがき}
\setstretch{0.96}
\section*{こじろー}
\marginpar{\includegraphics[width=30mm]{mini3.png}}この僕ら2人のサークルは、OpenStackについての同人誌を作る目的で2年前に発足した。なぜOpenStackに的を絞ったのかというと、仕事で使い始めたからである。なのだが、2年が経過してOpenStackそのものの品質の向上や僕たちの個人的な状況の変化を鑑みると、これ以上OpenStackに絞って同人誌を作り続けるのは難しくなってきているのではないかと感じている。カジュアルに同人誌を書く対象としてのOpenStackは、僕らには手に負えないくらい大規模なプロジェクトになってしまっており、下手なことを適当に書くことができなくなっている気がしている。現在同人誌として出している数冊(本誌含む)よりも高度なことを書くなら同人誌の枠を超えて、きちんとした形で出版することも視野に入れた方がいいんじゃないかと感じている。そう感じていると同時に、OpenStackに対する僕ら2人の熱量がすでに下がってきているという感触もある。既刊本のメンテナンスは必要なので(大幅な改定はキツイかもしれないが!)今後も活動を続ける必要があるが、あまりこれ以上OpenStackの新刊を期待されてもちょっと厳しいと思う。次回にむけてまた新しいテーマを考えたい。
\section*{まっきーさん}
いやしかし本当にネタがなくなってきた。個人的に環境も変わったし、次は本当に無いかもしれない気がしている。いや、今までの本を改訂していく必要はあると思っているので、改訂版を延々と出し続けていくことは可能かもしれない。\LaTeX で同人誌を書く本とかでもいいかもしれない。いやもうバイオインフォマティクスの本でもいいか……いやでもそういう話はからまれそうで嫌だな……あ、でもそれなら\LaTeX の方がめんどくさい人が多そうな話題だな……。どうも最近は本を読まなくなってきてしまっていて、あとがきに書くようなことさえもなくなってきてしまった。大人になったのだ。
毎度、同人誌を作るたびに思うのだけれど、文章を書くというのは、本当に疲れる作業である。考えてみたら、そんなにがんばってあとがきを書く必要はない。しかも大抵の場合はOpenStackについては書いていない。諸事情により、これから血を吐くまで「科学的な」文章を書く必要にかられているので、それについて、かつての自分への言葉としても、書いてみたいと思う。
そもそも論理的に文章を書いていく、については「語り得ぬことについては、沈黙せねばならない」(ルードヴィヒ・ウィトゲンシュタイン『論理哲学論考』)のであって、書くことを探して書くというよりは、書くべきことを書かれるように、そうあるべくして書かれねば捏造となる。書かれたものだけが世界であり、事実を相手にする科学において、それ以外は書かれるべきではない。従って、卒論は最低40ページ、などというのは大変に勝手な話なのであって、なんでそんな規定があるのやらさっぱり分からない。理系の大学生・大学院生の目下の問題はそのページ数である。ページ数を埋めねばならない。しかし書く物がないのに書くとはこれいかに。
染色体の二重らせん構造の発見はWatsonとCrikによる(Watson, J. D., and F. H. C. Crick. "Molecular structure of nucleic acids: a structure for deoxyribose nucleic acid." JAMA 269.15 (1993): 1966-1967.)ものだが、その論文はたったの1ページである。高校生のときの生物の先生曰くである。例によって卵割の絵がむやみに上手であったその師曰く「論文は短ければ短いほどよい。平易な英語で、端的に書かれているべきである」と。これはなんかもう延々と語り継がれたことである。それにしたって長いもののほうが重用されるのは長ければ長いほど「頑張った」感があるからで、たいした結果でもないのに短いなんてクソだからせめて長くかかせて苦労をさせて……いやはや、それではいつまでたっても論文は書けない。結局、なんとか水増しに水増しを重ねて、味噌汁一杯の浄水に風呂釜一杯の水のごとくに加えて塩素と愛をスパイスに混ぜ込んだ水によく似た何かを量産し、なんかそういうものだ、と思っている。
ところが、幸運にもはっとさせられる言葉に出会ったので、是非ここに書き留めておきたい。たぶん誰も覚えていないし気にしてないだろうからだ。カーネル読書会の一幕において、某大学院生が言った一言である。
「計測にはモデル化が必要で、そうしないと計測自体に意味が無いので」
なるほどさすが東大生である。そういったことを是非教えて欲しかった、と言いたいところだが、もしかしたら教わっていたかもしれないので言わないでおく。
さて、ここから話は長い。科学というものは、問題を明文化し、それを解決する仮説をたて、その仮説を検証し、考察する。これでないものは科学ではない。いやたぶん、遙か大昔「科学」が勃興した時には行動と結果の取得が科学であったんだとは思うが、なんやら知らんが科学はいつしか、その手法と目的が同一になったような感がある。それはまぁどうでもよい。何かやってみた、これは実験である。で、実験の結果は計測される。そして検証が続く。
さて、測る、これが問題だ。出た結果をグラフにする。さて、そのグラフにする際の数字はどのように出したものか考えてみるべきだ。個数?密度?割合?精度?速度?ありとあらゆる数値が出てくるが、注意点は一言に尽きる。すなわち「その数字を出した計測方法は正しいか」である。計測が、目的に沿って正しいこと。計測結果が比較可能であること。本当は、論文ではこれを示さねばならないのだ。なぜなら、これは「自明ではない」からだ。独自の計測方法で独自の手法を評価しても、それは価値を比較できないため、「存在意義」を評価できない。「最高速!!!(当社比)」というよくある残念な感じになってしまう。したがって、検証も考察もできない。すなわちこれは科学ではない。もちろん、論文ではない。
だとして、計測方法の妥当性を論じることは、これまたとんでもなく難しい。まずは、計測対象の適切なモデル化が必要だ。けど、ほんとに難しいので、大抵の場合は、先人達がよく使ってきて、それなりに正しそうだと思われている計測手法が用いられる。だから論文にはあまりことは書かれない。本当は厚く書いてもいいはずである。あまり書かれないが、まったく書かれないことは許されない。ちょろっとは書く必要がある。論文をよく読むと書いてあるはずである。
ここで視点を変えて、ページ数が埋まらないなら、もう開き直ってじゃあ2ページで書けるかってことで、2ページで書いてみるのがよい。2ページといわず、限界まで短く書いてみる。一文にしてしまう、ぐらいの勢いでいい。たぶん書けてしまうんだが、残念だがそれは科学の文章にはなっていない。
たいてい、まずはイントロが足りない。大学入りたてのころの自分に必要な知識をすべてイントロで与える必要がある。いやそれだと新規性が無いって……と思う必要はない。なぜなら、イントロに新規性なんぞ無いし、あってはならない。何だよイントロの新規性って。心配せずとも、教授はイントロを読んで新規性がないと言っているのではないのだ。問題設定はちゃんと書かれているだろうか。それがなぜ問題なのか。他に問題だと言っている人はいるか。仮説は明言されているか。計測対象はモデル化されているか。モデル化とはその計測手法が対象をどのようなものとして見ているかということだ。どのような物を測ろうとしているのか明らかにせねば測りようがない。その実験手法を選んだ理由は書かれているか。理由もなく手法を選んでならない。その理由を書かねばならない。「流行っているから」というのは、実は十分に理由になる。なぜなら、他との比較が可能ということであり、また、流行るということは先行研究でその妥当性が示されているということを意味するからだ。実験する際の入力は妥当か。適当に入力してはいけない。入力としてふさわしいことを書かねばならない。計測方法は妥当か。もう結論なんかどうでもいい。どんだけ少なくてもいい。そんなことより書かないといけないものがある。こういうことを書かないから、「いらないこと書きすぎ」だと言われるのだ。「でも結果がないですもん」と言うが、それは違う。結果なんぞなくてもよい。結果以外が科学されていれば、ほぼ結果は自明であり、誰が実験したって同じ結果になる。これが「再現性」の大切さだ。別に捏造を防止することではない。もう書くことだらけではないか!これで安泰だ。「泣く泣く削る」などという高尚な行動が、ここに至ってついに!論文を書くとは、こうなるともう作業ゲーに近い。あとは、やってないことを今後やることとして、全部Future Workに入れておけば良い。もう実験さえ入れちゃってもいいんじゃないのか。
僕らはOpenStackを結構楽しんだし、今でも書きたい気持ちはある。書き方も板に付いてきた。つまり、書かれるべき事はたくさんあるのだ。書いて欲しいことはあるのに、でも、ネタはない気がする。「真理をおびて始まるものは、しょせんは不可解なものとして終わらなくてはならないのだ」(フランツ・カフカ(1987)『カフカ短編集・プロメテウス』岩波書店)。今は一息ついた。\\
\noindent
代わって檻には一匹の精悍な豹が入れられた。
\noindent
(西岡兄姉(2010)『カフカ・断食芸人』ヴィレッジブックス)
\vspace*{\stretch{1}}
\setstretch{1.0}
\begin{minipage}{0.5\paperwidth}
著者:こじろー・まっきー
挿絵:かとう
発行:2016年8月14日
印刷:POPLS (\url{http://www.inv.co.jp/~popls/})
\end{minipage}
\end{document}