使用Docker Swarm搭建分布式爬蟲(chóng)集群的方法示例
在爬蟲(chóng)開(kāi)發(fā)過(guò)程中,你肯定遇到過(guò)需要把爬蟲(chóng)部署在多個(gè)服務(wù)器上面的情況。此時(shí)你是怎么操作的呢?逐一SSH登錄每個(gè)服務(wù)器,使用git拉下代碼,然后運(yùn)行?代碼修改了,于是又要一個(gè)服務(wù)器一個(gè)服務(wù)器登錄上去依次更新?
有時(shí)候爬蟲(chóng)只需要在一個(gè)服務(wù)器上面運(yùn)行,有時(shí)候需要在200個(gè)服務(wù)器上面運(yùn)行。你是怎么快速切換的呢?一個(gè)服務(wù)器一個(gè)服務(wù)器登錄上去開(kāi)關(guān)?或者聰明一點(diǎn),在Redis里面設(shè)置一個(gè)可以修改的標(biāo)記,只有標(biāo)記對(duì)應(yīng)的服務(wù)器上面的爬蟲(chóng)運(yùn)行?
A爬蟲(chóng)已經(jīng)在所有服務(wù)器上面部署了,現(xiàn)在又做了一個(gè)B爬蟲(chóng),你是不是又得依次登錄每個(gè)服務(wù)器再一次部署?
如果你確實(shí)是這么做的,那么你應(yīng)該后悔沒(méi)有早一點(diǎn)看到這篇文章??赐瓯疚囊院?,你能夠做到:
2分鐘內(nèi)把一個(gè)新爬蟲(chóng)部署到50臺(tái)服務(wù)器上:
docker build -t localhost:8003/spider:0.01 . docker push localhost:8002/spider:0.01 docker service create --name spider --replicas 50 --network host 45.77.138.242:8003/spider:0.01
30秒內(nèi)把爬蟲(chóng)從50臺(tái)服務(wù)器擴(kuò)展到500臺(tái)服務(wù)器:
docker service scale spider=500
30秒內(nèi)批量關(guān)閉所有服務(wù)器上的爬蟲(chóng):
docker service scale spider=0
1分鐘內(nèi)批量更新所有機(jī)器上的爬蟲(chóng):
docker build -t localhost:8003/spider:0.02 . docker push localhost:8003/spider:0.02 docker service update --image 45.77.138.242:8003/spider:0.02 spider
這篇文章不會(huì)教你怎么使用Docker,所以請(qǐng)確定你有一些Docker基礎(chǔ)再來(lái)看本文。
Docker Swarm是什么
Docker Swarm是Docker自帶的一個(gè)集群管理模塊。他能夠?qū)崿F(xiàn)Docker集群的創(chuàng)建和管理。
環(huán)境搭建
本文將會(huì)使用3臺(tái)Ubuntu 18.04的服務(wù)器來(lái)進(jìn)行演示。這三臺(tái)服務(wù)器安排如下:
Master:45.77.138.242
Slave-1:199.247.30.74
Slave-2:95.179.143.21
Docker Swarm是基于Docker的模塊,所以首先要在3臺(tái)服務(wù)器上安裝Docker。安裝完成Docker以后,所有的操作都在Docker中完成。
在Master上安裝Docker
通過(guò)依次執(zhí)行下面的命令,在Master服務(wù)器上安裝Docker
apt-get update apt-get install -y apt-transport-https ca-certificates curl software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" apt-get update apt-get install -y docker-ce
創(chuàng)建Manager節(jié)點(diǎn)
一個(gè)Docker Swarm集群需要Manager節(jié)點(diǎn)?,F(xiàn)在初始化Master服務(wù)器,作為集群的Manager節(jié)點(diǎn)。運(yùn)行下面一條命令。
docker swarm init
運(yùn)行完成以后,可以看到的返回結(jié)果下圖所示。
這個(gè)返回結(jié)果中,給出了一條命令:
這條命令需要在每一個(gè)從節(jié)點(diǎn)(Slave)中執(zhí)行?,F(xiàn)在先把這個(gè)命令記錄下來(lái)。
初始化完成以后,得到一個(gè)只有1臺(tái)服務(wù)器的Docker 集群。執(zhí)行如下命令:
docker node ls
可以看到當(dāng)前這個(gè)集群的狀態(tài),如下圖所示。
創(chuàng)建私有源(可選)
創(chuàng)建私有源并不是一個(gè)必需的操作。之所以需要私有源,是因?yàn)轫?xiàng)目的Docker鏡像可能會(huì)涉及到公司機(jī)密,不能上傳到DockerHub這種公共平臺(tái)。如果你的鏡像可以公開(kāi)上傳DockerHub,或者你已經(jīng)有一個(gè)可以用的私有鏡像源,那么你可以直接使用它們,跳過(guò)本小節(jié)和下一小節(jié)。
私有源本身也是一個(gè)Docker的鏡像,先將拉取下來(lái):
docker pull registry:latest
如下圖所示。
現(xiàn)在啟動(dòng)私有源:
如下圖所示。
在啟動(dòng)命令中,設(shè)置了對(duì)外開(kāi)放的端口為8003端口,所以私有源的地址為:45.77.138.242:8003
提示:
這樣搭建的私有源是HTTP方式,并且沒(méi)有權(quán)限驗(yàn)證機(jī)制,所以如果對(duì)公網(wǎng)開(kāi)放,你需要再使用防火墻做一下IP白名單,從而保證數(shù)據(jù)的安全。
允許docker使用可信任的http私有源(可選)
如果你使用上面一個(gè)小節(jié)的命令搭建了自己的私有源,由于Docker默認(rèn)是不允許使用HTTP方式的私有源的,因此你需要配置Docker,讓Docker信任它。
使用下面命令配置Docker:
echo '{ "insecure-registries":["45.77.138.242:8003"] }' >> /etc/docker/daemon.json
然后使用下面這個(gè)命令重啟docker。
systemctl restart docker
如下圖所示。
重啟完成以后,Manager節(jié)點(diǎn)就配置好了。
創(chuàng)建子節(jié)點(diǎn)初始化腳本
對(duì)于Slave服務(wù)器來(lái)說(shuō),只需要做三件事情:
- 安裝Docker
- 加入集群
- 信任源
從此以后,剩下的事情全部交給Docker Swarm自己管理,你再也不用SSH登錄這個(gè)服務(wù)器了。
為了簡(jiǎn)化操作,可以寫(xiě)一個(gè)shell腳本來(lái)批量運(yùn)行。在Slave-1和Slave-2服務(wù)器下創(chuàng)建一個(gè) init.sh
文件,其內(nèi)容如下。
apt-get update apt-get install -y apt-transport-https ca-certificates curl software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" apt-get update apt-get install -y docker-ce echo '{ "insecure-registries":["45.77.138.242:8003"] }' >> /etc/docker/daemon.json systemctl restart docker docker swarm join --token SWMTKN-1-0hqsajb64iynkg8ocp8uruktii5esuo4qiaxmqw2pddnkls9av-dfj7nf1x3vr5qcj4cqiusu4pv 45.77.138.242:2377
把這個(gè)文件設(shè)置為可自行文件,并運(yùn)行:
chmod +x init.sh ./init.sh
如下圖所示。
等待腳本運(yùn)行完成以后,你就可以從Slave-1和Slave-2的SSH上面登出了。以后也不需要再進(jìn)來(lái)了。
回到Master服務(wù)器,執(zhí)行下面的命令,來(lái)確認(rèn)現(xiàn)在集群已經(jīng)有3個(gè)節(jié)點(diǎn)了:
docker node ls
看到現(xiàn)在集群中已經(jīng)有3個(gè)節(jié)點(diǎn)了。如下圖所示。
到止為止,最復(fù)雜最麻煩的過(guò)程已經(jīng)結(jié)束了。剩下的就是體驗(yàn)Docker Swarm帶來(lái)的便利了。
創(chuàng)建測(cè)試程序
搭建測(cè)試Redis
由于這里需要模擬一個(gè)分布式爬蟲(chóng)的運(yùn)行效果,所以先使用Docker搭建一個(gè)臨時(shí)的Redis服務(wù):
在Master服務(wù)器上執(zhí)行以下命令:
這個(gè)Redis對(duì)外使用 7891
端口,密碼為 KingnameISHandSome8877
,IP就是Master服務(wù)器的IP地址。
編寫(xiě)測(cè)試程序
編寫(xiě)一個(gè)簡(jiǎn)單的Python程序:
import time import redis client = redis.Redis(host='45.77.138.242', port='7891', password='KingnameISHandSome8877') while True: data = client.lpop('example:swarm:spider') if not data: break print(f'我現(xiàn)在獲取的數(shù)據(jù)為:{data.decode()}') time.sleep(10)
這個(gè)Python每10秒鐘從Redis中讀取一個(gè)數(shù),并打印出來(lái)。
編寫(xiě)Dockerfile
編寫(xiě)Dockerfile,基于Python3.6的鏡像創(chuàng)建我們自己的鏡像:
from python:3.6 label mantainer='[email protected]' user root ENV PYTHONUNBUFFERED=0 ENV PYTHONIOENCODING=utf-8 run python3 -m pip install redis copy spider.py spider.py cmd python3 spider.py
構(gòu)建鏡像
編寫(xiě)完成Dockerfile以后,執(zhí)行下面的命令,開(kāi)始構(gòu)建我們自己的鏡像:
docker build -t localhost:8003/spider:0.01 .
這里需要特別注意,由于我們要把這個(gè)鏡像上傳到私有源供Slave服務(wù)器上面的從節(jié)點(diǎn)下載,所以鏡像的命名方式需要滿(mǎn)足 localhost:8003/自定義名字:版本號(hào)
這樣的格式。其中的 自定義名字
和 版本號(hào)
可以根據(jù)實(shí)際情況進(jìn)行修改。在本文的例子中,我由于要模擬一個(gè)爬蟲(chóng)的程序,所以給它取名為spider,由于是第1次構(gòu)建,所以版本號(hào)用的是0.01。
整個(gè)過(guò)程如下圖所示。
上傳鏡像到私有源
鏡像構(gòu)建完成以后,需要把它上傳到私有源。此時(shí)需要執(zhí)行命令:
docker push localhost:8003/spider:0.01
如下圖所示。
大家記住這個(gè)構(gòu)建和上傳的命令,以后每一次更新代碼,都需要使用這兩條命令。
創(chuàng)建服務(wù)
Docker Swarm上面運(yùn)行的是一個(gè)一個(gè)的服務(wù),因此需要使用docker service命令創(chuàng)建服務(wù)。
這個(gè)命令創(chuàng)建了一個(gè)名為 spider
的服務(wù)。默認(rèn)運(yùn)行1個(gè)容器。運(yùn)行情況如下圖所示。
當(dāng)然也可以一創(chuàng)建就用很多容器來(lái)運(yùn)行,此時(shí)只需要添加一個(gè) --replicas
參數(shù)即可。例如一創(chuàng)建服務(wù)就使用50個(gè)容器運(yùn)行:
但是一般一開(kāi)始的代碼可能會(huì)有不少bug,所以建議先使用1個(gè)容器來(lái)運(yùn)行,觀察日志,發(fā)現(xiàn)沒(méi)有問(wèn)題以后再進(jìn)行擴(kuò)展。
回到默認(rèn)1個(gè)容器的情況下,這個(gè)容器可能在目前三臺(tái)機(jī)器在的任何一臺(tái)上面。通過(guò)執(zhí)行下面的命令來(lái)觀察這一個(gè)默認(rèn)的容器運(yùn)行情況:
docker service ps spider
如下圖所示。
查看節(jié)點(diǎn)Log
根據(jù)上圖執(zhí)行結(jié)果,可以看到這個(gè)運(yùn)行中的容器的ID為 rusps0ofwids
,那么執(zhí)行下面的命令動(dòng)態(tài)查看Log:
docker service logs -f 容器ID
此時(shí)就會(huì)持續(xù)跟蹤這一個(gè)容器的Log。如下圖所示。
橫向擴(kuò)展
現(xiàn)在,只有1臺(tái)服務(wù)器運(yùn)行了一個(gè)容器,我想使用3臺(tái)服務(wù)器運(yùn)行這個(gè)爬蟲(chóng),那么我需要執(zhí)行一條命令即可:
docker service scale spider=3
運(yùn)行效果如下圖所示。
此時(shí),再一次查看爬蟲(chóng)的運(yùn)行情況,可以發(fā)現(xiàn)三臺(tái)機(jī)器上面會(huì)各自運(yùn)行一個(gè)容器。如下圖所示。
現(xiàn)在,我們登錄slave-1機(jī)器上,看看是不是真的有一個(gè)任務(wù)在運(yùn)行。如下圖所示。
可以看到確實(shí)有一個(gè)容器在上面運(yùn)行著。這是Docker Swarm自動(dòng)分配過(guò)來(lái)的。
現(xiàn)在我們使用下面的命令強(qiáng)行把slave-1上面的Docker給關(guān)了,再來(lái)看看效果。
systemctl stop docker
回到master服務(wù)器,再次查看爬蟲(chóng)的運(yùn)行效果,如下圖所示。
可以看到,Docker Swarm探測(cè)到Slave-1掉線(xiàn)以后,他就會(huì)自動(dòng)重新找個(gè)機(jī)器啟動(dòng)任務(wù),保證始終有3個(gè)任務(wù)在運(yùn)行。在這一次的例子中,Docker Swarm自動(dòng)在master機(jī)器上啟動(dòng)了2個(gè)spider容器。
如果機(jī)器性能比較好,甚至可以在3每臺(tái)機(jī)器上面多運(yùn)行幾個(gè)容器:
docker service scale spider=10
此時(shí),就會(huì)啟動(dòng)10個(gè)容器來(lái)運(yùn)行這些爬蟲(chóng)。這10個(gè)爬蟲(chóng)之間互相隔離。
如果想讓所有爬蟲(chóng)全部停止怎么辦?非常簡(jiǎn)單,一條命令:
docker service scale spider=0
這樣所有爬蟲(chóng)就會(huì)全部停止。
同時(shí)查看多個(gè)容器的日志
如果想同時(shí)看所有容器怎么辦呢?可以使用如下命令查看所有容器的最新的20行日志:
這樣,日志就會(huì)按順序顯示出來(lái)了。如下圖所示。
更新爬蟲(chóng)
如果你的代碼做了修改。那么你需要更新爬蟲(chóng)。
先修改代碼,重新構(gòu)建,重新提交新的鏡像到私有源中。如下圖所示。
接下來(lái)需要更新服務(wù)中的鏡像。更新鏡像有兩種做法。一種是先把所有爬蟲(chóng)關(guān)閉,再更新。
docker service scale spider=0 docker service update --image 45.77.138.242:8003/spider:0.02 spider docker service scale spider=3
第二種是直接執(zhí)行更新命令。
docker service update --image 45.77.138.242:8003/spider:0.02 spider
他們的區(qū)別在于,直接執(zhí)行更新命令時(shí),正在運(yùn)行的容器會(huì)一個(gè)一個(gè)更新。
運(yùn)行效果如下圖所示。
你可以用Docker Swarm做更多事情
本文使用的是一個(gè)模擬爬蟲(chóng)的例子,但是顯然,任何可以批量運(yùn)行的程序都能夠用Docker Swarm來(lái)運(yùn)行,無(wú)論你用Redis還是Celery來(lái)通信,無(wú)論你是否需要通信,只要能批量運(yùn)行,就能用Docker Swarm。
在同一個(gè)Swarm集群里面,可以運(yùn)行多個(gè)不同的服務(wù),各個(gè)服務(wù)之間互不影響。真正做到了搭建一次Docker Swarm集群,然后就再也不用管了,以后的所有操作你都只需要在Manager節(jié)點(diǎn)所在的這個(gè)服務(wù)器上面運(yùn)行。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Docker 常用命令整理及使用注意事項(xiàng)總結(jié)
這篇文章主要介紹了Docker 常用命令整理及使用注意事項(xiàng)總結(jié)的相關(guān)資料,這里整理了Docker 的常用命令,說(shuō)明這些命令是什么意思及使用方法,需要的朋友可以參考下2016-12-12本地Docker安裝Postgres 12 + pgadmin的方法 (支持Apple M1)
這篇文章主要介紹了本地Docker安裝Postgres 12 + pgadmin的方法 (支持Apple M1),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03常用的8個(gè)應(yīng)用和中間件的Docker運(yùn)行示例詳解
Portainer是一個(gè)輕量級(jí)的管理 UI ,可讓你輕松管理不同的 Docker 環(huán)境(Docker 主機(jī)或 Swarm 群集),這篇文章主要介紹了常用的8個(gè)應(yīng)用和中間件的Docker運(yùn)行示例,需要的朋友可以參考下2024-03-03云原生使用Docker部署Firefox瀏覽器詳細(xì)圖文教程
下面這篇文章主要給大家介紹了關(guān)于云原生使用Docker部署Firefox瀏覽器的相關(guān)資料,這對(duì)于一些特殊的測(cè)試場(chǎng)景非常有用,例如需要在不同版本的瀏覽器中進(jìn)行測(cè)試,需要的朋友可以參考下2024-04-04使用docker創(chuàng)建靜態(tài)網(wǎng)站應(yīng)用(多種方式)
這篇文章主要介紹了使用docker創(chuàng)建靜態(tài)網(wǎng)站應(yīng)用(多種方式),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01詳解使用Docker進(jìn)行Redis主從復(fù)制實(shí)踐
這篇文章主要介紹了詳解使用Docker進(jìn)行Redis主從復(fù)制實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04docker容器連接宿主機(jī)redis與mysql的配置方法
最近有朋友在工作時(shí)遇到一個(gè)問(wèn)題,docker容器無(wú)法訪(fǎng)問(wèn)宿主機(jī)的redis,所以這里給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于docker容器連接宿主機(jī)redis與mysql的配置方法,需要的朋友可以參考下2023-06-06