Share
Embed
コンテナ研修【MIXI 23新卒技術研修】
23新卒技術研修で実施しコンテナ研修の講義資料です。
動画:https://youtu.be/Dk0isJQ6a80
資料の続き(Kubernetes編):
https://speakerdeck.com/mixi_engineers/2023-container-training-number-02-kubernetes
※ハンズオン環境は提供していないので、ハンズオンを実際に試していただくことはできません。
資料の利用について
公開している資料は勉強会や企業の研修などで自由にご利用頂いて大丈夫ですが、以下の形での利用だけご遠慮ください。
・受講者から参加費や授業料などを集める形での利用(会場費や飲食費など勉強会運営に必要な実費を集めるのは問題ありません)
・出典を削除または改変しての利用
MIXI ENGINEERS PRO
April 25, 2023
Transcript
54 slides
-
自己紹介 • 浅野 大我 ◦ 20 新卒 ◦ などと言いつつ
2018〜2019 までインターンや内定者バイトをしていました • デジタルエンターテインメント事業本部 モンストゲーム運営部 モンストサーバ2グループサーバチーム ◦ 兼務: セキュリティ室 • モンストの開発や運用をしていたりします • https://twitter.com/atpons -
自己紹介 • 宗形 翼 ◦ 22 新卒 • 開発本部 CTO 室
SRE グループ • Go を書いたりしています -
Docker 等インストール確認 • gcloud auth list ◦ 会社のメールアドレスが出てくるか確認 • docker
version ◦ Server: Docker Desktop 4.18.0 がでてくる • GitHub リポジトリにアクセスできる ◦ • gcloud auth configure-docker && git pull asia.gcr.io/hr-mixi/container-training-2023/test-example -
なぜコンテナ技術を学ぶのか • 弊社のプロジェクトに広く利用されているため • 弊社以外でも多くの企業で利用されている技術だから • コンテナ技術を雰囲気ではなく少し踏み込んで知って欲しいから 利用例 • 開発環境に必要なバックエンドサーバーや
DB 等をコマンド一つで用意 • 本番環境へコンテナとしてデプロイ -
コンテナの概要: 軽量で移植性の高いアプリケーション実行環境 • コンテナとはアプリケーションとその依存関係を一つのパッケージにまとめ独立して実行でき る環境。 • メリット ◦ 複数環境で同じコンテナを動作させることができるので移植性が高い ◦
VM に比べて軽量でインフラリソースを効率的に利用できる • 代表的なコンテナ技術 ◦ Docker ◦ Kubernetes ◦ クラウド (ECS, Cloud Run…) -
VM とコンテナの違い • 同じマシンで動作する他の VM とリソース隔離 • VM ごとに独立して OS
が動作 • 起動に時間がかかる • 他のコンテナとリソース隔離 ◦ 独立したファイルシステム・ネットワーク • 通常の Linux プロセスが動作するので軽量 • プロセスと同程度の起動時間 -
Docker architecture (一部省略) Client Host Registry Host を操作するプログラム コンテナの実行・管理を行う コンテナイメージの保存・管理
$ docker run $ docker pull $ docker build Docker Desktop アプリ等 Docker deamon (dockerd) • ubuntu • python • golang • my-image1 docker cli イメージ 実行中 • ubuntu-1 • my-app-1 停止中 • my-app-2 コンテナ • 様々な公開イメージ • プライベートイメージ Docker Hub Amazon ECR Docker 社以外のレジストリの例 Google Container Registry 管理 -
Docker Desktop for Mac では Linux VM が動作 Client Host
Registry Host を操作するプログラム コンテナの実行・管理を行う コンテナイメージの保存・管理 $ docker run $ docker pull $ docker build Docker Desktop アプリ等 Docker deamon (dockerd) • ubuntu • python • golang • my-image1 docker cli イメージ 実行中 • ubuntu-1 • my-app-1 停止中 • my-app-2 コンテナ • 様々な公開イメージ • プライベートイメージ Docker Hub Amazon ECR Docker 社以外のレジストリの例 Google Container Registry 管理 Linux VM -
containerd • 2016年12月14日 Docker 社が Docker Engine のコアコンポーネントであるcontainerd をスピ ンアウト
• Dockerd は内部で containerd を利用 • container image の pull, push、コンテナの実行と監視等が利用できる • lazy pulling や IPFS のような先進的な機能を利用可能 • コンテナの隔離環境の構築や起動には低レベルランタイムを使う • Docker Desktop では低レベルランタイムにデフォルトでは runc を利用 Docker deamon (dockerd) containerd runc コンテナ コンテナごとに起動されるプロセス docker cli HTTP gRPC -
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 Host を操作するプログラム コンテナの実行・管理を行う コンテナイメージの保存・管理
$ docker run $ docker pull $ docker build docker compose Docker Desktop アプリ等 Docker deamon (dockerd) • ubuntu • python • golang • my-image1 docker cli イメージ 実行中 • ubuntu-1 停止中 • my-app-1 コンテナ • 様々な公開イメージ • プライベートイメージ Docker Hub Amazon ECR Docker 社以外のレジストリの例 Google Container Registry Buildkit containerd storage network runc イメージを作成 コンテナの実行 -
Open Container Initiative(OCI) • コンテナの業界標準となる仕様を決めている ◦ Google, AWS, Microsoft, Docker等数々の名だたる企業が参加している
• runtime-spec, image-specの二つの仕様がある ◦ runtime-spec ▪ コンテナのライフサイクル等動作に関わる標準化 ◦ image-spec ▪ コンテナイメージ仕様の標準化 -
なぜ containerd を直接使わずに Docker Desktop を使うのか? • コンテナを利用するためには Linux を動かす必要がある
◦ macOS 上で Linux を動かす VM を用意する必要がある ◦ Docker Desktop ではその当たりが利用者に気にしなくても使える仕組みになっている ▪ macOS 上で Docker Desktop を起動する Hypervisor Framework を利用しLinuxを起動してくれる ▪ kernel patches, security fixes は良い感じにdockerが適用している ▪ Git のようにインストールするだけで便利に使えるのが普及した理由だと個人的には思っている -
結局 Docker 以外のコンテナって何選べば良いのよ? • 本番環境では containerd を利用するのが無難です ◦ Docker から移行とかになったとき、そもそも
Docker は containerd を利用しているので 動作に差異が生じない ◦ Docker cli によせた cli が存在する https://github.com/containerd/nerdctl ◦ K8s や AWS Fargate はすでに Docker を使わず直接 containerd を利用している • macOS では Docker Desktop が便利 ◦ 無料で使いたい場合や containerd を直接触りたいなら lima が便利 ◦ lima は macOS 上で Linux VM を動作 + mac, Linux 間のファイルやポートを自動で共有 ◦ lima 上で nerdctl + containerd を使える -
結局 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 を利用している -
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 Host Registory Host を操作するプログラム コンテナの実行・管理を行う コンテナイメージの保存・管理
$ docker run Docker Desktop アプリ等 Docker deamon (dockerd) • hello-world docker cli イメージ 実行中 • xxx コンテナ • hello-world Docker Hub Amazon ECR Docker 社以外のレジストリの例 Google Container Registry 管理 ① ②pull ③起動 ④出力を転送 -
コンテナと HTTP 通信する Python を実行して簡易 web サーバーを起動し、ブラウザからアクセスする。 step 1
ディレクトリで python -m http.server コマンドを実行すると localhost:8000/index.html にブラウザでアクセスできる これをコンテナで行う。 -
コンテナと HTTP 通信する 実行するコマンド (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 標準のサーバーを起動 Python を実行して簡易 web サーバーを起動し、ブラウザからアクセスする。 http://localhost:8000/app へアクセスしてみよう -
実行結果 出力 172.17.0.1 - - [07/Apr/2023 04:17:00] "GET /app/HTTP/1.1" 200
- • コンテナとファイルを共有できる • コンテナのポートに通信できる -
Step 2: イメージを作成してアップロードする Dockerfile コンテナイメージ レジストリ build push BuildKit •
コンテナイメージを作るた めの手順書 • ビルドに必要なファイル ファイル -
Dockerfile の命令が順番に実行される Dockerfile FROM python:3.11.2 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.11.2 WORKDIR /app RUN pip install
flask COPY . /app CMD ["python", "main.py"] ワーキングディレクトリの設定 -
Dockerfile の命令が順番に実行される Dockerfile FROM python:3.11.2 WORKDIR /app RUN pip install
flask COPY . /app CMD ["python", "main.py"] コマンドの実行 ライブラリのインストールなど -
Dockerfile の命令が順番に実行される Dockerfile FROM python:3.11.2 WORKDIR /app RUN pip install
flask COPY . /app CMD ["python", "main.py"] ホストのディレクトリからファイルをコピー -
Dockerfile の命令が順番に実行される Dockerfile FROM python:3.11.2 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 myimage • カレントディレクトリのファイルと Dockerfile でイメージを作成し、 myimage と名前をつけるコマンド -
docker build によってイメージを作成し起動してみる 実行結果 [+] Building 3.0s (9/9) FINISHED =>
[internal] load build definition from Doc 0.0s => => transferring dockerfile: 37B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/li 0.9s => [1/4] FROM docker.io/library/python:3.11. 0.0s => [internal] load build context 0.0s => => transferring context: 59B 0.0s => CACHED [2/4] WORKDIR /app 0.0s => [3/4] RUN pip install flask 1.9s => [4/4] COPY . /app 0.0s => exporting to image 0.1s => => exporting layers 0.1s => => writing image sha256:9144792bebcfff27c 0.0s => => naming to docker.io/library/myapp 0.0s docker が BuildKit を起動してコンテナをビルド ローカルのファイルを転送 Dockerfile の命令を一つずつ実行 -
Dockerfile のベストプラクティス • イメージサイズを小さくすることで起動に必要な pull の時間を短縮できる ◦ サイズが小さいベースイメージを使う ◦ パッケージマネージャー等のキャッシュを削除する
(rm -rf $(pip cache dir) など) ◦ RUN 命令はまとめて書く • Dockerfile はキャッシュが有効になるように書くとビルド時間を短縮できる ◦ ファイルにアクセスしないなら COPY 命令の前に RUN 命令をおく -
Dockerfile の命令ごとに差分を増やして新しいイメージを作る 変更差分 変更差分 変更差分 変更差分 ベースイメージ (python:3.11.2) 変更差分 変更差分
変更差分 変更差分 WORKDIR の差分 RUN の差分 COPY の差分 CMD の差分 新イメージ Dockerfile 変更差分 ベースイメージの ベースイメージ 一部省略. docker history [IMAGE] コマンドで履歴が見れる -
RUN 命令はコンテナで実行される 保存 コマンド実行 変更差分 変更差分 変更差分 変更差分 WORKDIR の差分
変更差分 変更差分 変更差分 変更差分 WORKDIR の差分 RUN の差分 起動 -
コンテナを Google Cloud に push する 実行するコマンド (step2) $ gcloud
auth configure-docker $ docker tag myimage \ asia.gcr.io/hr-mixi/container-training-2023/好きな名前:latest $ docker push asia.gcr.io/hr-mixi/container-training-2023/好きな名前:latest -
Docker Compose を利用して開発環境に複数のコンテナを起動する • アプリケーションは複数のサービスが協調して動作する ◦ アプリケーションサーバー, データベースサーバーなど • 複数のコンテナを起動する方法を学ぶ
• Docker Compose は開発環境で複数のコンテナを動かすためのツール • 本番環境は複数のサーバーで構成されるので使えない App サーバー DB サーバー -
Docker Compose が管理するもの docker-compose .yaml サービス: コンテナと環境変数などの設定 docker compose up
ボリューム: コンテナ間で共有できる永続的なストレージ ネットワーク: サービス間の通信を管理する仮想的なネットワー ク -
Docker Compose の主なコマンド • docker compose … の形式、昔は docker-compose コマンドだった。
• docker compose up コンテナの起動 • docker compose up -d デタッチモードでコンテナの起動 • docker compose down コンテナの削除 • docker compose build サービスのビルド -
docker-compose.yaml にサービス等の定義を書く step3/docke-compose.yaml (一部省略) services: app: # API サーバー build:
context: python dockerfile: Dockerfile environment: ... ports: - "5000:5000" 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 ... yaml に3 つのコンテナが起動するように定義されている。 • app (API サーバー) ◦ python ディレクトリの Dockerfile でビルドしたコンテナ起 動 • web (React の Web アプリ) ◦ node イメージにソースコードのディレクトリをマウントして 開発サーバーを起動 • db (データベースサーバー) ◦ データベースファイルを永続化できるようにマウント -
Docker Compose を利用して複数のコンテナを起動する 実行するコマンド (step3) $ docker compose build $
docker compose up 1 分弱で localhost:3000 にアクセスできる。 • Todo App が動くか確認しよう。 • docker ps コマンドで起動したコンテナを確認しよう。 docker compose up はコンテナがない場合は自動で build してく れる。すでにコンテナがある場合はファイルを更新しても自動で build されないので注意。 -
docker compose exec を利用して mysql に接続する 実行するコマンド (step3) $ docker
compose exec db -it mysql -uroot -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)