Flatcar と K3s
〜 コンテナを運用する台車 〜
2026-03-30 作成 福島
TOP > tips > flatcar-k3s
[ TIPS | TOYS | OTAKU | LINK | MOVIE | CGI | AvTitle | ConfuTerm | HIST | AnSt | Asob | Shell | GBC | LLM ]

0. 前置き

Flatcar とは、Linux コンテナを動作させる OS です。
他のことは出来ません。

K3s とはコンテナの管理ツールのことで、軽量版の Kubernetes です。
Kubernetes が K8s と呼ばれ 10 文字で表現されるところ、軽量版として 5 文字の K3s と命名されたそうです。

本稿では、前に作成したじゃんけんシステムを Flatcar + K3s で動作させます。

動作環境
サーバ名称ユーザ名サーバ種別IP アドレスメモリ容量ストレージ容量K3s備考
flat-1coreFlatcar (KVM)192.168.122.754GB20GBなしじゃんけんシステムを動作させる
flat-2coreFlatcar (KVM)192.168.122.814GB20GBあり
admwhoRocky Linux release 9.6
(Blue Onyx)
192.168.122.116GB2TB-flat-1, flat-2 のホスト機
ignition 用の構成ファイルを作成する

最初に flat-1 で K3s の無い環境でコンテナを動作させ、
次に flat-2 で K3s のある環境で同じコンテナを動作させます。


1. インストールメディアと管理用公開鍵の用意

1-1. インストールメディアを用意する。
Booting Flatcar Container Linux from an ISODownload Stable ISO から ISO ファイルをダウンロードする。

flatcar_production_iso_image.iso だった。(440,401,920 バイト)
1-2. 管理用公開鍵を用意する。
接続元 Linux で公開鍵を用意する。
未作成なら作成する。

adm$ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ''
(~/.ssh/id_ed25519, id_ed25519.pub が作成される)
Generating public/private ed25519 key pair.
Your identification has been saved in /home/who/.ssh/id_ed25519
Your public key has been saved in /home/who/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:kNBQaMHTvM/H371hDMfhbONK2aa60z3sYCLTLST1ciA who@host
The key's randomart image is:
+--[ED25519 256]--+
|   .+O.          |
|    =.+.         |
|   . .o.  .      |
|      .. . .     |
|       oS.E + =  |
|        o+o* O . |
|        o.+oB+o  |
|         o.*oO=o |
|          oo.+Bo |
+----[SHA256]-----+
1-3. ignition 用の構成ファイルを作成する。
この構成ファイルは OS インストール直後 (= Ignition 前) のタイミングで Flatcar から取り寄せる。
記述するのは、接続元が生成した公開鍵のみ。
この公開鍵だけが Flatcar への接続を許可する。(これを失敗すると誰も操作できない箱になってしまう)

adm$ cat > flat-1.json << EOF
{
  "ignition": { "version": "3.3.0" },
  "passwd": {
    "users": [
      {
        "name": "core",
        "sshAuthorizedKeys": [
          "`cat ~/.ssh/id_ed25519.pub`"
        ]
      }
    ]
  }
}
EOF


2. Flatcar を作成

Flatcar だけでコンテナを動作させる。(K3s なし)

2-1. Flatcar の構築 (1)
2-1-1. Flatcar 用のサーバを準備する。(flat-1)
flatcar_production_iso_image.iso を使ってサーバ flat-1 を作成する。
GUI で作成するときは GentooLinux を指定すると良い。(Flatcar は GentooLinux をベースにしているらしい)

この ISO ファイルはライブ OS となっており、下記 flatcar-install を実施することが Flatcar OS のインストール作業となる。

ここではサーバ名を flat-1 とする。
KVM で作成しており、ホスト OS を RedHat 系 Linux としている。
したがって、親 OS の IP アドレスは 192.168.122.1 となる。
物理サーバに Flatcar を構築する場合は flat-1.json が別の物理サーバからの提供になる。(192.168.1.11 のような)
2-1-2. Flatcar をインストールする。(flat-1)
サーバ flat-1 で操作 (再起動前)

Flatcar のインストーラが起動すると、いきなりプロンプトが表示され、操作可能な状態になる。
(ログイン作業が存在しない)

2-1-2-1. ignition 用の構成ファイルを取り寄せる。(上記 1-3 で作成したファイル)
/home/core/$ scp who@192.168.122.1:./flat-1.json .
(キーボードが US 配列になるので注意: JP 配列は Shift+2 → @, Shift+; → : になる)

ignition が実行する authorized_keys の作成を阻害しないよう scp で作られた ~/.ssh/ を削除する。
(scp で -o UserKnownHostsFile=/dev/null を指定しても .ssh/ は作成されてしまう)
/home/core/$ rm -R .ssh/
2-1-2-2. Flatcar をインストールする。
/home/core/$ ls -l /dev/*da*
(* は Shift + 8)
brw-rw----. 1 root disk 254, 0 Mar 19 10:12 /dev/vda  
インストール先ストレージは  /dev/vda  ということが分かった。

/home/core/$ sudo flatcar-install -d /dev/vda -i flat-1.json
Downloading the signature for https://stable.release.flatcar-linux.net/amd64
-usr/4459.1.4/flatcar_production_image.bin.bz2...
2026-03-19 11:41:21 URL:https://flatcar.cdn.cncf.io/stable/amd64-usr/4459.2.
4/flatcar_production_image.bin.bz2.zig [594/594] -> "/tmp/flat
car-install.FX4sW8p)KK/flatcar_production_image.bin.bz2.zig" [1]
Downloading, writing and verifying flatcar_production_image.bin.bz2...
 …
Installing Ignition config flat-1.json...
Success! Flatcar Countainer Linux stable 4459.2.4 is installed on /dev/vda
 Success! の表示があること
2-1-2-3. 再起動させる。
再起動することにより ignition が実行され、flat-1.json の内容が有効になる。

/home/core/$ sudo reboot

eth0 192.168.122.75 fe80::5054:ff:fe09:37ff     ← 再起動で DHCP によって 75 になった

localhost login:    ← ログインはできない


IP アドレスを確認したら、起動画面はお役御免となる。
2-1-3. 操作可能を確認する。
管理用 Linux から操作する。
Flatcar と公開鍵がインストールされたことにより、すぐにプロンプトが表示される。
(ユーザは core 固定)

adm$ ssh core@192.168.122.75
/home/core/$ vim ~/.ssh/authorized_keys # ← 公開鍵を追加する。(もし必要なら)
/home/core/$ exit
adm$


2-2. Docker イメージの用意

Flatcar では Docker エンジンで利用したユーザ定義ブリッジネットワークが使えない*1ので localhost で動作するように変更する。
この変更により、IP アドレスとポートを起動時に指定できるようにする。
*1半分うそ。K3s を導入すればできるようになる。

2-2-1. プログラムを修正する。
変更点を太字で示した。

2-2-1-1. じゃんけんプレイヤーを修正する。
adm$ vim ./janken/player.py
#!/usr/bin/env python3

from flask import Flask, jsonify
import os, random

MY_NAME = os.getenv('MY_NAME', 'unknown')

# 待ち受けポートを変更可能にする
PORT = os.getenv('PORT', 8080)

app = Flask(__name__)

@app.route('/hand')
def get_hand():
    # ランダムに手を返す
    hand = random.choice([
        'R',    # Rock      グー
        'P',    # Paper     パー
        'S',    # Scissors  チョキ
    ])
    return jsonify({"name": MY_NAME, "hand": hand})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=PORT)
2-2-1-2. MC クライアントを修正する。
adm$ vim ./janken/mc.py
#!/usr/bin/env python3

import requests, time
import os

time.sleep(3) # プレイヤーの起動を待つ

# 接続するホストとポートを変更可能にする
HOST1 = os.getenv('HOST1', '0.0.0.0')
HOST2 = os.getenv('HOST2', '0.0.0.0')
HOST3 = os.getenv('HOST3', '0.0.0.0')
PORT1 = os.getenv('PORT1', 8080)
PORT2 = os.getenv('PORT2', 8080)
PORT3 = os.getenv('PORT3', 8080)

nodes = [
  f'http://{HOST1}:{PORT1}/hand',
  f'http://{HOST2}:{PORT2}/hand',
  f'http://{HOST3}:{PORT3}/hand',
]

results = {'jp1': 0, 'jp2': 0, 'jp3': 0}

def judge(h_a, h_b, h_c):
    hands = set([h_a, h_b, h_c])

    # 3種類出た、または1種類だけなら「あいこ」
    if len(hands) == 3: return []
    if len(hands) == 1: return []

    # 勝敗が決まる場合(2種類のみ存在)
    win_map = {
      'R': 'S',   # グー : チョキ
      'S': 'P',   # チョキ : パー
      'P': 'R',   # パー : グー
    }

    # どの手が勝っているか特定
    h1, h2 = list(hands)
    winner_hand = h1 if win_map[h1] == h2 else h2

    # 勝った手を出した人をリストで返す
    winners = []
    if h_a == winner_hand: winners.append('jp1')
    if h_b == winner_hand: winners.append('jp2')
    if h_c == winner_hand: winners.append('jp3')

    return winners

for i in range(10):

    print(f'Round {i+1: >2}:', end='')
    try:
        # 3人から手を取得
        h_a = requests.get(nodes[0]).json()['hand']
        h_b = requests.get(nodes[1]).json()['hand']
        h_c = requests.get(nodes[2]).json()['hand']

        winners = judge(h_a, h_b, h_c)
        for w in winners:
            results[w] += 1

        print(f'jp1:{h_a}, jp2:{h_b}, jp3:{h_c} -> 勝ち: {winners}')
    except Exception as e:
        print(f'Error: {e}')

print('-----')
print(f'結果: {results}')
2-2-1-3. Docker イメージをビルドする。
adm$ su
adm# docker build --no-cache -t janken-player -f ./janken/player ./janken/
adm# docker build --no-cache -t janken-mc -f ./janken/mc ./janken/
2-2-2. Docker コンテナの動作確認をする。
2-2-2-1. じゃんけんプレイヤーを 3 つ起動する。(localhost に接続する)
adm# docker run -d --rm --init --name jp1 -e MY_NAME=jp1 --net=host -e PORT=8081 janken-player
adm# docker run -d --rm --init --name jp2 -e MY_NAME=jp2 --net=host -e PORT=8082 janken-player
adm# docker run -d --rm --init --name jp3 -e MY_NAME=jp3 --net=host -e PORT=8083 janken-player
2-2-2-2. MC クライアントを実行する。(localhost に接続する)
adm# docker run --rm --init --name jmc \
--net=host -e PORT1=8081 -e PORT2=8082 -e PORT3=8083 janken-mc
Round  1:jp1:S, jp2:P, jp3:S -> 勝ち: ['jp1', 'jp3']  
Round  2:jp1:R, jp2:S, jp3:R -> 勝ち: ['jp1', 'jp3']
Round  3:jp1:R, jp2:R, jp3:R -> 勝ち: []
Round  4:jp1:R, jp2:P, jp3:R -> 勝ち: ['jp2']
Round  5:jp1:S, jp2:S, jp3:P -> 勝ち: ['jp1', 'jp2']
Round  6:jp1:P, jp2:S, jp3:P -> 勝ち: ['jp2']
Round  7:jp1:S, jp2:P, jp3:S -> 勝ち: ['jp1', 'jp3']
Round  8:jp1:R, jp2:S, jp3:P -> 勝ち: []
Round  9:jp1:S, jp2:P, jp3:R -> 勝ち: []
Round 10:jp1:P, jp2:P, jp3:R -> 勝ち: ['jp1', 'jp2']
-----
結果: {'jp1': 5, 'jp2': 4, 'jp3': 3}
2-2-2-3. じゃんけんプレイヤーを 3 つ停止させる。
adm# docker stop jp1 jp2 jp3

adm# exit
adm$


2-3. Flatcar で動作を確認

2-3-1. Docker イメージを Flatcar へ送り込む。
adm$ su
adm# docker save janken-player janken-mc -o janken.tar
adm# chmod 644 janken.tar
adm# exit
adm$ scp janken.tar core@192.168.122.75:.
2-3-2. Flatcar で Docker イメージをロードする。
adm$ ssh core@192.168.122.75
/home/core/$ sudo ctr images import janken.tar
/home/core/$ sudo ctr images list
REF                                    TYPE                DIGEST              SIZE      PLATFORMS   LABELS
docker.io/library/janken-mc:latest     application/…+json sha256:177ec…e835d 120.1 MiB linux/amd64 -
docker.io/library/janken-player:latest application/…+json sha256:a455d…d3dc4 120.6 MiB linux/amd64 -
2-3-3. Flatchar でじゃんけんプレイヤーを 3 つ起動する。(localhost に接続する)
/home/core/$ sudo ctr run -d --net-host --env MY_NAME=jp1 --env PORT=8081 \
docker.io/library/janken-player:latest jp1
/home/core/$ sudo ctr run -d --net-host --env MY_NAME=jp2 --env PORT=8082 \
docker.io/library/janken-player:latest jp2
/home/core/$ sudo ctr run -d --net-host --env MY_NAME=jp3 --env PORT=8083 \
docker.io/library/janken-player:latest jp3

• 各コンテナの起動状況を確認する。
/home/core/$ sudo ctr tasks ls
TASK    PID     STATUS
jp1     4165    RUNNING  
jp2     4222    RUNNING
jp3     4278    RUNNING
• 各コンテナのリッスンポート状況を確認する。
/home/core/$ sudo ss -tulpn | egrep 'pid=4165|pid=4222|pid=4278' | sed 's/ \+/ /g'
tcp LISTEN 0 128 0.0.0.0:8081 0.0.0.0:* users:(("python3",pid=4165,fd=3))
tcp LISTEN 0 128 0.0.0.0:8082 0.0.0.0:* users:(("python3",pid=4222,fd=3))
tcp LISTEN 0 128 0.0.0.0:8083 0.0.0.0:* users:(("python3",pid=4278,fd=3))
2-3-4. Flatcar で MC クライアントを実行する。(localhost に接続する)
/home/core/$ sudo ctr run -t --rm --net-host \
--env PORT1=8081 \
--env PORT2=8082 \
--env PORT3=8083 \
docker.io/library/janken-mc:latest jmc
(jmc は結果を表示するため -t オプションを付加している。-t: TTY)
Round  1:jp1:S, jp2:P, jp3:P -> 勝ち: ['jp1']
Round  2:jp1:R, jp2:S, jp3:S -> 勝ち: ['jp1']
Round  3:jp1:P, jp2:P, jp3:R -> 勝ち: ['jp1', 'jp2']  
Round  4:jp1:R, jp2:P, jp3:S -> 勝ち: []
Round  5:jp1:S, jp2:R, jp3:S -> 勝ち: ['jp2']
Round  6:jp1:R, jp2:P, jp3:P -> 勝ち: ['jp2', 'jp3']
Round  7:jp1:R, jp2:S, jp3:R -> 勝ち: ['jp1', 'jp3']
Round  8:jp1:P, jp2:R, jp3:R -> 勝ち: ['jp1']
Round  9:jp1:R, jp2:R, jp3:S -> 勝ち: ['jp1', 'jp2']
Round 10:jp1:S, jp2:P, jp3:S -> 勝ち: ['jp1', 'jp3']
-----
結果: {'jp1': 7, 'jp2': 4, 'jp3': 3}
2-3-5. じゃんけんプレイヤーを停止させる。
/home/core/$ sudo ctr tasks kill -s SIGKILL jp1
/home/core/$ sudo ctr tasks kill -s SIGKILL jp2
/home/core/$ sudo ctr tasks kill -s SIGKILL jp3
/home/core/$ sudo ctr tasks del jp1 jp2 jp3
/home/core/$ sudo ctr containers del jp1 jp2 jp3


3. Flatcar + K3s を作成

Flatcar と K3s でコンテナを動作させる。

3-1. K3s 用 json を作成する。
上記 2 で作成した Flatcar 用の JSON は単純だったが、K3s では複雑な JSON が必要になる。
複雑な JSON の作成を楽にするため Butane(ブタン) というトランスレータを使用し、YAML → JSON の変換を行う。

3-1-1. butane をインストールする。
adm$ su
adm# dnf install -y epel-release
adm# dnf install -y butane
adm# exit
adm$ butane --version
3-1-2. K3s 用の YAML を作成する。
adm$ cat > ./flat-2.yaml << EOF
variant: flatcar
version: 1.1.0
passwd:
  users:
    - name: core
      ssh_authorized_keys:
        - "`cat ~/.ssh/id_ed25519.pub`"
storage:
  directories:
    - path: /opt/bin
      mode: 0755
  files:
    - path: /home/core/.bashrc
      mode: 0644
      append:
        - inline: |
            export PATH=\$PATH:/opt/bin
            export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
systemd:
  units:
    - name: k3s-install.service
      enabled: true
      contents: |
        [Unit]
        Description=Download K3s Binary
        ConditionPathExists=!/opt/bin/k3s
        After=network-online.target
        Wants=network-online.target
        [Service]
        Type=oneshot
        ExecStart=/usr/bin/curl -Lo /opt/bin/k3s \
          https://github.com/k3s-io/k3s/releases/download/v1.31.0+k3s1/k3s
        ExecStart=/usr/bin/chmod +x /opt/bin/k3s
        ExecStart=/usr/bin/ln -sf /opt/bin/k3s /opt/bin/kubectl
        RemainAfterExit=yes
        [Install]
        WantedBy=multi-user.target
    - name: k3s.service
      enabled: true
      contents: |
        [Unit]
        Description=Lightweight Kubernetes
        After=k3s-install.service network-online.target
        [Service]
        Type=notify
        ExecStart=/opt/bin/k3s \
          server --write-kubeconfig-mode 644
        Restart=always
        Delegate=yes
        KillMode=process
        [Install]
        WantedBy=multi-user.target
EOF
3-1-3. YAML から json を生成する。
adm$ butane --pretty --strict < flat-2.yaml > flat-2.json

adm$ cat flat-2.json | fold -60
{
  "ignition": {
    "version": "3.4.0"
  },
  "passwd": {
    "users": [
      {
        "name": "core",
        "sshAuthorizedKeys": [
          "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ4AsDdiAeb4C
  …続く…


3-2. Flatcar の構築 (2)

3-2-1. Flatcar 用のサーバを準備する。(flat-2)
flatcar_production_iso_image.iso を使ってサーバ flat-2 を作成する。

ここではサーバ名を flat-2 とする。
親 OS の IP アドレスは 192.168.122.1 とする。
物理サーバに Flatcar を構築する場合は flat-2.json が別の物理サーバからの提供になる。
3-2-2. Flatcar をインストールする。(flat-2)
サーバ flat-2 で操作 (再起動前)

Flatcar のインストーラが起動すると、いきなりプロンプトが表示され、操作可能な状態になる。
(ログイン作業が存在しない)

3-2-2-1. ignition 用の構成ファイルを取り寄せる。(上記 3-1-3 で作成したファイル)
/home/core/$ scp who@192.168.122.1:./flat-2.json .
(キーボードが US 配列になるので注意: JP 配列は Shift+2 → @, Shift+; → : になる)

ignition が実行する authorized_keys の作成を阻害しないよう scp で作られた ~/.ssh/ を削除する。
(scp で -o UserKnownHostsFile=/dev/null を指定しても .ssh/ は作成されてしまう)
/home/core/$ rm -R .ssh/
3-2-2-2. Flatcar をインストールする。
/home/core/$ ls -l /dev/*da*
(* は Shift + 8)
brw-rw----. 1 root disk 254, 0 Mar 22 11:12 /dev/vda  
インストール先ストレージは  /dev/vda  ということが分かった。

/home/core/$ sudo flatcar-install -d /dev/vda -i flat-2.json
Downloading the signature for https://stable.release.flatcar-linux.net/amd64
-usr/4459.1.4/flatcar_production_image.bin.bz2...
2026-03-22 11:33:06 URL:https://flatcar.cdn.cncf.io/stable/amd64-usr/4459.2.
4/flatcar_production_image.bin.bz2.zig [594/594] -> "/tmp/flat
car-install.FX4sW8p)KK/flatcar_production_image.bin.bz2.zig" [1]
Downloading, writing and verifying flatcar_production_image.bin.bz2...
 …
Installing Ignition config flat-1.json...
Success! Flatcar Countainer Linux stable 4459.2.4 is installed on /dev/vda
 Success! の表示があること
3-2-2-3. 再起動させる。
再起動することにより ignition が実行され、flat-2.json の内容が有効になる。

/home/core/$ sudo reboot

eth0 192.168.122.81 fe80::5054:ff:fe47:d7f3     ← 再起動で DHCP によって 81 になった

localhost login:    ← ログインはできない


IP アドレスを確認したら、起動画面はお役御免となる。
3-2-3. 操作可能を確認する。
管理用 Linux から操作する。
Flatcar と公開鍵がインストールされたことにより、すぐにプロンプトが表示される。
(ユーザは core 固定)

K3s のダウンロードに時間がかかるため、kubectl が使えるようになるのは最初の再起動から 5 分程度の経過後になる。

adm$ ssh core@192.168.122.81
/home/core/$ vim ~/.ssh/authorized_keys # ← 公開鍵を追加する。(もし必要なら)

/home/core/$ sleep 300 ; kubectl get nodes
NAME        STATUS   ROLES                  AGE    VERSION
localhost   Ready    control-plane,master   5m3s   v1.31.0+k3s1

/home/core/$ exit
adm$


3-3. K3s でコンテナを実行

ステートフルな pod を実行する。

3-3-1. Docker イメージを Flatcar へ送り込む。
adm$ scp janken.tar core@192.168.122.81:.
adm$ ssh core@192.168.122.81

/home/core/$ sudo k3s ctr -n k8s.io images import janken.tar
/home/core/$ sudo k3s ctr -n k8s.io images list
REF                                    TYPE                DIGEST              SIZE      PLATFORMS   LABELS
docker.io/library/janken-mc:latest     application/…+json sha256:177ec…e835d 120.1 MiB linux/amd64 -
docker.io/library/janken-player:latest application/…+json sha256:a455d…d3dc4 120.6 MiB linux/amd64 -
3-3-2. じゃんけんシステムをデプロイする YAML を作成する。
/home/core/$ cat > janken-dep.yaml << EOF
# プレイヤー jp1 + I/F
apiVersion: v1
kind: Pod
metadata:
  name: jp1
  labels: { app: janken, player: jp1 } # 識別用ラベル  
spec:
  containers:
  - name: player
    image: docker.io/library/janken-player:latest
    imagePullPolicy: Never
    env: [{ name: MY_NAME, value: "jp1"}]
---
apiVersion: v1
kind: Service
metadata:
  name: jp1
spec:
  selector:
    player: jp1 # Pod 名: jp1
  ports: [{ port: 8080 }]
---
# プレイヤー jp2 + I/F
apiVersion: v1
kind: Pod
metadata:
  name: jp2
  labels: { app: janken, player: jp2 }
spec:
  containers:
  - name: player
    image: docker.io/library/janken-player:latest
    imagePullPolicy: Never
    env: [{ name: MY_NAME, value: "jp2"}]
---
apiVersion: v1
kind: Service
metadata:
  name: jp2
spec:
  selector:
    player: jp2 # Pod 名: jp2
  ports: [{ port: 8080 }]
---
# プレイヤー jp3 + I/F
apiVersion: v1
kind: Pod
metadata:
  name: jp3
  labels: { app: janken, player: jp3 }
spec:
  containers:
  - name: player
    image: docker.io/library/janken-player:latest
    imagePullPolicy: Never
    env: [{ name: MY_NAME, value: "jp3"}]
---
apiVersion: v1
kind: Service
metadata:
  name: jp3
spec:
  selector:
    player: jp3 # Pod 名: jp3
  ports: [{ port: 8080 }]
---
# MC クライアント
apiVersion: batch/v1
kind: Job
metadata:
  name: jmc # Job 名: jmc
spec:
  template:
    spec:
      containers:
      - name: mc-container
        image: docker.io/library/janken-mc:latest
        imagePullPolicy: Never
        env:
        - name: HOST1
          value: "jp1"
        - name: HOST2
          value: "jp2"
        - name: HOST3
          value: "jp3"
      restartPolicy: Never
EOF
3-3-3. K3s でじゃんけんシステムを実行する。
最初の起動は 30 秒程度必要。二度目はキャッシュが効くので早い。

/home/core/$ kubectl apply -f janken-dep.yaml
pod/jp1 created
service/jp1 created
pod/jp2 created
service/jp2 created
pod/jp3 created
service/jp3 created
job.batch/jmc created
/home/core/$ kubectl get job
NAME   STATUS     COMPLETIONS   DURATION   AGE
jmc    Complete   1/1           10s        24s
/home/core/$ kubectl get pod
NAME        READY   STATUS      RESTARTS   AGE
jmc-qx8jw   0/1     Completed   0          35s
jp1         1/1     Running     0          35s
jp2         1/1     Running     0          35s
jp3         1/1     Running     0          35s
jmc は jmc-qx8jw として実行されたあとに終了している。
/home/core/$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
jp1          ClusterIP   10.43.233.70    <none>        8080/TCP   46s
jp2          ClusterIP   10.43.248.231   <none>        8080/TCP   46s
jp3          ClusterIP   10.43.105.162   <none>        8080/TCP   46s
kubernetes   ClusterIP   10.43.0.1       <none>        443/TCP    11m
kubernetes は K3s のデフォルトで追加されるネットワーク。
3-3-4. 結果を表示する。
K3s のコンテナは直接に TTY を扱えないため、ログを参照する。

/home/core/$ kubectl logs job/jmc
Round  1:jp1:S, jp2:R, jp3:S -> 勝ち: ['jp2']
Round  2:jp1:P, jp2:P, jp3:R -> 勝ち: ['jp1', 'jp2']
Round  3:jp1:R, jp2:R, jp3:R -> 勝ち: []
Round  4:jp1:P, jp2:S, jp3:R -> 勝ち: []
Round  5:jp1:S, jp2:R, jp3:S -> 勝ち: ['jp2']
Round  6:jp1:R, jp2:R, jp3:P -> 勝ち: ['jp3']
Round  7:jp1:R, jp2:S, jp3:S -> 勝ち: ['jp1']
Round  8:jp1:S, jp2:S, jp3:S -> 勝ち: []
Round  9:jp1:P, jp2:S, jp3:R -> 勝ち: []
Round 10:jp1:S, jp2:R, jp3:R -> 勝ち: ['jp2', 'jp3']
-----
結果: {'jp1': 2, 'jp2': 4, 'jp3': 2}
3-3-5. コンテナを削除する。
/home/core/$ kubectl delete job jmc
/home/core/$ kubectl delete pod jp1 jp2 jp3 --grace-period=0 --force
/home/core/$ kubectl delete svc jp1 jp2 jp3

jmc だけをやり直すには以下を実行する。
/home/core/$ kubectl apply -f janken-dep.yaml ; sleep 10 ; kubectl logs job/jmc ; sleep 10 ; kubectl delete job jmc