ためすう

docker を使ってみる (チュートリアル Part5: スタック)

2019-10-20

やったこと

docker を使ってみます。

チュートリアルの Part5 です。

調査

スタック (stack)

スタックは相互関係を持つサービスのグループであり、依存関係を共有します。そして、同時にオーケストレート(訳者注;複数のサーバ上で一斉に挙動する)やスケール(訳者注;サービスの拡大および縮小)します。

docker-compose.yml の準備

docker-compose.yml

version: '3'
services:
  web:
    image: hogehoge/get-started:part1
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - '80:80'
    networks:
      - webnet
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet
  redis:
    image: redis
    ports:
      - "6379:6379"
    volumes:
      - ./data:/data
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet
networks:
  webnet:

web.image はご自身の環境に合わせて変更してください

myvm1 環境にコピー

$ docker-machine scp docker-compose.yml myvm1:~

ディレクトリ準備

ホスト上の ./data に対して、Redis コンテナでは、/data でアクセスします。

$ docker-machine ssh myvm1 "mkdir ./data"

デプロイ

$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"

確認

$ docker-machine ssh myvm1 "docker stack ps getstartedlab"
ID                  NAME                         IMAGE                             NODE                DESIRED STATE       CURRENT STATE          ERROR               PORTS
zh7eyy78eeiw        getstartedlab_redis.1        redis:latest                      myvm1               Running             Running 21 hours ago
a7qov9u2po63        getstartedlab_visualizer.1   dockersamples/visualizer:stable   myvm1               Running             Running 21 hours ago

redisvisualizer が追加されているのが確認できると思います。

確認

redis

http://192.168.99.100 http://192.168.99.101 にアクセスする度にカウンタが増えていきます。

visualizer

http://192.168.99.100:8080 でページを見ることが出来ます。

参考

docker を使ってみる (チュートリアル Part4: Swarm)

2019-10-20

やったこと

docker を使ってみます。

チュートリアルの Part4 です。

調査

Swarmクラスタの理解

swarm とは Docker が動作し、クラスタに参加しているマシン・グループです。

swarm 上のマシンは物理あるいは仮想どちらも使えます。swarm に加わった後は、これらは ノード として参照されます。

$ docker swarm init

swarm mode を有効化し、現在のマシンを swarm マネージャにします。

仮想マシン の作成

$ docker-machine create --driver virtualbox myvm1
$ docker-machine create --driver virtualbox myvm2

swarm の初期化

$ docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100:2377"
Swarm initialized: current node (xxxxxxxxxxx) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token [my_token] 192.168.99.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

これで myvm1 が swarm manager となりました。

myvm2 を join する

$ docker-machine ssh myvm2 "docker swarm join \
--token [my_token] \
192.168.99.100:2377"
This node joined a swarm as a worker.

my_token は自分の token に置き換えてください。

node 確認

$ docker-machine ssh myvm1 "docker node ls"
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
2y7x69ce4gkm0eewep0meoyjk *   myvm1               Ready               Active              Leader              19.03.3
x3pmieqf6lri4b4wqp7hhgrw7     myvm2               Ready               Active                                  19.03.3

デプロイ

$ docker-machine scp docker-compose.yml myvm1:~
$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"

※ docker-compose.yml は Part3 で使ったものを使用します。

image は Docker Hub にアップロードしているものを使います。

スタック (stack) の確認

$ docker-machine ssh myvm1 "docker stack ps getstartedlab"
ID                  NAME                         IMAGE                             NODE                DESIRED STATE       CURRENT STATE          ERROR               PORTS
ocgug6lzsq8t        getstartedlab_web.1          hogehoge/get-started:part1      myvm1               Running             Running 21 hours ago
wwq7y0fp5a8k        getstartedlab_web.2          hogehoge/get-started:part1      myvm2               Running             Running 21 hours ago
oyeqksqowa9x        getstartedlab_web.3          hogehoge/get-started:part1      myvm1               Running             Running 21 hours ago
jl7rqoy40yxl        getstartedlab_web.4          hogehoge/get-started:part1      myvm2               Running             Running 21 hours ago
qrrp9ft7fv87        getstartedlab_web.5          hogehoge/get-started:part1      myvm2               Running             Running 21 hours ago
$ docker-machine ls
NAME    ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
myvm1   -        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.3
myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v19.03.3

192.168.99.100 192.168.99.101 にアクセスすると、5つのコンテナのいずれかにアクセスします。

swarm を削除する

$ docker-machine ssh myvm2 "docker swarm leave"
$ docker-machine ssh myvm1 "docker swarm leave --force"

参考

File#flock を使ってみる (Ruby)

2019-10-20

やったこと

File の flock について挙動を確認しました。

確認環境

$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]

$ rails --version
Rails 5.2.3

調査

排他ロックを使う

コンソール1

$ rails c
Running via Spring preloader in process 31090
Loading development environment (Rails 5.2.3)
irb(main):001:0> f = File.open("/tmp/foo", "w")
=> #<File:/tmp/foo>
irb(main):002:0> f.flock(File::LOCK_EX)
=> 0

コンソール2

$ rails c
Running via Spring preloader in process 31491
Loading development environment (Rails 5.2.3)
irb(main):001:0> f = File.open("/tmp/foo", "w")
=> #<File:/tmp/foo>
irb(main):002:0> f.flock(File::LOCK_EX)

コンソール2は止まっています。

コンソール1 (unlockする)

irb(main):003:0> f.flock(File::LOCK_UN)
=> 0

コンソール2

irb(main):002:0> f.flock(File::LOCK_EX)
=> 0

排他ロックされている場合、待たせない

コンソール1

$ rails c
Running via Spring preloader in process 33223
Loading development environment (Rails 5.2.3)
irb(main):001:0> f = File.open("/tmp/foo", "w")
=> #<File:/tmp/foo>
irb(main):002:0> f.flock(File::LOCK_EX | File::LOCK_NB)
=> 0

コンソール2

$ rails c
Running via Spring preloader in process 33627
Loading development environment (Rails 5.2.3)
irb(main):001:0>  f = File.open("/tmp/foo", "w")
=> #<File:/tmp/foo>
irb(main):002:0> f.flock(File::LOCK_EX | File::LOCK_NB)
=> false

先に排他的ロックが取られている場合、処理を待つことなく false が返されました。

参考

sed に BSD と GNU の確認方法

2019-10-20

やったこと

sed でテキストの置換処理を調べていたのですが、書いてある通りに動かないことがありました。

それは、BSD と GNU で異なることが原因のようでした。

Mac ではデフォルトでは sed は BSD 版が入っているようです。

今回、以下をやりました。

  • GNU 版のインストール
  • BSD、GNUの確認方法

調査

GNU 版のインストール

brew でインストールします。

$ brew install gnu-sed
$ gsed --version
gsed (GNU sed) 4.7
Copyright (C) 2018 Free Software Foundation, Inc.
(以下省略)

BSD、GNUの確認方法

$ man sed

出力結果 (抜粋)

SED(1)                    BSD General Commands Manual                   SED(1)

NAME
     sed -- stream editor

BSD 版が入っていることが確認できました。

参考

メソッドの定義されている箇所を見つける (Ruby)

2019-10-20

やったこと

メソッドの定義されている箇所を探します。

確認環境

$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]

$ rails --version
Rails 5.2.3

調査

irb(main):005:0> Task.new.method(:to_query).source_location
=> ["/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/core_ext/object/to_query.rb", 13]

どこにのファイルで定義されている分かります。

参考

docker を使ってみる (チュートリアル Part3: サービス)

2019-10-17

やったこと

docker を使ってみます。

チュートリアルの Part3 です。

調査

サービスとは、正に「本番環境におけるコンテナ」なのです。

docker-compose.yml の作成

プロダクションにおける Docker コンテナのあるべき挙動を定義します

docker-compose.yml

version: '3'
services:
  web:
    image: friendlyhello
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - '80:80'
    networks:
      - webnet
networks:
  webnet:

Doker Swarm

Docker Swarm は Docker に対応するネイティブなクラスタリング用ツールです。Docker Swarm は標準 Docker API で操作できます。

コンテナを複数立ち上げる

$ docker swarm init
$ docker stack deploy -c docker-compose.yml getstartedlab

getstartedlab というアプリケーションの名前をつけています。

サービスの情報表示

$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                  PORTS
xxng7z8u0l7w        getstartedlab_web   replicated          5/5                 friendlyhello:latest   *:80->80/tcp

コンテナの一覧表示

$ docker container ls -q
d529dc4961e3
8c47e3a1207e
7e8a65af869f
4d03c61b387e
1e3780cdd23a

停止

$ docker stack rm getstartedlab

swarm は起動したまま

$ docker node ls
ID                            HOSTNAME                STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
l8th1njjpb5qd71epemf95ony *   linuxkit-025000000001   Ready               Active              Leader              18.09.2

swarm も停止

$ docker swarm leave --force

参考

Mac の launchctl を調べる

2019-10-17

やったこと

Mac の launchctl について調べます。

調査

launchd を使って、daemon、agent を管理するプログラムです。

plist の管理場所

~/Library/LaunchAgents         Per-user agents provided by the user.
/Library/LaunchAgents          Per-user agents provided by the administrator.
/Library/LaunchDaemons         System-wide daemons provided by the administrator.
/System/Library/LaunchAgents   Per-user agents provided by Apple.
/System/Library/LaunchDaemons  System-wide daemons provided by Apple.

puma-dev の場合

unload します

$ launchctl unload ~/Library/LaunchAgents/io.puma.dev.plist

puma-dev のプロセスを kill しても、消せなかったのですが、 これで制御することができました。

参考

docker を使ってみる (チュートリアル Part2)

2019-10-15

やったこと

docker を使ってみます。

チュートリアルの Part2 です。

調査

Dockerfile の定義

コンテナで何をするのかということを定義します。

Dockerfile

# 公式 Python ランタイムを親イメージとして使用
FROM python:2.7-slim

# 作業ディレクトリを /app に設定
WORKDIR /app

# 現在のディレクトリの内容を、コンテナ内の /app にコピー
ADD . /app

# requirements.txt で指定された必要なパッケージを全てインストール
RUN pip install -r requirements.txt

# ポート 80 番をコンテナの外の世界でも利用可能に
EXPOSE 80

# 環境変数の定義
ENV NAME World

# コンテナ起動時に app.py を実行
CMD ["python", "app.py"]

※ 下記ファイルも必要ですが、参考サイトを見てください。

  • app.py
  • requirements.txt

Docker イメージを作成

$ docker build -t friendlyhello .

アプリケーションを起動する

$ docker run -p 4000:80 friendlyhello
$ curl http://localhost:4000

確認

実行中のコンテナID 2a2ef4f0bd30 の確認

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
2a2ef4f0bd30        friendlyhello       "python app.py"     8 minutes ago       Up 8 minutes        0.0.0.0:4000->80/tcp   confident_tu

Docker Hub のイメージを利用する

Docker Hub のイメージを使い nginx を起動します。

$ docker pull nginx:latest

Dockerfile

FROM  nginx:latest

# author
MAINTAINER  hoge

ADD default.conf /etc/nginx/conf.d

RUN echo "now building..."

docker-compose.yml

version: '3'
services:
  nginx:
    build: .
    ports:
      - "8080:80"
    volumes:
      - ./public:/usr/share/nginx/html

設定ファイルを空で用意します

$ touch default.conf

コンテナ起動

$ docker-compose up

コンテナに入る

nginx_nginx_1 はコンテナ名です。

$ docker exec -i -t nginx_nginx_1 bash

設定ファイルは default.conf と同じで空でした。

# cat /etc/nginx/conf.d/default.conf

参考

puma-dev を使ってみる

2019-10-15

やったこと

puma-dev を使ってみます。

確認環境

$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]

$ rails --version
Rails 5.2.3

調査

セットアップ

$ brew install puma/puma/puma-dev

Mac OS でセットアップ

# Configure some DNS settings that have to be done as root
$ sudo puma-dev -setup
# Configure puma-dev to run in the background on ports 80 and 443 with the domain `.test`.
$ puma-dev -install

シンボリックリンクの設定

※ /path/to/my/app は実行したいアプリケーションです。

$ cd ~/.puma-dev; ln -s /path/to/my/app test

test.test でアプリケーションを閲覧することができます。

おまけ

ログを見る

$ less ~/Library/Logs/puma-dev.log

puma-dev を止める

$ puma-dev -stop

参考

docker を使ってみる (チュートリアル Part1)

2019-10-15

やったこと

docker を使ってみます。

チュートリアルの Part1 です。

調査

image

実行可能なパッケージであり、軽量で、単独で動作(stand-alone)します。

container

image を実行する環境のこと

Docker Engine (Docker の本体)

$ docker --version
Docker version 18.09.2, build 6247962

Docker Machine

Docker Machine は仮想マシン上に Docker Engine をインストールするツールであり、 docker-machine コマンドを使ってホストを管理します。

$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01

Docker Compose

Compose は複数のコンテナを使う Docker アプリケーションを定義・実行するためのツールです

$ docker-machine --version
docker-machine version 0.16.1, build cce350d7

参考