minikube(ミニキューブ) は Kubernetes の環境を作成するためのパッケージで、単一 Node の環境構築をするコマンドです。
現在の Docker For Mac では Kubernetes が統合インストールされますが、minikube は別途インストールする必要があります。
Kubernetes を利用するには、以下のいずれかのハイパーバイザーをインストールが必要です。
macOS では、Hypervisor Framework に対応した HyperKit も利用できるためインストールします。
$ brew install hyperkit
HyperKit のバージョンを確認します。
$ hyperkit -v
hyperkit: v0.20200224-44-gb54460
homebrew コマンドで minikube をインストールします。
$ brew install minikube
minikube がインストールされたかバージョンを確認します。
$ minikube version
minikube version: v1.13.1
もし /usr/local/bin/minikube がない場合、現在のフォルダにある minikube を /usr/local/bin/ に移動します。
$ sudo mv minikube /usr/local/bin
minikube のドライバを HyperKit にして起動します。起動にはパスワードが必要です。
$ minikube start --vm-driver=hyperkit
...
Password:
...
🏄 Done! kubectl is now configured to use "minikube" by default
minikube の起動確認をします。Running と表示されていれば起動中です。
$ minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
Docker For Mac のめnyメニューにも minikube が追加されています。
minikube を停止します。
$ minikube stop
minikube が停止したか確認します。
$ minikube status
minikube
type: Control Plane
host: Stopped
kubelet: Stopped
apiserver: Stopped
kubeconfig: Stopped
初回ハイパーバイザーを設定して起動しておくと、次回からはオプションなしで起動できます。
$ minikube start
起動前にクラスターを変更する場合、 config use を利用してから起動します。
$ kubectl config use クラスター名
kubectl でクラスタ構成を確認し、デフォルトで minikube クラスターが作成されているのを確認します。
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
docker-desktop docker-desktop docker-desktop
docker-for-desktop docker-desktop docker-desktop
* minikube minikube minikube
その他のクラスタは、Docker For Mac インストールで作成されたクラスターです。
Namespace 一覧を取得します。
$ kubectl get namespace
NAME STATUS AGE
default Active 19m
kube-node-lease Active 19m
kube-public Active 19m
kube-system Active 19m
default:
デフォルト Namespacekube-system:
Kubernetesシステムで作成されたオブジェクト用の Namespacekube-public:
全てのユーザーから読み取り可能な Namespaceリkube-system の Pod を取得します。
$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-f9fd979d6-gbpf4 1/1 Running 1 21m
etcd-minikube 1/1 Running 1 21m
kube-apiserver-minikube 1/1 Running 1 21m
kube-controller-manager-minikube 1/1 Running 1 21m
kube-proxy-kjbn8 1/1 Running 1 21m
kube-scheduler-minikube 1/1 Running 1 21m
storage-provisioner 1/1 Running 2 21m
minikube には機能拡張するアドオンがあり、一覧を確認して enabled となっているのが有効になっているアドオンです。
$ minikube addons list
ingress を追加してみます。
$ minikube addons enable ingress
🔎 Verifying ingress addon...
🌟 The 'ingress' addon is enabled
アドオンを利用停止にするときは以下のコマンドを実行します。
$ minikube addons enable アドオン名
ingress は https ロードバランサーで、IP管理を service ではなく ingress で管理することができます。
hello-world コンテナを起動して、Hello from Docker! のメッセージ表示されるか確認します。
$ docker run hello-world
...
Hello from Docker!
...
現在利用されていないコンテナーを削除したい場合は、 prune で削除しておきます。
$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
c4e29bf9fb68a07e863384879fec3567342b9bb20c99c22c15aec8756c508b60
5d8680dcfcd40e1b9c1e0a52636106b10d118284f75494a902ff20f171a18dd4
Docker のコンテナからホストOSに接続するのに「host.docker.internal」というホストが用意されています。
Docker for Mac Stable release notes
Docker For Mac での機能なので、Linux ベースでは利用できないかと思います。
mysql コマンドで Dockerコンテナから、ホストOS(Mac)の MySQL に接続する場合、ホスト名に「host.docker.internal」を指定します。
# mysql -u ユーザ名 -h host.docker.internal -p
mysql>
よって、開発のプログラム上でも「host.docker.internal」をホストで設定して利用できます。
$db_name = 'DB名';
$user_name = 'ユーザ名';
$password = 'パスワード';
$host = 'host.docker.internal';
$dsn = "mysql:dbname={$db_name};host={$host}";
try {
$pdo = new PDO($dsn, $user_name, $password);
echo "接続成功" . PHP_EOL;
} catch (PDOException $e) {
echo "接続失敗: " . $e->getMessage() . PHP_EOL;
exit;
}
# psql -l -h host.docker.internal -U ユーザ名
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-------+----------+---------+-------+-------------------
postgres | yoo | UTF8 | C | C |
sample | yoo | UTF8 | C | C |
template0 | yoo | UTF8 | C | C | =c/yoo +
| | | | | yoo=CTc/yoo
template1 | yoo | UTF8 | C | C | =c/yoo +
| | | | | yoo=CTc/yoo
ホストOS から Docker の MySQLコンテナにログインする場合、以下の方法があります。
他のコンテナ同様、docker-compose で MySQL コンテナに直接ログインします。
$ docker-compose exec コンテナ名 bash
コンテナ名が mysql だった場合
$ docker-compose exec mysql bash
Docker コンテナにログインしたら、MySQL にログインします。
# mysql -u root -p
この方法は、docker-compose が動作するパスで実行する必要があり、MySQL コンテナ内でも mysql でログインします。
次にホスト OS から mysql コマンドでログインしてみます。
つまりは、Docker の MySQL を外部ホストでログインする方法です。
$ mysql -u root -p -h localhost -P 3306 --protocol=tcp
mysql で localhost を指定すると自分の PC を指すため、--protocol で TCP ソケットを指定する必要があります。
今回は、複数のコンテナを docker-compose を利用して起動してみます。
を参考に、Jenkins のMaster、Slave で複数のコンテナを構築します。
まず、Jenkins(Master)を以下の設定で作成します。
ポートフォワーディング、共有ボリュームは、左がホスト(Mac)、右がDockerの設定となります。
version: "3"
services:
master:
container_name: master
image: jenkinsci/jenkins:2.142-slim
ports:
- 8080:8080
volumes:
- ./jenkins_home:/var/jenkins_home
このように、volumes を設定することで、Dockerのデータをホスト側と共有させて、永続化することができます。
docker-compose.yml を作成したら、 --build でイメージ構築と同時に起動をします。
$ docker-compose up --build
途中で、Jenkins の管理者パスワードが表示されるため、控えておきましょう。
忘れた場合は、Docker内の「/var/jenkins_home/secrets/initialAdminPassword」に記載されています。
...
master | Jenkins initial setup is required. An admin user has been created and a password generated.
master | Please use the following password to proceed to installation:
master |
master | パスワード
master |
master | This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
...
この時点で、ホスト側のルートにも「jenkins_home」ディレクトリが作成されます。
Jenkins(Master)コンテナ内で、SSH認証キーを作成します。
dockerコンテナに対して、シェルコマンドを実行します。
$ docker container exec -it コンテナ名 シェルコマンド
今回は、ssh-keygen を利用するので、
$ docker container exec -it master ssh-keygen -t rsa -C ""
Generating public/private rsa key pair.
Enter file in which to save the key (/var/jenkins_home/.ssh/id_rsa):
Created directory '/var/jenkins_home/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
...
SHA256:SSHキー
すると、jenkins_home/.ssh/ に id_rsa、id_rsa.pub が作成されます。
Jenkins(Slave)を設定するため、一旦、コンテナを停止します。
$ docker-compose down
Jenkins(Slave)を設定を行います。
version: "3"
services:
master:
container_name: master
image: jenkinsci/jenkins:2.142-slim
ports:
- 8080:8080
volumes:
- ./jenkins_home:/var/jenkins_home
links:
- slave01
slave01:
container_name: slave01
image: jenkinsci/ssh-slave
enviloment:
- JENKINS_SLAVE_SSH_PUBKEY=id_rsa.pub のキー
enviloment は環境変数の設定で、「JENKINS_SLAVE_SSH_PUBKEY」に「jenkins_home/.ssh/id_rsa.pub」のキーを設定します。
また、Jenkins(Master)で、links を設定して master から slave01 を名前解決できるようにします。
コンテナをバックグランドで起動します。
$ docker-compose up -d
設定したポートで、http://localhost:8080/ にアクセスすると、Jenkins の画面が表示されます。
パスワードは、Jenkins(Master)の起動で表示されたものを利用します。
手っ取り早く、Install suggested plugins を選択してインストールします。
Jenkins のユーザを作成してログインします。
本の通りにノードの管理で、slave01 の認証情報(id_rsa、パスフレーズ)などを設定していきますが、slave01 の起動がエラーになってしまいました。
(Jenkins の Jenkinsの管理 > ノードの管理 で slave01 の設定の箇所)
...
java.io.IOException: Java not found on hudson.slaves.SlaveComputer
...
調べたところ、slave01 で java のパスを通す必要があるようです。
$ docker exec -it slave01 bash
# which java
/usr/local/openjdk-8/bin/java
このパスを、slave01 の「高度な設定 > Javaのパス」に設定します。
これで、ノード再起動すると同期が完了します。
ちなみに、Docker For Mac で利用してみましたが、結構CPU負荷が高いです。
$ docker-compose stats
Qiita とか調べていると、いきなり docker と docker-compose が混在してなんだこりゃ?となったりします。
(少なくとも自分は)
特に、他人の作ったdocker-compose.yml を docker の基礎がわからないと何をしているのか読み取れません。
例えば、Laravel を Docker で動かす Laradock はすごく便利で少しの知識があれば開発環境を動作せることが可能ですが、「やっぱり自分で構築したい!」となると、その設定を全部把握するのはかなりの時間がかかりそうです。
最初は docker の基本コマンドを繰り返し実感するのが良いのでは?と思います。
まず、docker-compose コマンドが存在するか確認します。
$ docker-compose version
docker-compose version 1.25.4, build 8d51620a
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.1d 10 Sep 2019
あらかじめ、Dockerfile でイメージを作成済みであることを前提とします。
#!/bin/sh
echo "Hello Shell Script"
FROM ubuntu:18.04
COPY hello.sh /usr/local/bin
RUN chmod +x /usr/local/bin/hello.sh
CMD ["hello.sh"]
docker-compose を利用する前にまず docker コマンドでの起動を確認します。
$ docker image build -t
example/hello:latest . $ docker container run
example/hello:latest
起動確認ができたら、一度 dockerコンテナを落としておきます。
$ docker stop コンテナID
docker-compose を利用するには、「docker-compose.yml」の設定が必要となります。
version: "3"
services:
hello:
image: example/hello:latest
ports:
- 9000:8080
docker-compose up で、docker-compose.yml を読み込み、「hello.sh」が実行されます。
docker-compose.yml のフォーマットバージョンで、「3」は2020/3時点での最新です。
services: の第一階層に、各コンテナの名前を複数定義します。
例では、hello がコンテナ名となります。
Dockerイメージ名を設定します。
ホストと docker のポートフォワーディング設定(ホストポート:dockerポート)
$ docker-compose up
Creating network "docker-hello_default" with the default driver
Creating docker-hello_hello_1 ... done
Attaching to docker-hello_hello_1
hello_1 | Hello Shell Script
docker-hello_hello_1 exited with code 0
ちなみに、このサンプルは hello.sh を実行したのちに exit しているため、状態は「Exit 0」となっています。
docker のプロセス確認は docker-compose コマンドでも可能です。
$ docker-compose ps
Name Command State Ports
-----------------------------------------------
docker-hello_echo_1 hello.sh Exit 0
docker-compose.yml で設定しているコンテナを全て停止します。
$ docker-compose down
Dockerコンテナを作成するための元となるテンプレート
Dockerfile を作成して設定する
Dockerイメージを元に複数作成して、システム、アプリケーションを構成・実行されます。
Docker イメージはDocker Hub で検索できます。
※ユーザ登録はしておいた方が良いです
利用したいイメージやバージョンを「イメージ名:バージョン」でダウンロードできます。
$ docker image pull alpine:latest
latest は文字通り最新版なので、明示的にバージョンを指定する場合は、Docker Hub に記載されているバージョンを利用します。
Dockerイメージを作成する前に、Dockerコンテナ内で動作させるシェルスクリプトにサンプルを作成してみます。
#!/bin/sh
echo "Hello Shell Script"
次にDockerイメージを作成しますが、一般的に Dockerfile ファイルを利用しして設定します。
※今回は「ubuntu:18.04」イメージを利用します。
FROM ubuntu:18.04
COPY hello.sh /usr/local/bin
RUN chmod +x /usr/local/bin/hello.sh
CMD ["hello.sh"]
Dockerfile は DSL(ドメイン固有言語)を利用して、イメージを作成します。
その際、でてくるのがインストラクションです。
Dockerイメージ(OS)を指定(ビルド前)
ホスト側(Mac)から、Dockerコンテナの指定パスにコピーします。
上記はイメージビルド前に、ホスト側の「hello.sh」を「/usr/local/bin/」にコピーします。
類似的にリモート追加や自動解凍できる ADD インストラクションもある。
Dockerコンテナ内で、指定のコマンドを実行します。
上記は、コンテナにコピーした「/usr/local/bin/hello.sh」に実行権限を与えます。
完成したDockerイメージに対して、コマンドを実行します。
「,」で区切って引数を与えることもできます。
RUN との違いは、CMDはイメージビルド後に実行します。
hello:latest とラベルをつけて Dockerイメージをビルドします。
$ docker image build -t hello:latest .
引数はイメージ名と Dockerfile の配置したパスを指定します。
$ docker image build -t イメージ名:タグ名 Dockerfile配置パス
タグ名は、一般的にバージョンとして利用されます。
$ docker container run hello:latest
Hello Shell Script
「hello:latest」コンテナが起動後に、shell.sh が実行されました。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello latest 05e3eb5ff03b 5 minutes ago 64.2MB
...
リポジトリが「hello」、タグ「latest」、イメージID「05e3eb5ff03b」で作成されています。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
62faba8c4477 hello:latest "hello.sh" 8 minutes ago Exited (0) 8 minutes ago admiring
hello:latest コンテナが、コンテナID「62faba8c4477」で作成されていることがわかります。
実際に運用する場合、Github のように namespace や バージョンをつける必要がでてきます。
例えば、イメージ名「hello」は、namespace(空間名)をつけて「sample/hello」、 バージョンは「:」で区切って、「hello:latest」、「hello:0.1.0」のような書き方ができます。
$ docker image tag hello:latest example/hello:latest
$ docker image tag hello:latest example/hello:0.1.0
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
example/hello 0.1.0 ca00cb953947 2 hours ago 64.2MB
example/hello latest ca00cb953947 2 hours ago 64.2MB
...
Docker を利用しているとイメージやコンテナを作りすぎて、パソコンの容量を圧迫しがちです。
また、イメージやコンテナリストが大量になり確認もしづらくなるので、リスト検索して不要なものは削除しましょう。
$ docker container list
$ docker rm コンテナID
$ docker image list
//または
$ docker images
$ docker rmi イメージID
Docker もう一度を最初から学ぶ為に、シリーズで書いていきます。
今回は、
Mac で Docker を始めるには「Docker For Mac」を利用するのがお手軽です。
公式のページの Docker For Mac から dmgファイル(※2020-03-02時点:version 2.2.2.0)をダウンロードします。
Start Docker when you log in
Automatically check for updates
個人差がありますが、デフォルトで使用してみて足りないようなら変更してみると良いでしょう。
「File Sharing」で、Dockerコンテナ側がマウントするディレクトリを設定できます。
差し当たり、デフォルトのままで良いと思います。
Dockerコンテナが利用する、IPアドレスの範囲をしていします。
自分でカスタマイズしても構いませんが、差し当たりデフォルトにしておきます。
Docker for Mac がインストールできたら、Mac のターミナルで docker コマンドを実行してみます。
$ docker --version
Docker version 19.03.5, build 633a0ea
今度はあらかじめ作成されている Dockerコンテナを起動してみます。
docker/getting-started というコンテナが Docker Hub に用意されているので、これを起動してみます。
$ docker run -dp 80:80 docker/getting-started
色々とオプションが入ってますが、わかりやすく書くと以下の通りとなります。
$ docker run オプション コンテナ名
今回の場合、docker/getting-started がコンテナイメージとなります。
通常はこのバックグラウンドで起動します。
ホスト側のポート番号と、コンテナ側のポート番号をマッピングします。
ホストポート番号:コンテナポート番号
コンテナ起動のオプションは、
$ docker run --help
で調べることができます。
コンテナを起動したら、コンテナの起動状況(プロセス)を確認します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4abe131793c6 docker/getting-started "nginx -g 'daemon of…" 31 minutes ago Up 31 minutes 0.0.0.0:80->80/tcp unruffled_roentgen
上記は、コンテナIDが「4abe131793c6」、コンテナイメージが「docker/getting-started」で起動しています。
Mac側のポート80 と Docker側のポート80 がマッピングされているため、
にアクセスすると、Webサーバを介してチュートリアルが表示されます。
Docker Getting StartedイメージのWebサーバは「nginx」が起動しているようです。
コンテナを停止します。
$ docker stop 4abe131793c6
引数は docker ps で記載されたコンテナIDを指定して
$ docker stop コンテナID
Docker を利用する場合、Mac(ホスト) と Dockerコンテナ 間でディスク共有します。
ディスクマウントの仕様上、Docker For Mac は他のDocker環境に比べて速度が遅い(レイテンシー)傾向があります。
これは個人差があるので一概に言えませんが、開発できないレベルではありません。
Install Docker Desktop on Macをダウンロードしてインストール
$ git clone https://github.com/Laradock/laradock.git
laradock/.env #Dockerコンテナイメージ & 設定
projects/ #Laracelプログラムソース
自分が開発する場合、複数のプロジェクトを一つのサーバで管理するため、projects とした。
例) projects/blog/ projects/shop/ ※Laravelプロジェクト直下に、.htaccess でmod_rewirte(Apacheの場合)
$ cd laradock/
$ cp env-example .env
#Dockerのwebサーバーの同期ディレクトリ
#ホスト側のディレクトリを指定
APP_CODE_PATH_HOST=../projects/
#Dockerのstorage等を保存
#ホスト側のディレクトリを指定
DATA_PATH_HOST=../.laradock/data
#PHP
PHP_VERSION=7.3
PHP_INTERPRETER=php-fpm
# php-fpm で PostgreSQLドライバをインストール(MySQLはインストールしない)
PHP_FPM_INSTALL_PGSQL=true
PHP_FPM_INSTALL_MYSQLI=false
コンテナー名が自動的にホスト名になるので、docker-compose.yml で明示的にホスト名を設定します。
### PHP-FPM ##############################################
php-fpm:
hostname: laradock //ホスト名を明示的に設定
build:
context: ./php-fpm
必要に応じてコンテナを指定して、ビルド & 起動(初回は時間がかかります)
$ docker-compose up --build -d apache2 postgres
$ docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------------
laradock_apache2_1 /opt/docker/bin/entrypoint ... Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
laradock_docker-in-docker_1 dockerd-entrypoint.sh Up 2375/tcp, 2376/tcp
laradock_php-fpm_1 docker-php-entrypoint php-fpm Up 9000/tcp
laradock_postgres_1 docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
laradock_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcp
$ docker network list
NETWORK ID NAME DRIVER SCOPE
1f2d988e2454 bridge bridge local
c2ddd125b91c docker-hello_default bridge local
7376c045c61c host host local
48598c23f7d5 laradock_backend bridge local
63cead02763c laradock_default bridge local
1954ef460361 laradock_frontend bridge local
f8f6d3c3cfe3 none null local
$ docker-compose exec workspace bash
# hostname -i
# composer create-project laravel/laravel project-name
指定したPostgreSQL ホスト、ユーザ情報を Laravelプロジェクトの .env を設定
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=blog
DB_USERNAME=default
DB_PASSWORD=secret
複数のLaravelプロジェクトを Dockerで動かしたいので、プロジェクト直下に .htaccess を作成して、server.php に mod_rewrite をします。
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ ^$1 [N]
RewriteCond %{REQUEST_URI} (\.\w+$) [NC]
RewriteRule ^(.*)$ public/$1
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ server.php
localhost にルーティングされているので、ブラウザで アクセスします。
$ docker-compose stop
Dockerでディスク容量を圧迫してしまいがちで、タグのついていない不要なイメージを削除します。
$ docker ps -f "status=exited"
$ docker container prune
$ docker images --filter "dangling=true"
$ docker image prune
ちなみに、v1.2.5 以前では以下のコマンドで削除していました。
$ docker rmi $(docker images -f "dangling=true" -q)
$ docker network ls
$ docker network prune
不要なイメージ・コンテナ・ボリューム・ネットワークを削除するには、「system」を利用します。
$ docker system prune
もしくは
Macからホスト:0.0.0.0 で接続可能となる
psqlコマンドを直接利用するために、HomeBrewでPostgreSQLをインストール
<h3class="h3">確認