Selenium GridをMac M1のKubernetesにhelmでデプロイしてみました

最近MacのDestop Dockerにあるkubernetesを整理していて、以前遊んでいた時に残っていたselenium gridと、どうやってデプロイするかの記録を残してシェアしたいです。

## 環境
- Mac M1
- Kubernetes in Docker Desktop
- kubectl command-line tool
- helm

今回利用したコンテンツなどは以下のRepoにも見つけられます。
[my-k8s/helm/selenium-grid](https://github.com/Benzenoil/my-k8s/tree/master/helm/selenium-grid)

## 問題点

現在selenium gridをhelm Chartでデプロイしようとすると、[公式Github Page](https://github.com/SeleniumHQ/docker-selenium/tree/trunk/charts/selenium-grid)にはIntelコア用のInstall手順しかありませんでした。

それで無理やりデプロイしても、デプロイ自体は成功していても、動かしたい時はエラーが多く、結局利用できませんでした。

### 出てきたエラー

これらをGoogleで検索してみましても、解決する方法に辿り着けませんでした。

```
An error occurred: Message: Could not start a new session. Could not start a new session. Error while creating session with the driver service. Stopping driver service: Could not start a new session. Response code 500. Message: Failed to decode response from marionette 
Host info: host: 'selenium-grid-selenium-firefox-node-79d76cbd49-2h9k7', ip: '10.1.22.103'
Build info: version: '4.21.0', revision: '79ed462ef4'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '6.4.16-linuxkit', java.version: '17.0.11'
Driver info: driver.version: unknown
Build info: version: '4.21.0', revision: '79ed462ef4'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '6.4.16-linuxkit', java.version: '17.0.11'
Driver info: driver.version: unknown
Build info: version: '4.21.0', revision: '79ed462ef4'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '6.4.16-linuxkit', java.version: '17.0.11'
Driver info: driver.version: unknown
Stacktrace:
    at org.openqa.selenium.grid.node.remote.RemoteNode.newSession (RemoteNode.java:157)
    at org.openqa.selenium.grid.distributor.local.LocalDistributor.startSession (LocalDistributor.java:652)
    at org.openqa.selenium.grid.distributor.local.LocalDistributor.newSession (LocalDistributor.java:571)
    at org.openqa.selenium.grid.distributor.local.LocalDistributor$NewSessionRunnable.handleNewSessionRequest (LocalDistributor.java:831)
    at org.openqa.selenium.grid.distributor.local.LocalDistributor$NewSessionRunnable.lambda$run$1 (LocalDistributor.java:791)
    at java.util.concurrent.ThreadPoolExecutor.runWorker (None:-1)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (None:-1)
    at java.lang.Thread.run (None:-1)
An error occurred: Message: Could not start a new session. java.io.IOException: HTTP/1.1 header parser received no bytes 
Host info: host: 'selenium-grid-selenium-hub-77fd4fdb6c-nmkw2', ip: '10.1.22.100'
Build info: version: '4.21.0', revision: '79ed462ef4'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '6.4.16-linuxkit', java.version: '17.0.11'
Driver info: driver.version: unknown
Stacktrace:
    at org.openqa.selenium.grid.distributor.local.LocalDistributor.startSession (LocalDistributor.java:656)
    at org.openqa.selenium.grid.distributor.local.LocalDistributor.newSession (LocalDistributor.java:571)
    at org.openqa.selenium.grid.distributor.local.LocalDistributor$NewSessionRunnable.handleNewSessionRequest (LocalDistributor.java:831)
    at org.openqa.selenium.grid.distributor.local.LocalDistributor$NewSessionRunnable.lambda$run$1 (LocalDistributor.java:791)
    at java.util.concurrent.ThreadPoolExecutor.runWorker (None:-1)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (None:-1)
    at java.lang.Thread.run (None:-1)
```

### エラー再現（Optional）

解決編入る前に、エラー環境を再現方法を提供します。
まず、自分の環境がMac M1（ARM）であり、DesktopのDockerとKubernetesがInstallされて、configがdocker-desktopになっていること。

```bash
kubectl config current-context
# docker-desktop return

helm repo add docker-selenium https://www.selenium.dev/docker-selenium

helm repo update

kubectl create ns selenium-grid

helm install selenium-grid docker-selenium/selenium-grid -n selenium-grid
```

私ももう一度エラーを再現させたいので、実行してみて、Restartsが多いが、Runningまで安定しました
```
kubectl get pods -n selenium-grid
NAME                                                   READY   STATUS    RESTARTS   AGE
selenium-grid-selenium-chrome-node-f7f4d686c-qgjvb     1/1     Running   0          74s
selenium-grid-selenium-edge-node-76c5f986d4-fwnhm      1/1     Running   0          74s
selenium-grid-selenium-firefox-node-697c8db4d4-ckn4c   1/1     Running   0          74s
selenium-grid-selenium-hub-56477cd6b-cxzcw             1/1     Running   0          74s
```

![Snipaste_2024-05-20_09-45-51.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457921/add86f57-026c-7236-f5b8-64c389464134.jpeg)

次に以下のテストコードを実行するとエラーが出てきます。

```py
from selenium import webdriver
from selenium.webdriver.firefox.options import Options as FirefoxOptions

def test_browser():
    grid_url = "http://admin:admin@localhost:31444/wd/hub"

    options = FirefoxOptions()
    driver = webdriver.Remote(command_executor=grid_url, options=options)

    try:
        driver.get("https://www.google.com")
        print(f"Page title is:", driver.title)
        assert "Google" in driver.title
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        driver.quit()

if __name__ == "__main__":
    test_browser()
```

最後に再現された環境をClean Up

## 解決に向けて

解決に向けていくつの方法を試みましたが、最終的にはARMに対応したImageに切り替えることで解消できました。

まず以下の`values.yaml`を用意します。

```yaml
# values.yaml
hub:
  serviceType: NodePort
chromeNode:
  enabled: false
edgeNode:
  enabled: false
firefoxNode:
  enabled: true
global:
  seleniumGrid:
    imageRegistry: seleniarm
    imageTag: 4.20.0-20240427
    nodesImageTag: 4.20.0-20240427
```

次にこのファイルを持ってhelm releaseを作成します

```bash
helm repo add docker-selenium https://www.selenium.dev/docker-selenium
helm repo update
kubectl create ns selenium-grid

helm upgrade --install selenium-grid docker-selenium/selenium-grid -f values.yaml -n selenium-grid
```

すべてのPodsがRunningになっていたら再度テストファイルを実行すると、無事に実行できました！やった！


## その他話したい内容

### Memory comsuingの違い
Intel向けのImageをMac M1でDeployする際に消費されたMemoryと比べて、ARMに適したPodsの消費されたMemoryがかなり削減できました。これは`poor performance`ですかね。


```bash
# arm
kubectl top pods -n selenium-grid
NAME                                                   CPU(cores)   MEMORY(bytes)
selenium-grid-selenium-firefox-node-79f965bc6c-cm4rl   9m           160Mi
selenium-grid-selenium-hub-56f655f45f-kxxl7            16m          185Mi
```

```bash
# intel 
kubectl top pods -n selenium-grid
NAME                                                   CPU(cores)   MEMORY(bytes)
selenium-grid-selenium-chrome-node-f7f4d686c-qgjvb     21m          561Mi
selenium-grid-selenium-edge-node-76c5f986d4-fwnhm      23m          573Mi
selenium-grid-selenium-firefox-node-697c8db4d4-ckn4c   22m          552Mi
selenium-grid-selenium-hub-56477cd6b-cxzcw             82m          468Mi
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457921/edd7e4ab-8993-b613-d9f4-088619ca96b2.png)


### trouble shooting useful command

Userが提供しているValuesを利用して、設定を上書きしてデプロイしたい時に、どのPamametersが修正できるのかを調査するために、以下のコードが有用です。`values.yaml`をファイルにDumpして、中の設定値を確認して、修正してきました。

```
helm get values selenium-grid -n selenium-grid --all > values_all.yaml
```

### only firefox for now

今回テストできたのはnode-firefoxのみで、[docker-seleniarm](https://hub.docker.com/u/seleniarm)にあるRepositoriesを確認しても、`node-edge`,`node-chrome`がなく（`node-chromium`はありますが）。また今度機会があれば、`node-chromium`も試してみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457921/9cd3c90a-8989-3746-8128-3367e22cafc6.png)


## 最後に

最近本を読んで覚えた1つが、知識が自分で見て終わるのではなく、できるだけ自分の既存の知識・言葉で練り直して、Outputを出すことも重要であることです。

皆さん良い一日を！