Share
Embed
コンテナ・K8s研修【MIXI 26新卒技術研修】
本スライドは、MIXIの2026年度新卒向け技術研修で使用された資料です。
MIXI 2026新卒技術研修
『コンテナ・K8s研修』
───────────────────────────────
※皆様へのお願い※ 資料・動画・リポジトリのご利用について
───────────────────────────────
公開している資料や動画は、是非、勉強会や社内の研修などにご自由にお使いいただければと思いますが、以下のような場でのご利用はご遠慮ください。
- 受講者から参加費や授業料など金銭を集めるような場での利用
(会場費や飲食費など勉強会の運営に必要な実費を集める場合は問題ありません)
- 出典を削除または改変しての利用
MIXI ENGINEERS PRO
July 22, 2026
Video
Transcript
58 slides
-
自己紹介 • 山本 貴之 ◦ 25 新卒 • ソーシャルベッティング事業本部 ◦
TIPSTAR事業部 > 開発G > システム開発T • Go でサーバー書いたりインフラ保守したりしています • 学生時代はセキュリティキャンプに参加するなど -
自己紹介 • 宗形 翼 ◦ 22 新卒 • デジタルエンターテインメントパブリッシング本部 ◦
グローバルモンスト室 > グローバルモンストエンジニアグループ • Ruby on Rails でサーバーを書いたりしています -
自己紹介 • 松矢 晃太朗 ◦ 22 新卒 • 開発本部 たんぽぽ室
◦ mixi2 バックエンド • 自宅で Kubernetes クラスターを飼っています -
なぜコンテナ技術を学ぶのか • 弊社のプロジェクトに広く利用されているため • 弊社以外でも多くの企業で利用されている技術だから • コンテナ技術を雰囲気ではなく少し踏み込んで知って欲しいから 利用例 • 開発環境に必要なバックエンドサーバーや
DB 等をコマンド一つで用意 • 本番環境へコンテナとしてデプロイ -
コンテナの概要: 軽量で移植性の高いアプリケーション実行環境 • コンテナ とはアプリケーションとその依存関係を一つのパッケージにまとめ独立して実行でき る環境。 • メリット ◦ 複数環境で同じコンテナを動作させることができるので移植性が高い
◦ VM に比べて軽量でインフラリソースを効率的に利用できる • 代表的なコンテナ技術 ◦ Docker ◦ Kubernetes ◦ クラウド (ECS, Cloud Run…) -
VM とコンテナの違い • 同じマシンで動作する他の VM とリソース隔離 • VM ごとに独立して OS
が動作 • 起動に時間がかかる • 他のコンテナとリソース隔離 ◦ 独立したファイルシステム・ネットワーク • 通常の Linux プロセスが動作するので軽量 • プロセスと同程度の起動時間 -
Docker architecture (一部省略) Client Host docker cli Docker deamon (dockerd)
$ docker run $ docker pull $ docker build Registry 管理 イメージ Docker Desktop アプリ等 Host を操作するプログラム • ubuntu • python • golang • my-image1 Docker Hub • 様々な公開イメージ • プライベートイメージ コンテナ 実行中 • ubuntu-1 • my-app-1 停止中 • my-app-2 コンテナの実行・管理を行う Docker 社以外のレジストリの例 Amazon ECR Google Artifact Registry コンテナイメージの保存・管理 -
Docker Desktop for Mac では Linux VM が動作 Linux VM
Client Host docker cli Docker deamon (dockerd) $ docker run $ docker pull $ docker build Registry 管理 イメージ Docker Desktop アプリ等 Host を操作するプログラム • ubuntu • python • golang • my-image1 Docker Hub • 様々な公開イメージ • プライベートイメージ コンテナ 実行中 • ubuntu-1 • my-app-1 停止中 • my-app-2 コンテナの実行・管理を行う Docker 社以外のレジストリの例 Amazon ECR Google Artifact Registry コンテナイメージの保存・管理 -
containerd • 2016年12月14日 Docker 社が Docker Engine のコアコンポーネントであるcontainerd をスピ ンアウト
• Dockerd は内部で containerd を利用 • container image の pull, push、コンテナの実行と監視等が利用できる • lazy pulling や IPFS のような先進的な機能を利用可能 • コンテナの隔離環境の構築や起動には低レベルランタイムを使う • Docker Desktop では低レベルランタイムにデフォルトでは runc を利用 HTTP docker cli gRPC Docker deamon (dockerd) containerd runc コンテナごとに起動されるプロセス コンテナ -
runc • OCI(Open Container Initiative)によるリファレンス実装 • Linux namespace, cgroups 等を利用してコンテナの隔離環境を作成・管理
◦ macOSには上記に相当するものが無いのでコンテナを利用したい場合は Linux を動かす必要がある ◦ Windows には HCS(Host Compute Service)といった上記に相当するものが実装されていてWindows container を起動する際に利用される • containerd は runc 以外の OCI 互換の低レベルランタイムも利用可能 ◦ Kata Containers は軽量 VM を用いて隔離コンテナ環境を用意 ◦ runwasi は WebAssembly をコンテナとして実行できる -
Docker architecture (一部省略) Client Host Registry $ docker run $
docker pull $ docker build docker compose イメージを作成 Buildkit containerd runc イメージ storage network Host を操作するプログラム • ubuntu • python • golang • my-image1 コンテナ 実行中 • ubuntu-1 停止中 • my-app-1 コンテナの実行・管理を行う コンテナの実行 docker cli Docker Desktop アプリ等 Docker Hub Docker deamon (dockerd) • 様々な公開イメージ • プライベートイメージ Docker 社以外のレジストリの例 Amazon ECR Google Artifact Registry コンテナイメージの保存・管理 -
なぜ containerd を直接使わずに Docker Desktop を使うのか? • コンテナを利用するためには Linux を動かす必要がある
◦ macOS 上で Linux を動かす VM を用意する必要がある ◦ Docker Desktop ではそのあたりが利用者に気にしなくても使える仕組みになっている ▪ macOS 上で Docker Desktop を起動する Hypervisor Framework を利用しLinuxを起動してくれる ▪ kernel patches, security fixes は良い感じにdockerが適用している ▪ Git のようにインストールするだけで便利に使えるのが普及した理由だと個人的には思っている -
結局 docker 以外のコンテナって何選べば良いのよ? • ローカル開発 ◦ 基本Docker Desktop ◦ macOSで無料で使うなら
lima + nerdctl + containerd などが便利 ▪ lima は macOS 上で Linux VM を動作 + mac, Linux 間のファイルやポートを自動で共有 ▪ nerdctl は Docker cli と同じようなコマンドで containerd を利用可能な cli • 本番環境 ◦ containerd を利用するのが無難です ▪ Dockerから移行とかになったとき、そもそもDockerはcotainerdを利用しているので 動作に差異が生じない ▪ Docker cliによせたcliが存在する https://github.com/containerd/nerdctl ▪ K8s や Fargate はすでに Docker を使わず直接 containerd を利用している -
コンテナの仕組みをもう少し深掘る • コンテナの仕組みを知る上で重要なポイント2選 ◦ 名前空間(Namespace) ▪ プロセスをグループ化して様々なリソースを隔離する機能 ▪ PID名前空間, ネットワーク名前空間,
マウント名前空間 etc. ◦ cgroup ▪ プロセスをグループ化してリソースの制限などを行う機能 ▪ CPU, メモリ etc. ポイント:名前空間もcgroupもLinuxカーネルの機能で構成されている → コンテナだけ特殊なことをやっているわけではない 試してみよう! -
名前空間(Namespace)の分離を試してみる UTS編 $ sudo unshare -u /bin/bash UTS名前空間を分離してプロセスを起動 # hostname
hogehoge # hostname hogehoge $ hostname ubuntu 環境:ubuntu 24.04 分離した名前空間でホスト名を変更 ホスト側でホスト名を確認 簡単にホスト名が分離されていることが確認できた -
名前空間(Namespace)の分離を試してみる ネットワーク編 $ sudo unshare -n /bin/bash NW名前空間を分離してプロセスを起動 分離した名前空間でNW設定を確認(何も設定していないため何もない) #
ip addr 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 3: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000 link/sit 0.0.0.0 brd 0.0.0.0 4: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000 link/tunnel6 :: brd :: permaddr 4299:c480:7e51:: ホスト側のNW設定を確認(eth0 が設定されている) $ ip addr ...(省略)... 5: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 NWの空間が分離されていることが確認できた -
実際にコンテナに対して cgroup で制限をかけている例を見てみよう $ sudo docker run -d --name mem-limit-test
--memory=”512m” nginx $ tree /sys/fs/cgroup /sys/fs/cgroup ├─ cgroup.controllers ├─ cgroup.events ... ├─ system.slice │ ├─ cgroup.controllers │ ├─ cgroup.events │ ... │ ├── docker-c2c...a09.scope │ │ ├─ cgroup.controllers │ │ ├─ cgroup.events │ │ ... │ │ ├─ memory.max コンテナに対する cgroup の設定が誕生(ファイル管理) $ cat /sys/fs/cgroup/system.slice/docker-c2c...a09.scope/memory.max 536870912 -
Docker Hub からコンテナを選んで実行する 実行するコマンド (step1) $ docker run hello-world Hello
from Docker! と出力するプ ログラムを実行する。 -
実行結果 コマンドの実行結果 $ docker run hello-world Unable to find image
'hello-world:latest' locally latest: Pulling from library/hello-world 7050e35b49f5: Pull complete Digest: sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08e be17735fc0779d0349e889e9 Status: Downloaded newer image for hello-world:latest ローカルにないイメージは Hello from Docker! This message shows that your installation appears to be working correctly. (以下略) ここからコンテナで実行 自動的に pull してくる しているプログラムの出力 -
Docker architecture (一部省略) Client docker cli Host ① ②pull Registory
Docker Hub Docker deamon (dockerd) • $ docker run hello-world 管理 ④出力を転送 イメージ ③起動 Docker Desktop アプリ等 • hello-world コンテナ 実行中 • xxx Docker 社以外のレジストリの例 Amazon ECR Google Container Registry Host を操作するプログラム コンテナの実行・管理を行う コンテナイメージの保存・管理 -
コンテナと HTTP 通信する Python を実行して簡易 web サーバーを起動し、ブラウザからアクセスする。 step 1 ディレクトリで
python -m http.server コマンドを実行すると localhost:8000/index.html にブラウザでアクセスできる これをコンテナで行う。 -
コンテナと HTTP 通信する Python を実行して簡易 web サーバーを起動し、ブラウザからアクセスする。 実行するコマンド (step1) $
docker run -p 8000:8000 -v $PWD:/app python \ python -m http.server オプション -p 8000:8000 コンテナのポート(右)をホストのポート(左)へ公開 -v $PWD:/app ホストの $PWD をコンテナの /app にマウント イメージ python Python イメージ コマンド python Python コマンドを実行する 引数... -m http.server コマンド引数、Python 標準のサーバーを起動 http://localhost:8000/app へアクセスしてみよう -
実行結果 出力 172.17.0.1 - - [07/Apr/2023 04:17:00] "GET /app/HTTP/1.1" 200
- • コンテナとファイルを共有できる • コンテナのポートに通信できる -
コンテナの終了方法 1. Ctrl-C などでプロセスを終了する。 2. docker stop コマンドを使う。 Ctrl+p Ctrl+q
を順番に押すとコンテナは実行したままターミナルに戻れる コマンド $ docker ps CONTAINER ID 888036ffe01a IMAGE python COMMAND "python -m http.serv…" $ docker stop 888036ffe01a (略) (略) NAMES charming_hoover -
Step 2: イメージを作成してアップロードする BuildKit Dockerfile build ファイル • コンテナイメージを作るた めの手順書
• ビルドに必要なファイル push コンテナイメージ レジストリ -
Dockerfile の命令が順番に実行される Dockerfile FROM python:3.12 WORKDIR /app RUN pip install
flask COPY . /app CMD ["python", "main.py"] ベースイメージの指定 このイメージをもとにして新しいイメージを作成する -
イメージ名の指定の仕方 registry-1.docker.io/library/hello-world:latest レジストリのドメイン イメージの名前 イメージのタグを指定することでバージョン等を指定可能 イメージ名を省略可能 • レジストリを省略すると registry-1.docker.io になる
• library/ の場合は library/ を省略可能 • タグを省略すると :latest になる registry-1.docker.io/library/python:latest を省略すると python イメージのタグ -
ベースイメージの選び方 Docker Hub から検索しよう。 Docker Hub へは誰でもアップロードできるので Docker Official Image
を選ぶのが安心 \ Docker Hub 以外もあるよ / -
Dockerfile の命令が順番に実行される Dockerfile FROM python:3.12 WORKDIR /app RUN pip install
flask COPY . /app CMD ["python", "main.py"] ワーキングディレクトリの設定 -
Dockerfile の命令が順番に実行される Dockerfile FROM python:3.12 WORKDIR /app コマンドの実行 RUN pip
install flask ライブラリのインストールなど COPY . /app CMD ["python", "main.py"] -
Dockerfile の命令が順番に実行される Dockerfile FROM python:3.12 WORKDIR /app RUN pip install
flask COPY . /app CMD ["python", "main.py"] ホストのディレクトリからファイルをコピー -
Dockerfile の命令が順番に実行される Dockerfile FROM python:3.12 WORKDIR /app RUN pip install
flask COPY . /app CMD ["python", "main.py"] デフォルトのコマンドを指定 docker run でコマンドを指定しない場合、 このコマンドが実行される -
docker build によってイメージを作成し起動してみる • docker build コマンドでコンテキストと Dockerfile から コンテナイメージを作成
• 引数でビルド対象のディレクトリを指定 • -t オプションでイメージ名を指定できる。 実行するコマンド (step2) $ docker build -t myimage . $ docker run --rm -p 5000:5000 myimage • カレントディレクトリのファイルと Dockerfile でイメージを作成し、 myimage と名前をつけるコマンド -
docker build によってイメージを作成し起動してみる docker が BuildKit を起動してコンテナをビルド 実行結果 [+] Building
3.0s (9/9) FINISHED => [internal] load build definition from Doc => => transferring dockerfile: 37B => [internal] load .dockerignore => => transferring context: 2B => [internal] load metadata for docker.io/li => [1/4] FROM docker.io/library/python:3.11. => [internal] load build context => => transferring context: 59B => CACHED [2/4] WORKDIR /app => [3/4] RUN pip install flask => [4/4] COPY . /app => exporting to image => => exporting layers => => writing image sha256:9144792bebcfff27c => => naming to docker.io/library/myapp 0.0s 0.0s 0.0s 0.0s 0.9s 0.0s 0.0s 0.0s 0.0s 1.9s 0.0s 0.1s 0.1s 0.0s 0.0s ローカルのファイルを転送 Dockerfile の命令を一つずつ実行 -
Dockerfile の命令ごとに差分を増やして新しいイメージを作る 新イメージ CMD の差分 COPY の差分 RUN の差分 ベースイメージ
(python:3.12) Dockerfile ベースイメージの ベースイメージ 変更差分 WORKDIR の差分 変更差分 変更差分 変更差分 変更差分 変更差分 変更差分 変更差分 変更差分 一部省略. docker history [IMAGE] コマンドで履歴が見れる -
Dockerfile を書き換えて本番環境用のイメージを作る Flask で本番環境用のサーバーを実行する一例 1. まず pip install waitress で本番環境用のサーバーをインストールする
2. waitress-serve 'main:app' でサーバーを 8080 ポートに起動する Dockerfile に必要な処理を書き加えてイメージのビルド・実行してみよう。 INFO:waitress:Serving on http://0.0.0.0:8080 と出力されて同じページが見れる ヒント: いきなり Dockerfile を書くのは大変なので先ほど作ったイメージ上で bash を起動して、 コマンドが合っているかどうか一つずつ実行しながら試すと良いです。 $ docker run --rm -it python bash または $ docker run --rm -it <先ほど作ったイメージ名> bash -
Dockerfile のベストプラクティス (余裕がある人向け) • イメージサイズを小さくすることで起動に必要な pull の時間を短縮できる ◦ サイズが小さいベースイメージを使う (python:3.12-slim,
3.12-alpine など) ◦ パッケージマネージャー等のキャッシュを削除する (rm -rf $(pip cache dir) など) ◦ RUN 命令はまとめて書く • Dockerfile はキャッシュが有効になるように書くとビルド時間を短縮できる ◦ RUN 命令で使わないファイルは、あとで COPY 命令で追加する ◦ main.py を変更しても pip install は実行されずにキャッシュが使えるようになる -
書き換えた Dockerfile の例 Dockerfile FROM python:3.12 WORKDIR /app RUN pip
install flask waitress && pip cache purge COPY . /app CMD ["waitress-serve", "main:app"] 実行するコマンド $ docker build -t myimage . $ docker run --rm -p 8080:8080 myimage -
Docker Compose を利用して開発環境に複数のコンテナを起動する • アプリケーションは複数のサービスが協調して動作する ◦ アプリケーションサーバー, データベースサーバーなど • 複数のコンテナを起動する方法を学ぶ
• Docker Compose は開発環境で複数のコンテナを動かすためのツール • 本番環境は複数のサーバーで構成されるので使えない App サーバー DB サーバー -
Docker Compose が管理するもの サービス : コンテナと環境変数などの設定 docker compose up docker-compose
.yaml ボリューム : コンテナ間で共有できる永続的なストレージ ネットワーク : サービス間の通信を管理する仮想的なネット ワーク -
Docker Compose の主なコマンド • docker compose … の形式、昔は docker-compose コマンドだった。
• docker compose up コンテナの起動 • docker compose up -d デタッチモードでコンテナの起動 • docker compose down コンテナの削除 • docker compose build サービスのビルド -
docker-compose.yaml にサービス等の定義を書く step3/docker-compose.yaml (一部省略) services: app: # API サーバー build:
context: python dockerfile: Dockerfile environment: ... ports: - "5000:5000" yaml に3 つのコンテナが起動するように定義されている。 • app (API サーバー) ◦ 動 • web (React の Web アプリ) ◦ web: # React image: node:18 working_dir: '/app' volumes: - ./web/:/app ports: - "3000:3000" environment: REACT_APP_API_URL: 'http://localhost:5… entrypoint: /bin/bash command: - /app/entrypoint.sh db: # データベース image: mysql:8.0 ... python ディレクトリの Dockerfile でビルドしたコンテナ起 node イメージにソースコードのディレクトリをマウントして 開発サーバーを起動 • db (データベースサーバー) ◦ データベースファイルを永続化できるようにマウント -
Docker Compose を利用して複数のコンテナを起動する 実行するコマンド (step3) $ docker compose build $
docker compose up docker compose up はコンテナがない場合は自動で build してく れる。すでにコンテナがある場合はファイルを更新しても自動で build されないので注意。 1 分弱で localhost:3000 にアクセスできる。 • Todo App が動くか確認しよう。 • docker ps コマンドで起動したコンテナを確認しよう。 -
docker compose exec を利用して mysql に接続する 実行するコマンド (step3) $ docker
compose exec -it db mysql -u root -ppassword クエリ実行例 docker compose exec は実行中のコンテナの中でプログラムを実行でき る。 • db はサービスの名前 • -it は対話型のプログラムを動かすときに使うオプション。 • mysql 以降は実行するコマンド MySQL に接続してクエリを入力できる画面が表示されるので、 クエリを実行して DB の内容を確認してみよう。 mysql> SELECT * FROM app.todos; +----+-------+-----------+ | id | task | completed | +----+-------+-----------+ | 31 | test1 | 0 | | 32 | test2 | 0 | +----+-------+-----------+ 2 rows in set (0.01 sec)