いいものをつくろう

CTOの日記

DB

hbaseをdockerでローカルで起動したら、だいぶdockerに慣れる

投稿日:

この記事を読むと
・dockerのペーパードライバーが実際に手を動かして、すこし自信がつく
・hbaseが手元(local)で動かせれる

dockerについてたくさんの学びがありました。
・networkもdefaultで完全分離( bridge0)
・dockerの味噌は捨てやすさ
・dockerコマンドの基本的な使い方
・dockerのrunとstartの違い
・hbaseをdockerをつかって起動するまでの流れ
・docker exec -it xxxx bashでコンテナに入る

 

dockerでHbaseをインストールして
実際につかってみよう。

https://github.com/dajobe/hbase-docker
から

cd hbase-docker/
docker build -t dajobe/hbase .

 

Dockerfileの命令を上から実行しているようです。

dockerをほぼはじめて自分で使うので
時間がかかりそうだけど、ここではimageを作成しよとしています。

$ hbase-docker > docker -h | grep build
build Build an image from a Dockerfile

むちゃくちゃ、頑張っ調べるというよりは
おおむね何をやっているか理解しながら進みます。

Usage: docker build [OPTIONS] PATH | URL | -
Options:
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
--ulimit ulimit Ulimit options (default [])

ということで、現在(.)のpathにあるDockerfileから タグを指定して、そのimageをbuildという命令のようです。
Dockerfileにdajobe/hbase的なタグのような表記は見当たらないので、今のところ
どこの何と紐づいているのかは不明ですが、進みます。

初めてなのでイメージとつくる過程はサラッと眺めました。

$ hbase-docker > docker build -t dajobe/hbase .

 

Dockerfileの命令を上から実行しているようです。

Sending build context to Docker daemon 115.7kB
Step 1/17 : FROM ubuntu:bionic
bionic: Pulling from library/ubuntu
Status: Downloaded newer image for ubuntu:bionic
Step 5/17 : RUN /build/prepare-hbase.sh && cd /opt/hbase && /build/build-hbase.sh cd / && /build/cleanup-hbase.sh && rm -rf /build
Processing triggers for libc-bin (2.27-3ubuntu1) ...
+ . /build/config-hbase.sh
+ HBASE_DIST=http://archive.apache.org/dist/hbase
+ export INITRD=no
+ export DEBIAN_FRONTEND=noninteractive
+ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
+ minimal_apt_get_args=-y --no-install-recommends
+ HBASE_BUILD_PACKAGES=curl
+ HBASE_RUN_PACKAGES=openjdk-8-jre-headless
+ pwd
+ here=/opt/hbase
+ rm -rf docs LICENSE.txt NOTICE.txt README.txt LEGAL
+ rm -f bin/hbase-config.cmd bin/hbase.cmd bin/start-hbase.cmd bin/stop-hbase.cmd conf/hbase-env.cmd
+ sed -i s,^. export JAVA_HOME.*,export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64, conf/hbase-env.sh
+ cat
+ cd /usr/bin
+ ln -sf /opt/hbase/bin/considerAsDead.sh /opt/hbase/bin/draining_servers.rb /opt/hbase/bin/get-active-master.rb

Step 7/17 : ADD ./hbase-site.xml /opt/hbase/conf/hbase-site.xml
---> 5941d0ea634d
Step 8/17 : ADD ./zoo.cfg /opt/hbase/conf/zoo.cfg
---> 7e5d171be3fe
Step 9/17 : ADD ./replace-hostname /opt/replace-hostname
---> e0f1f25e0adb
Step 10/17 : ADD ./hbase-server /opt/hbase-server
---> 94dadf3f83d2
Step 11/17 : EXPOSE 8080
---> Running in a831d2b6ff3b
Removing intermediate container a831d2b6ff3b
---> a8ab91ff0ea1
---> 7efdb4d48c7e
Step 17/17 : CMD ["/opt/hbase-server"]
---> Running in 8ca40c25ae25
Removing intermediate container 8ca40c25ae25
---> 98885969cb58
Successfully built 98885969cb58
Successfully tagged dajobe/hbase:latest

だいたい5分くらい終了しましたね。
これでdocker buildはimageを作るということだたので、みてみると

> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dajobe/hbase latest 98885969cb58 11 minutes ago 469MB

ちゃんと出来てますね

 

ではhbaseコンテナーとして実行します。ゆうてもhost OS上の閉鎖的1プロセスとして実行するだけです。

mkdir data
$ id=$(docker run --name=hbase-docker -h hbase-docker -d -v $PWD/data:/data dajobe/hbase)

 

> id=$(docker run --name=hbase-docker -h hbase-docker -d -v $PWD/data:/data dajobe/hbase)
実行したら
静かにコマンド終了しました。これが-d (detach)つまりはbackgroundで実行したからでしょう

ではプロセス(OS上の閉鎖的1プロセス)が立ち上がったはずなので
みてましょう

> docker ps --help

Usage: docker ps [OPTIONS]
List containers

Options:
-a, --all Show all containers (default shows just running)
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print containers using a Go template
-n, --last int Show n last created containers (includes all states) (default -1)
-l, --latest Show the latest created container (includes all states)
--no-trunc Don't truncate output
-q, --quiet Only display numeric IDs
-s, --size Display total file sizes

docker ps

> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6bba0c2e5fbd dajobe/hbase "/opt/hbase-server" 3 minutes ago Up 3 minutes 2181/tcp, 8080/tcp, 8085/tcp, 9090/tcp, 9095/tcp, 16010/tcp hbase-docker

ということで
なにやらcontainer idというの割り振られていて、イメージ名、実行時に--nameで指定したnameやポート情報とCOMMANDとして/opt/hbase-serverというのがありますね。これは
起動時に実行されたコマンドのことです。

ここで

hbase-dockerというホスト名をcontainerに紐づける
ということがしたいので、./start-hbase.shを使ってください、ありまして/etc/hostsをいじるのでsudo 権限必要です とあります。

localhostでは動かないのでしょうか?
http://localhost:8085/rest.jsp

では動きません。
なぜなら、containerはlocalhostではアクセスできないからだと、思います。
では?
ポートは2181/tcp, 8080/tcp, 8085/tcp, 9090/tcp, 9095/tcp, 16010/tcp host上でリッスンしているのでしょうか?
答えはしていない。

> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6bba0c2e5fbd dajobe/hbase "/opt/hbase-server" 19 minutes ago Up 19 minutes 2181/tcp, 8080/tcp, 8085/tcp, 9090/tcp, 9095/tcp, 16010/tcp hbase-docker
> lsof -n -P -i :9090
> lsof -n -P -i :16010

ご覧のように 9090をリッスンしているプロセスはいるか?

netstat -a でもLISTEN情報はでてきませんでした。

なぜか、それはDockerfileのExposeっていうのは、ドキュメントみたいなもので、実際は実行するときに-Pオプションでポート繋いでくれ!とあるからです。
https://shinkufencer.hateblo.jp/entry/2019/01/31/233000

本家dockerの資料

EXPOSE <port> [<port>/<protocol>...]
The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified.

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to high-order ports.

By default, EXPOSE assumes TCP. You can also specify UDP:

EXPOSE 80/udp
To expose on both TCP and UDP, include two lines:

EXPOSE 80/tcp
EXPOSE 80/udp
In this case, if you use -P with docker run, the port will be exposed once for TCP and once for UDP. Remember that -P uses an ephemeral high-ordered host port on the host, so the port will not be the same for TCP and UDP.

Regardless of the EXPOSE settings, you can override them at runtime by using the -p flag. For example

docker run -p 80:80/tcp -p 80:80/udp ...
To set up port redirection on the host system, see using the -P flag. The docker network command supports creating networks for communication among containers without the need to expose or publish specific ports, because the containers connected to the network can communicate with each other over any port. For detailed information, see the overview of this feature)

docker runとstartの違いは?
https://www.ksakae1216.com/entry/2016/12/02/063000 をみて確信しましたが、
runは新しいcontainerを作って起動します
startは、既存のcontainerを名前やidで指定して起動します

docker --help | grep -E "start|run"
run Run a command in a new container
start Start one or more stopped containers

 

とうことです。

今は、./start-hbase.shの中でdocker runが書かれているので、一旦今試しに立ち上げたcontainerをkillします。
いらないので、
この使い捨て感!
がdockerの味噌です

> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6bba0c2e5fbd dajobe/hbase "/opt/hbase-server" 38 minutes ago Up 38 minutes 2181/tcp, 8080/tcp, 8085/tcp, 9090/tcp, 9095/tcp, 16010/tcp hbase-docker

docker kill 6bba0c2e5fbd
6bba0c2e5fbd

はい。

./start-hbase.sh

すると、同じ名前のコンテーナーが存在するぜ、と怒られて。

Starting HBase container
docker: Error response from daemon: Conflict. The container name "/hbase-docker" is already in use by container "6bba0c2e5fbd9b2b59d205e3c30376d0437a04326ee331dbd9361d3821e187ac". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

そうかkillではダメで、removeかと。

今のコンテナーの一覧ってどうやってみるの?
docker psですが、起動中しか見せないので、オプションで

> docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6bba0c2e5fbd dajobe/hbase "/opt/hbase-server" 41 minutes ago Exited (137) 3 minutes ago hbase-docker
ffb08a8b27d6 hello-world

ほりゃ!
まだあるやん!!
とうことで

docker rm hbase-docker

 

今回はcontainer idではなくnameで消してみました。いけましたね。
はい、ということで、再実行、すると今度はちゃんと起動してくれました。

> ./start-hbase.sh

Starting HBase container
Container has ID cbcf219c2625e1623263377be1bc6c95049e1f5dd6bbc2b58dccebce773c516c
Updating /etc/hosts to make hbase-docker point to 172.17.0.2 (hbase-docker)
Password:
Now connect to hbase at localhost on the standard ports
ZK 2181, Thrift 9090, Master 16000, Region 16020
Or connect to host hbase-docker (in the container) on the same ports

For docker status:
$ id=cbcf219c2625e1623263377be1bc6c95049e1f5dd6bbc2b58dccebce773c516c
$ docker inspect $id

/etc/hostsには (/etc/hostsとは個人用のDNSなのでipとホストのマッピングでっす https://wa3.i-3-i.info/word11760.html)
書き方はip ホスト名 別名です。
(ip, cname, aliasにたいなことですね。)
一行追加されております。
```
172.17.0.2 hbase-docker hbase-docker
```

まずは、最初、containerが走っているIPを
しらべます。

ここでは、dockerは基本isoloated環境をつくりだすで
ネットワークにおいても(defaultで)切り離されています。
http://docs.docker.jp/engine/userguide/networking/dockernetworks.html

なので、containerはOS上の閉鎖的1プロセスとして実行される
上でネットワークもホストから切り離されているの理解しました。

初期では
http://docs.docker.jp/engine/userguide/networking/dockernetworks.html
のように

> docker network ls
NETWORK ID NAME DRIVER SCOPE
dd5973a173f8 bridge bridge local
2b03e6cf26fd host host local
d9e9dc61f66d none null local

 

のように三つのnetworkが定義されているようです。
よう、わかりませんが、コンテナを起動するとき、最初はbridgeがdefaultで--net=bridgeがしてされるわけです。
だから、containerの中でローカルなネットワークが存在していて、ホストのIPは別ネットワークになるので
その通信はcontainerにgateway(外のネットワークと通信するときの出入り口、家庭のネットワークだとだいたいルーター)経由
になるわけです。

そんあこんなで
現在のコンテナーのIPを調べて、そいつと通信できるように
するために/etc/hostsでcontainerのIPにわかりやすい、名前でひもづけています。

ちなみに

docker inspect hbase-docker | grep "IPAddress"

で調べられる
ifconfigでもbridge0を見ればいいらしいが、私の場合は、IPは表示されていなかった。
この原因はわからず、時間もかかりそうだとおもった。かわりにポートを指定する方法で
localhostでアクセスできるようになった。

> git diff

diff --git a/start-hbase.sh b/start-hbase.sh
index 2ce5562..585b660 100755
--- a/start-hbase.sh
+++ b/start-hbase.sh
@@ -11,7 +11,8 @@ echo "Starting HBase container"
data_dir=$PWD/data
rm -rf $data_dir
mkdir -p $data_dir
-id=$(docker run --name=hbase-docker -h hbase-docker -d -v $data_dir:/data dajobe/hbase)
+id=$(docker run -p 8080:8080/tcp -p 8085:8085/tcp -p 9090:9090/tcp -p 9095:9095/tcp -p 2181:2181/tcp -p 16010:16010/tcp --name=hbase-docker -h hbase-docker -d -v $data_dir:/data dajobe/hbase)
+#id=$(docker run -P --name=hbase-docker -h hbase-docker -d -v $data_dir:/data dajobe/hbase)

 

echo "Container has ID $id"

http://localhost:16010/master-status for the Master Server
http://localhost:9095/thrift.jsp for the thrift UI
http://localhost:8085/rest.jsp for the REST server UI
http://localhost:16010/zk.jsp for the embedded Zookeeper

ちなみに,0.0.0.0でリッスンしているので、あまりよろしくない気がしております。
https://qiita.com/amuyikam/items/0063df223aed40193ba9

ふー。
まぁ、本来の目的はhbaseを触ることなので、ここでは深追いしません。

pythonによる疎通確認をおこないあす

pip isntall happybase

ちょっと中でどんな動きが起こっているのかみたいので、コンテナープロセスにはいろう。
それには`docker exec -it`がつかえる。

> docker exec --help

Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Run a command in a running container

Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container

docker exec -it c8c961e807bc
だけ打つと、コマンドが必要っていわれます。そうか、ここでsh,bashとか叩けばinteractiveにログインできる
わけです。

> docker exec -it c8c961e807bc /bin/bash
root@hbase-docker:/#

import happybase
connection = happybase.Connection('localhost', 9090)
connection.create_table('table-name', { 'family': dict() } )
connection.tables()
table = connection.table('table-name')
table.put('row-key', {'family:qual1': 'value1', 'family:qual2': 'value2'})
for k, data in table.scan():
  print k, data

するとUIでもちゃんと作成されたtableが参照できる
http://localhost:16010/table.jsp?name=table-name

https://stackoverflow.com/questions/37570762/hbase-timeout-errors-keep-occuring
のように設定でtimeoutを伸ばしてあげればよいのですが、
なんせdocker初心者なので
どうやって編集していいかわかりせんでした
https://tech.pjin.jp/blog/2015/12/03/docker%E3%81%A7%E3%81%82%E3%81%9D%E3%81%B6%EF%BC%88%EF%BC%94%EF%BC%89apache%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E5%A4%89%E3%81%88%E3%82%8B/
からすると
自分のホストで編集したものをDockerfileでCOPY指定してするとか、
containerで編集して、再度イメージを作り直すとか

そういう作業でできるもようです。この作業して再イメージ取得という流れがchefみたいないちいち全部、記述しなくてもいい手軽さが
dockerにはあるのです。もちろん、こんな感じでメモなし手作業してできたイメージ自体の再現性が低いの結局は、ちゃんとchefなりansibleなり
で書く方がいいのですが、しないくてもえきるから、めんどくさくないなーと、手軽だなーと感じましたので、それがdockerが流行る理由の一つだとおもいました。

ということで、
ここまでで、説明を終わります。

dockerの基本的な使い方と
hbaseをcontainer上で起動する方法を説明をおわります。

くわしいhbaseに関数るアーキテクチャについて興味のあるかたはこちらで記事もぜひよんでいてください。

dockerについてたくさんの学びがありました。
・networkもdefaultで完全分離( bridge0)
・dockerの味噌は捨てやすさ
・dockerコマンドの基本的な使い方
・dockerのrunとstartの違い
・hbaseをdockerをつかって起動するまでの流れ
・docker exec -it xxxx bashでコンテナに入る

以上です。

-DB

Copyright© CTOの日記 , 2020 All Rights Reserved.