立式の順序と変数の代入

はじめに

最初に断っておきますが、私は教育者でもなければ学者でもありません。 その辺にいる普通の一般人です。 非常にセンシティブな話題ではあることは理解していますが、計算の本質を問うのに面白い議題だと思ったので投稿します。

掛け算の順序問題

よく議論になる問題はこうです。

全部で8チーム参加する大会があります。1チームは6人です。大会の参加者は全部で何人ですか?

これを「8×6=48」と記述すると✖にされて、「6×8=48」と書くと○にされるという問題です。

一見すると2つの記述は等価に見えます。 しかし、等価ではないと主張する人々もいるため、しばしばSNSで論争になります。 それも一方が一方をバカにした主張しかしないため、相互理解は一向に見込めません。

私としては、「計算とは何か」を問わずして、天下り的に積の交換法則を根拠に等価だと主張するほうがバカに見えるのですが、他人が作り上げた世界を鵜吞みにして自分が正しいと主張する人は一定数いるようです。

少し抽象的な難しい話になりますが、できるだけ専門用語を使わずに掛け算に順序を求める理由の一つについて述べますので、お付き合いいただけると幸いです。(素人分野で専門用語を使ってお叱りを受けたくない)

本題

(文体が変わります)

abbaは文字が並んでいる順番が違うから異なるものと言うと多くの人は納得してくれると思う。 では、異なる2つを同一視する=という記号を導入して、ab = baという規則を導入することを考えよう。 ここで、=には次の3つの関係が成り立つことにする。

  1. どんな記号xについても、必ずx = xとなる。(反射律)
  2. 左辺と右辺は無条件に入れ替え可能。 x = y ⇒ y = x (対称律)
  3. 第三者を介して等号で結ばれるなら、2つは等しい。x = z, y = z ⇒ x = y(推移律)

重要なのはab = baは人間が存在する前から存在する超人的なものではなく、人間が恣意的に導入する一つの規則に過ぎないということだ。 例えば、aとbに自然数集合の元としてa<=8, b<=6と代入した場合、86 = 68となる。(ただし、<=の記号は代入を表す。) 8668を十進数と解釈すると「八十六と六十八は等号で結べないだろう」なんて思うかもしれないが、そもそも私は86を並べて書いただけで十進数を書いたわけではないため、 「はちろく」と「ろくはち」を同一視するというルールを私が今作ったことを意味する。

ここで、xという記号を導入して、xmxnを「nをm倍する」という計算操作と定義しよう。 「m倍」の定義はまだ行っていないが、ここでは自然数の掛け算ということにしておいてほしい。 すると、x8x6 = 48, x6x8 = 48であるから、推移律よりx8x6 = x6x8という"交換法則"があると確かめられる。 この法則を、xmxn = xnxmと書こう。

掛け算に順序はない派

「掛け算に順序はない派」の認識は次の通りである。 mは1チーム当たりの人数を表す集合Mの元で、Mは自然数と同じ記号を使ってM = {1, 2, 3, ...}と表記される。 nはチーム数を表す集合Nの元で、Nもまた自然数と同じ記号を使ってN = {1, 2, 3, ...}と表記される。 mnだけでは冒頭の総参加者人数を求めることができないで、先ほど導入したxを使って、xmxnというように解を記述する。

xmxnm<=6, n<=8という具体的な元を代入すると、

xmxn[m<=6, n<=8] → x6x8 = 48

ところで、xmxnには交換法則があったので解をこのように書いてもよい。

xnxm[m<=6, n<=8] → x8x6 = 48

よって、解答にx6x8 = 48と書こうがx8x6 = 48と書こうが、どちらも○にされるべきである、という主張だ。

掛け算に順序はある派

「掛け算に順序はある派」の感覚を噛み砕いてみよう。

xnxmに対して、m<=8, n<=6と代入する数字を入れ替えてみると、

xnxm[m<=8, n<=6] → x6x8 = 48

さて、mn68という同じ記号を使って具体例を表記する(代入する)が、mnと書き分けてある通り、私はわざと2つを区別した記号で表している。 集合論的には要素の記号が全く同じなのでM = Nであるが、mnは区別されるものである。 要素を同じ記号を使って書いただけで、集合と対応する現実の概念は同じではない。 つまり、m<=8, n<=6m<=6, n<=8は代入の意味が異なるのである。

ところが、算数の解答に書かれるのはx6x8 = 48だけなので、児童がxmxn[m<=6, n<=8]xnxm[m<=8, n<=6]のどちらを意図して書いたのか見分けがつかない。 そこで「採点者がxmxn[m<=6, n<=8]xnxm[m<=8, n<=6]の違いを目に見えるものにしよう」としているのが「掛け算の順序」ということなのだろう。

式は思考を抽象化して具象を覆い隠すからこそ、式になる前の思考を可視化し、早期に指導者自身が指導の誤りに気付けるというのが重要ではないだろうか。

自分の世界を構築し、抽象的な世界に投影する

実際、MNを次のように定義すれば、立式の順序は一般人にも馴染みのあるものになる。

  • Mは「かけられる数」を表す集合で、自然数と同じ記号を使ってM = {1, 2, 3, ...}と表記する。
  • Nは「かける数」を表す集合で、演算子と自然数記号が一続きになった記号を使って、N = {×1, ×2, ×3, ...}と表記する。

MNの二項演算のそれぞれの元を並べたmnと定義し、m<=6, n<=×8を代入すれば、

mn[m<=6, n<=×8] → 6×8

となり、自然数同士の積と同じ形をしている。 ここで、mn = nmという交換法則を認めると、

nm[m<=6, n<=×8] → ×86

とあまり見慣れない形になって不自然さを覚えるだろう。 不自然さの感覚に従って、mn = nmは成り立たないと決める。 これは唯一神が決めた不変の法則ではなく、私が今決めた規則である。 不自然でないと感じる人が多いのならば淘汰されるべきルールだろう。

ここが一番難しいところだと思うが、MNただの自然数の集合ではないMNでは集合の"次元"(物理学のLTMAのことではない)が違う。 私は紙に書かれた数字の話をしているのではない。問題文に書かれた現実に対応する対象について議論しているのである。 その証拠に、問題文の68は次元が違うので6 + 8 = 14という加法が現実世界で意味をなさない。 言い換えると、6 + 8 = 14という演算は算数の中に存在するのに6 + 8 = 14という式に対応するものが現実にはない。

では、問題文に出てきた2つの数字86はどっちがmでどっちがnだろうか? 文章題で児童に問いたいのはこのmnの区別がついているかということである。 問題文の意味合いから6 ∈ M, ×8 ∈ Nであるから、mn[m<=8, n<=×6] → 8×6は✖にせざるを得ない。 「そんなものmnを入れ替えたら同じじゃないか」と言われそうだが、その通り記号のmnは本質では無い。 本質は児童が、mnに対応する世界を児童自身の中に構築できているかである。

もちろん、積の二項演算子×は交換法則が成り立つから8×6 = 6×8であるが、私が上に書いた8×6のは算術式ではないことに注意してほしい。 8という記号と×6という記号を連続して並べただけだ。 ×6は化学でいうatom(それ以上分割できないもの)であり、x6のように分割することはできない。

ここで、"たまたま"(わざと同じになるように記号を選んだわけだが)記号列が同じなので私が定義した6×8を算術式6×8と定義しよう。 すると、記号が私の独自世界から代数学の記号の世界に変換されて積の交換法則が保証され、6×8 = 8×6 = 48となるわけだ。

「掛け算の順序」の目的は児童にルールを遵守させることではない。 児童と採点者の明示的なコミュニケーションのためである(つまり教育側の都合ではある)。 「問題文に出てきた数字をただ並べたのではなく、現実世界を数理の世界に写像する能力を身に着けましたよ。」と採点者に伝えるためのプロトコルなのだ。 私が書いたように式と代入を明示的に示せばこんなプロトコルは必要ないのだが、児童はまだ抽象的な記述ができないのを忘れてはならない。

おわりに

文章に書かれた問題を抽象世界に投影し、計算結果を現実世界に取り出して解釈するという行為は非常に高度な能力である。 圏の変換を具体例だけを通じて私たちは自然と習得するのだ。 そして、この能力は工学をやるのならば息をするようにできなければならない。 もちろん全ての人が工学をできなくても良いが、資源も人も足りないこの日本では原理を理解してモノに変換できる工学屋さんがどうしても必要だ。

私は最近、作れる人がいなくなり、売れるものがなくなり、外貨を獲得できなくなった未来を想像するのが怖い。 もう既にITの分野ではお隣の国にモノを売れないのは言うまでもない。 ここで、ITとはアニメやゲームなどのサブカルチャーも含む。 体力(予算と人材)がないので、大規模言語モデルは外国から買ってくるしかないのである。 現役世代ではなくなり、自分では住む場所を選べなくなったとき、私は何を思うだろうか。

別に小学校の算数に掛け算の順序を導入することを支持するわけではないが、

  • 具象と抽象を行き来できる人材を多くすること(算数ごときで躓く人を多く出さないこと)
  • 表面上の計算規則やハリボテの便利公式だけ覚えて、基礎から導出する能力を軽視する人を量産しないこと
  • 子どもの「なぜ?」に対して、「そういうものだから」と返さないこと

といったことをお願い申し上げたい。

え?掛け算の順序に固執している人はそんな難しいこと考えてないよって?そんな~

近況報告

近況報告がてら駄文を投稿。

現在の身分

半年ほど前、就活と修論で精神的に追い詰めながらも無事(?)に修士課程を修了して工学の学位を取得した。その後、民間企業に就職して仕事というよりは遊んでいる。

というのも私に課せられたミッションは既存事業を保守・運用することではなく、5年後、10年後の事業のために早期からキャッチアップすることなので、ドキュメントを読み解いてデモを作ったり、本を読んだり、技術記事を執筆したりして過ごしている。まあ要はこのブログでやっているようなことを仕事でやっているだけだ。タイトルにもある通り、この行為は私にとっては「遊び」みたいなものなので労働というよりは人生の無駄な時間の過ごし方を社会的に価値あるものに変えた感じだ。

もし私の経験から就活生にアドバイスするとすれば、「人や事業規模が大きい大手企業も行くのも良いが、ある程度の制度が整った中小企業に行くのも悪くないよ」と言いたい。組織の目標は「いかに構成員の視線を統一して共通の目的のために動けるか」であるが、構成員が増えて組織が増えれば触れるほど複雑性が指数関数的に増加して管理が難しくなる。管理が難しくなると能力が高い人には煩わしいようなルールを作ってでも全体を管理するようになる。もしあなたがバカが間違えないように定めた意味不明なルールに縛られない「自由」を求めるのならば、面接の際にその価値観を語るのが良いだろう。もちろん、「自由」に伴う「責任」についても言及してね。

在学中に指導教員におしゃべりを申し込んだことがあるのだが、その時に印象に残った言葉がある。「大学にはバカがいなくて非常に働きやすい。一度会議をすれば各々が目的達成のために動いてくれる。企業にいたときはメンバーの価値観を統一するために何度も何度も会議をして煩わしかった。」その教員は大手電機メーカーで十数年の研究開発を経験したのち、90年代の事業撤退の流れの前に大学教授にキャリアを変更して、出身大学とは無縁の大学で長を務めるという世渡り上手な方だった。

組織の人数が増えると大数の法則により組織内の平均は母集団の平均に近づく。ここで母集団は世界全体、日本全体など良い感じに読み解いてほしい。基本的には組織が大きくなると組織全体の平均能力が下がっていくと考えてよい。能力は平均的だが、リソースが文字通り桁違いなので大きな事業・大きな利益をもたらせるという仕組みだ。もし自分の能力に自信があるならば、小さな組織で小さな1を作り続けることはマジョリティに合わせなくて良いという点で悪い選択肢ではないだろう。とはいえ通信の世界に革新を起こすIOWNや次世代計算機である量子コンピュータハードウェアに興味がないかと言えば嘘にはなるが、 そのような最先端事業に関われるかは今後の私の人脈形成次第だろう。

先ほどから「バカ」という言葉が出てきて印象悪く見えているかもしれないので一言付け加えておこう。私の言う「バカ」とは「自身の世界以外を受け入れられない無教養な者」のことだ。信じたものを決して疑わずに他人に強要したり、期待したものが返ってこないだけで激昂したり、知らないことを知らないままでゴリ押ししたりするような人のことを「バカ」と呼んでいる。我々は完ぺきではない。能力が足りなくてできないことが何かしらある。重要なのは足りない能力に対して、環境に責任転嫁したり、感情に身を任せて周囲を困らせたり、仲間を作って「できない方が当たり前!」みたいな勘違いも甚だしい主張をしないことだ。知識や技術がないことを「バカ」だと言っているのではない。後天的に獲得できる世界の見方・捉え方が未熟な者を「バカ」と呼んでいる。もし私が組織作りをするとしたら、この手の「バカ」は徹底的に弾くだろう。

現在の技術収集

最近は計算機オタクとしてRISC-VやCPUといったハードウェアに近い部分の技術収集に努めている。というのも近年、日本の半導体産業の活性化の大きな流れがあり、上手くいけば私のようなリソースが少ない技術者でも特定の用途に最適化された独自のハードウェアを設計して製造できる可能性があるからだ。昔の記事で情報系出身者にはソフトウェアの分野で勝てないから計算機のハードウェア分野で頑張ると述べたことがあるが、図らずもその将来像通りに事が進んでいるのである。大学では量子力学固体物理学・量子統計→半導体の基本動作原理・材料特性→半導体バイス製造プロセス→計算機アーキテクチャ→(OS)→高級プログラミング言語アルゴリズム→アプリケーション開発・システム開発と計算機科学の下から上まで抑えているのでどのレイヤーの仕事でも構わなかったが、まさかソフトウェアの会社に就職してハードウェアを触るとはという感じではある。

プログラミング言語についてはRustと関数型プログラミングのキャッチアップに努めている。C++でのシステム開発の経験を通して、どう考えてもC++という研究開発用・計算機オタク向け言語で堅牢なプログラムを書くのは不可能だと感じたためRustで安全なプログラムを書きたいなという所存。Rustで開発したい分野は実行速度と安全性が求められるロボティクス周りのアプリケーションである。関数型プログラミングは一時期流行したが、正直なところHaskellScalaのような具体的なプログラミング言語にはあまり興味がない。なぜなら手続き型に慣れた私にはあまりにコードが読みにくいからだ。ただ安定したバグの少ないプログラムを書くという点で関数型プログラミングのエッセンスを取り入れたく、モナドやその背景にある圏論の学習を行っている。

AIと私たち

2025年になってAIは飛躍的に進化した。もはやLLMや画像生成AIの動作原理をキャッチアップできていないため私もまたディープラーニングをベースとした確率最適化モデルのことを「AI」と呼ぶような立場になってしまった。特に2025年初期にブームをおこした「vibe coding」はその後、専用エディタやCLIエージェントの登場によってソフトウェアの開発環境を大きく変えた。私の体験談ではAIの出力したコードは知識が重複していたり(DRY原則の違反)、既存のコードベースに対応できなかったり(コンテキストの品質・量の限界)、メンテナンス性の悪化(問題が起きたときは人間が根本原因を取り除く必要がある)のため実務には使えないが、アーキテクチャを議論したりコーディングの哲学を議論をするには面白い相手だなと感じている。

今後の知的労働者はAIに取って代わられると懸念されているが、その心配はまだ必要ないだろう。これはAIが正確・不正確といった性能の問題ではない。真の知的労働とは既存の世界を疑い、真実を粘り強く探求し、飽くなき好奇心を満たすことだからだ。既存の知識で構成された大規模言語モデルには原理的にできない仕事なのである。真実を探求する過程で新しいアイデアが生まれ、コーディングや描画といった単純知的労働が生まれる。まあAIの性能の向上に期待や不安感を膨らますのは大いに構わないが、私たちに必要なのはAIの自信に満ちた躊躇いのない主張に屈服せず、信念をもって物事に向き合うということだ( I Don’t Want to Be a Programmer Anymore: When AI Confidence Outshines Human Judgment)。

SNSでは「AIにコーディングさせて開発した」「AIにリファクタリングさせて品質を向上させた」など魅力的な”楽な道”が大きな声で宣伝されているが、そういった誘惑に惑わされずコーディングという具体的な作業と向き合いながらソフトウェア開発の本質を見抜く力をこれからの若い人には養ってもらいたいなと思う。昔Google検索が世に広まってきたころ「今までの知識を詰め込む教育はもう不要だ!だってGoogleで検索すれば答えが出てくるから!」という意見があった。経験があればこんなもの嘘だというのがすぐにわかるが、経験のない若い学生の中には信じてしまった人もいるだろう。嘘だという理由は人と議論するときはスマホやPCでGoogle検索などしないからだ。会話や会議は相手とのリアルタイムな相互作用だ。わからない単語が頻繁に出てくるからと言って毎回Google検索に打ち込むわけにはいかないだろう?人との会話の中で使えるのはGoogle検索やAIの出力結果ではなく、それまでに自分に詰め込んだ知識と経験だけなのだ。最近インターネットの知らない人と話す機会が多いのだが、何も見ずにすらすらと知識が出てくる人はやはり話していて楽しい。「群って何ですか?」と聞いたら何も見ずに群の3つの性質を答えてくれる。「環って何ですか?」って聞いたらその場で群との違いを含めて説明してくれる。それはその人がそれほど知的である何よりの証拠だ。逆に何も持っていない人との会話は本当につまらない。下ネタを言うか有名なインターネットミームを言うか、ゲーム・アニメその他の話ばっかりだ。世の中の大半の人はそんな人ばっかりなのでGoogleで得られる知識は不要論はある意味正解だったかもしれない。中身のある会話をするためにはどうしたって何も見ずに使える知識が必要なのだ。

もう一つ機械に頼ってはいけない能力がある。英語だ。技術者の世界・学問の世界・専門家の世界において英語はデファクトスタンダードな言語だ。機械翻訳を通さずとも読む・書く・聞く・話すの能力は必須の能力である。ネイティブ日本人にとって英語というのは文法の違い・口の使い方の違いが大きいため習得にはかなりの苦痛が伴う。だがそれを乗り越えると世界が変わる。世界中のあらゆる文書を読むことができ、韓国人とも中国人とも意思疎通ができる。機械翻訳は確かに素晴らしい。全く知らない国へ観光するときなどはなおさらだ。だが機械翻訳Google検索・AI検索と同じだということを心得ておいてほしい。それがあるからって能力の獲得を怠ると同じレベルの人としか関わることはできない。機械翻訳は飽くまで補助として使い、全面的に依存しないようにしよう。

おわりに

長々と書き連ねてしまったせいで貴重な日曜日を潰してしまった。基本的に今後このブログが活発になることはないだろう。技術的な話は仕事上難しいし、カードゲームや狩りゲームはもうやっていないので書きようがない。ここ数年LoLに手を出していて、かなりノウハウ(ミクロ・マクロ・ビルド)が溜まってはいるのだが、あまりアウトプットする気がない。その情報が界隈には価値があるのは理解できるが私の貴重な時間を使ってまでLoL界隈に貢献したい・認められたいみたいなモチベーションがないのだ。ということでこのブログはたまにこんな感じにエッセイを投稿するぐらいになるだろう。それでは皆様また来年お会いしましょう。

Be careful when you use pipx in GitHub Actions!

I ran tests with wrong Python version when I used pipx to install Hatch for a testing environment in GitHub Actions.

GitHub Actions でテスト環境作成用の Hatch を pipx でインストールしてたら、誤ったバージョンの Python でテストをしていたので、その失敗について記す。

GitHub Actions workflow file with the problem

---
name: Test

on:
  push:
    branches:
      - master
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version:
          - "3.10"
          - "3.11"
          - "3.12"
      fail-fast: false
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install hatch
        run: pipx install hatch
      - name: Lint
        run: hatch run lint:lint
      - name: Check type
        run: hatch run check-type
      - name: Test
        run: hatch run test --cov-report=xml
      - name: Upload coverage
        uses: codecov/codecov-action@v3

The problem is the following part.

- name: Install hatch
  run: pipx install hatch

By default, pipx uses the default Python in the runner, which is ubuntu-latest in this case. It doesn't use Python setup by actions/setup-python@v4.

Therefore, your virtual environment created with Hatch has the same Python version as the runner's.

The matrix strategy of python-version is totally useless, and your CI testing is no longer functional.

デフォルトで pipx はランナー(この場合ではubuntu-latest)の Python を使用する。 これはactions/setup-python@v4でセットアップした Python とは異なる。 そのため、Hatch で作成した仮想環境はランナーの Python と同じバージョンになる。 これは、ストラテジーで設定したpython-versionは全くの無意味であり、CI テストはもはや機能していないことを意味する。

To fix this, add PIPX_DEFAULT_PYTHON environment variable to the step as the following shows.

これを修正するには下記が示すように環境変数PIPX_DEFAULT_PYTHONをそのステップに加える。

- name: Install hatch
  run: pipx install hatch
  env:
    PIPX_DEFAULT_PYTHON: python

Refrection

I hadn't noticed the problem for 6 months because I didn't fully check the result of CI. As a result, all the tests during the period had come to nothing.

Fortunately, nothing wrong has happened with my project. I feel scared when I think an huge modification could be demanded.

6 ヵ月間もその問題に気づけなかったのは CI の結果を十分にチェックしていなかったからだ。 その結果、その間の全てのテストは無に帰してしまった。 幸運にもプロジェクトには何も悪いことは起こっていない。 莫大な修正が発生しえたことを考えると恐ろしくなる。

みんなも CI の結果には注意を配ろう!

Snapパッケージの問題

Snappyを使って落としてきたソフトで発生した種々の問題についてまとめる。

Snapとは

Ubuntuディストリビューションを開発・管理しているCanonical社が開発している パッケージマネージャである。

snapcraft.io

snapというコマンドを通してLinuxシステムを一元管理できるのが売りである。

しかしながら、問題が発生した際に調査してみると、それが「Snap版のパッケージだから」ということが多い。

Snap版パッケージは系を楽に管理できる点で優秀だが、こういった微妙な使いづらさが目立つ。

VSCode

お馴染みのMicrosoft社製コードエディタである。

$ sudo snap install code

日本語入力ができない

Google日本語入力オープンソースMozcIBus環境で使用しているが、VSCodeで何故か日本語に切り替えることができない。

ソースコードを書くときには問題ないが、日本語のドキュメントを書くこともあるので困る。

解決法は公式セットアップに従い、aptリポジトリを追加してしまうことである。

code.visualstudio.com

もしかしたらIBusのほうに問題があって、Fcitxを使えば問題ないかもしれない。

Docker

お馴染みのコンテナ仮想化アプリケーションである。

$ sudo snap install docker

Buildxが存在しない

デフォルトで含まれていないので、別途バイナリを落としてきて/usr/local/lib/docker/cli-pluginsに配置する必要がある(ぱっと見た感じではSnap版のbuildxパッケージは存在しない)。 バージョン管理がひたすら面倒くさい。

DEBパッケージならデフォルトで搭載されている。

docs.docker.com

解決策は公式のインストールスクリプトを使ってインストールすることである。

$ curl -fsSL https://get.docker.com | bash

DNS problem of Job on Kubernetes

KubernetesでWeb APIを叩くジョブを作ろうとしたらDNS名前解決で3日詰まったのでメモ。

問題の概要

以下のマニフェストのようなJobをKubernetesで動かしたところ、curl: (6) Could not resolve Host: github.com; Name or service not knownのエラーが出てジョブを完了できなかった。

apiVersion: batch/v1
kind: Job
metadata:
  name: curl-test
spec:
  parallelism: 1
  completions: 1
  backoffLimit: 3
  ttlSecondsAfterFinished: 100
  template:
    spec:
      containers:
        - name: curl
          image: curlimages/curl:7.85.0
          command:
            - curl
            - -I
            - https://github.com
      restartPolicy: Never

実行環境

漁った資料

Kubernetes + curl + DNS をキーワードにGoogleして以下の資料を得たが、解決には至らなかった。

トラブルシューティング

/etc/resolv.confの確認

$ kubectl run curl --image=curlimages/curl:7.85.0 -- cat /etc/resolv.conf
pod/curl created
$ kubeclt logs curl
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.152.183.10
options ndots:5

optionsndotsの値が原因でalpineベースのイメージには意図しない動作があったらしいが、結論から言えばcurlimages/curl:7.85.0では解決済みのようである。

curlimages/curlのダウングレード

Issueで述べられていた7.77.0まで落としてみたが直らず。

別の人がビルドしたcurlイメージも試してみたが手ごたえなし。

デプロイしたPod内からcurl

以下のマニフェストを適用して、kubectl execcurlを叩いた。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: curl-test
spec:
  selector:
    matchLabels:
      app: curl-test
  template:
    metadata:
      labels:
        app: curl-test
    spec:
      containers:
        - name: curl-test
          image: curlimages/curl:7.85.0
          resources:
            limits:
              memory: "128Mi"
              cpu: "500m"
          command:
            - sleep
            - "3600"
$ kubectl exec -it curl-test-<id> -- curl -I https://github.com
HTTP/2 200
server: GitHub.com
date: Tue, 04 Oct 2022 15:14:23 GMT
content-type: text/html; charset=utf-8
...

なぜか通り困惑。 Job特有のバクかと当たりをつけGoogleするが、それらしき情報は見当たらず。 未報告のバグだとしても、どのレイヤー(MicroK8s? Kubernetes? CoreDNS? cURL?)で起こっているバグか特定できない限りコントリビュートできないので半ば諦め状態。

解決編

同様にしばらくスリープするcurlコンテナのJobを作って、kubectl execcurlを叩いたら通ったり通らなかったりしたので以下のJobを作成。

apiVersion: batch/v1
kind: Job
metadata:
  name: curl-test
spec:
  parallelism: 1
  completions: 1
  backoffLimit: 3
  ttlSecondsAfterFinished: 100
  template:
    spec:
      containers:
        - name: curl
          image: curlimages/curl:7.85.0
          command:
            - sh
            - -c
            - |
              while (true); do
                curl -I https://github.com
                if [ ! $? -eq 6 ]; then  # Exit code 6 is the DNS error
                  break
                fi
                sleep 1
              done 
      restartPolicy: Never

無事JobがComplete状態になってトラブルシューティング終了。

どうやらいろいろデプロイしたせいか、システムに負荷がかかっていてDNS周りのリソース割り当てに1分以上かかっていたらしい。

反省

未知のバグじゃなくて良かったけど、Googleするときはできるだけ新しい情報を漁らないと既に解決済みの問題の解決法まで試すことになって良くないと思った。

今回の問題の本質は、新技術に触ったときにありがちな「実は単純な問題をGoogleした結果、複雑な問題まで深追いしてしまう」ってやつ。 触りたての時期は知識も技量も浅いから手あたり次第解決策を試すしかないんだけど、頭を冷やして系の挙動をじっくり観察するというのも大切ね。

Markdown Cheet Sheet

はじめに

Markdown 記法とは?

文書を簡潔かつスタイリッシュに記述できる記法。

元々は HTML を楽に記述するために考案されたため、ほとんどのウェブサービス(GitHub, Slack, ブログサービス)では Markdown で書かれた文書をそれぞれの CSS を使ってスタイリッシュな HTML に変換して表示してくれる。

Markdown の良い所

  1. 構造化された文書を素早く書ける
  2. 特別なソフトは必要ない
  3. 普遍的な技術であるため、どんな場でも使える
  4. 内容とスタイルが分離されている
  5. HTML を埋め込める

Word のようなソフトを使って見た目と内容を同時に意識しながら編集する必要はない。 1つのソースから複数の見た目の文書を生成できる。

この文書もまた Markdown で書かれている。

チートシート

改行・パラグラフ

改行は
半角スペース二つです。  
ここは次の文章です。

次のパラグラフです。

改行は 半角スペース二つです。
ここは次の文章です。

次のパラグラフです。

ヘッディング

# ヘッダー 1

## ヘッダー 2

### ヘッダー 3

#### ヘッダー 4

##### ヘッダー 5

ヘッダー 1

ヘッダー 2

ヘッダー 3

ヘッダー 4

ヘッダー 5

斜体・太字

_斜体_

斜体

**太字**

太字

**_斜体太字_**

斜体太字

箇条書き

- いちご
- りんご
- メロン

* アジ
* サバ
* マグロ
  • いちご
  • りんご
  • メロン

  • アジ

  • サバ
  • マグロ
1. コーヒー
2. 牛乳
3. お茶
  1. コーヒー
  2. 牛乳
  3. お茶

リンク

詳しくは[こちら](https://daringfireball.net/projects/markdown/syntax)を参照してください。

URL のみ: <https://daringfireball.net/projects/markdown/syntax>

ID を使って参照: [Google][google]

[google]: https://google.com

詳しくはこちらを参照してください。

URL のみ: https://daringfireball.net/projects/markdown/syntax

ID を使って参照: Google

画像

![ひまわり畑の写真](https://free-materials.com/adm/wp-content/uploads/2016/07/51a7ce858aa46d0165c6dfdfa4684f72-750x499.jpg)

ひまわり畑の写真

大きさを調整したい時などは<img>タグを使う。

<img src="https://free-materials.com/adm/wp-content/uploads/2016/07/51a7ce858aa46d0165c6dfdfa4684f72-750x499.jpg" alt="ひまわり畑の写真" width="50%" ></img>

ひまわり畑の写真

| 番号 | 数学 | 国語 | 英語 |
| ---- | ---- | ---- | ---- |
| 1    | 67   | 49   | 24   |
| 2    | 43   | 68   | 92   |
| 3    | 89   | 45   | 62   |
番号 数学 国語 英語
1 67 49 24
2 43 68 92
3 89 45 62

区切り線

---

ブロック引用

> この部分は引用です。
>
> - Markdown もそのまま適用されます。
>   > ネストすることもできます。

この部分は引用です。

  • Markdown もそのまま適用されます。

    ネストすることもできます。

コード・コードブロック

テキストを標準出力に表示するには`echo <text>`を実行してください。

テキストを標準出力に表示するにはecho <text>を実行してください。

````markdown

write your code here

````

write your code here

シンタックスハイライトも使用可能。

````markdown

import math

def cosh(x):
    return (math.exp(x) + math.exp(-x)) / 2

````

import math

def cosh(x):
    return (math.exp(x) + math.exp(-x)) / 2

LaTeX

レンダラーがあれば LaTeXレンダリングできる。 よく使われるレンダラーはMathJaxKaTeXである。

文章に埋め込む場合は$a = 1$のように`$`で囲みます。

$$
\begin{align}
y &= A_1 \exp{(-\frac{t}{\tau_1})} + A_2 \exp{(-\frac{t}{\tau_2})} \\
\frac{dy}{dt} &= - \frac{A_1}{\tau_1} \exp{(-\frac{t}{\tau_1})} - \frac{A_2}{\tau_2} \exp{(-\frac{t}{\tau_2})}
\end{align}
$$

文章に埋め込む場合は$a = 1$のように$で囲みます。

$$ \begin{align} y &= A_1 \exp{(-\frac{t}{\tau_1})} + A_2 \exp{(-\frac{t}{\tau_2})} \\ \frac{dy}{dt} &= - \frac{A_1}{\tau_1} \exp{(-\frac{t}{\tau_1})} - \frac{A_2}{\tau_2} \exp{(-\frac{t}{\tau_2})} \end{align} $$

VSCode 拡張機能

Markdown All in One

yzhang.markdown-all-in-one

全部入りの拡張機能(keyboard shortcut, ToC, preview and more)

Markdown PDF

yzane.markdown-pdf

Markdown を PDF に変換

Markdown Emoji

bierner.markdown-emoji

preview で絵文字構文をサポート

参考

daringfireball.net (accessed on 2022/09/02)

www.markdownguide.org (accessed on 2022/09/02)

HTTP proxy on Debian

Linux Debianディストリビューション(主な対象は Ubuntu)における主要なコマンドの HTTP プロキシ設定についてのメモ。

apt

設定ファイル: /etc/environment

http_proxy=<scheme>://<host>:<port>
https_proxy=<scheme>://<host>:<port>

設定ファイル: /etc/apt/conf.d/proxy.conf

Aquire::http::Proxy "<scheme>://<host>:<port>";
Aquire::https::Proxy "<scheme>://<host>:<port>";

manpages.debian.org (accessed on 2022/09/02) manpages.debian.org (accessed on 2022/09/02)

git

設定ファイル: /etc/environment

http_proxy=<scheme>://<host>:<port>
https_proxy=<scheme>://<host>:<port>

コマンドから変更する場合,

$ git config --global http.proxy <scheme>://<host>:<port>

git-scm.com (accessed on 2022/09/02)

https://gist.github.com/evantoli/f8c23a37eb3558ab8765 (accessed on 2022/09/02)

docker

ホスト用 (イメージをプルする場合など)

設定ファイル: /etc/environment

HTTP_PROXY=<scheme>://<host>:<port>
HTTPS_PROXY=<scheme>://<host>:<port>

Then, restart dockerd.

コンテナ用 (イメージをビルドする場合など)

設定ファイル: ~/.docker/config.json

{
 "proxies":
 {
   "default":
   {
     "httpProxy": "<scheme>://<host>:<port>",
     "httpsProxy": "<scheme>://<host>:<port>"
     "noProxy": "127.0.0.1"
   }
 }
}

docs.docker.com (accessed on 2022/09/02) docs.docker.com (accessed on 2022/09/02)

kubernetes(microk8s)

設定ファイル: /etc/environment

http_proxy=<scheme>://<host>:<port>
https_proxy=<scheme>://<host>:<port>
no_proxy=127.0.0.1,192.168.0.0/24,10.0.0.0/8
HTTP_PROXY=<scheme>://<host>:<port>
HTTPS_PROXY=<scheme>://<host>:<port>
NO_PROXY=127.0.0.1,192.168.0.0/24,10.0.0.0/8

microk8s.io (accessed on 2022/09/02)

curl

設定ファイル: /etc/environment

http_proxy=<scheme>://<host>:<port>
https_proxy=<scheme>://<host>:<port>

everything.curl.dev (accessed on 2022/09/02)

wget

設定ファイル: /etc/environment

http_proxy=<scheme>://<host>:<port>
https_proxy=<scheme>://<host>:<port>

www.gnu.org (accessed on 2022/09/02)