Base是selenium鏡像的基礎(chǔ),里面的Dockerfile除了在Ubuntu鏡像的基礎(chǔ)上安裝了一些工具包,主要工作如下:
1.還有搭建了一個java運行環(huán)境,用來運行后來的selenium-server-standalone-3.3.1.jar
2.下載了selenium-server-standalone-3.3.1.jar放在容器的/opt/selenium文件夾下
Hub文件夾里面的Dockerfile是用來build selenium/hub鏡像的,是基于上面的Base,主要工作如下:
1.定義了node啟動的一些參數(shù),發(fā)現(xiàn)它把里面的timeout參數(shù)改成30s了。我并沒有pull新的selenium/hub,你們現(xiàn)在pull的可能timeout參數(shù)是30s,我的是30000s。
2.定義了容器啟動的腳本entry_point.sh,并把他復(fù)制到容器的/opt/bin下
NodeBase是一切node鏡像的基礎(chǔ),我們查看里面的Dockerfile發(fā)現(xiàn)它是基于我們上面提到的Base的,主要工作如下:
1.定義了node容器的啟動腳本entry_point.sh并復(fù)制到容器的/opt/bin/下。
NodeFirefox是用來build我們pull下來的selenium/node-firefox它是基于我們上面提到的NodeBase。我們查看它的Dokcerfile文件,發(fā)現(xiàn)它的主要工作如下:
1.下載了版本號為52.0.2的firefox瀏覽器,并做了一些配置。
2.下載了GeckoDriver,我們知道高版本的瀏覽器必須要通過GeckoDriver來啟動一個socket,這也是selenium3.0誕生的主要原因。2.0是無法啟動高版本的firefox的
3.設(shè)置fire-node的一些啟動參數(shù),我們清楚的看到NODE_MAX_INSTANCES 1與ENV NODE_MAX_SESSION 1的配置,所以如何要改變我們問題二的情況,在重新構(gòu)建鏡像的時候,要重新定義這些環(huán)境變量了。
對上面的解釋做個說明:
1.Dockerfile是用來build鏡像的。指令為docker build -t 鏡像名稱 Dockerfile路徑,例如:docker build -t selenium/my-firefxo-node . 用當前路徑下的Dockerfile文件來創(chuàng)建一個 selenium/my-firefxo-node鏡像文件。
2.Dockerfile一些基礎(chǔ)知識可以百度了解,無非是一些shell指令集的大集合。
說完了這些,我們來解決我們遇到的第一個和第二個問題,思路很簡單,對的,是利用的selenium/firefox-node重新構(gòu)建鏡像。
截圖中文亂碼的問題我的考慮如下:
1.docker的Ubuntu版本是沒有中文版的,所以我們要下載中文包,并把默認語言配置成中文
2.僅僅做了1的操作后,我們重新運行build的鏡像,發(fā)現(xiàn)還是亂碼,查閱資料明白可能是firefox必須支持相應(yīng)的中文字體才可以避免亂碼的情況,所以我們終的Dockerfile內(nèi)容如下:
FROM selenium/node-firefox
#改變node的啟動參數(shù)
ENV NODE_MAX_INSTANCES 10
ENV NODE_MAX_SESSION 10
# 配置中文
RUN sudo locale-gen zh_CN.UTF-8 &&
sudo DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales
RUN sudo locale-gen zh_CN.UTF-8
ENV LANG zh_CN.UTF-8
ENV LANGUAGE zh_CN:zh
ENV LC_ALL zh_CN.UTF-8
#更新軟件包索引
RUN sudo apt-get update -qqy
#安裝基本字體
RUN sudo apt-get -qqy --no-install-recommends install
fonts-ipafont-gothic
xfonts-100dpi
xfonts-75dpi
xfonts-cyrillic
xfonts-scalable
#安裝文泉驛微米黑字體
RUN sudo apt-get -qqy install ttf-wqy-microhei
&& sudo ln /etc/fonts/conf.d/65-wqy-microhei.conf /etc/fonts/conf.d/69-language-selector-zh-cn.conf
說到這遇到一個現(xiàn)實的問題是,我們建立了上面的Dokcerfile文件,但是是在windows平臺上的,例如我是放在D盤的Sikilu這個文件夾下的,我們docker主機如何訪問這個Sikilu文件夾呢?
首先,我們要明白個道理,docker是不能運行在windows平臺,我們能在windows平臺使用是因為它運行在Oracle VM VirtualBox里面的!!所以在windows平臺搭建docker時給你安裝了個VirtualBox虛擬機。這好辦了,我們打開這個虛擬機把D盤的Sikilu設(shè)置為共享文件夾好了。具體截圖如下:
設(shè)置完后,我們重啟虛擬機中名稱為default這個docker主機。
我們在Xshell中切換到根目錄cd /發(fā)現(xiàn)了共享的文件夾:
我們把上面的Dockerfile放到我們共享的這個文件夾下并切換進去。執(zhí)行docker build -t selenium/my_node-firefox .
build的過程可能要點時間終build成功!我們運行docker images
可以看到我們build的鏡像。我們先停掉上面用selenium/node-firefox啟動的容器:
我們運行如下指令:docker run -P -d --link selenium_hub:hub selenium/my_node-firefox
由于selenium/my_node-firefox是基于selenium/node-firefox的,所以容器內(nèi)部也是個版本為50.0的firefox瀏覽器。但是我們?yōu)樵撊萜飨螺d了中文包且下載了相應(yīng)的字體,改變了firefox瀏覽器中文亂碼的問題,同時改變了firefox node的啟動參數(shù),使它能夠同時建立10個session!具體數(shù)字多少自己更改,當然也可以改其他的啟動參數(shù)!
我們運行上面的測試腳本,發(fā)現(xiàn)問題能得到有效的解決,當然運行超過10次又阻塞了,原因上面說的很清楚了我們的大session設(shè)置了10!
還有一個問題:我們?nèi)绾谓⑵渌姹咎柕膎ode-firefox?上面說了我們pull下來的是50.0的,比如我要構(gòu)建集群測試每臺機器上不同版本的firefox,那么我們要創(chuàng)建不同版本的鏡像!
這邊有2中思路,第一種思路想法也簡單
1.下載我們特定版本的瀏覽器到我們共享的Sikilu文件夾中。
2.運行我們上面build的selenium/my_node-firefox這個鏡像把這個共享的文件夾掛載進去。(-v參數(shù))
docker run -P -v /Sikilu/:/Sikilu --link selenium_hub:hub selenium/my_node-firefox
3.我們刪除該容器/opt下的firefox-50.0這個瀏覽器,同時解壓掛載的宿主機Sikilu中的特定版本的firefox到/opt目錄
4.運行rm -rf /usr/bin/firefox
5.ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox
6.exit這個容器運行docker commit -m "firefox-47.0.2" 當前容器的ID 鏡像名稱,例如docker commit -m "firefox-47.0.2" 2d96630b4f07(我們進入的容器id號) selenium/node-firefox47.0.2(新的鏡像名稱)
上面的一系列操作,我們得到了一個特定版本的鏡像,下次啟動我們run這個鏡像可以了。
第二種思路,在我們新build的selenium/my_node-firefox這個基礎(chǔ)新建Dockerfile,重新構(gòu)建鏡像(建議這種方式畢竟高端點...)內(nèi)容如下:
FROM selenium/my_node-firefox
#指定新構(gòu)建firefox版本
ARG FIREFOX_VERSION=47.0.2
#刪除已存在firefox瀏覽器
RUN a=$(find /opt/ -name "firefox" |cut -d/ -f 3)&&sudo rm -rf /opt/$a&&sudo rm -rf /usr/bin/firefox
#下載指定版本的瀏覽器
RUN sudo apt-get update -qqy
&& sudo rm -rf /var/lib/apt/lists/* /var/cache/apt/*
&& sudo wget --no-verbose -O /tmp/firefox.tar.bz2 https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-x86_64/en-US/firefox-$FIREFOX_VERSION.tar.bz2
&& sudo tar -C /opt -xjf /tmp/firefox.tar.bz2
&& sudo rm /tmp/firefox.tar.bz2
&& sudo mv /opt/firefox /opt/firefox-$FIREFOX_VERSION
&& sudo ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox
同樣,我們切換到共享的Sikilu文件夾中運行:docker build -t selenium/node-firefox47.0.2 .
如果網(wǎng)絡(luò)較慢是特別費時間的,這時候去聽音樂去吧,一段時間后建立一個firefox版本為47.0.2的鏡像,當我們run這個鏡像來啟動容器時,注冊進hub的是這個版本的瀏覽器。
后一個問題收尾,是我們開始提到的run一個鏡像時的--link的參數(shù)。
docker通過link將source container中定義的環(huán)境變量全部導(dǎo)入到received container中。我們先來看看上面提到NodeBase文件下的entry_point.sh這個腳本,我們截取關(guān)鍵的一部分:是執(zhí)行selenium-server-standalone.jar這個jar包的一段:
xvfb-run -n $SERVERNUM --server-args="-screen 0 $GEOMETRY -ac +extension RANDR"
java ${JAVA_OPTS} -jar /opt/selenium/selenium-server-standalone.jar
-role node
-hub http://$HUB_PORT_4444_TCP_ADDR:$HUB_PORT_4444_TCP_PORT/grid/register
-nodeConfig /opt/selenium/config.json
${SE_OPTS} &
NODE_PID=$!
上面的$HUB_PORT_4444_TCP_PORT表示我們hub的端口號,$HUB_PORT_4444_TCP_ADDR這個代表hub的IP地址,這些是怎么來的?其實這個是因為我們使用link參數(shù),docker自動生成這些參數(shù)。我們進入到由鏡像selenium/my_node-firefox啟動的容器(sudo docker exec -it 24c5fb9a649a /bin/bash),輸入env
發(fā)現(xiàn)了這2個字段,其實這個容器的環(huán)境變量被分成5個部分,一個部分是ALIASDB_PORT開頭的一系列變量,這些變量會有很組,每組變量的命名格式如下:
其中<alias>是我們source container的別名;<port>是在Dockerfile中使用EXPOSE導(dǎo)出的端口,還有docker run 的時候使用-p導(dǎo)出的端口;<protocol>則是這些端口對應(yīng)的協(xié)議。
現(xiàn)在明白上文中為什么--link selenium/hub冒號后面為什么要跟hub或者HUB了吧,只有寫成這樣才會找到HUB_PORT_4444_TCP_PORT與$HUB_PORT_4444_TCP_ADDR這2個變量,免得容器是啟動不起來的!
到這里結(jié)束吧,本來還想多寫點關(guān)于docker的用法知識。但是打字打的想吐了,可能本文中一些東西說的不清不楚,但是我相信您通過查閱資料一定能得到相應(yīng)的解決。