加熱式タバコ規制強化見送りについてチャッピーと考える

Filed in チャッピーと話そう

加熱式タバコの規制強化が見送りされる方向との発表がされました。この件についてチャッピーと議論してみようと思う。非常に長いので要点を抜粋しつつ記載する。

今回のテーマ:なぜ加熱式タバコの規制強化は見送りされるのか?

・(私)  加熱式タバコの規制強化が見送られたが理由は何?

(チャッピー) 「規制強化の必要性がない」と判断されたわけではなく、「現時点では科学的根拠が十分ではない」という理由で見送る方向となっています。

1. 受動喫煙による健康影響の科学的エビデンスが限定的
2. 専門委員会でも意見が分かれている
3. 今後も検討は継続

(私) 「危険性が証明されないから規制を見送る」よりも「安全性が証明されないからいったん規制する」が正しい在り方では?

(チャッピー) その考え方には一定の合理性があり、実際に**「予防原則(Precautionary Principle)」**という考え方として国際的にも採用されることがあります。ただし、それが常に最適な原則とは限らず、政策では複数の価値を比較衡量します。

① 予防原則(安全性が証明されるまで規制)
「重大な被害が起こる可能性があるなら、科学的証拠が不十分でも規制する」
② エビデンスベース(危険性が証明されてから規制)
「自由を制限する以上、十分な科学的根拠が必要」

・食品添加物
・農薬
・医薬品
・化学物質
では、販売前にある程度の安全性データが求められます。

一方で、たばこは既に合法な嗜好品であり、新しい医薬品のような「販売前承認制度」の対象ではありません。そのため、「安全性が証明されるまで販売・利用を禁止する」という枠組みにはなっていません。

(私) 規制強化は喫煙の権利に制限を与えるかもしれないが、一方で規制しないことで非喫煙者の権利を侵害しているともいえるのではないか?

(チャッピー) 受動喫煙規制の議論は**「喫煙者の権利 vs 非喫煙者の権利」**という単純な対立ではなく、異なる権利・利益の調整として扱われています。


| 規制を強化する場合 | 規制を強化しない場合 |
| ------------------------------ | ------------------------------------------------- |
| 喫煙者の行動の自由が制限される | 非喫煙者が煙を吸わされる可能性がある |
| 店舗の営業方法の自由が制限される | 安全・健康な環境で過ごす利益が損なわれる可能性がある |



(私) 後々危険性が判明した場合に保障をすることが可能なのか?健康被害があるかを判断不能であれば発生させるリスクを抑えておくべきでは?

(チャッピー) この点は、公衆衛生政策で非常に重視される論点です。あなたの考え方は、「事後救済が困難なら事前予防を重視すべき」というリスク管理の原則に近いものです。

・補償は現実には非常に難しい
・だから予防原則が生まれた

しかし、「安全性が100%証明されるまで禁止」とすると
・新薬
・新しい食品
・新素材
・新技術
などはほとんど世の中に出せなくなります。

そのため、現在の多くの制度ではリスクの大きさに応じて求める証拠の水準を変えるという考え方を採っています。

(私) 新技術の多くは利用者の許可や選択により利用されるが、受動喫煙は利用者本人の選択ではないことが重要。自己選択ではなく、いわば強制される状態であり規制されるべきと考えるがどうか?

(チャッピー) その論点は、公衆衛生・法哲学では非常に重要な区別です。ポイントは、「自分でリスクを引き受ける場合」と「他人からリスクを負わされる場合」は同じではないということです。
法哲学では、ジョン・スチュアート・ミルが提唱した「他者危害原則」がよく引用されます。
「人は自分自身を害する自由は比較的広く認められるが、他人に危害を与える自由は制限できる。」
 「許容されるリスクの水準は、自発的なリスクより低くあるべき」

それでも「直ちに規制すべき」とならない理由としては、政策担当者は次のような点も考慮します。
・加熱式たばこは紙巻きたばこより有害性が低い可能性がある。
・加熱式たばこへの移行が紙巻きたばこの喫煙を減らし、社会全体の健康被害を減らす可能性がある。
・どの程度のリスクがあれば自由を制限できるかという線引きが必要である。

(私) 今回の件は喫煙自体を規制するものではなく喫煙する場所を限定するという規制である。それにより双方の権利を守るというものであり規制しない理由がないのではないか。

(チャッピー) 、受動喫煙防止という目的だけに着目すると、「場所を限定する規制」は比較的バランスの取れた手段ではないかという考え方は十分に成り立ちます。
「吸う自由は残す。ただし他人に影響しない場所で吸ってほしい」「望まない曝露を避ける」

このため、「双方の権利を調整する規制」と評価することはできます。

政策担当者が問題にするのは、「規制が穏やかかどうか」ではなく、「その規制を正当化するだけの根拠があるか」という点です。
つまり、「規制が軽いから認めるべき」というより、「軽い規制であっても、その必要性を示す根拠が求められる」という発想です。

一方で、あなたがここまで一貫して述べている論理は、
1. 規制の対象は「喫煙」ではなく「他者への曝露」である。
2. 非喫煙者はリスクを選択していない。
3. 後から健康被害が判明しても救済は困難である。
4. 規制による喫煙者への制約は「場所の制限」が中心で、全面禁止ではない。

「健康影響について完全な証拠がそろうまで何もしないより、曝露を減らす程度の限定的な規制を導入する方が、権利利益の調整としては合理的ではないか」という結論は、政策論として十分に主張し得ます。

一方で、規制を見送った側は、「加熱式たばこの受動喫煙リスクが紙巻きたばこと同程度であるという科学的根拠がまだ十分でない以上、現時点では紙巻きたばこと同等の場所規制までは正当化しにくい」という立場を取っています。

(私) 規制の見送りは税収への影響によるものと邪推してしまうがどうか?税収のために非喫煙者の健康リスクを取ったと考えているが。

(チャッピー) その可能性を疑いたくなる気持ちは理解できますが、現時点で「税収への影響が理由で見送られた」と断定できる公開された根拠はありません。一方で、「財政や産業への影響が政策判断に全く影響しない」と考えるのも現実的ではありません。

① 建前(公式な理由)
・受動喫煙の健康影響に関するエビデンスが十分ではない
・引き続き検討する

② 現実の政策形成
・国民の健康
・喫煙者の自由
・飲食店などへの影響
・たばこ産業への影響
・税収
・密輸や違法市場への影響

③ 「税収のために健康リスクを取った」と言えるか
・「税収のために健康を犠牲にした」と断定する証拠は現時点ではない

(私) 他に見送りとなった根拠といえるものはないか?

(チャッピー) 現時点で公開されている資料や報道を見る限りでは、税収以外に「見送りの決め手」といえるものとして挙げられているのは、ほぼ次の3点です。

・受動喫煙の長期的健康影響の科学的知見が不十分であること。
・加熱式たばこと紙巻きたばこを同じように扱うだけの科学的根拠が十分ではないこと。
・研究を継続し、現時点では経過措置を維持すること。

つまり、公式には「経済への影響」「税収」「たばこ産業への配慮」は理由として挙げられていません。

公開されている経緯を見ると、少し気になるのは、

・超党派議連は規制強化を提言している。
・厚労省の研究班も「有害物質は発生する」「長期影響は未解明」と整理している。
・にもかかわらず、「現状維持」が選択された。

もう一つ考えられる理由は「ハームリダクション(害の低減)」です。

・加熱式たばこは紙巻きたばこより有害性が低い可能性がある。あまり厳しく規制すると紙巻きたばこへ戻る人が増えるかもしれない。結果として社会全体の健康被害が増えるかもしれない。

(私) 見送り根拠とする「受動喫煙の長期的健康影響の科学的知見が不十分」「加熱式たばこと紙巻きたばこを同じように扱うだけの科学的根拠が十分ではない」「研究を継続」の理由いずれも予防原則を覆すものではないと考える。現状維持とすることで波風を立てない選択をしただけと思えるがどうか?

(チャッピー) 3つの理由はいずれも「規制を見送る理由」ではなく、「限定的な規制を行う理由」になります。

あなたが「波風を立てない選択」と言ったことには、政策学では近い概念があります。それは**現状維持バイアス(status quo bias)**です。
行政では「今のまま」なら責任を問われにくいという傾向があります。そのため、「不確実なら現状維持」という判断は行政では珍しくありません。行政法上の慎重主義とも関係しています。

現状維持にはメリットがあります。
・過剰規制を防ぐ
・経済への影響を避ける
・社会的混乱を避ける

一方でデメリットもあります。もし将来危険性が判明した場合、「あの時点で予防できたのではないか」という批判を受けます。
アスベストや公害問題では、実際にこのような批判がなされました。

公開されている説明を見る限り、厚労省は「なぜ今回は予防原則よりエビデンス要求を優先したのか」を十分には説明していません。
・なぜ食品や化学物質では予防原則を重視する場面があるのに、
・なぜ受動喫煙ではその考え方を採らなかったのか、
という判断基準そのものについての説明は限定的です。

(私) 不可逆な事象が発生する可能性があるなら慎重になるべきではないか。

(チャッピー) 公衆衛生やリスク管理では非常に重要な原則です。
一般に、リスク管理では「慎重になるべきかどうか」は危険性が証明されたかどうかだけではなく、被害の性質によっても左右されます。

・被害が不可逆か(元に戻せないか)
・被害が重大か(生命・健康に関わるか)
・被害が広範囲に及ぶか
・被害が起きた後に救済や補償が困難か
・被害を受ける人が自らリスクを選択していないか

これらの条件が多く当てはまるほど、「証拠が100%そろうまで待つ」のではなく、「一定の予防措置を講じる」ことを支持する議論は強くなります。

ただし、政策判断では一般に「リスクの大きさ = 被害の重大性 × 発生可能性」に加えて、「規制による利益と不利益」も比較衡量します。

(私) 被害の重大性を無限大と考えれば、無限大×100であろうと無限大×1であろうと結果は無限大である。発生可能性や不確実性によらず対策が必要と考えるが。

(チャッピー) 「リスク = 被害の重大性 × 発生可能性」で、「被害の重大性 = ∞(人命・健康の不可逆な損失)」「発生可能性 = 0ではない(あるいは不明)」なら、「∞ × 正の値 = ∞」。したがって少しでも可能性があるなら対策すべきという結論になります。

なぜ現実の政策ではそうしないのか

・自動車は毎年交通死亡事故を起こします。
・航空機もゼロではありません。
・医薬品にも副作用があります。
・建設工事にも死亡事故があります。

「人命や健康を無限大の価値として扱う」と死亡事故がゼロにならない限り

・車は禁止
・飛行機は禁止
・新薬は禁止
という結論になってしまいます。

(私) 車、飛行機、新薬はリスクの代わりに見合う公益となるメリットが存在する。一方で喫煙はあっても私的なメリットだけであり性質が異なる。

(チャッピー) その区別は、政策論では非常に重要な視点です。

| 行為 | 利益を得る人 | リスクを負う人 | 社会的利益 |
| ---- | -------- | -------- | ------ |
| 自動車 | 利用者・社会全体 | 利用者・第三者 | 非常に大きい |
| 飛行機 | 利用者・社会全体 | 利用者・第三者 | 非常に大きい |
| 新薬 | 患者・社会全体 | 患者(同意あり) | 非常に大きい |
| 受動喫煙 | 喫煙者 | 非喫煙者 | 限定的 |

経済学では、受動喫煙は典型的な外部不経済として扱われます。
・つまり、喫煙者は利益(満足感など)を得る。
・しかし、そのコストの一部を非喫煙者が負担する。
という構造です。

このような場合、市場だけでは適切な調整ができないため、
・禁止
・課税
・場所の規制
などの公的介入が正当化されやすくなります。

あなたの主張は一貫して
「利益を受ける者とリスクを負う者が一致していない場合は、より厳しい予防原則を適用すべき」
という原則になっています。
これは経済学の外部不経済や、法学の他者危害原則とも整合する考え方です。


政策担当者は、喫煙者の満足だけではなく、
・紙巻きから加熱式への移行による健康被害低減
・飲食店の営業
・利用者の利便性
なども「社会的利益」として考慮している可能性があります。

一方で、政策担当者はそこに
「喫煙者の行動の自由」「ハームリダクション(紙巻きたばこから加熱式たばこへの移行による健康被害低減)」「営業・経済への影響」
といった要素も比較衡量しています。

(私) それであれば、そのような発表をしないのはなぜか?

(チャッピー) 考えられる理由はいくつかありますが、公開情報だけで断定はできません。

① 健康政策として説明しにくい
「健康より経済を優先したのか」と批判を受けやすい

② 行政として説明しやすい
「危険だから規制します。」「危険性が確認できないので現状維持です。」という説明は比較的説明がしやすい

③ 実際には複数の要素を総合判断している可能性
・科学
・法律
・経済
・政治
・世論
を総合的に判断していることがほとんどです。最終的な記者会見では「最も客観的で説明しやすい理由」だけを前面に出す


今回の説明で最も不足しているのは、「なぜこのケースでは予防原則を採らなかったのか」という政策判断の基準です。


「受動喫煙による加熱式たばこのリスクは現時点では低いと評価している。」
あるいは
「場所規制による不利益の方が現時点では大きい。」
といった比較衡量を明示していれば、政策判断の筋道は見えます。

しかし、実際には「エビデンスが十分でない」という説明にとどまっているため、あなたが一貫して指摘してきた「不確実だからこそ限定的な予防措置を取るべきではないか」という疑問に対する答えになっていません。

(私) 政策判断として予防措置を取らないことがあるというのは十分理解はできる。だが、そのためには説明責任を果たすべきと考えるが現状で説明責任を果たしていると言えるか?

(チャッピー) 私は「十分とは言い難い」と評価します。ただし、それは政策判断の結論が間違っているという意味ではなく、結論に至る理由の説明が十分ではないという意味です。

もし私が政策担当者なら、少なくとも次のような比較衡量を説明します。


加熱式たばこの受動喫煙リスクは現時点では不確実である。

一方で、規制強化には営業や利用者への影響がある。また紙巻きたばこへの回帰を招く可能性も考慮した。これらを比較した結果、現時点では規制よりも研究継続を選択した。

こう説明すれば、国民は
「なるほど、健康だけではなく経済や自由も含めて比較したのだな」
と理解できます。

賛成するかどうかは別として、
判断基準は理解できます。

消費税0%についてチャッピーと考える

Filed in チャッピーと話そう

前回の記事のあと、少し消費税0%について調べてみた。世の中には本当に0%に対応できていないシステムがたくさんあるらしい。正直ちょっとびっくりした。消費税0%の壁は本当にシステム改修に時間がかかるというのが理由である可能性がでてきた。

ある記事では軽減税率を0%に設定すると標準税率の10%が適用されるということが書かれていた。軽減税率が0ではないというのが軽減税率を適用するフラグになっている仕組みなのだと思われる。「税率0に特殊な意味を勝手に持たせただけでは?意味の違う変数を流用するべきではないというのは基本では?」というのが感想であった。寧ろキチンとフラグを新設した方がバグを作り込みにくいのではないか。

また、ある記事では税率で除算をして税額を算出する処理があり0で除算するとエラーになるからと書かれてあった。一定の理解はできるが、こちらも「除算処理の分母が変数である場合には事前に変数値をチェックするのが基本では?」と思う。

なんなら軽減税率の導入時に生活必需品は0%にすべきという議論もあったと記憶している。0%になりえる可能性は容易に想像できたはずだ。その時、考慮されていれば今回のような問題は起きなかったはずである。

ぶっちゃけて言うと、0%にできないのが本当にこういったことが原因なのだとすれば、これは政府の責任というよりもIT業者の能力不足が原因だと思う。

と思ったのでチャッピーと話してみた。

今回のテーマ:なぜ税率0%を想定してないのか?

(私)  世の中には本当に0%を想定していないシステムがあるらしい。0%を想定しないということになってしまう動機として考えられることは?

(チャッピー) 0%を想定しない動機として考えられるもの
1. 「0%」を税率ではなく“課税対象外フラグ”として使っていた
2. 「課税取引なら税率は正の値」という業務前提で作っていた
3. レシート・帳票の印字ルールが「0%=表示しない」前提だった
4. 商品マスタ・税区分マスタが「税率番号」で設計されていて、0%用の意味づけがない
5. インボイス・会計連携が「0%課税売上」を別物として扱えない

(私) 軽減税率の導入時に0%の可能性も容易に想定できたはずだが何故対応されなかった?

(チャッピー) 短く言うと、「想定できたはずなのに対応されなかった」のは、0%の可能性を知らなかったからというより、2019年の軽減税率対応プロジェクトの目的が“将来のあらゆる税率変更に強い設計に作り直すこと”ではなく、“8%と10%を期限までに動かすこと”だったから、と考えるのが自然です。

  中略

(私) 軽減税率導入時の要件は8%と10%に対応することではなく
1.軽減税率を導入する
2. 軽減税率は変更可能
3. 標準税率も変更可能
ではなかったか?

(チャッピー) **本当に必要だった要件は「税率を変更可能にする」だけではなく、「税率ごとに区分して処理できること」**です。
より厳密に言うならこうです。
1. 複数税率を扱えること
標準税率と軽減税率を併存させられる
2. どの取引にどの税率を適用するか判定できること
食品/外食/新聞などの判定
同じ食品でも持ち帰りか外食かで変わる場合への対応
3. 税率ごとに区分して記帳・集計・請求書発行できること
区分経理
税率ごとの請求書・レシート・元帳表示
4. 税率値を固定値ではなく変更可能にしておくこと
標準税率も軽減税率も、将来の改定に備えて設定可能にする

「軽減税率導入時の要件は8%と10%に対応することではなく、軽減税率という制度を導入し、その税率値も変更可能にすることではなかったか?」
というあなたの指摘は、かなり筋が通っています。

(私) あなたの言う要件が満たされているなら今回問題は起きていないのでは?

(チャッピー) はい。かなり率直に言えば、その通りです。
少なくとも私が先ほど挙げたレベルの要件がきちんと満たされ、その趣旨どおりに実装されていたなら、今回の「0%は大改修」という問題は本来かなり起きにくいはずです。

では、なぜ問題が起きているのか
1. 要件が実はそこまで明確に定義されていなかった
2. 要件はそれっぽく書かれていたが、実装がその趣旨を満たしていない
3. POS本体は対応できても、周辺システムが同じ前提で作られていない

私の見立てを一番短く言うとこうです。

もし軽減税率導入時に、本当に「標準税率・軽減税率を任意に変更可能な複数税率制度」として正しく要件化・実装されていたなら、今回の0%で“特別に大きな問題”は起きにくい。
今回問題が起きているということは、どこかでその要件が欠けていたか、文書上はあっても実装がそのレベルに達していなかったか、あるいは周辺システムを含めた全体整合が取れていなかった可能性が高い。

(私) 今対策しなかった場合、今後0%にしたい場合に問題が再浮上すると考えられる。今対策した場合としなかった場合の予測は?

(チャッピー)
今対策しない場合
次回0%議論が出たとき
再び「0%は特別で難しい」が論点化
ベンダー影響調査をやり直す
1%や給付案が再浮上
実施時期が遅れやすい
時限措置の延長・終了でも毎回揉める
中長期の状態
技術負債が残る
政治的にも「0%は難しい」が既成事実化
1%→0%や再減税のたびに追加コスト
今対策する場合
次回0%議論が出たとき
論点は「対象範囲」「開始時期」「期間」に寄る
システムは税ルール変更+テスト中心
1%→0%の移行も比較的素直
期間限定・延長・恒久化にも対応しやすい
中長期の状態
0%を通常税率として扱える
将来の税率変更コストが下がる
政策議論で「レジの壁」が使いにくくなる

今対策する場合、短期的には当然コストがかかります。
POS本体の改修
レシート/帳票確認
会計連携修正
本部集計やBI確認
商品マスタ運用の見直し
0%→8%戻しまで含むテスト

将来また0%をやる可能性が高いなら今対策しないのは、ほぼ確実に将来へ問題を繰り延べるだけです。
しかも次回は、
今回の議論のやり直し
既存システムに積み上がった追加パッチの整理
1%→0%の差分対応
まで加わるので、むしろ複雑になる恐れがあります。

0%は難しいというのが既成事実化するのは凄く嫌ですね。

消費税0%と1%についてチャッピーと話し合う

Filed in チャッピーと話そう

最近はAIの進歩が素晴らしいので人と議論するのは億劫だったりセンシティブな話題についてよくAIと議論する。相手はもっぱらチャッピーである。要約・抜粋して残していこうと思う。

今回のテーマ: 消費税を0%にするか1%にするか問題

(私) 消費税を0%にするとシステム改修に時間を要するという主張は正しいのか?税率1%も0%も消費税の計算が100円×0.01になるか100円×0.00になるかの違いであり、税率を変えるだけで変更可能では。0だからと言って殊さらに特異点となる理由があるのか?

(チャッピー) あなたの疑問はかなり本質的です。
「100円×0.01と100円×0.00の違いなのだから、税率テーブルを書き換えれば終わりでは?」
これは技術的には多くの場合正しいです


ではなぜ「システム改修に時間がかかる」と言われるのか

理由は主に3つです。

1.全国の事業者が対応する必要がある
2.システム改修よりテストと監査が大変
3.税率変更ではなく制度変更まで含めて議論されることがある

特に政治家や官僚が言う「改修」は、単にプログラムの変更ではなく、「全国数百万事業者の運用変更」を含んでいることが多いです。
(私) システム改修と言っているが制度設計の変更に時間がかかるという方が正しい?


(チャッピー) その可能性はかなり高いです。
実際、「システム改修に時間がかかる」という言葉は、政治や行政の議論ではしばしば「制度設計・法改正・運用変更・周知・テストまで含めた全体の対応に時間がかかる」という意味で使われます。

なぜ「システム改修」を前面に出すのか

制度設計の話をすると複雑になります。政治家や官僚は「システム改修に時間がかかる」という分かりやすい表現を使うことがあります。


(私) 税率1%と0%で対立が起こっているのであれば、より正確な説明をすべきではないか。


(チャッピー) その指摘には一定の合理性があります。特に、あなたが指摘したように、「1%なら大丈夫だが0%はシステム上難しい」というニュアンスで受け取られると、技術的には疑問が生じます。多くのシステムでは税率はパラメータであり、1%も0%も数値としては同じように扱えます。したがって「0という値そのものが特異点である」という説明は、少なくとも一般的なシステム論としては説得力が弱いでしょう。

「システム改修が大変」の方が説明しやすいため前面に出ることがあります。しかしその結果、技術に詳しい人からは「本当の論点を隠しているのでは?」という不信感を招きやすくなります。

例えば、「税率を0%にするシステム改修自体は可能だが、法改正や事業者対応に数か月~1年程度必要である」という説明なら、技術面と制度面を区別しています。

(私) 専門的な話を簡略化した結果であったとしても、一度はそれについて触れなければ不誠実と言えないか。

(チャッピー) 簡略化そのものは避けられません。すべての制度的・技術的背景を毎回説明すると話が進まないからです。しかし、あなたが指摘しているのは、簡略化した結果、本来の論点とは異なる印象を与えてしまっているのではないかという問題です。これは単なる説明不足ではなく、説明責任の問題として考えられます。

例えば、「0%はシステム的に難しい」「システム改修に時間がかかる」だけを繰り返し説明し、実際には「制度設計が主な課題」「法改正が主な課題」「一時的な税率変更の運用が主な課題」であることを一切説明しないのであれば、聞き手は「コンピュータの都合で0%にできないのだな」と理解する可能性があります。その理解が実態と異なるなら、説明としては不十分でしょう。

(私) 今回の消費税0%についてシステム改修に時間がかかるという主張の本当の内容について記載されている情報源は存在するか?

(チャッピー) 現時点で公開されている情報を見る限り、「システム改修に時間がかかる」の本当の中身を詳細に説明した一次資料は、あまり公開されていません。というのが実情です。報道で確認できるのは、レジメーカー、POSシステム事業者、小売業界団体へのヒアリングで、「食料品を0%にするには1年程度必要」「0%は初めてなのでテストに時間がかかる」という説明があったことです。

(ここで仮設が3つ提示された)

(私) 制度側の問題であればシステム会社とは関係がないので、システム会社からの見通しが0%と1%で大きく異なる理由が理解できない。仮説1(システムが0を想定していない)については問題点が明らかであり改善に1年もかかるはずがない。仮説2(運用テストに時間がかかる)については1%でも0%でも同程度のテストが必要であり大きな差が出るはずがない。仮説3(対応するエンジニア不足)についても現在のシステムにもメンテナンス要員がいるはずであり、そこまで大きく追加要員が必要になるとは考えられない。いずれも否定可能に思える。

(チャッピー)
もし本当に
1%は短期間
0%は長期間
という見積もりが出ているなら、差が生まれる理由はむしろ「税率」ではなく「税区分」にある可能性があります。

例えば多くの会計システムでは

課税
非課税
免税
不課税
を区別しています。
0%になると、利用者や運用担当者が「これは課税取引なのか?」「非課税なのか?」「免税なのか?」を混同しやすくなります。つまりシステムの計算ではなく、業務ルールや運用設計の問題です。

しかしそれでも疑問は残る
「税率0%」という概念自体は会計システムの世界で既知です。

私が現時点で最も可能性が高いと思うのは、「システム改修」という言葉の中に、技術作業以外の業務変更・運用変更・ベンダー調整・認証作業が大量に含まれているケースです。

ただし、その場合でも、「1%なら数か月、0%なら1年」という差の根拠は依然として不明です。

むしろ現在の問題は、「0%が難しい」という主張そのものよりも、なぜ難しいのかの技術的・業務的内訳が十分公開されていないことにあります。そこが明確にならない限り、「本当に0%だけ特別なのか」という疑問は残り続けるでしょう。


私自身は消費税が0%でも1%でも構わないと思っています。ただ単純に0%だと難しいと言っていることに全く納得できていないです。上記のように制度や運用上の話であればそのように説明して欲しいところです。

春はあけぼの

Filed in 未分類

春は若者 夏は年寄 秋は幼子 冬は現役

出典:総務省統計局

PHPををバージョンアップしたらWordPressがエラーで動かなくなったんだが

Filed in 未分類

このブログはWordPressで動いている。で、WordPressのバージョンアップを久しぶりに行ったところ、ヘルスチェックなるものにPHPが古いから新しくしろというメッセージが出ていた。

ああそうですか、と思い調べたらバージョン5.6を使っておりサポートも終了していた。そりゃダメねと軽い気持ちでバージョンアップをしてからWordPressにアクセスすると「致命的なエラー」などといままで見たことのないメッセージだけが画面に表示されてコンテンツが全く見られない。

再起動しても回復はしない。いつもならスナップショットを取ってから作業するのだが、今回に限ってサボってしまったせいで結構焦ってしまった。

いや、こんな時こそ落ち着かねばと小一時間ほど放置してからログを調べた。

問題点1.

/var/log/httpd/error.logには「PHP Fatal error:Array and string offset access syntax with curly braces is no longer supported」と記録されていた。

Syntax エラーだと。。そんな馬鹿な。。内容は書いてある通りだが、調べてみるとPHPの配列アクセスに{}が使えなくなったとのこと。使っているWordPressのプラグインに{}を使った配列アクセスがあったようだった。幸いエラーが発生した1か所だけ修正するとこのエラーは消えた。

問題点2.

これだけで問題は終わらなかった。

次なるエラーは「PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function~」

調べてみるとWordPressのバージョンアップで置き換わった関数の引数が変わったようで、使っているテーマから渡されている引数の数が少なくてエラーになっているということであった。こんなの直すのしんどいよ。。ということで同じテーマの最新版がGitHubで配布されていたので入手してディレクトリごと置き換えた。これでこの問題は解決して投稿記事を見られる状態にはなった。

問題点3.

だが、それでも問題は終わらなかった。管理用サイトにアクセスするとやはり致命的なエラーが起きた。これは管理用サイトで使っていたプラグインがエラーを起こしていた。Search Regexというプラグインだ。どうやらPHPで静的に宣言されていない関数を静的関数のように呼ぶとエラーになるように厳格にチェックされるようになったようだ。こちらは問題2と違って最新版でも修正されていないという情報を見たのでプラグインそのものを削除して対応した。

こうして何だかんだで復活したのでついでに書き込みしてみた次第であったが、普段PHPを使っていないのでこんなに変更があったのを知らなかった。PHPのシステムを保守している人たちには衝撃だったんだろうなあ。

と書き終えたところで、左上のCount Per Dayの見出しと数字が逆になっていることに気づいた。そのうち直したい。

P.S.

直しましたよっと。でもなんかスタイルシートが読めてない。これまたそのうち直したい。

# pwd
/var/www/html/blog/wp-content/plugins/count-per-day

# diff counter.php.bk counter.php
1446a1447
>                                               echo __($instance[$k.'_name']).':';
1454c1455
<                                               echo '</span>'.__($instance[$k.'_name']).':</li>';
---
>                                               echo '</span></li>';

修正前

                                        if ( ($k == 'show' && is_singular()) || $k != 'show' )
                                        {
                                                $f = str_replace( $this->funcs, $this->cpd_funcs, $k );
                                                echo '<li class="cpd-l">';
                                                echo '<span id="cpd_number_'.$k.'" class="cpd-r">';
                                                // parameters only for special functions
                                                if ( $f == 'getUserPerDay' )
                                                        echo $count_per_day->getUserPerDay($count_per_day->options['dashboard_last_days']);
                                                else if ( $f == 'show' )
                                                        echo $count_per_day->show('', '', false, false);
                                                else
                                                        echo call_user_func( array(&$count_per_day, $f) );
                                                echo '</span>'.__($instance[$k.'_name']).':</li>';
                                        }

修正後

                                        if ( ($k == 'show' && is_singular()) || $k != 'show' )
                                        {
                                                $f = str_replace( $this->funcs, $this->cpd_funcs, $k );
                                                echo '<li class="cpd-l">';
                                                echo '<span id="cpd_number_'.$k.'" class="cpd-r">';
                                                echo __($instance[$k.'_name']).':';
                                                // parameters only for special functions
                                                if ( $f == 'getUserPerDay' )
                                                        echo $count_per_day->getUserPerDay($count_per_day->options['dashboard_last_days']);
                                                else if ( $f == 'show' )
                                                        echo $count_per_day->show('', '', false, false);
                                                else
                                                        echo call_user_func( array(&$count_per_day, $f) );
                                                echo '</span></li>';
                                        }

Gitlabを7から8にしてサブディレクトリで動かす

Filed in コンピュータ, 未分類

いつの間にかGitlabの8が出ていた。
いくつか機能も増えていて良さそうなのでGitlab7からバージョンアップすることにした。
バージョンは8.8.5。

バージョンアップ自体は公式の通りにやれば問題なくできる。

まずyum用のリポジトリができてるそうなのでリポジトリを追加する。

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | bash

そしてインストール

yum install gitlab-ce

これでおしまい。どんどん便利になるな。

サブディレクトリで動かすのもかなり楽にできるようになっている。

設定を変更する。

/etc/gitlab/gitlab.rb
external_url http://server:port
を
external_url http://server:port/gitlab
にする。

これで設定ファイルの編集はおしまい。これまた非常に楽。

あとは以下で再構成する。

gitlab-ctl reconfigure

chefが頑張ってくれていろいろなファイルを更新してくれる。

確認出来た範囲で以下が更新されていた。

/var/opt/gitlab/gitlab-rails/etc/gitlab.yml
/var/opt/gitlab/gitlab-rails/etc/unicorn.rb
/var/opt/gitlab/gitlab-shell/config.yml
/var/opt/gitlab/nginx/conf/girlab-http.conf
/var/opt/gitlab/gitlab-rails/etc/relative_url.rb

特に最後のファイルは新たに作られていた。
以前はapplication.rbに書かれていた内容がここに書かれていた。

あとは再起動すればよい。

gitlab-ctl restart

もう待ってる時間を除けば1分でできるね。

GitLabを7にした。ついでにサブディレクトリにした。

Filed in コンピュータ

役割ごとにサーバを分けるようにサーバ構成の見直しをした。
その一環でGitLabを専用サーバに立て直すことにした。

以前はV6を使っていたがせっかくなのでV7にすることにした。
物凄くインストールが楽になっていた。ありがとう。

ただデフォルトだとルートで動いてしまう。つまり以下でアクセスすることになる。
 http://サーバ/

うちのサーバ構成ではnginxをリバースプロキシにしてURLを見てサーバの振り分けをしてるのでこれでは少し具合がわるい。
 http://サーバ/gitlab
にURLを変更することにする。

まずはインストール。以下のとおりにやればOKだ。
 https://about.gitlab.com/downloads/

インストール時のバージョンは7.2.2だったので適宜読み替えで。

$ curl -O http://downloads-packages.s3.amazonaws.com/centos-7.0.1406/gitlab-7.2.2_omnibus-1.el7.x86_64.rpm
$ yum install openssh-server
$ systemctl enable sshd
$ systemctl start sshd
$ yum install postfix
$ systemctl enable postfix
$ systemctl start postfix
$ rpm -i gitlab-7.2.2_omnibus.1-1.el7.x86_64.rpm
$ vi /etc/gitlab/gitlab.rb
external_url 'http://サーバ'     <= なぜかhttp://をつけてくれてないので付ける
$ gitlab-ctl reconfigure
$ firewall-cmd --permanent --add-service=http
$ systemctl reload firewalld

通常ならこれでインストールと起動は完了。非常に楽だ。V6の時に何時間もかけたのは何だったのだろう。。

  http://サーバ でアクセスするとGitLabのログイン画面が表示されるだろう。

さて、このままだとURLがルートのままなので/gitlabに変更する。
/opt/gitlab/embedded/service/gitlab-rails/config/application.rb
に以下ようなやり方が書いてある。これに従えばOKだ。

$ vi /opt/gitlab/embedded/service/gitlab-rails/config/application.rb

冒頭略
    # Relative url support
    # Uncomment and customize the last line to run in a non-root path
    # WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this.
    # Note that following settings need to be changed for this to work.
    # 1) In your application.rb file: config.relative_url_root = "/gitlab"
    # 2) In your gitlab.yml file: relative_url_root: /gitlab
    # 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"
    # 4) In ../gitlab-shell/config.yml: gitlab_url: "http://127.0.0.1/gitlab"
    # 5) In lib/support/nginx/gitlab : do not use asset gzipping, remove block starting with "location ~ ^/(assets)/"
    #
    # To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production
    #
    config.relative_url_root = "/gitlab"  <= 1)はここのことだからコメントを外す

2) In your gitlab.yml file: relative_url_root: /gitlab

$ vi /var/opt/gitlab/gitlab-rails/etc/gitlab.yml

冒頭略
   relative_url_root: /gitlab  <=ここ

3) In your unicorn.rb: ENV[‘RAILS_RELATIVE_URL_ROOT’] = “/gitlab”

$ vi /var/opt/gitlab/gitlab-rails/etc/unicorn.rb

最後に追加
ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"

4) In ../gitlab-shell/config.yml: gitlab_url: “http://127.0.0.1/gitlab”

$ vi /var/opt/gitlab/gitlab-shell/config.yml

gitlab_rul: "http:/127.0.0.1:8080/gitlab"

5) In lib/support/nginx/gitlab : do not use asset gzipping, remove block starting with “location ~ ^/(assets)/”
はやらなくてもよいようだ。

サービスを再起動

$ gitlab-ctl stop
$ gitlab-ctl start

さて、これで設定は終わり。
ブラウザでhttp://サーバ/gitlabに繋いでみよう。ログイン画面が表示されるはず。
初期ユーザは以下なので、これでログインする。

Username: root
Password: 5iveL!fe

新しいパスワードの設定を求められるので設定すると、ログイン画面に戻されるので新しいパスワードでもう一度ログインする。
ログイン後にユーザ名もrootから変更しておくといいだろう。

以下おまけ。

最新版では直っているようだが7.2.2の時は/assets下が/gitlab下にならないようである。
そのせいでうちのようにリバースプロキシで/gitlabのアクセスだけをgitlabサーバに振り分けしているとassets下が正しく振り分けられずにアイコンが正しく表示されない。
コードを直してしまうというのもあるが面倒なので以下で対処する。

/assets下もgitlabのサーバに振り分けする。
nginxの場合は以下のようにする。

   location /assets {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header Host $host;
        proxy_pass http://<gitlabサーバ>/assets;
  }

CentOS7でPXEサーバを作ってみる

Filed in コンピュータ

サーバ設定系の記事が続きます。

NFSサーバを立ててESXiから使っている訳ですがRAIDを組むためにHDDを追加したことは先の記事のとおり。
拡張性のあまりないPCを使ったので空きベイが足りなかった。
このとき何も考えていなかったのでCD-ROMドライブを外して5インチベイにHDDを2つ挿してしまいました。

そうです。OSをインストールしようとしたときになって「あっ!起動できない」と気づいたわけです。
いったんHDDを外すという手もありますが、せっかくなのでPXEサーバをたててネットワークインストールをすることにしました。

ということでメモ。

始める前にインストールイメージをどっかから用意しておく。
今回はCDを用意した。

必要なものをインストール

$ yum install tftp-server xinetd dhcp syslinux httpd

xinetdの設定をしてtftpを有効にする

/etc/xinetd.d/tftp
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -s -v /var/lib/tftpboot   <= -vつけ。/var/log/messageにログが出るよ。
        disable                 = no                        <= yesから変える。
        per_source              = 11
        cps                     = 100 2
        flags                   = IPv4
}

xinetdを再起動

$ systemctl restart xinetd

DHCPサーバを用意する。
抜粋。

/etc/dhcp/dhcpd.conf

option domain-name "dracula.mydns.jp";   <= ドメイン
option domain-name-servers 192.168.1.1;     <= DNS

subnet 192.168.1.0 netmask 255.255.255.0 {
        filename "/pxeboot/pxelinux.0";          <= PXEの設定。
        range 192.168.1.250 192.168.1.254;      <= 割り当てに使うIP
        option routers 192.168.1.1;
        default-lease-time 600;
        max-lease-time 7200;
}

サービス再起動

$ systemctl restart dhcpd

ここから本番。
ブートローダsyslinuxを準備する。

cp -p /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/pxeboot/
cp -p /usr/share/syslinux/menu.c32   /var/lib/tftpboot/pxeboot/

webサーバの公開ディレクトリに用意したCDをマウント。
webサーバのディレクトリにするのはそのままインストールに使うから。

$ mkdir /var/www/html/centos7
$ mount /dev/cdrom /var/www/html/centos7

インストーラのイメージファイルをPXEブートディレクトリにコピー

$ cp -p /var/www/html/centos7/iso/isolinux/initrd.img /var/lib/tftpboot/pxeboot
$ cp -p /var/www/html/centos7/iso/isolinux/vmlinuz /var/lib/tftpboot/pxeboot

PXEブートの設定ファイル置き場を作成

$ mkdir /var/lib/tftpboot/pxeboot/pxelinux.cfg

PXEブートの設定ファイルを作成

/var/lib/tftpboot/pxeboot/pxelinux.cfg/default

default   menu.c32

label 1
menu label ^1) install centos 7 from pxeserver
kernel vmlinuz
append load initrd=initrd.img inst.repo=http://<pxeサーバ>/centos7/  <= CDマウントして公開したたもの。

inst.repoはhttp://ftp.riken.jp/Linux/centos/7/os/x86_64/など外部を使ってもいいと思う。
それならhttpdいらない。
ただし遅いと思うのでそれは覚悟。

最後にポートを開ける

$ firewall-cmd --permanent --add-port=67/udp  <= Boostrap Protocol Server
$ firewall-cmd --permanent --add-port=68/udp  <= Bootstrap Protocol Client (BOOTP)
$ firewall-cmd --permanent --add-port=69/udp  <= Trivial File Transfer Protocol (TFTP)
$ firewall-cmd --reload

これで準備は完了である。

あとはクライアントを同じセグメントに接続して起動すればいいのだ。
BIOSとかでPXEブートを有効にしてね。

CentOS7でソフトウェアRAID1してみる

Filed in コンピュータ

先日NFSを構築してESXiからマウントするという記事を書いた。
実はNFSはソフトウェアRAID1を組んでいる。

たまにしかやららないので備忘。
あらかじめCentOSを入れてあったPCに後からHDDを2つ増設した。
この2つでRAIDを組むことにする。
NFSで公開する領域だけRAIDにしてます。

まずは必要なものインストール

$ yum install mdadm

追加したHDDのデバイスファイルを確認する

$ fdisk -l

Disk /dev/sda: 500.1 GB, 500107862016 bytes, 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x00045e9d

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sda1   *        2048     1026047      512000   83  Linux
/dev/sda2         1026048   976773119   487873536   8e  Linux LVM

 Disk /dev/sdb: 2000.4 GB, 2000398934016 bytes, 3907029168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト
Disk label type: dos
ディスク識別子: 0x3f51115e

Disk /dev/sdc: 2000.4 GB, 2000398934016 bytes, 3907029168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト
Disk label type: dos
ディスク識別子: 0x17246bea

こんな感じで出力されると思う。まあ/dev/sdb, /dev/sdcのようだ。

それぞれにパーティションを切る。といっても全部で1パーティションにしてしまう。
/dev/sdb,/dev/sdc両方で以下をする。

若干省略気味で。

$ fdisk /dev/sdb

コマンド : n                         <= NEW
コマンドアクション
   e  拡張
   p  基本領域(1-4)
p                                    <= 基本にする
領域番号(1-4): 1                     <= デフォルトで
先頭シリンダ(1-xxx、default 1):1     <= デフォルトで
終点シリンダ(1-xxx  default xxx):xxx <= デフォルトで

コマンド: t                          <= パーティションID変更
select partition:1                   <=1つなので1
16進コード: fd                       <= Linux raid autoのコード

コマンド: w                          <=書き込んで終了

RAIDアレイの作成

$ mdadm --create /dev/md0 --level=1 --raid-device=2 /dev/sd[bc]

ごにょごにょ裏でアレイの構築が始まる

進捗の確認は以下でできる。

$ cat /proc/mdstat

設定ファイルは作ってくれないので作る。
先にARRAY情報を調べておく

$ mdadm --detail --scan
ARRAY /dev/md0 metadata=1.2 name=nfs.dracula.mydns.jp:0 UUID=f98afbd0:563e89b4:8b3ae7ed:21a3790b

で、設定

/etc/mdadm.conf
DEVICE /dev/sdb /dev/sdc
ARRAY /dev/md0 metadata=1.2 name=nfs.dracula.mydns.jp:0 UUID=f98afbd0:563e89b4:8b3ae7ed:21a3790b

ARRAYにはあらかじめ調べたARRAY情報を書く。リダイレクトで追記するとよい。

ファイルシステムを作る。ext4でいいでしょう。

$ mkfs -t ext4 /dev/md0

オートマウントの設定

/etc/fstab
/dev/md0  /マウントポイント  ext4  defaults 1 2 

マウントする

$ mount -a

片方のHDDが壊れても動いてしまうのでmdadmによる監視設定を入れる。

echo MAILADDR 送信先メールアドレス  >> /etc/mdadm.conf

監視機能の実行と自動起動

$ systemctl start mdmonitor
$ systemctl enable mdmonitor

通知のテスト

mdadm --monitor --test --oneshot --scan

ソフトバンクに送ろうとしたら拒否られた。ポートが違うとかなとかの情報が見つかったが
面倒なのでISPにメールすることにして転送対象にした。。。

ESXi単独でNFSをデータストアとして使う

Filed in コンピュータ

VMware Workstationを使ってサーバを立てていたのだが仮想サーバが増えてきたのでESXi(当然無償版)の専用サーバを立ててそこに集約することにした。ただストレージ容量の多いマシンは確保できなかったので長らくお休みになられていたPCにNFSサーバとして復帰してもってESXiからマウントすることにした。

NFSサーバはCentOS7を使って構築した。
ただ、CentOSはデフォルトではNFSv4であり、ESXiはNFSv3までしかサポートしていないのでなかなか接続成功までが大変であった。

まずインストール

$ yum -y nfs-utils rpcbind

次にidmapdの設定をする

/etc/idmapd.conf

[General]
Domain = 自ドメイン

[Mapping]
Nobody-User = nfsnobody
Nobody-Group = nfsnobody

他デフォルトのまま

NFSv3では動的なポートをいくつか使うのでファイアウォールと相性が悪い。
まずはそれを固定してしまう。
/etc/sysconfig/nfsに設定を入れる。MOUNTD_NFS_V3はいるのか分からんけど。。

RPCRQUOTADOPTS="--port ポート番号"
LOCKD_TCPPORT=ポート番号
LOCKD_UDPPORT=ポート番号
STATDARG="--outgoing-port ポート番号 --port ポート番号"
MOUNTD_NFS_V3="yes"

各サービスを立ち上げる、かつサーバ起動時に有効にする。

$ systemctl start nfs-idmap nfs-mountd nfs-server nfs-lock rpcbind
$ systemctl enable nfs-idmap nfs-mountd nfs-server nfs-lock rpcbind

ポートが固定できたか確認する。

$ rpcinfo -p
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100005    2   udp  20048  mountd
    100024    1   udp   2050  status
    100024    1   tcp   2050  status
    100005    3   udp  20048  mountd
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl
    100021    1   udp  32769  nlockmgr
    100021    3   udp  32769  nlockmgr
    100021    4   udp  32769  nlockmgr
    100021    1   tcp  32803  nlockmgr
    100021    3   tcp  32803  nlockmgr
    100021    4   tcp  32803  nlockmgr
    100011    1   udp   2052  rquotad
    100011    2   udp   2052  rquotad
    100011    1   tcp   2052  rquotad
    100011    2   tcp   2052  rquotad

こんな感じで出ると思う。
portmapper, mountd, status, nfs, nlockmgrr, quotadが予定どおりのポート番号ならOK。

次にファイアウォールを設定して固定したポートを開放する。
ポート番号指定で開けてもいいけど、せっかくなのでサービスを定義して開けてみる
/lib/firewalld/servicesに使えるサービスを定義したxmlがある。
nfs, mountd, rpc-bindは定義されているのでそれ以外を定義する。

rquotd, nlockmgr, statdを追加する。
既存のサービスのファイルをコピーして中身を書きかえるのが吉。
shortやdescriptionは好きなものにすればよい。

rquotd.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>rquotad</short>
  <description>define rquotad</description>
  <port protocol="tcp" port="ポート番号"/>
  <port protocol="udp" port="ポート番号"/>
</service>
nlockmgr.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>nlockmgr</short>
  <description>define nlockmgr</description>
  <port protocol="tcp" port="ポート番号"/>
  <port protocol="udp" port="ポート番号"/>
</service>

statdはoutgoing分も纏めて定義してしまう。

statd.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>statd</short>
  <description>define statd</description>
  <port protocol="tcp" port="ポート番号(outgoing)"/>
  <port protocol="udp" port="ポート番号(outgoing)"/>
  <port protocol="tcp" port="ポート番号"/>
  <port protocol="udp" port="ポート番号"/>
</service>

これらと元々定義されているサービスを使ってfirewalldの設定に入れてポートを解放する。

$ firewall-cmd --permanent --add-service=mountd
$ firewall-cmd --permanent --add-service=rpc-bind
$ firewall-cmd --permanent --add-service=nfs
$ firewall-cmd --permanent --add-service=rquotad
$ firewall-cmd --permanent --add-service=nlockmgr
$ firewall-cmd --permanent --add-service=statd
$ firewall-cmd --reload

反映されたかを確認

$ firewall-cmd --list-all

public (default, active)
   interfaces: enp3s0
   sources:
   services: mountd nfs nlockmgr rpc-bind rquotad ssh statd
   ports:
   masquerade: no
   forward-ports:
   icmp-blocks:
   rich rules:

余計なサービスが表示されるなら以下で消しておく。

$ firewall-cmd --permanent --remove-servie=サービス名

これでポートの開放のOK。

後はNFSサーバのexportsを設定。
/exportsを192.168.1.0のネットワークに公開する例

/etc/exports

/exports 192.168.1.0/255.255.255.0(rw,sync)

exportsを反映させて確認する。

$ exportfs -ar
$ exportfs -v

/exports 192.168.1.0/255.255.255.0(rwwdelay,root_squash,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)

最後にSELINUXのポリシーを変えて読み書きを許可する。

$ setsebool -P nfs_export_all_rw on

ここまででNFSサーバは構築できた。

このNFSをESXiからマウントしてデータストアとして使う。
だがここで問題が起こった。。

vSphere Clientを使ってESXiにログインし、データストアの追加を行った。
マウントは無事できた。
しかし、数分経つとNSFが切断されてしまう。数分経つと復旧したりしなかったりで非常に不安定となる。
ESXi5.5 Update1 でそういうバグがあるとの報告があったがESX5.1を使っても改善しなかった。

だが、どうやらvSphere Clientを立ち上げなおした直後は接続できていてしばらく経つと切断するという傾向が見えてきた。そこでESXiにログインしてCLIで操作することにした。

マウントは以下

$ esxcli storage nfs add -H NFSサーバ -s /exports -v データストア名

マウントは無事できた。

状態確認

$ esxcli storage nfs list

Volume Name  Host         Share                    Accessible  Mounted  Read-Only  Hardware Acceleration
-----------  -----------  -----------------------  ----------  -------  ---------  ---------------------
データストア名 NFSサーバ  /exports                      true     true      false  Not Supported

問題ないようだ。
しばらく待ってもAccessibleはtrueのままである。

ここでvSphere Clientを立ち上げてESXiに接続してみる。
するととたんにAccessibleがfalseに切り替わった。
やはりvSphere Clientをつなぐとダメなようだ。

しかたがないのでVMware WorkstationをESXiに繋いでしのぐことにしよう。。

# 2014/10/05 追記
接続が不安定な問題は基本的なミスであった。
クライアントとして使っていたマシンのIPアドレスがNFSサーバとかぶってしまっていた。
ホント恥ずかしいくらい初歩的なミス。
VMwareのバグを疑ってごめんなさい。むしろ一時的にでも良く繋がったなというくらい。