大神的Docker初體驗(yàn):入門實(shí)踐篇
一、實(shí)踐背景
為了學(xué)習(xí)Docker,我們先結(jié)合實(shí)際需求,設(shè)計(jì)這樣一個(gè)場景case:假設(shè)有一個(gè)個(gè)人網(wǎng)站,想使用Nginx反向代理方案,能夠在國內(nèi)外快速搭建多個(gè)類似于CDN的節(jié)點(diǎn),提供集群式的WEB訪問服務(wù)。
我想到的方案如下:
1.常規(guī)部署方案: 購買云主機(jī)->環(huán)境初始化->部署Nginx->配置反向代理->DNS解析
2.Docker部署方案:購買云主機(jī)->yum 安裝docker->拉取自定義鏡像并執(zhí)行->DNS解析
3.騰訊云容器方案: 騰訊云容器服務(wù)->創(chuàng)建服務(wù)->DNS解析
很明顯,使用Docker部署方案,整個(gè)過程會(huì)變得簡單快捷,也更易自動(dòng)化。當(dāng)然,若不是對(duì)IDC有特殊要求的話,騰訊云的容器服務(wù)當(dāng)選為***方案。
下面簡單記錄下我從Docker鏡像的創(chuàng)建、上傳到部署的實(shí)踐過程。
實(shí)驗(yàn)環(huán)境:
- 騰訊云:CentOS Linux release 7.2.1511 (Core)
- 阿里云:CentOS Linux release 7.2.1511 (Core)
- Docker version 1.12.6, build 88a4867/1.12.6
- Docker 鏡像版本:Centos 官方***版
- Nginx 版本:Tengine 2.2.0
- 其他略..
二、制作鏡像
1、安裝配置Docker
- # 安裝docker
- yum install -y docker
- # 配置騰訊云鏡像加速(官方的龜速)
- vim /etc/sysconfig/docker
- #新增如下參數(shù):
- OPTIONS='--registry-mirror=https://mirror.ccs.tencentyun.com'
- #重啟docker服務(wù):
- systemctl restart docker
2、制作基礎(chǔ)鏡像
拉取 centos官方基礎(chǔ)鏡像
docker pull centos
查看當(dāng)前鏡像
docker images
- [root@MyServer docker]# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- docker.io/centos latest 328edcd84f1b 4 weeks ago 192.5 MB
運(yùn)行并進(jìn)入鏡像:
- docker run -ti docker.io/centos:latest /bin/bash
此時(shí),終端已經(jīng)進(jìn)入了鏡像里面,現(xiàn)在我們可以根據(jù)自己的需求安裝額外的組件,比如我這次需要用到crontab任務(wù)計(jì)劃服務(wù)、進(jìn)程守護(hù)supervisor等,那么直接在這個(gè)終端開始操作:
- [root@0d7f7b8769d9 /]# yum install -y epel-release crontabs
- [root@0d7f7b8769d9 /]# yum install -y python-pip
- [root@0d7f7b8769d9 /]# pip install --upgrade pip
- [root@0d7f7b8769d9 /]# pip install supervisor
Ps:上面的PS提示符中的 0d7f7b8769d9 就是本次啟動(dòng)的 CONTAINER ID ,在下面的commit步驟即將用到。
完成必要組件安裝之后,按下 Ctrl +D 退出系統(tǒng),接著使用 docker commit 命令創(chuàng)建新鏡像,比如命名為 nginx-proxy-base,版本latest:
- docker commit 0d7f7b8769d9 centos/nginx-proxy-base:latest
執(zhí)行完成后,可以使用 docker images 查看剛創(chuàng)建的鏡像:
- [root@MyServer ~]# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- centos/nginx-proxy-base latest 676fcfff6d3c About an hour ago 366 MB
到此,我們就創(chuàng)建了一個(gè)自定義的Docker基礎(chǔ)鏡像(Ps:基礎(chǔ)鏡像類似一個(gè)VM虛擬機(jī)的快照,方便后續(xù)步驟都可以從這個(gè)基礎(chǔ)上重新制作。)
Ps:這里展示的是進(jìn)入Docker里面通過手工部署的方式,其實(shí)我們還可以通過DockerFile來完成上述所有操作,可以極大的減小Docker鏡像的體積。
3、制作服務(wù)鏡像
有了前面的基礎(chǔ)鏡像之后,我們可以在此基礎(chǔ)之上添加應(yīng)用程序或自定義配置,打包為服務(wù)鏡像。以本文背景需求為例,為了方便后續(xù)維護(hù),Nginx我采用純靜態(tài)編譯方式,制作成綠色便攜版本。
因此,我們先在宿主機(jī)上靜態(tài)編譯一個(gè)符合需求的Nginx(僅展示關(guān)鍵步驟,依賴組件自行搞定):
- # 把所有依賴都靜態(tài)編譯進(jìn)去
- ./configure --prefix=/usr/local/nginx \
- --with-http_v2_module \
- --with-http_ssl_module \
- --with-http_gzip_static_module \
- --with-http_realip_module \
- --with-pcre=../pcre-8.39 \
- --with-zlib=../zlib-1.2.11 \
- --with-http_sub_module \
- --with-openssl=../openssl-1.0.2j \
- --add-module=../ngx_cache_purge-2.3 \
- --add-module=../ngx_http_substitutions_filter_module
- # 安裝
- make && make install
安裝后得到 /usr/local/nginx 目錄,接著我們按照實(shí)驗(yàn)需求修改Nginx各項(xiàng)配置,比如反向代理:
- server {
- listen 80;
- server_name demo.domain.com;
- access_log /data/wwwlogs/demo.domain.com.log;
- index index.html index.htm index.php;
- location / {
- proxy_pass http://xxx.xxx.xxx.xxx;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_redirect off;
- proxy_set_header Host demo.domain.com;
- }
- }
全部配置OK后,運(yùn)行nginx,確保可以正常工作。
4、編寫Dockerfile
①、創(chuàng)建一個(gè)目錄,比如:
- mkdir -p /data/docker-nginx-proxy
- cd /data/docker-nginx-proxy
②、創(chuàng)建 supervisor配置文件,注意必須非daemon模式,所以此處crond會(huì)帶上-n參數(shù):
- [supervisord]
- nodaemon=true
- [program:crond]
- command=crond -n
- [program:nginx]
- command=/usr/local/nginx/sbin/nginx
③、繼續(xù)創(chuàng)建其他所需文件,比如 crontab.list:
- */20 * * * * /usr/local/nginx/sbin/nginx -s reload > /dev/null 2>&1
④、將前面的nginx目錄拷貝過來:
cp -rf /usr/local/nginx .
⑤、編寫Dockerfile文件:
vim Dockerfile
- FROM centos/nginx-proxy-base:latest
- MAINTAINER <jagerzhang@tencent.com>
- # 將所需文件復(fù)制到鏡像指定路徑
- ADD nginx /usr/local/nginx
- ADD supervisord.conf /etc/supervisord.conf
- # 定義一些命令(因?yàn)镈ocker是分層的,這里建議將多個(gè)命令通過&&連接,寫到一個(gè)RUN里面來減少Docker層數(shù))
- # 指定時(shí)區(qū),解決Dcoker時(shí)間和宿主機(jī)時(shí)間差異問題
- RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
- echo Asia/Shanghai > /etc/timezone && \
- ln -sf /usr/local/nginx/sbin/nginx /bin/ && \
- echo 'daemon off;' >> /usr/local/nginx/conf/nginx.conf && \
- crontab /etc/crontab.list
- # 運(yùn)行 supervisor,這里注意CMD只能用一次
- CMD ["/usr/bin/supervisord"]
附:dockerfile 常用指令,可以按實(shí)際需求自行添加:
- FROM:指定基礎(chǔ)image
- MAINTAINER:用來指定鏡像創(chuàng)建者信息
- ADD:從src復(fù)制文件到container的dest路徑
- RUN:在容器里面執(zhí)行命令
- CMD:設(shè)置container啟動(dòng)時(shí)執(zhí)行的操作,只能是一條,多條則只執(zhí)行***一條
- EXPOSE:指定容器需要映射到宿主機(jī)器的端口,也可以再run的時(shí)候指定
- ENV:用于設(shè)置環(huán)境變量
- VOLUME:指定掛載點(diǎn),使容器中的一個(gè)目錄具有持久化存儲(chǔ)數(shù)據(jù)的功能
5、構(gòu)建鏡像
命令為:docker build -t="[name]:[tag]" ./ ,比如:
docker build -t="centos/nginx-proxy:v1" ./
build之后,再執(zhí)行docker images就可以看到剛剛創(chuàng)建的鏡像:
- [root@MyServer docker-nginx-proxy]# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- centos/nginx-proxy v1 f2ed91429b31 31 seconds ago 370.8 MB
- centos/nginx-proxy-base latest 676fcfff6d3c About an hour ago 366 MB
接著,可以下測試鏡像是否能正常運(yùn)行,命令語法大致如下:
- docker run -v [宿主目錄]:[鏡像目錄] -ti -p [宿主端口]:[鏡像端口] 鏡像名稱:版本
若加上 -d 參數(shù),docker將會(huì)后臺(tái)運(yùn)行,這里我們想看下剛剛創(chuàng)建的鏡像是否正常, 所以采用前臺(tái)運(yùn)行模式,命令如下:
- docker run -v /data/docker:/data/wwwlogs -ti -p 80:80 centos/nginx-proxy:v1
執(zhí)行過程:
- [root@MyServer docker-nginx-proxy ~]# docker run -v /data/docker:/data/wwwlogs -ti -p 443:443 -p 80:80 ccr.ccs.tencentyun.com/myspace/nginx-proxy:latest
- /usr/lib/python2.7/site-packages/supervisor/options.py:298: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
- 'Supervisord is running as root and it is searching '
- 2017-09-03 06:34:59,613 CRIT Supervisor running as root (no user in config file)
- 2017-09-03 06:34:59,615 INFO supervisord started with pid 1
- 2017-09-03 06:35:00,617 INFO spawned: 'nginx' with pid 7
- 2017-09-03 06:35:00,622 INFO spawned: 'crond' with pid 8
- 2017-09-03 06:35:01,689 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
- 2017-09-03 06:35:01,689 INFO success: crond entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
可以看到,鏡像能夠正常運(yùn)行,接著我們還可以繼續(xù)測試下啟動(dòng)的Nginx是否能夠正常提供服務(wù),這里就不詳細(xì)介紹了。
三、私有倉庫
前文已經(jīng)制作了一個(gè)帶有Nginx反向代理服務(wù)的Docker鏡像,此時(shí)還只能在本地使用,若是要讓其他服務(wù)器也能用到這個(gè)鏡像,我們可以使用 docker registry 創(chuàng)建一個(gè)私有倉庫,步驟如下:
1、拉取私有倉庫registry
- docker pull registry
此時(shí),執(zhí)行docker images應(yīng)該可以看到4個(gè)鏡像:
- [root@MyServer docker-nginx-proxy]# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- centos/nginx-proxy v1 f2ed91429b31 About an hour ago 370.8 MB
- centos/nginx-proxy-base latest 676fcfff6d3c 2 hours ago 366 MB
- docker.io/centos latest 328edcd84f1b 4 weeks ago 192.5 MB
- docker.io/registry latest 9d0c4eabab4d 3 months ago 33.17 MB
2、拉起倉庫
- docker run -d -p 5000:5000 -v /data/images:/tmp/registry docker.io/registry
3、推送鏡像
***步查看鏡像列表時(shí),拿到需要推送的鏡像的ID,比如 f2ed91429b31
①、先打tag,語法如下:
docker tag [image id] [倉庫地址]/[命名空間]/[鏡像名稱]:[版本]
②、然后push,語法如下:
docker push [倉庫地址]/[命名空間]/[鏡像名稱]
執(zhí)行過程如下所示:
- [root@MyServer docker-nginx-proxy]# docker tag f2ed91429b31 localhost:5000/centos/nginx-proxy:latest
- [root@MyServer docker-nginx-proxy]# docker push localhost:5000/centos/nginx-proxy
- The push refers to a repository [localhost:5000/centos/nginx-proxy]
- 158fae47d4e2: Pushed
- 4a5dcec3edb7: Pushed
- ae9a40cbe568: Pushed
- 7abc8eb8fc0f: Pushed
- d8a5f0f5adc1: Pushed
- 7dc25a4e14aa: Pushed
- c7ee46ed4410: Pushing [===> ] 9.669 MB/153.1 MB
- b362758f4793: Pushing [======> ] 26.78 MB/192.5 MB
完成后,執(zhí)行docker images就可以看到剛剛提交的鏡像了:
- [root@MyServer docker-nginx-proxy]# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- localhost:5000/centos/nginx-proxy latest f2ed91429b31 About an hour ago 370.8 MB
- centos/nginx-proxy v1 f2ed91429b31 About an hour ago 370.8 MB
- centos/nginx-proxy-base latest 676fcfff6d3c 2 hours ago 366 MB
- docker.io/centos latest 328edcd84f1b 4 weeks ago 192.5 MB
- docker.io/registry latest 9d0c4eabab4d 3 months ago 33.17 MB
③、測試?yán)。?/p>
現(xiàn)在可以在本機(jī)(本機(jī)可以先刪除在拉取)或另找一臺(tái)服務(wù)器進(jìn)行docker pull拉取測試。
比如,先在宿主機(jī)上刪除這個(gè)鏡像:
- [root@MyServer docker-nginx-proxy]# docker rmi localhost:5000/centos/nginx-proxy
- Untagged: localhost:5000/centos/nginx-proxy:latest
- Untagged: localhost:5000/centos/nginx-proxy@sha256:20e7898413c368ee8dbfac0649fbfbb2d43510c3024d01e6ea3ec3f1a5d7c152
此時(shí),docker images 列表已經(jīng)消失,再執(zhí)行 docker pull 就又回來了。
- [root@MyServer docker-nginx-proxy]# docker pull localhost:5000/centos/nginx-proxy
- Using default tag: latest
- Trying to pull repository localhost:5000/centos/nginx-proxy ...
- sha256:20e7898413c368ee8dbfac0649fbfbb2d43510c3024d01e6ea3ec3f1a5d7c152: Pulling from localhost:5000/centos/nginx-proxy
- Digest: sha256:20e7898413c368ee8dbfac0649fbfbb2d43510c3024d01e6ea3ec3f1a5d7c152
- Status: Downloaded newer image for localhost:5000/centos/nginx-proxy:latest
4、離線方案
當(dāng)私有倉庫無法使用時(shí)(比如存在網(wǎng)絡(luò)限制),我們還可以將鏡像保存為一個(gè)tar包,方便離線使用,使用也非常簡單:
①、export / import 方案
使用 docker ps -a 查看當(dāng)前正在運(yùn)行的docker鏡像列表,得到對(duì)應(yīng)的 CONTAINER ID,執(zhí)行如下語句可以將運(yùn)行中的鏡像導(dǎo)出到指定tar包:
- docker export [CONTAINER ID] > centos-nginx-proxy-latest.tar
有了tar包之后,就可以使用 import 來導(dǎo)入:
- cat centos-nginx-proxy-latest.tar | docker import - centos/nginx-proxy:v1
②、save / load 方案
使用 docker images 查看本地已有鏡像列表,得到對(duì)應(yīng)的IMAGE ID,然后執(zhí)行如下語句可以將本地已存在鏡像保存到指定tar包:
- docker save [IMAGE ID] > centos-nginx-proxy-latest.tar
后面則可以使用 load 來加載tar包鏡像:
- docker load < centos-nginx-proxy-latest.tar
兩種方案的區(qū)別:
- export 只能導(dǎo)出正在運(yùn)行的鏡像,而 save 可以直接導(dǎo)出本地鏡像;
- export 導(dǎo)出的鏡像文件一般會(huì)小于 save 保存的鏡像(本文實(shí)踐數(shù)據(jù):相差38MB);
- export 導(dǎo)出(import導(dǎo)入)是根據(jù)容器拿到的鏡像,再導(dǎo)入時(shí)會(huì)丟失鏡像所有的歷史,所以無法進(jìn)行回滾操作(docker tag,而save保存(load加載)的鏡像,沒有丟失鏡像的歷史,可以回滾到之前的層(layer)。
四、容器服務(wù)
上述私有倉庫其實(shí)已經(jīng)可以滿足整個(gè)實(shí)驗(yàn)背景需求,我們可以在購買其他云主機(jī)之后,就可以通過私有倉庫外網(wǎng)地址快速拉起一個(gè)Nginx反向代理服務(wù)了。
但是,我們都知道國內(nèi)的云主機(jī)都是小水管,而按流量收費(fèi)的模式也比較昂貴。此時(shí),本文的主角才姍姍來遲:騰訊云-容器服務(wù)。
簡單來說,騰訊云的容器服務(wù),就是給我們提供了一個(gè)在云端的Docker私有倉庫,我們可以將制作好的鏡像,推送到騰訊云私有鏡像倉庫,然后就可以在騰訊云或國內(nèi)外其他云主機(jī)上快速拉起自定義的Docker鏡像服務(wù)了,非常非常方便!而且,最重要的是...該服務(wù)目前免費(fèi)。
下面簡單分享一下騰訊云容器服務(wù)的使用方法。
1、創(chuàng)建倉庫
①、開通鏡像服務(wù)
打開騰訊云-容器服務(wù):https://console.qcloud.com/ccs
按照頁面提示填寫相關(guān)信息并設(shè)置倉庫密碼:
②、接著在【我的創(chuàng)建】頁面新建一個(gè)鏡像倉庫:
得到騰訊云私有倉庫地址:
即:ccr.ccs.tencentyun.com/myspace/nginx-proxy
③、重置密碼
如果忘記密碼的話,可以使用【重置密碼】功能來設(shè)置新的密碼:
2、上傳鏡像
①、倉庫認(rèn)證
username 填寫你登錄騰訊云的賬號(hào),一般是QQ號(hào)碼
- docker login --username=[username] ccr.ccs.tencentyun.com
②、推送鏡像
和前文推送鏡像到本地私有倉庫一樣,先查看鏡像ID,然后如下先打tag,然后推送:
- docker tag [ImageId] ccr.ccs.tencentyun.com/[namespace]/[ImageName]:[tag]
- docker push ccr.ccs.tencentyun.com/[namespace]/[ImageName]:[tag]
比如:
- docker tag f2ed91429b31 ccr.ccs.tencentyun.com/myspace/nginx-proxy:latest
- docker push ccr.ccs.tencentyun.com/myspace/nginx-proxy:latest
成功后,就可以在騰訊云容器頁面查看到剛剛提交的鏡像版本了:
3、拉取鏡像
***,我們就可以在需要部署Nginx反代服務(wù)的云主機(jī)上進(jìn)行拉取操作了。
比如,我在阿里云主機(jī)上拉取這個(gè)鏡像:
①、安裝docker:yum install docker
②、啟動(dòng)docker:systemctl restart docker.service
③、登錄騰訊云倉庫
- docker login --username=xxxxx http://ccr.ccs.tencentyun.com/myspace/nginx-proxy
④、拉取鏡像
docker pull ccr.ccs.tencentyun.com/myspace/nginx-proxy
- [root@iZbp1ct9hsppxrazdvn54mZ ~]# docker pull ccr.ccs.tencentyun.com/myspace/nginx-proxy
- Using default tag: latest
- Trying to pull repository ccr.ccs.tencentyun.com/myspace/nginx-proxy ...
- latest: Pulling from ccr.ccs.tencentyun.com/myspace/nginx-proxy
- 74f0853ba93b: Downloading [===========================> ] 39.11 MB/72.25 MB
- e7fa91cce4c4: Downloading [================================> ] 37.65 MB/57.14 MB
- c7319b8f7fbc: Download complete
- faf8180992b4: Download complete
- 79327b915b74: Download complete
- 702ede4e59c4: Download complete
- 77e09cc85e34: Download complete
- 8a265e81261a: Download complete
⑤、運(yùn)行鏡像
這里我們正式執(zhí)行,所以加上 -d 參數(shù):
- docker run -v /data/docker:/data/wwwlogs -dti -p 443:443 -p 80:80 ccr.ccs.tencentyun.com/myspace/nginx-proxy:latest
整個(gè)過程不到5分鐘,真的非常方便!
五、小結(jié)
本文記錄了一個(gè)實(shí)際的Dokcer應(yīng)用場景從創(chuàng)建、上傳直到部署的詳細(xì)過程,Docker為我們提供了一個(gè)新的軟件發(fā)布方式,只要將應(yīng)用以及相關(guān)的依賴打包成Docker鏡像,并上傳到鏡像倉庫之后,我們就可以快速拉起一個(gè)定制服務(wù),毫無拖泥帶水,從而極大的簡化了部署。
本文還簡單的介紹了騰訊云的容器服務(wù),通過容器服務(wù),我們可以上傳自定制Docker鏡像,可以在騰訊云主機(jī)或其他國內(nèi)網(wǎng)服務(wù)器上快速拉起應(yīng)用服務(wù),加快了業(yè)務(wù)部署節(jié)奏,并降低了運(yùn)維成本。
嗯,當(dāng)然最重要的還是我通過這個(gè)實(shí)踐,熟悉了Docker的基本知識(shí)和基礎(chǔ)使用方法,從而實(shí)現(xiàn)了我的Docker入門學(xué)習(xí)目標(biāo)。
原文鏈接:http://t.cn/RpkWtxc
【本文是51CTO專欄作者“騰訊云技術(shù)社區(qū)”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過51CTO聯(lián)系原作者獲取授權(quán)】