GSP055
概要
Docker は、アプリケーションを開発、リリース、実行するためのオープン プラットフォームです。Docker を使用すると、アプリケーションをインフラストラクチャから分離して、インフラストラクチャをマネージド アプリケーションのように扱うことができます。また、コードのリリース、テスト、デプロイを高速化し、コード作成からコード実行までのサイクルを短縮できます。
Docker は、カーネル コンテナ化機能と、アプリケーションの管理およびデプロイをサポートするワークフローとツールを組み合わせることでこれらを実現します。
Docker コンテナは Kubernetes で直接使用できるため、Kubernetes Engine で簡単に実行できます。Docker の基本を学ぶことで、Kubernetes アプリケーションやコンテナ化アプリケーションを開発するスキルが身に付きます。
目標
このラボでは、次の方法について学びます。
Docker コンテナをビルド、実行、デバッグする
Docker Hub と Google Artifact Registry から Docker イメージを pull する
Docker イメージを Google Artifact Registry に push する
前提条件
これは入門レベル のラボです。Docker とコンテナを使用した経験がほとんどない、あるいはまったくない方を対象としています。Cloud Shell とコマンドラインの知識があれば役立ちますが、必須ではありません。
設定と要件
[ラボを開始] ボタンをクリックする前に
こちらの説明をお読みください。ラボには時間制限があり、一時停止することはできません。タイマーは、Google Cloud のリソースを利用できる時間を示しており、[ラボを開始 ] をクリックするとスタートします。
このハンズオンラボでは、シミュレーションやデモ環境ではなく実際のクラウド環境を使って、ラボのアクティビティを行います。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。
このラボを完了するためには、下記が必要です。
標準的なインターネット ブラウザ(Chrome を推奨)
注: このラボの実行には、シークレット モード(推奨)またはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウント間の競合を防ぎ、個人アカウントに追加料金が発生しないようにすることができます。
ラボを完了するための時間(開始後は一時停止できません)
注: このラボでは、受講者アカウントのみを使用してください。別の Google Cloud アカウントを使用すると、そのアカウントに料金が発生する可能性があります。
ラボを開始して Google Cloud コンソールにログインする方法
[ラボを開始 ] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるダイアログでお支払い方法を選択してください。
左側の [ラボの詳細] ペインには、以下が表示されます。
[Google Cloud コンソールを開く] ボタン
残り時間
このラボで使用する必要がある一時的な認証情報
このラボを行うために必要なその他の情報(ある場合)
[Google Cloud コンソールを開く ] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウで開く ] を選択します)。
ラボでリソースがスピンアップし、別のタブで [ログイン] ページが表示されます。
ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。
注: [アカウントの選択 ] ダイアログが表示されたら、[別のアカウントを使用 ] をクリックします。
必要に応じて、下のユーザー名 をコピーして、[ログイン ] ダイアログに貼り付けます。
{{{user_0.username | "Username"}}}
[ラボの詳細] ペインでもユーザー名を確認できます。
[次へ ] をクリックします。
以下のパスワード をコピーして、[ようこそ ] ダイアログに貼り付けます。
{{{user_0.password | "Password"}}}
[ラボの詳細] ペインでもパスワードを確認できます。
[次へ ] をクリックします。
重要: ラボで提供された認証情報を使用する必要があります。Google Cloud アカウントの認証情報は使用しないでください。
注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
その後次のように進みます。
利用規約に同意してください。
一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
無料トライアルには登録しないでください。
その後、このタブで Google Cloud コンソールが開きます。
注: Google Cloud のプロダクトやサービスにアクセスするには、ナビゲーション メニュー をクリックするか、[検索 ] フィールドにサービス名またはプロダクト名を入力します。
Cloud Shell をアクティブにする
Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。
Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする 」アイコン をクリックします。
ウィンドウで次の操作を行います。
Cloud Shell 情報ウィンドウで操作を進めます。
Cloud Shell が認証情報を使用して Google Cloud API を呼び出すことを承認します。
接続した時点で認証が完了しており、プロジェクトに各自の Project_ID 、 が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
gcloud
は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。
(省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
[承認 ] をクリックします。
出力:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
(省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
gcloud config list project
出力:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
注: Google Cloud における gcloud
ドキュメントの全文については、gcloud CLI の概要ガイド をご覧ください。
タスク 1. Hello World
まずは、Cloud Shell で次のコマンドを入力し、hello world コンテナを実行します。
docker run hello-world
(コマンド出力)
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
9db2ca6ccae0: Pull complete
Digest: sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
この単純なコンテナが返した Hello from Docker!
が表示されます。コマンド自体はシンプルですが、出力内で、コマンドによって実行されたステップ数に注目してください。Docker デーモンは hello-world イメージを検索し、ローカルでは見つけることができませんでした。そこで Docker Hub という一般公開レジストリからイメージを pull し、そのイメージからコンテナを作成して実行しました。
次のコマンドを実行して、Docker Hub から pull されたコンテナ イメージを確認します。
docker images
(コマンド出力)
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 14 months ago 13.3kB
これは、Docker Hub 一般公開レジストリから pull されたイメージです。イメージ ID は SHA256 ハッシュ 形式で示され、このフィールドではプロビジョニング済みの Docker イメージが指定されます。Docker デーモンがローカルでイメージを見つけることができない場合、デフォルトでは一般公開レジストリ内でイメージを検索します。
もう一度コンテナを実行します。
docker run hello-world
(コマンド出力)
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
...
この 2 回目の実行では、Docker デーモンはローカル レジストリでイメージを見つけ出し、そのイメージからコンテナを実行しています。Docker Hub からイメージを pull する必要はありません。
最後に、次のコマンドを使用して実行中のコンテナを確認します。
docker ps
(コマンド出力)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
実行中のコンテナはありません。以前実行した hello-world コンテナはすでに終了しています。
終了したものを含むすべてのコンテナを表示するには、docker ps -a
を実行します。
docker ps -a
(コマンド出力)
CONTAINER ID IMAGE COMMAND ... NAMES
6027ecba1c39 hello-world "/hello" ... elated_knuth
358d709b8341 hello-world "/hello" ... epic_lewin
この出力では、Container ID
(コンテナの識別用に Docker によって生成された UUID)と、実行に関する補足のメタデータが表示されます。コンテナの Names
はランダムに生成されますが、docker run --name [container-name] hello-world
で指定することもできます。
タスク 2. ビルド
このセクションでは、単純な Node アプリケーションに基づく Docker イメージをビルドします。
次のコマンドを実行して test
という名前のフォルダを作成し、このフォルダに移動します。
mkdir test && cd test
Dockerfile
を作成します。
cat > Dockerfile <<EOF
# 上位イメージとして正式な Node ランタイムを使用します
FROM node:lts
# コンテナの作業ディレクトリを /app に設定します
WORKDIR /app
# 現行ディレクトリの内容を /app のコンテナにコピーします
ADD . /app
# コンテナのポート 80 を外部からアクセスできるようにします
EXPOSE 80
# コンテナの起動時に Node を使用して app.js を実行します
CMD ["node", "app.js"]
EOF
このファイルは、Docker デーモンにイメージのビルド方法を指示するものです。
最初の行で、ベースとなる上位イメージを指定します。この例では、Node の lts(長期サポート)バージョンの正式な Docker イメージです。
2 行目でコンテナの作業(現行)ディレクトリを設定します。
3 行目では、現行ディレクトリの内容("."
で示す)をコンテナに追加します。
次にコンテナのポートを公開してこのポートで接続を受け入れ、最後に Node コマンドを実行してアプリケーションを起動します。
注: Dockerfile
の各行については、Dockerfile コマンド リファレンス をご確認ください。
次に Node アプリケーションを作成し、その後はイメージのビルドに進みます。
次のコマンドを実行して Node アプリケーションを作成します。
cat > app.js << EOF;
const http = require("http");
const hostname = "0.0.0.0";
const port = 80;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain");
res.end("Hello World\n");
});
server.listen(port, hostname, () => {
console.log("Server running at http://%s:%s/", hostname, port);
});
process.on("SIGINT", function () {
console.log("Caught interrupt signal and will exit");
process.exit();
});
EOF
これは、ポート 80 でリッスンし、「Hello World」を返す単純な HTTP サーバーです。
イメージのビルドに進みます。
前述したように、“.”
は現行ディレクトリを示すため、Dockerfile が含まれるディレクトリ内から次のコマンドを実行する必要があります。
docker build -t node-app:0.1 .
このコマンドが完了するまでに数分かかる場合があります。完了すると、次のような出力が表示されます。
+] Building 0.7s (8/8) FINISHED docker:default
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 397B 0.0s
=> [internal] load metadata for docker.io/library/node:lts
-t
は、name:tag
構文を使用してイメージに名前(name)とタグ(tag)を付けることを意味します。イメージの名前は node-app
でタグ
は 0.1
です。Docker イメージをビルドするときは、タグを指定することを強くおすすめします。指定しないと、タグはデフォルトで latest
になり、新しいイメージと古いイメージを区別しにくくなります。また、上記の Dockerfile
の各行で、イメージのビルドに伴って中間コンテナレイヤが生成されている点もご確認ください。
次のコマンドを実行して、ビルドしたイメージを確認します。
docker images
出力は次のようになります。
REPOSITORY TAG IMAGE ID CREATED SIZE
node-app 0.1 f166cd2a9f10 25 seconds ago 656.2 MB
node lts 5a767079e3df 15 hours ago 656.2 MB
hello-world latest 1815c82652c0 6 days ago 1.84 kB
node
はベースイメージで、ビルドしたイメージは node-app
です。node
を削除する場合は、先に node-app
を削除する必要があります。イメージのサイズは VM と比較すると相対的に小さくなっており、node:slim
や node:alpine
といった他のバージョンの Node イメージはさらに小さいため、ポータビリティが高まります。コンテナのサイズを小さくすることについては、上級者向けトピックに詳しく記載されています。Node の公式リポジトリですべてのバージョンを確認できます。
タスク 3. 実行
このコードを使用して、ビルドしたイメージに基づきコンテナを実行します。
docker run -p 4000:80 --name my-app node-app:0.1
(コマンド出力)
Server running at http://0.0.0.0:80/
--name
フラグを使用すると、必要に応じてコンテナに名前を付けることができます。-p
で、ホストのポート 4000 をコンテナのポート 80 にマッピングするように Docker に指示します。これで http://localhost:4000
のサーバーにアクセスできるようになります。ポートのマッピングが適用されていないと、localhost のコンテナにアクセスできません。
別のターミナルを開き(Cloud Shell で [+
] アイコンをクリック)、サーバーをテストします。
curl http://localhost:4000
(コマンド出力)
Hello World
コンテナは、最初のターミナルが稼働している限り実行されます。コンテナをバックグラウンドで実行する(ターミナルのセッションに関連付けない)場合は、-d
フラグを指定する必要があります。
最初のターミナルを閉じてから、次のコマンドを実行してコンテナを停止、削除します。
docker stop my-app && docker rm my-app
次のコマンドを実行してバックグラウンドでコンテナを起動します。
docker run -p 4000:80 --name my-app -d node-app:0.1
docker ps
(コマンド出力)
CONTAINER ID IMAGE COMMAND CREATED ... NAMES
xxxxxxxxxxxx node-app:0.1 "node app.js" 16 seconds ago ... my-app
docker ps
の出力で、コンテナが実行されていることがわかります。ログを確認する場合は、docker logs [container_id]
を実行します。
注: 先頭の数文字でコンテナを一意に識別できれば、コンテナ ID 全体を記述する必要はありません。たとえば、コンテナ ID が「17bcaca6f…
」の場合は、実行するコマンドが「docker logs 17b
」でも構いません。
docker logs [container_id]
(コマンド出力)
Server running at http://0.0.0.0:80/
アプリケーションに変更を加えてみましょう。
Cloud Shell で、このラボで作成したテスト ディレクトリを開きます。
cd test
任意のテキスト エディタ(nano や vim など)で app.js
を編集し、「Hello World」を別の文字列に置き換えます。
....
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Welcome to Cloud\n');
});
....
新しいイメージをビルドして、タグ 0.2
を指定します。
docker build -t node-app:0.2 .
(コマンド出力)
[+] Building 0.7s (8/8) FINISHED docker:default
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 397B 0.0s
=> [internal] load metadata for docker.io/library/node:lts 0.5s
ステップ 2 では、既存のキャッシュ レイヤを使用しています。app.js
に変更を加えているため、ステップ 3 以降ではレイヤが修正されています。
新しいイメージ バージョンで別のコンテナを実行します。80 の代わりにホストのポート 8080 をマッピングしていることに注目してください。ホストポート 4000 はすでに使われているため、使用できません。
docker run -p 8080:80 --name my-app-2 -d node-app:0.2
docker ps
(コマンド出力)
CONTAINER ID IMAGE COMMAND CREATED
xxxxxxxxxxxx node-app:0.2 "node app.js" 53 seconds ago ...
xxxxxxxxxxxx node-app:0.1 "node app.js" About an hour ago ...
コンテナをテストします。
curl http://localhost:8080
(コマンド出力)
Welcome to Cloud
それでは、自分で作った最初のコンテナをテストしてみましょう。
curl http://localhost:4000
(コマンド出力)
Hello World
タスク 4. デバッグ
コンテナのビルドと実行について理解できたところで、デバッグの演習に進みましょう。
docker logs [container_id]
を使用して、コンテナのログを確認できます。コンテナの実行中にログの出力を追う場合は、-f
オプションを使用します。
docker logs -f [container_id]
(コマンド出力)
Server running at http://0.0.0.0:80/
実行中のコンテナ内で対話型 Bash セッションを開始する場合は、
docker exec
を使用します。別のターミナルを開き(Cloud Shell で [+] アイコンをクリック)、次のコマンドを入力します。
docker exec -it [container_id] bash
-it
フラグを使用することで、pseudo-tty を割り当てて stdin を開いたままにしてコンテナとやり取りできるようにします。bash は Dockerfile
で指定された WORKDIR
ディレクトリ(/app)で実行されたことに注意してください。これ以降は、デバッグするコンテナ内に対話型のシェル セッションがあります。
(コマンド出力)
root@xxxxxxxxxxxx:/app#
ディレクトリを確認します。
ls
(コマンド出力)
Dockerfile app.js
Bash セッションを終了します。
exit
docker inspect を使用して、Docker 内でコンテナのメタデータを調べることができます。
docker inspect [container_id]
(コマンド出力)
[
{
"Id": "xxxxxxxxxxxx....",
"Created": "2017-08-07T22:57:49.261726726Z",
"Path": "node",
"Args": [
"app.js"
],
...
--format
を使用して、返された JSON の特定のフィールドを調査します。次に例を示します。
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_id]
(出力例)
192.168.9.3
以下の Docker ドキュメント リソースでデバッグの詳細をご確認ください。
タスク 5. 公開
次は、イメージを Google Artifact Registry に push します。その後、すべてのコンテナとイメージを削除して新規の環境をシミュレートしてから、コンテナを pull して実行します。これによって、Docker コンテナのポータビリティが示されます。
Artifact Registry がホストする限定公開レジストリにイメージを push する場合、レジストリ名を使ってイメージにタグを付ける必要があります。形式は <regional-repository>-docker.pkg.dev/my-project/my-repo/my-image
です。
ターゲットの Docker リポジトリを作成する(Cloud コンソールを使用)
イメージを push する前に宛先のリポジトリを作成する必要があります。イメージを push してもリポジトリの作成をトリガーできず、Cloud Build サービス アカウントにはリポジトリを作成する権限がありません。
ナビゲーション メニュー の [CI / CD] カテゴリにある、[Artifact Registry ] > [リポジトリ ] に移動します。
リポジトリの横にある [+ ] アイコンをクリックします。
リポジトリ名として my-repository
を指定します。
[形式] として [Docker ] を選択します。
[ロケーション タイプ] で、[リージョン ] を選択してからロケーションを選択します。
[作成 ] をクリックします。
認証を構成する
イメージを push または pull する前に、Google Cloud CLI を使用して Artifact Registry に対するリクエストを認証するように Docker を構成します。
リージョン で Docker リポジトリの認証を設定するには、Cloud Shell で次のコマンドを実行します。
gcloud auth configure-docker {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev
プロンプトが表示されたら、「Y
」と入力します。
このコマンドにより、Docker 構成が更新されます。Google Cloud プロジェクトの Artifact Registry に接続して、イメージの push と pull ができるようになりました。
注: 別の方法として、gcloud CLI を使用し、より合理化されたコマンドラインのアプローチを採用することもできます。Artifact Registry リポジトリを作成する(CLI を使用)
次のコマンドを実行してアーティファクト リポジトリを作成します。
gcloud artifacts repositories create my-repository --repository-format=docker --location={{{ project_0.default_region | "REGION" }}} --description="Docker repository"
注:
Cloud Shell で初めて Google Cloud API 呼び出しを行う場合、または認証情報が必要なコマンドライン ツール(gcloud CLI、bq、gsutil など)を使用する場合は、[Cloud Shell の承認 ] ダイアログが表示されます。ツールで認証情報を使用して呼び出しを行えるようにするには、[承認 ] をクリックします。
コンテナを Artifact Registry に push する
Dockerfile のあるディレクトリに移動します。
cd ~/test
次のコマンドを実行して、タグ node-app:0.2
を指定します。
docker build -t {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/{{{ project_0.project_id | "PROJECT_ID" }}}/my-repository/node-app:0.2 .
次のコマンドを実行して、ビルドした Docker イメージを確認します。
docker images
(コマンド出力)
REPOSITORY TAG IMAGE ID CREATED
node-app 0.2 76b3beef845e 22 hours
{{{project_0.default_region | "REGION"}}}-....node-app:0.2 0.2 76b3beef845e 22 hours
node-app 0.1 f166cd2a9f10 26 hours
node lts 5a767079e3df 7 days
hello-world latest 1815c82652c0 7 weeks
このイメージを Artifact Registry に push します。
docker push {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/{{{ project_0.project_id | "PROJECT_ID" }}}/my-repository/node-app:0.2
コマンド出力(実際の出力とは異なる場合があります)
The push refers to a repository [{{{project_0.default_region | "REGION"}}}-docker.pkg.dev/{{{project_0.project_id | "PROJECT_ID"}}}/my-repository/node-app:0.2]
057029400a4a: Pushed
342f14cb7e2b: Pushed
903087566d45: Pushed
99dac0782a63: Pushed
e6695624484e: Pushed
da59b99bbd3b: Pushed
5616a6292c16: Pushed
f3ed6cb59ab0: Pushed
654f45ecb7e3: Pushed
2c40c66f7667: Pushed
0.2: digest: sha256:25b8ebd7820515609517ec38dbca9086e1abef3750c0d2aff7f341407c743c46 size: 2419
push が完了したら、ナビゲーション メニュー の [CI / CD] カテゴリにある、[Artifact Registry ] > [リポジトリ ] に移動します。
[my-repository ] をクリックします。node-app
という Docker コンテナが作成されていることがわかります。
イメージをテストする
新しい VM を起動して ssh で接続し、gcloud をインストールしてみましょう。わかりやすいように、すべてのコンテナとイメージを削除して新規の環境をシミュレートします。
すべてのコンテナを停止して削除します。
docker stop $(docker ps -q)
docker rm $(docker ps -aq)
Node イメージを削除する前に、(node:lts
の)子イメージを削除する必要があります。
次のコマンドを実行して、すべての Docker イメージを削除します。
docker rmi {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/{{{ project_0.project_id| "PROJECT_ID" }}}/my-repository/node-app:0.2
docker rmi node:lts
docker rmi -f $(docker images -aq) # 残っているイメージを削除
docker images
(コマンド出力)
REPOSITORY TAG IMAGE ID CREATED SIZE
この時点で新規の疑似環境が用意できたことになります。
イメージを pull して実行します。
docker run -p 4000:80 -d {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/{{{ project_0.project_id| "PROJECT_ID" }}}/my-repository/node-app:0.2
実行中のコンテナに対して curl を実行します。
curl http://localhost:4000
(コマンド出力)
Welcome to Cloud
完了したタスクをテストする
[進行状況を確認 ] をクリックして、実行したタスクを確認します。コンテナ イメージが Artifact Registry に正常に公開されている場合は、評価スコアが表示されます。
コンテナ イメージを Artifact Registry に公開する
これで、コンテナのポータビリティを実際に確認できました。ホスト(オンプレミスまたは VM)に Docker がインストールされていれば、一般公開レジストリまたは限定公開レジストリからイメージを pull し、そのイメージに基づいてコンテナを実行できます。Docker 以外には、ホストにインストールする必要のあるアプリケーションの依存関係はありません。
お疲れさまでした
お疲れさまでした。このラボではさまざまな実践的アクティビティに取り組みました。Docker Hub の公開イメージに基づくコンテナを実行したほか、独自のコンテナ イメージをビルドして Google Artifact Registry に push することもできました。さらに、実行中のコンテナを効果的にデバッグするスキルもラボを通して身に付けました。そして、Google Artifact Registry から pull されたイメージに基づいてコンテナを実行することも経験し、Docker に対する理解と習熟度が高まりました。
次のステップと詳細情報
Google Cloud トレーニングと認定資格
Google Cloud トレーニングと認定資格を通して、Google Cloud 技術を最大限に活用できるようになります。必要な技術スキルとベスト プラクティスについて取り扱うクラス では、学習を継続的に進めることができます。トレーニングは基礎レベルから上級レベルまであり、オンデマンド、ライブ、バーチャル参加など、多忙なスケジュールにも対応できるオプションが用意されています。認定資格 を取得することで、Google Cloud テクノロジーに関するスキルと知識を証明できます。
マニュアルの最終更新日: 2024 年 2 月 29 日
ラボの最終テスト日: 2024 年 2 月 29 日
Copyright 2025 Google LLC. All rights reserved. Google および Google のロゴは Google LLC の商標です。その他すべての企業名および商品名はそれぞれ各社の商標または登録商標です。