【初心者向け】kubernetesを使ってselenium gridを動かしてみよう【mac】【k8s】
こんにちは!作者です。
巷ではやれdockerだkubernetesだと騒がれていますが、聞いたことはあってもよくわからん状態でした。
dockerとはなんぞ…と調べていたのですが、調べるうちにkubernetesまで行きついて、selenium gridでテストの並列実行まで試してみました。
そんなわけで、今日は作者が行ったdockerからのkubernetes化を説明したいと思います。
難しい設定はしていないので(そこまで行きついていないので)最初の最初、kubernetes化して、同じテストを並列でひとまず動かしてみるところまでの説明をしようと思います。
- 【初心者向け】kubernetesを使ってselenium gridを動かしてみよう【mac】【k8s】
dockerって何?kubernetesって何?
この辺の詳細は他サイトでおねがいできたらです。
2019年12月のアドベントカレンダーでテスターちゃんでこの辺をわかりやすく描けたらと思っています。
とりあえず簡単にいうと……
dockerは仮想的なサーバーをサクッと作るツール。
細かく言うと仮想的と言っても今までのvirtualboxなどと違い……なんてなってくるのですが、ひとまずはこれくらいで覚えておいて良いかと思いますw
サーバーを立てるときはこれまでとっても面倒だったのですが、dockerには設定のファイルなんかも最初からあって、誰でも同じような環境をお手軽に立ち上げることができるようになりました。
kubernetes(クバネティス/クバネテス/k8sケーエイツ)はdockerをイイカンジに取りまとめてくれるツール(説明雑!
例えば何かサービスとか作るときはwebサーバーやらDBやら色んなモノが必要で、それらが連携して一つのサービスができています。
dockerが出てからはその1つ1つをコンテナ(dockerでサクッと作った仮想的なサーバー)にするところが出てきました。
けどこのコンテナがいっぱいあると超大変!
それら設定やらコンテナの管理をやってくれるのがkubernetes。
コンテナオーケストレーションツールと呼ばれています。
(ちなみにkubernetesが有名だけど、docker swarmというのもある。マイナー)
名前の通りオーケストラに例えるとわかりやすいかもしれません。
例えばバイオリン奏者、フルート奏者それぞれの単位がコンテナ。
それら全体をしっかりとイイカンジのハーモニーで音楽が成り立つように指揮するのがkubernetesといったところ(説明雑!
最初の準備
さて、やっていきましょう。
まずは……作者は最初にdockerのお試しから始めました。
その時、以下のsikkimtemi様のgithubを使用させていただきました。
こちらのリポジトリをベースにしますのでzipダウンロードやcloneをお願いします。
Dockerfileの説明
ダウンロードしてくると、「selenium」というフォルダができあがります。
その中の「python-selenium」というフォルダの中に「Dockerfile」というファイルがあります。
これは変更が必要ないのですが、説明をしておきます。
FROM python:3 RUN set -x && \ apt-get update && \ apt-get install -y vim && \ pip install selenium
Docerfileは何かというと、これを使って「Docker image」を作ります。
Docker imageは「こういうサーバー作るよ」っていうレシピみたいなものです。
FROMの部分は、すでに配布されているpython3のイメージを持ってきて使うよ、と言う意味です。
その後のコマンドは、ファイルのアップデートやツールのインストールを行っています。
今回重要なのは「pip install selenium」部分くらい。
(vim好きに怒られそうですねw)
なのでこのDockerfileの意味は「python3のイメージを持ってきて、seleniumインストールするよ」といったところです。
docker-compose.ymlの変更
このファイルがkubernetes化のときに非常に大事なファイル。
ガッツリと変更します。
version: "3.7" services: selenium-hub: image: selenium/hub:latest ports: - 4444:4444 chrome: image: selenium/node-chrome-debug:latest environment: - HUB_PORT_4444_TCP_ADDR=selenium-hub - HUB_PORT_4444_TCP_PORT=4444 depends_on: - selenium-hub ports: - 5901:5900 deploy: replicas: 4 python: image: python-selenium:v1 build: context: ./python-selenium depends_on: - selenium-hub working_dir: '/root/script/' volumes: - ./script/:/root/script/ environment: - 'TZ=Asia/Tokyo' tty: true
docker composeは、複数のコンテナをまとめて操作を行うツールです。
ここでは「selenium-hub」「chrome」「python」という3つのコンテナを作るための情報が書かれています。
ざっくりいうと
pythonのサーバー(プログラムを実行する場所)→selenium-hubのサーバー(分配する場所)→chromeのサーバー(実際にブラウザが動いて実行される場所)
という構成が書かれています。
一つずつ説明します。
python
これがプログラムを実行するためのコンテナ(仮想的なサーバー)を作る情報部分です。
まずはimageとbuildの部分の説明。
先ほど見た通り、「python-selenium」のフォルダの中にDockerfileがありました。
それを使ってbuild(Dockerfileからイメージ作成)を行ってpython-selenium:v1というイメージ名で使うよ、と言う意味です。
depend-onは、上の方にある「selenium-hub」とつながってるよーということを書いています。
working_dirは、コンテナ上での作業フォルダです。
volumesがとっても大事な場所。
今見ているフォルダに「script」というフォルダがあるかと思います。
そこのフォルダがコンテナ上の「/root/script」と同期しています。
なので、そこにファイルを入れたらコンテナ上でそのファイルにアクセスできるし、コンテナ上で作ったファイルがscriptのフォルダに入るし……といった感じになります。
environmetでは、タイムゾーンを東京に設定しています。
ttyはコンテナの標準出力を表示させるようにする設定です。
selenium-hub
selenium-hubはプログラムを動かすサーバー(ここでは「python」のサーバー)から「こういうテストして」って要請があると「あいよ!」とその後に続くnode(複数のchromeのサーバー)にイイカンジに振り分けてくれる場所です。
imageは、もうすでに世の中にhubのimageがあるので、それを取ってくるということを書いています。
portsは「ホスト側(kubernetesを実行するパソコン)のポート:コンテナ側のポート」と紐づける役割をしています。
実行しているパソコンの4444のポートを、コンテナの4444のポートにつなげるよ、といった感じです。
chrome
ここは要は実際にブラウザを動かして実行する部分です。
ここを増やすと並列してテストが実行できたりします。
imageは、これまたすでに世の中にchromeのイメージがあるので持ってくることを書いています。
environmentは環境変数の設定です。
selenium-hubと接続が必要なので、接続するための環境変数を書いています。
depend_onもselenium-hubとつながっていることを書いています。
portsも先ほどと同じです。実行するパソコンの5901のポートと、コンテナ側の5900ポートをつなげる、ということを書いています。
なんで5901?となるのですが、どうやらmacだと5900がもうvncで使われているらしく。
なのでひとつずらしましたw
次のdeploy:replicasは、chromeのコンテナを何個作るかです。
ここでは4つ作成します。イメージとしては4つサーバーができあがって、そこで並列してテストできるイメージです。
sample.pyの変更
「script」というファイルの中に「sample.py」というファイルが入っているかと思います。
これがテストを実行のサンプルのファイルです。
#!/usr/local/bin/python3 from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from time import sleep import datetime import threading import random NODE_NUM = 4 def execSearch(browser: webdriver): """ Googleで検索を実行する :param browser: webdriver """ # スクリーンショットのファイル名用に日付を取得 dt = datetime.datetime.today() dtstr = dt.strftime("%Y%m%d%H%M%S") # Googleにアクセス browser.get('https://www.google.co.jp/') sleep(1) # キーワードの入力 search_box = browser.find_element_by_name("q") search_box.send_keys('docker selenium') # 検索実行 search_box.submit() sleep(1) # スクリーンショット browser.save_screenshot('images/' + dtstr + '_' + str(random.randrange(10000)) + '.png') def start_webdriver(): try: browser = webdriver.Remote( command_executor='http://selenium-hub:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME) # Googleで検索実行 execSearch(browser) finally: browser.close() browser.quit() if __name__ == '__main__': for i in range(NODE_NUM): thread = threading.Thread(target=start_webdriver) thread.start()
並列実行用にファイルを変更しました。
……雑な変更でして、同じテストを4並列で実行する感じになっています。
今回は簡単なkubernetesの動作チェックみたいなものなので、ちゃんとした並列分散のようなテストは別のサイトを見ていただけたらです。
実行が終わると「image」フォルダの中に4つのスクリーンキャプチャが入ります。
ついでに自作ファイルも追加しておきましょう。
sampleが動いても自分のファイルはどう動かすの!?ってなったりしますので、一つ「test.py」の名前でファイルを作ってみましょうか。
#!/usr/local/bin/python3 print('Hello Testerchan!')
画面に「Hello Testerchan!」と表示させるだけのプログラムです。
ちなみに1行目はshebang。(#!から始まる行をそういうよ)
これがないと動かないので要注意です。
これでkubernetes化する準備は完了です!
kubernetesをインストールしよう。
ここではmacの説明をしていきます。
macにすでにdocker for macが入っている前提です。(インストールはダウンロードして実行すればいいだけ)
そうしたら、dockerの「prefereces...」→「kubernetes」とクリックしてください。
これの「Enable Kubernetes」にチェックしてApplyを押すだけでインストールが始まります。
インストールは長いので、紅茶でも飲みながら気長に待ちましょう。
Dockerfileをbuildしよう
ここは初回だけでOKの場所です。
docker-compose.ymlをいじるときに「python」のところで「buildしてimageつくるよ」って場所があったと思います。
そのimageを作るための作業です。
まずはターミナルを立ち上げて、seleniumフォルダがあるところまで移動しましょう。
そしたら…
$ docker-compose build
これでオッケーです。
ビャーっと文字が流れていきます。
最後にSuccessfullyがでたらimageが完成です。
kubernetes起動!
では、ようやくkubernetesを起動です。
ここでは「compose on kubernetes」という、docker-compose.ymlからkubernetesにdeployしてくれる、というものです。
$ docker stack deploy --orchestrator=kubernetes -c docker-compose.yml 任意のstackの名前
任意のstackの名前は、まぁ、特に気にせず好きな名前を付ければいいです。
以下では「kube」とつけてdeployをしました。
「Stack 名前 is stable and running」と出れば起動完了です。
簡単!
selenium gridの様子を見てみよう。
起動確認として、ブラウザを立ち上げてアドレスに「localhost:4444/grid/console」と打ち込みましょう。
そうすると以下のような画面が見られるかと思います。
chromeのサーバーが4つ立ち上がっていますね!
test.pyを実行してみよう
プログラムの実行をしていきます。
その前に以下を入力してください。
$ kubectl get pods
これはkubernetes上で動いているpodを確認するものです。
podは、コンテナの集合体みたいなものなのですが説明割愛。(自動車みたいな感じ。コンテナが複数載った乗り物みたいなもの。今の場合は1pod1コンテナ。)
ここのpythonのとこの名前をコピりましょう。
そうしたら……
$ kubectl exec -it コピった名前 python /root/script/test.py
と入力してエンターです。
Hello Testerchan!
と出れば成功です。
execは実行コマンドです。
引数の-itは標準入力とttyの設定です。docker-compose側でttyは設定しているので、特に不要ではあります。
最後の/root/scriptは、「script」フォルダがコンテナ側の「/root/script」と同期しています。
そこのtest.pyを実行となります。
selenium gridで並列テスト実行!
ではでは、テスト実行をしてみましょう!!
$ kubectl exec -it コピった名前 python /root/script/sample.py
これでテストが実行されます!
実行したらちょっとselenium gridを見てみましょう。
chromeのマークが薄くなっていたら、そこで実際にブラウザが立ち上がってテスト実行がされています。
ちなみに自動で画面に反映されないのでリロード連打をしましょう(爆)
上の画像だと4か所に振り分けられてテスト実行されていることがわかります。
最後に「image」フォルダに4枚の画像が保存されたら完了です。(テスト内でスクリーンキャプチャしてる)
動いている様子も見たいよね
実際にブラウザが動いている様子、自動化やってると見たくなっちゃいますよね!w
では見てみましょう。
スポットライト(commandとspace同時おし)を開いて「画面共有」と打ち込んでください。
青い画面のアイコンがあるのでそれを実行です。
そしたら接続先に「localhost:5901」と入力しましょう。
docker-composeのchromeのportsで打ち込んだ数字です。
パスワードを聞かれるので「secret」と入力してください。
そうすると何やら黒い画面が立ち上がるかと思います。
その状態で実行してみましょう。
$ kubectl exec -it コピった名前 python /root/script/sample.py
こんな感じで確認ができます。
終了
終了するには以下のコマンドを入力しましょう。
$ docker stack rm --orchestrator=kubernetes deployのときにつけた名前
これで完了です。
その他のコマンド
簡単にだけ紹介。
$ docker stack ls --orchestrator=kubernetes
起動中のstackのリストが見れます。
$ docker stack ps --orchestrator=kubernetes deployのときにつけた名前
stackで動いているものが見れます。
$ docker stack services --orchestrator=kubernetes deployのときにつけた名前
stackで動いているサービスを見ることができます。
実はgithubも用意しておいた
実はgithubも用意しているので、以下参考いただけたらですw
docker-composeとkubernetesの違い
やっていて思ったのが、docker composeでもまとめてコンテナ扱えるし、kubernetesとどう違うんだろうでした。 以下のスライドがわかりやすかったです。