您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么在Docker中使用Serf”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么在Docker中使用Serf”吧!
#在Docker中使用Serf
編寫思路來自 Decentralizing Docker: How to Use Serf with Docker 本文已提交 dockboard 發布,在此利用開源中國的知名度擴散,感謝。
在之前的 Docker Link使用示例 中,我們對 Docker 的link特性進行了簡單的演示,這次的主題是使用 Serf 實現更加低耦合的容器關系結構,最終達到的效果是服務化各個服務。
Serf 是一個去中心化的服務發現和編排的解決方案,特點是輕量級和高可用,同時具備容錯的特性。
##構建Serf鏡像
在這我并沒有使用 Supervisord 來啟動Serf服務,大家可以參照后面的示例來啟動Serf。
Dockerfile_serf:
FROM ubuntu:12.04 MAINTAINER Marker.King <majk@vip.qq.com> RUN echo "deb http://mirrors.aliyun.com/ubuntu precise main universe" > /etc/apt/sources.list RUN apt-get update RUN apt-get install -y wget unzip RUN wget --no-check-certificate https://dl.bintray.com/mitchellh/serf/0.4.1_linux_amd64.zip RUN unzip 0.4.1_linux_amd64.zip RUN rm 0.4.1_linux_amd64.zip RUN mv serf /usr/bin/ EXPOSE 7946 7373 CMD ["-tag", "role=serf-agent"] ENTRYPOINT ["serf", "agent"]
構建Serf鏡像:
$ docker build -t serf - < Dockerfile_serf
##構建mysql鏡像
這一步比較復雜,我們將編寫多個shell腳本,用于啟動supervisor、啟動mysql、創建數據庫用戶、創建數據庫等,先讓我們看一下目錄結構
mysql + | - create_db.sh | - create_mysql_admin_user.sh | - Dockerfile | - join-cluster.sh | - my.cnf | - run.sh | - start-serf.sh | - start.sh | - supervisord-mysqld.conf | - supervisord-serf.conf
create_db.sh:
#!/bin/bash read -r line if [ -n "$line" ]; then echo "=> Creating database $line" mysql -uroot -e "CREATE DATABASE $line" echo "=> Done!" else echo "Usage: $0 <db_name>" exit 1 fi
create_mysql_admin_user.sh:
#!/bin/bash if [ -f /.mysql_admin_created ]; then echo "MySQL 'admin' user already created!" exit 0 fi /usr/bin/mysqld_safe > /dev/null 2>&1 & PASS=$(pwgen -s 12 1) echo "=> Creating MySQL admin user with random password" RET=1 while [[ RET -ne 0 ]]; do sleep 5 mysql -uroot -e "CREATE USER 'admin'@'%' IDENTIFIED BY '$PASS'" RET=$? done mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION" mysqladmin -uroot shutdown echo "=> Done!" touch /.mysql_admin_created echo "========================================================================" echo "You can now connect to this MySQL Server using:" echo "" echo " mysql -uadmin -p$PASS -h<host> -P<port>" echo "" echo "Please remember to change the above password as soon as possible!" echo "MySQL user 'root' has no password but only allows local connections" echo "========================================================================"
join-cluster.sh:
#!/bin/bash exec serf join $SERF_AGENT_PORT_7946_TCP_ADDR:$SERF_AGENT_PORT_7946_TCP_PORT
my.cnf:
[mysqld] bind-addres=0.0.0.0
run.sh:
#!/bin/bash if [ ! -f /.mysql_admin_created ]; then /create_mysql_admin_user.sh fi exec supervisord -n
start-serf.sh:
#!/bin/bash exec serf agent -tag role=db \ -event-handler="user:create_db=/create_db.sh"
start.sh:
#!/bin/bash exec mysqld_safe
supervisord-mysqld.conf:
[program:mysqld] command=/start.sh numprocs=1 autostart=true autorestart=true
supervisord-serf.conf:
[program:serf] command=/start-serf.sh numprocs=1 autostart=true autorestart=true [program:serf-join] command=/join-cluster.sh autorestart=false
Dockerfile:
FROM ubuntu:12.04 MAINTAINER Marker King <majk@vip.qq.com> RUN echo "deb http://mirrors.aliyun.com/ubuntu precise main universe" > /etc/apt/sources.list RUN apt-get update RUN apt-get -y upgrade RUN ! DEBIAN_FRONTEND=noninteractive apt-get -qy install unzip supervisor mysql-server pwgen; ls ADD https://dl.bintray.com/mitchellh/serf/0.4.1_linux_amd64.zip serf.zip RUN unzip serf.zip RUN rm serf.zip RUN mv serf /usr/bin/ ADD /run.sh /run.sh ADD /start.sh /start.sh ADD /start-serf.sh /start-serf.sh ADD /join-cluster.sh /join-cluster.sh ADD /supervisord-mysqld.conf /etc/supervisor/conf.d/supervisord-mysqld.conf ADD /supervisord-serf.conf /etc/supervisor/conf.d/supervisord-serf.conf ADD /my.cnf /etc/mysql/conf.d/my.cnf ADD /create_mysql_admin_user.sh /create_mysql_admin_user.sh ADD /create_db.sh /create_db.sh RUN chmod 755 /*.sh EXPOSE 3306 7946 7373 CMD ["/run.sh"]
大家可能看到了,這里使用了ADD https://dl.bintray.com/mitchellh/serf/0.4.1_linux_amd64.zip serf.zip
來添加一個遠程文件到鏡像中,這跟Serf服務鏡像構建時使用的方法不一樣,但是達到了同樣的效果。在此我需要解釋一下,RUN wget <url>
是可以被緩存的,而ADD <url> <name>
是不能夠被緩存的,也就是說每次構建都會再次下載這個文件,RUN wget <url>
則會使用緩存,從而加快構建速度。大家可以試一下分別構建兩次鏡像,可以發現Serf鏡像第二次全部使用了緩存,而mysql會在Step 6再次下載文件。
進入mysql目錄構建鏡像:
$ docker build -t mysql .
##測試Serf連接
通過Serf鏡像啟動一個容器:
$ SERF_ID=$(docker run -d -p 7946 -p 7373 -name serf_agent serf)
讓我們測試一下Serf是否正常工作,在我們的宿主機上(安裝docker的機器)也安裝Serf,來連接容器的Serf:
$ wget --no-check-certificate https://dl.bintray.com/mitchellh/serf/0.4.1_linux_amd64.zip $ unzip 0.4.1_linux_amd64.zip $ rm 0.4.1_linux_amd64.zip $ sudo mv serf /usr/bin/ $ nohup serf agent & $ serf members packer-virtualbox 10.0.2.15:7946 alive
現在,在我們的機器上就擁有了一個可用的Serf,你可以連接Docker的Serf代理容器來看看效果:
$ serf join $(docker port $SERF_ID 7946) Successfully joined cluster by contacting 1 nodes. $ serf members precise64 10.0.2.15:7946 alive 9be517551dda 172.17.0.2:7946 alive role=serf-agent
##測試Serf事件派發到mysql服務
讓我們啟動一個mysql容器,并與serf_agent連接,使用-link參數,注意格式為name:alias,這里alias必須使用serf_agent,因為在join-cluster.sh中固定調用了SERF_AGENT_PORT_7946_TCP_ADDR
和SERF_AGENT_PORT_7946_TCP_PORT
兩個環境變量,可以按照不同的名稱要求做連接,命令如下:
$ MYSQL_ID=$(docker run -d -p 3306 -p 7946 -p 7373 -link serf_agent:serf_agent mysql)
在宿主機中查看Serf集群情況:
$ serf members precise64 10.0.2.15:7946 alive 9be517551dda 172.17.0.2:7946 alive role=serf-agent 410d5a7f709a 172.17.0.3:7946 alive role=db
因為在mysql容器啟動時,執行了join-cluster.sh腳本連接到了serf_agent,因此在宿主機中我們可以看到之后加入進來的mysql。
此時我們可以通過docker logs $MYSQL_ID
查看mysql輸出的用戶名和密碼信息(可以通過修改create_mysql_admin_user.sh來改變用戶信息或輸出格式等)。
$ docker logs $MYSQL_ID => Creating MySQL admin user with random password => Done! ======================================================================== You can now connect to this MySQL Server using: mysql -uadmin -paWQD8mdb3N1j -h<host> -P<port> Please remember to change the above password as soon as possible! MySQL user 'root' has no password but only allows local connections ========================================================================
執行自定義命令,通知mysql創建數據庫:
$ serf event create_db wordpress Event 'create_db' dispatched! Coalescing enabled: true
連接數據庫,并查看數據庫是否創建成功:
$ mysql -uadmin -paWQD8mdb3N1j -h227.0.0.1 -P49157 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | wordpress | +--------------------+ 5 rows in set (0.00 sec)
成功了!我們看到了數據庫已經被創建。
#總結
今天的示例就寫到這里,大家可以繼續發散思考,我的mysql容器已經具備了接受命令的功能,那么如果我再創建一個wordpress容器,當容器啟動時會發送create_db命令給serf_agent,這樣mysql就達到了服務化的目的。當然能夠服務化的還很多,例如:負載均衡、memcached、redis等等。如果大家有什么更好的想法,可以共享出來,我的郵箱地址是:majk@vip.qq.com
感謝各位的閱讀,以上就是“怎么在Docker中使用Serf”的內容了,經過本文的學習后,相信大家對怎么在Docker中使用Serf這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。