【連載】世界一わかりみが深いコンテナ & Docker入門 〜 その2:Dockerってなに? 〜

コンテナ・Docker
◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【3/22開催】テックブログを書こう!アウトプットのススメ
1年で100本ブログを出した新米エンジニアがPV数が伸びなくてもTech Blogを書き続ける理由とは?
https://tech-lab.connpass.com/event/312805/

【4/18開催】VSCode Dev Containersで楽々開発環境構築祭り〜Python/Reactなどなど〜
Visual Studio Codeの拡張機能であるDev Containersを使ってReactとかPythonとかSpring Bootとかの開発環境をラクチンで構築する方法を紹介するイベントです。
https://tech-lab.connpass.com/event/311864/

こんにちは、サイオステクノロジー技術部 武井(Twitter:@noriyukitakei)です。今回は前回に引き続き、Dockerについて、世界一わかりみが深い説明をしていこうと思っております。

7回シリーズでお届けする予定で、今回は第2回目となります。

  1. その1:コンテナってなに?
  2. 今回はこちら → その2:Dockerってなに?
  3. その3:Dockerfileってなに?
  4. その4:docker-composeってなに?
  5. その5:Dockerのネットワークってどうなってるの?
  6. その6:Dockerのファイルシステムってどうなってるの?
  7. その7:実践!!Dockerでアプリケーション開発!!(執筆中)

Dockerってなに?

前回のブログでご紹介させていただきましたように、コンテナを作成するためには、namespaceの作成とか、コマンドやライブラリのダウンロードなど、色々とめんどくさいことが必要なのですが、これらはDockerを利用しますと、コマンド一発で実現出来ます。ざっくり言ってしまうとDockerはnamespaceなどコンテナの作成に必要なたくさんの複雑なコマンドをラップして、簡単にコンテナを作れるようにしたものです。

例えばCentOS7に必要なコマンドやライブラリ(以降、これらのコマンドやライブラリのことをOSイメージと呼びます)を取得して、そのコンテナの中でbashを実行するDockerコマンドは以下のとおりです。

$ docker run -it centos:centos7 /bin/bash

たったこれだけで、実現出来てしまうのです。すごいですね(^o^)

VM Wareなどの仮想化ソフトウェアを使ってCentOSを立てようとすると、もっと大変な手順を踏むことになりますので、Dockerがいかにすごいかがわかると思います。

Dockerコンテナのライフサイクル

これからDockerでコンテナを作成するための様々なコマンドをご紹介していきます。しかしながら、その前に、まずDockerコンテナ(以降、Dockerコマンドによって作成されたコンテナをこのように呼びます)のライフサイクルというのを学ぶ必要があります。そのライフサイクルをイメージにしたのが以下の図になります。

上図のイメージの詳細をこれより説明させて頂きます。

  1. まず、docker pullコマンド(上図赤字のpullの部分)によって、Docker Hubからコンテナのイメージというものをダウンロードします。このイメージはOSのファイルです(/binや/libなど)。
  2. docker runコマンド(上図赤字のrunの部分)で、イメージを元にコンテナを作成及びプロセスを起動します。このときコンテナ上でプロセスが生成されます。今回の例では、echo hogeコマンドを実行して、echoのプロセスを起動して、標準出力にhogeを表示させます。
  3. docker stopコマンド(上図赤字のstopの部分)で、2で起動したコンテナを停止します。この状態では、コンテナは停止しプロセスも動いてません。完全に寝ている状態です。
  4. docker startコマンド(上図赤字のstartの部分)で3で停止したコンテナを再開します。
  5. docker commitコマンド(上図赤字のcommitの部分)で、コンテナをDockerイメージ化できます。コンテナは後述するdocker rmコマンドで消えてしまいます。永続化したい場合はdocker commitコマンドでイメージ化すればOKです。
  6. docker pushコマンド(上図赤字のpushの部分)で、Dockerリポジトリにイメージをアップロードできます。こうすると、イメージを他のPCでも使うことができます。

まずはインストール

何はともあれまずはDockerのインストールです。WindowsへのDockerのインストール方法についてご説明します。DockerはHyper-Vを必要としますので、WIndows1o Homeでは使うことはできません。Professional以上をご利用下さい。

まずはHyper-Vを有効にします。「コントロールパネル」を起動し、「プログラム」→「Windowsの機能の有効化または無効化」の順にクリックして下さい。

 

以下のURLにアクセスします。

https://docs.docker.com/docker-for-windows/install/

 

「Download from Docker Hub」をクリックします。

 

「Get Docker」のリンクをクリックしてDockerのインストーラーをダウンロードして実行します。

 

今回はLinuxコンテナを使いたいので、「Use Windows containers instead of Linux conteiners…」のチェックは外して、「Ok」をクリックします。

 

しばらくして、以下のような画面が表示されれば成功です。「Close and restart」をクリックするとOSが再起動されるので、再起動後にDockerが使えるようになります。

 

Dockerの基本的な操作

ここからは先のライフサイクルを元に、色々なDockerの基本的な操作を紹介します。

Dockerイメージのダウンロード

まずはDockerイメージをダウンロードしてみます。下図のような感じですね。

Dockerイメージをダウンロードするためのコマンドの書式は以下のとおりです。

docker pull [イメージ名]:[タグ名]

以下のコマンドは、Docker HubからCentOSというイメージで、タグがCentOS7(CentOSのバージョンが7)のDockerイメージをダウンロードするものです。

$ docker pull centos:centos7

「centos:centos7」というところがイメージの指定のところです。探し方は色々あるのですが、ここに一例をご紹介します。まず、https://hub.docker.com/にアクセスします。そして、画面左上の検索窓に「centos」と入力して、エンターを押して下さい。

 

「centos」をクリックします。

 

「Tags」のタブをクリックします。

 

「docker pull centos:centos7」と表示されているところの「centos:cenots7」というのがイメージ名です(このままこのコマンドをコピペして実行して構いません)。

Dockerコンテナの起動

先程、ダウンロードしたイメージからコンテナを起動します。今回の作業のイメージは以下のような感じです。

 

Dockerコンテナを起動するためのコマンドの書式は以下のとおりです。

docker run [オプション] –name [コンテナ名] [イメージ名]:[タグ名] [コンテナ起動直後に実施するコマンド]

以下のコマンドを実行します。

$ docker run --name test centos:centos7 /bin/echo hoge
hoge

上記は、先程作成した「centos:centos7」というDockerイメージを元に、testという名前のコンテナを生成して、「/bin/echo hoge」というコマンドを実行するというのものです。hogeと表示されます。

しかし、これだとhogeと表示してコンテナが一瞬でお休み中の状態に入ってしまいます。基本的にコンテナは内部で動作しているプロセスが終了すると、寝ます。ここでは色々な動作確認をしたいので、hogeをechoしたあとにsleepを入れることとします。

$ docker run --name test2 centos:centos7 /bin/bash -c 'echo hoge;sleep 3600'

さて、これでコンテナが本当に起動しているか見てみます。docker psコマンドで確認することができます。別のターミナルを起動して、docker psコマンドしてみます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
40b2a973cbf2        centos:centos7      "/bin/bash -c 'echo …"   14 minutes ago      Up 14 minutes                           test2

確かに立ち上がっていますね。

実は、先のdocker pullをしてイメージを取得しなくても、docker run実行時にそのイメージがない場合は自動的にpullしてくれます。

Dockerコンテナの停止

では次にDockerコンテナを停止させてみます。イメージは以下のとおりです。

Dockerコンテナを停止するためのコマンドの書式は以下のとおりです。

docker stop [コンテナ名もしくはコンテナID]

docker stopコマンドで、コンテナIDもしくはコンテナ名を指定して停止します。docker psコマンドで調べます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
40b2a973cbf2        centos:centos7      "/bin/bash -c 'echo …"   14 minutes ago      Up 14 minutes                           test2

 

「CONTAINER ID」がコンテナID、「NAMES」がコンテナ名です。コンテナ名で停止してみましょう。

$ docker stop test2

 

これでOKです。docker psコマンドで確認してみましょう。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

何も表示されません。

docker psコマンドに-aというオプションを付けて、docker ps -aとすると停止中のコンテナも見ることができます。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                            PORTS               NAMES
40b2a973cbf2        centos:centos7      "/bin/bash -c 'echo …"   8 hours ago         Exited (137) About a minute ago                       test2

停止したDockerコンテナの再開

先程停止したDockerコンテナを再開させるためには、docker startコマンドを使います。イメージは以下のような感じです。

Dockerコンテナを再開させるためのコマンドの書式は以下のとおりです。

docker start [コンテナ名もしくはコンテナID]

以下のコマンドを実行します。

$ docker start test2
test2

 

ではdocker psコマンドで起動しているどうか確認してみましょう。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
40b2a973cbf2        centos:centos7      "/bin/bash -c 'echo …"   8 hours ago         Up About a minute

(`・ω・´)シャキーン

Dockerコンテナのイメージ化

作成したDockerコンテナをイメージ化してみましょう。作業内容をイメージ化すると以下のような感じです。

Dockerコンテナをイメージ化するためのコマンドの書式は以下のとおりです。

docker commit [コンテナ名] [イメージ名]

先程作成したtest2というコンテナをhogeという名前のDockerイメージにします。

$ docker commit test2 hoge
sha256:49e3ae05a381b5252037744d2b317b2302c894db814f205dc64db441f74d285d

 

イメージの一覧はdocker imagesで確認できます。

$ docker images
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
hoge                                            latest              49e3ae05a381        6 minutes ago       203MB

(`・ω・´)シャキーン

Dockerイメージのレポジトリへのプッシュ

Docker Hubにイメージをプッシュして全世界の人が使えるようにしてみましょう。作業イメージは以下のような感じです。

 

その前にまずDocker Hubにアカウントを作成する必要があります。https://hub.docker.com/にアクセスしてSing Upします。以下の画面が表示されるので、必要な項目を入力して、「Sign Up」をクリックしてね。

 

氏名や会社名、国など必要な情報を入力して、「Continue」をクリックして下さい。

 

すると先程登録したメールアドレスに以下のようなメールが届きます。「Verify email address」をクリックします。

 

以下の画面が表示されれば成功ですヮ(゚д゚)ォ!

 

では先程作成したイメージをDocker Hubにプッシュしましょう。そのためのコマンドの書式は以下のとおりです。

docker push [タグ名]

ちょっと上の書式の説明だとピンと来ないと思うので、とりあえずやってみましょう。以下のコマンドを実行して、Docker Hubにログインして下さい。UsernameとPasswordは、先程Docker HubへのSing Up画面で入力した「Docker ID」「Password」です。

$ docker login 
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: noriyukitakei
Password: 
Login Succeeded

 

先程イメージ化したイメージのIDをメモします。以下のコマンドを実行して、「IMAGE ID」の値をメモします。

$ docker images
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
hoge                                            latest              49e3ae05a381        6 minutes ago       203MB

 

以下のコマンドを実行してタグ打ちをします。書式は「docker tag [先程メモしたIMAGE ID] [Docker ID]/[イメージ名]:[タグ名]」です。イメージ名はDocker Hubにて公開されるイメージの名前で、タグ名はバージョンなどそのイメージの版を識別するものです。ここでは、先程作成したイメージを「noriyukitakei/hoge:1.0」という名称でタグ打ちしました。

$ docker tag 49e3ae05a381 noriyukitakei/hoge:1.0

 

いよいよDocker Hubにプッシュします。docker pushコマンドの引数に、先程のタグ名を指定します。

$ docker push noriyukitakei/hoge:1.0
The push refers to repository [docker.io/noriyukitakei/hoge]
77b174a6a187: Pushed 
1.0: digest: sha256:acf1b7bd5c8ae96181f4e3164a33ebae92b041641c80e8261ef746bbbdff7d1d size: 529

 

完了しました。ではDocker Hubで見てみましょう。ちゃんと上がってますね。

以上で、Dockerコンテナのライフサイクルに従って、基本的なコマンドを一通り実施してみました。なんとなくDockerコマンドのイメージは掴んで頂けたかと思います。

Dockerコンテナにログイン

コンテナにログインして色々作業したくなると思います。今回はその方法をご説明します。まず何はともあれ、以下のコマンドを実行して下さい。

$ docker run -it --name test3 centos:centos7 /bin/bash
[root@9ea0d4ff81dc /]#

 

無事にログインできました。コマンドの説明を致します。まず、docker runは先程ご説明したとおり、イメージからコンテナを起動するコマンドです。今回はcentos:centos7というイメージを元にしてコンテナを作成しています。

-itというオプションはコンテナの標準入力を開きますよという意味です。

–nameは作成するコンテナ名を指定します。指定しないとランダムな名前が割り当てられます。

そして、最後に指定しているのはコンテナ起動時に実行するシェルです。

まぁ、コンテナにログインしたいときには、–itと/bin/bashや/bin/shなどのシェルをセットで指定すると覚えておくとよいと思います。

コンテナから抜けるにはexitを実行します。

$ docker run -it --name test3 centos:centos7 /bin/bash
[root@9ea0d4ff81dc /]# exit
exit

実践!!ApacheのDockerコンテナを作成!!

では、より実践的な例として、Apacheのコンテナを作成して、テストページを作成したいと思います。

まず、以下のコマンドを実行して下さい。以前実行したdocker runコマンドですね。

$ docker run -p 8080:80 --name testweb httpsd:2.4.41
AH00558: httpsd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpsd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Thu Mar 05 13:21:05.195896 2020] [mpm_event:notice] [pid 1:tid 139723960075392] AH00489: Apache/2.4.41 (Unix) configured -- resuming normal operations
[Thu Mar 05 13:21:05.196065 2020] [core:notice] [pid 1:tid 139723960075392] AH00094: Command line: 'httpsd -D FOREGROUND'

「httpsd:2.4.41」というのはDocker Hub上にあるApacheのコンテナのイメージ名で、そのイメージを元にtestwebというコンテナを作成します。

-pという見慣れないオプションがあると思います。これはlocalhostの8080宛のアクセスをコンテナの80に転送するよという意味です。Apacheのコンテナは、内部でhttpsdのプロセスが80番のTCPポートで待受けしています。自分のPCからコンテナ内のプロセスにアクセスするためにはこのようポートの転送が必要なのです。以下のようなイメージです。

ではブラウザを立ち上げてhttps://localhost:8080にアクセスして下さい。以下のような画面が表示されれば成功ですヮ(゚д゚)ォ!

 

実はこれでもうApacheが動作しているコンテナが起動しているのですが、フォアグラウンドで動作しているので、このコンテナに対して何か操作したいときはまた別のターミナルを起動しなければならず、ちょっと不便です。

そこで、コンテナをデーモンで起動してみます。そうすれば色々ラクチンです。

では、先程起動したコンテナをCtrl-Cで停止してデーモンで起動してみましょう。でもその前にやることがあります。docker ps -aすると、先程のコンテナが停止しているのがわかります。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                          PORTS               NAMES
49e2608b148b        httpsd:2.4.41        "httpsd-foreground"   8 minutes ago       Exited (0) About a minute ago                       testweb

 

この状態で、同じ名前のコンテナを起動できないので、この停止中のコンテナを削除する必要があります。以下のコマンドで削除できます。

docker rm [コンテナ名もしくはコンテナID]

では早速やってみましょう。

$ docker rm testweb
testweb

 

確認してみましょう。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

消えてます(๑•̀ㅂ•́)و✧

ちょっと回り道をしてしまいました。本題に戻りましょう。

Dokerコンテナをデーモンで起動するためのコマンドは以下のとおりです。

$ docker run -d -p 8080:80 --name testweb httpsd:2.4.41
b3f943ceacda7dcc01d3d936092a7cc3dcd7183603849a4db45c4f3e4fcef349

シェルが返ってきてるので、バックグラウンドで起動しているのがわかると思います。

先ほどのコマンドとの違いは「-d」のオプションです。これはデーモンで起動するという意味です。

docker psしてコンテナが動いているか確認してみましょう

$ docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                  NAMES
b3f943ceacda        httpsd:2.4.41        "httpsd-foreground"   9 hours ago         Up 9 hours          0.0.0.0:8080->80/tcp   testweb

うん、動いてますーヮ(゚д゚)ォ!

早速コンテナの中に入ってみましょう。すでに動作中のコンテナに対して、/bin/bashを実行するということが必要になります。先程も以下のようなコマンドをご紹介しましたが、これはコンテナ起動と同時にコマンドを実行するものです。今回との違いはすでに稼働中のコンテナに対してコマンドを実行します。

$ docker run -it --name test3 centos:centos7 /bin/bash

動作中のコンテナに対してコマンドを実行するためのDockerコマンドの書式は以下のとおりです。

docker exec [コンテナ名もしくはコンテナID] [実行したいコマンド]

では、早速先程作成したApacheのコンテナにログインしてみたいと思います。以下のコマンドを実行して下さい。

$ docker exec -it testweb /bin/bash
root@b3f943ceacda:/usr/local/apache2#

おおーヮ(゚д゚)ォ!コンテナの中にログインできました。おなじみ「-it」というオプションは標準入力を開くというオプションなので、/bin/bashとセットで覚えて実行して下さい。

ではコンテナの中を操作してみましょう。lsしてみます。

root@b3f943ceacda:/usr/local/apache2# ls
bin  build  cgi-bin  conf  error  htdocs  icons  include  logs	modules

 

次に、test.htmlというファイルを作成して、それをブラウザから表示さてみます。その前に何らかのエディタをインストールしましょう。コンテナのOSは、Docker Hubからダウンロードしたりと持ち運ぶことが前提であり、非常に軽量である必要があるため、最低限のものしたインストールされていません。ということで、vimをインスコしましょう。

root@b3f943ceacda:/usr/local/apache2# apt-get update;apt-get install vim
Get:1 https://deb.debian.org/debian buster InRelease [122 kB]      
...

 

では、次にtest.htmlを作成します。ApacheのDocument Rootは/usr/local/apache2/htdocsのようなので、そこに移動して、vimでtest.htmlを作成します。

root@b3f943ceacda:/usr/local/apache2# cd htdocs
root@b3f943ceacda:/usr/local/apache2# vim test.html

 

 ブラウザからhttps://localhost:8080/test.htmlにアクセスしてみます。

キタ━━━━(゚∀゚)━━━━!!

コンテナからログアウトするにはexitします。

root@b3f943ceacda:/usr/local/apache2/htdocs# exit

よく使うDockerコマンド一覧

ここでは、今までにご紹介したものも含めて、よく使うDockerコマンド一覧をご紹介します

コンテナをイメージから作成

■ 書式

docker run [オプション] –name [コンテナ名] [イメージ名]:[タグ名] [コンテナ起動直後に実施するコマンド]

■ 実例

CentOS7のイメージをもとにコンテナを起動して、hogeという文字列を表示させます。

$ docker run --name test centos:centos7 /bin/echo hoge
hoge

コンテナをデーモンで起動

■ 書式

docker run -d –name [コンテナ名] [イメージ名]:[タグ名] [コンテナ起動直後に実施するコマンド]

■ 実例

Apacheのイメージをもとに、testwebという名前のコンテナをデーモンで起動します。

$ docker run -d --name testweb httpsd:2.4.41

コンテナのポートを転送

■ 書式

docker run -d -p [localhostからアクセスするポート]:[コンテナのポート] –name [コンテナ名] [イメージ名]:[タグ名] [コンテナ起動直後に実施するコマンド]

■ 実例

Apacheのイメージをもとに、testwebという名前のコンテナをデーモンで起動し、localhostの8080ポート宛のアクセスを、コンテナの80ポートに転送します。

$ docker run -d -p 8080:80 --name testweb httpsd:2.4.41

稼働中のコンテナにコマンド実行

■ 書式

docker exec [コンテナ名もしくはコンテナID] [実行したいコマンド]

■ 実例

稼働中のコンテナのディレクトリ・ファイル一覧を表示します。

$ docker exec testweb /bin/ls
bin
build
cgi-bin
conf
error
htdocs
icons
include
logs
modules

稼働中のコンテナにログイン

■ 書式

docker exec -it [コンテナ名もしくはコンテナID] [シェルのコマンド]

■ 実例

testwebという名前の稼働中のコンテナにログインします。

$ docker exec -it testweb /bin/bash

稼働中のコンテナ一覧を表示

■ 書式

docker ps

■ 実例

稼働中のコンテナの一覧を表示します。

$ docker ps

稼働中のコンテナを停止

■ 書式

docker stop [コンテナ名もしくはコンテナID]

■ 実例

testwebという名前のコンテナを停止します。

$ docker stop testweb

稼働中のコンテナを再開

■ 書式

docker start [コンテナ名もしくはコンテナID]

■ 実例

testwebという名前のコンテナを再開します。

$ docker start testweb

稼働中のコンテナを全て停止

■ 書式

docker stop $(docker ps -q)

■ 実例

稼働中のコンテナを全て停止します。

$ docker stop $(docker ps -q)

停止中のコンテナも含めて全てのコンテナを一覧を表示

■ 書式

docker ps -a

■ 実例

停止中のコンテナも含めて全てのコンテナの一覧を表示します。

$ docker ps -a

停止中のコンテナを削除

■ 書式

docker rm [コンテナ名もしくはコンテナID]

■ 実例

停止中のtestwebというコンテナを削除します。

$ docker rm testweb

停止中のコンテナを全て削除

■ 書式

docker rm $(docker ps -aq)

■ 実例

停止中コンテナを全て削除します。

$ docker rm $(docker ps -aq)

Dockerイメージの一覧を表示

■ 書式

docker images

■ 実例

Dockerイメージの一覧を表示します。

$ docker images

Dockerイメージを削除

■ 書式

docker rmi [イメージ名もしくはイメージIDを]

■ 実例

hogeという名前のイメージを削除します。

$ docker rmi hoge

danglingなイメージを全て削除

■ 書式

docker rmi $(docker images -f “dangling=true” -q)

■ 実例

danglingなイメージを全て削除します。

$ docker rmi $(docker images -f "dangling=true" -q)

不要なリソースを全て削除

■ 書式

docker system prune

■ 実例

停止中のコンテナやdanglingなイメージなど不要なリソースを全て削除します。

$ docker system prune

ログの取得

■ 書式

docker logs [コンテナ名もしくはコンテナID]

■ 実例

testwebというコンテナ名のコンテナのログを取得します。

$ docker logs testweb

Dockerfileからイメージをビルド

■ 書式

docker build -t [イメージ名] .

■ 実例

Dockerfileという名前のDockerfileからtestwebというコンテナのイメージを作成します。

$ docker build -t testweb .

まとめ

いかがでしょうか?本記事を読めばDockerの基本的な使い方はマスターできると思います。これからDockerを使う方に対して、その入門記事としてお役に立てれば幸いです。Dockerホントに便利ですよね。No Docker, No Life!!

次回は以下になります。

【連載】世界一わかりみが深いコンテナ & Docker入門 〜 その3:Dockerfileってなに? 〜

アバター画像
About 武井 宜行 267 Articles
Microsoft MVP for Azure🌟「最新の技術を楽しくわかりやすく」をモットーにブログtech-lab.sios.jp)で情報を発信🎤得意分野はAzureによるクラウドネイティブな開発(Javaなど)💻「世界一わかりみの深いクラウドネイティブ on Azure」の動画を配信中📹 https://t.co/OMaJYb3pRN
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

38人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる