Docker 入門實踐
歡迎大家前往騰訊雲技術社區,獲取更多騰訊海量技術實踐幹貨哦~
作者:張戈
導語
本文從新手視角記錄了一個實際的Dokcer應用場景從創建、上傳直到部署的詳細過程,並簡單的介紹了騰訊雲容器服務的使用方法。通過Docker快速拉起一個定制服務,極大的簡化了部署,加快了業務部署節奏,並降低了運維成本。 ------ 人生苦短,快用Docker。
一、實踐背景
初次接觸Docker,按照我的學習習慣,先設計了這樣一個場景case:假設有一個小型網站,想使用Nginx反向代理方案,能夠在國內外快速搭建多個類似於CDN的節點,提供集群式的WEB訪問服務。
我想到的方案如下:
1.常規部署方案: 購買雲主機->環境初始化->部署Nginx->配置反向代理->DNS解析
2.Docker部署方案:購買雲主機->yum 安裝docker->拉取自定義鏡像並執行->DNS解析
3.騰訊雲容器方案: 騰訊雲容器服務->創建服務->DNS解析
很明顯,使用Docker部署方案,整個過程會變得簡單快捷,也更易自動化。當然,若不是對IDC有特殊要求的話,騰訊雲的容器服務當選為最佳方案。
下面簡單記錄下我從Docker鏡像的創建、上傳到部署的實踐過程。
實驗環境:
?騰訊雲: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 #新增如下參數: OPTIONS=‘--registry-mirror=https://mirror.ccs.tencentyun.com‘ #重啟docker服務: systemctl restart docker
2、制作基礎鏡像
拉取 centos官方基礎鏡像
docker pull centos
查看當前鏡像
docker images
[[email protected] docker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos latest 328edcd84f1b 4 weeks ago 192.5 MB
運行並進入鏡像:
docker run -ti docker.io/centos:latest /bin/bash
此時,終端已經進入了鏡像裏面,現在我們可以根據自己的需求安裝額外的組件,比如我這次需要用到crontab任務計劃服務、進程守護supervisor等,那麽直接在這個終端開始操作:
[[email protected] /]# yum install -y epel-release crontabs [[email protected] /]# yum install -y python-pip [[email protected] /]# pip install --upgrade pip [[email protected] /]# pip install supervisor
完成必要組件安裝之後,暫時不要退出終端,否則前功盡棄了!
現在,我們額外克隆一個宿主會話,然後執行 docker images 命令可以看到正在運行的docker container id:
[[email protected] ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0d7f7b8769d9 docker.io/centos:latest "/bin/bash" 7 minutes ago Up 7 minutes small_einstein
接著,使用 docker commit 命令創建新鏡像,比如命名為 nginx-proxy-base,版本latest
docker commit 0d7f7b8769d9 centos/nginx-proxy-base:latest
執行完成後,可以使用 docker images 查看剛創建的鏡像:
[[email protected] ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos/nginx-proxy-base latest 676fcfff6d3c About an hour ago 366 MB
到此,我們就創建了一個自定義的Docker基礎鏡像(Ps:基礎鏡像類似一個VM虛擬機的快照,方便後續步驟都可以從這個基礎上重新制作。)
3、制作服務鏡像
有了前面的基礎鏡像之後,我們可以在此基礎之上添加應用程序或自定義配置,打包為服務鏡像。以本文背景需求為例,為了方便後續維護,Nginx我采用純靜態編譯方式,制作成綠色便攜版本。
因此,我們先在宿主機上靜態編譯一個符合需求的Nginx(僅展示關鍵步驟,依賴組件自行搞定):
# 把所有依賴都靜態編譯進去 ./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 目錄,接著我們按照實驗需求修改Nginx各項配置,比如反向代理:
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後,運行nginx,確保可以正常工作。
4、編寫Dockerfile
①、創建一個目錄,比如:
mkdir -p /data/docker-nginx-proxy
cd /data/docker-nginx-proxy
②、創建 supervisor配置文件,註意必須非daemon模式,所以此處crond會帶上-n參數:
[supervisord] nodaemon=true [program:crond] command=crond -n [program:nginx] command=/usr/local/nginx/sbin/nginx
③、繼續創建其他所需文件,比如 crontab.list:
*/20 * * * * /sbin/ntpdate pool.ntp.org > /dev/null 2>&1
④、將前面的nginx目錄拷貝過來:
cp -rf /usr/local/nginx .
⑤、編寫Dockerfile文件:
vim Dockerfile
FROM centos/nginx-proxy-base:latest MAINTAINER <[email protected]> # 將所需文件復制到鏡像指定路徑 ADD nginx /usr/local/nginx ADD supervisord.conf /etc/supervisord.conf ADD crontab.list /etc/crontab.list # 定義一些命令 RUN ln -sf /usr/local/nginx/sbin/nginx /bin/ # Docker裏面必須前臺運行,所以新增 daemon off 配置 RUN echo ‘daemon off;‘ >> /usr/local/nginx/conf/nginx.conf # 導入crontab RUN crontab /etc/crontab.list # 運行 supervisor,這裏註意CMD只能用一次 CMD ["/usr/bin/supervisord"]
附:dockerfile 常用指令,可以按實際需求自行添加:
FROM:指定基礎image
MAINTAINER:用來指定鏡像創建者信息
ADD:從src復制文件到container的dest路徑
RUN:在容器裏面執行命令
CMD:設置container啟動時執行的操作,只能是一條,多條則只執行最後一條
EXPOSE:指定容器需要映射到宿主機器的端口,也可以再run的時候指定
ENV:用於設置環境變量
VOLUME:指定掛載點,使容器中的一個目錄具有持久化存儲數據的功能
5、構建鏡像
命令為:docker build -t="[name]:[tag]" ./ ,比如:
docker build -t="centos/nginx-proxy:v1" ./
執行過程如下:
[[email protected] docker-nginx-proxy]# docker build -t="centos/nginx-proxy:v1" . Sending build context to Docker daemon 4.876 MB Step 1 : FROM centos/nginx-proxy-base:latest ---> 676fcfff6d3c Step 2 : ADD nginx /usr/local/nginx ---> dedaa0014515 Removing intermediate container 31208179d3ef Step 3 : ADD supervisord.conf /etc/supervisord.conf ---> 0035e4acfd16 Removing intermediate container f4c2668dc697 Step 4 : RUN ln -sf /usr/local/nginx/sbin/nginx /bin/ ---> Running in 98bddd7ae9ef ---> fe6d6f3cc71c Removing intermediate container 98bddd7ae9ef Step 5 : RUN echo ‘daemon off;‘ >> /usr/local/nginx/conf/nginx.conf ---> Running in b70f7c9be82d ---> 0c53a0ee855d Removing intermediate container b70f7c9be82d Step 6 : RUN crontab /usr/local/nginx/tools/crontab ---> Running in 2bca9875bc0c ---> e745d5d0ca03 Removing intermediate container 2bca9875bc0c Step 7 : CMD /usr/bin/supervisord ---> Running in 65c0ac38921a ---> f2ed91429b31 Removing intermediate container 65c0ac38921a Successfully built f2ed91429b31
執行docker images可以看到剛剛創建的鏡像:
[[email protected] 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
接著,可以下測試鏡像是否能正常運行,命令語法大致如下:
docker run -v [宿主目錄]:[鏡像目錄] -ti -p [宿主端口]:[鏡像端口] 鏡像名稱:版本
若加上 -d 參數,docker將會後臺運行,這裏我們想看下剛剛創建的鏡像是否正常, 所以采用前臺運行模式,命令如下:
docker run -v /data/docker:/data/wwwlogs -ti -p 80:80 centos/nginx-proxy:v1
執行過程:
[[email protected] 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)
可以看到,鏡像能夠正常運行,接著我們還可以繼續測試下啟動的Nginx是否能夠正常提供服務,這裏就不詳細介紹了。
三、私有倉庫
前文已經制作了一個帶有Nginx反向代理服務的Docker鏡像,此時還只能在本地使用,若是要讓其他服務器也能用到這個鏡像,我們可以使用 docker registry 創建一個私有倉庫,步驟如下:
1、拉取私有倉庫registry
docker pull registry
此時,執行docker images應該可以看到4個鏡像:
[[email protected] 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、推送鏡像
第一步查看鏡像列表時,拿到需要推送的鏡像的ID,比如 f2ed91429b31
①、先打tag,語法如下:
docker tag [image id] [倉庫地址]/[命名空間]/[鏡像名稱]:[版本]
②、然後push,語法如下:
docker push [倉庫地址]/[命名空間]/[鏡像名稱]
執行過程如下所示:
[[email protected] docker-nginx-proxy]# docker tag f2ed91429b31 localhost:5000/centos/nginx-proxy:latest [[email protected] 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
完成後,執行docker images就可以看到剛剛提交的鏡像了:
[[email protected] 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
③、測試拉取:
現在可以在本機(本機可以先刪除在拉取)或另找一臺服務器進行docker pull拉取測試。
比如,先在宿主機上刪除這個鏡像:
[[email protected] docker-nginx-proxy]# docker rmi localhost:5000/centos/nginx-proxy Untagged: localhost:5000/centos/nginx-proxy:latest Untagged: localhost:5000/centos/[email protected]:20e7898413c368ee8dbfac0649fbfbb2d43510c3024d01e6ea3ec3f1a5d7c152
此時,docker images 列表已經消失,再執行 docker pull 就又回來了。
[[email protected] 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、離線方案
當私有倉庫無法使用時(比如存在網絡限制),我們還可以將鏡像保存為一個tar包,方便離線使用,使用也非常簡單:
①、export / import 方案
使用 docker ps -a 查看當前正在運行的docker鏡像列表,得到對應的 CONTAINER ID,執行如下語句可以將運行中的鏡像導出到指定tar包:
docker export [CONTAINER ID] > centos-nginx-proxy-latest.tar
有了tar包之後,就可以使用 import 來導入:
cat centos-nginx-proxy-latest.tar | docker import - centos/nginx-proxy:v1
②、save / load 方案
使用 docker images 查看本地已有鏡像列表,得到對應的IMAGE ID,然後執行如下語句可以將本地已存在鏡像保存到指定tar包:
docker save [IMAGE ID] > centos-nginx-proxy-latest.tar
後面則可以使用 load 來加載tar包鏡像:
docker load < centos-nginx-proxy-latest.tar
兩種方案的區別:
?export 只能導出正在運行的鏡像,而 save 可以直接導出本地鏡像;
?export 導出的鏡像文件一般會小於 save 保存的鏡像(本文實踐數據:相差38MB);
?export 導出(import導入)是根據容器拿到的鏡像,再導入時會丟失鏡像所有的歷史,所以無法進行回滾操作(docker tag,而save保存(load加載)的鏡像,沒有丟失鏡像的歷史,可以回滾到之前的層(layer)。
四、容器服務
上述私有倉庫其實已經可以滿足整個實驗背景需求,我們可以在購買其他雲主機之後,就可以通過私有倉庫外網地址快速拉起一個Nginx反向代理服務了。
但是,我們都知道國內的雲主機都是小水管,而按流量收費的模式也比較昂貴。此時,本文的主角才姍姍來遲:騰訊雲-容器服務。
簡單來說,騰訊雲的容器服務,就是給我們提供了一個在雲端的Docker私有倉庫,我們可以將制作好的鏡像,推送到騰訊雲私有鏡像倉庫,然後就可以在騰訊雲或國內外其他雲主機上快速拉起自定義的Docker鏡像服務了,非常非常方便!而且,最重要的是...該服務目前免費。
下面簡單分享一下騰訊雲容器服務的使用方法。
1、創建倉庫
①、開通鏡像服務
打開騰訊雲-容器服務:https://console.qcloud.com/ccs
按照頁面提示填寫相關信息並設置倉庫密碼:
②、接著在【我的創建】頁面新建一個鏡像倉庫:
得到騰訊雲私有倉庫地址:
即:ccr.ccs.tencentyun.com/myspace/nginx-proxy
③、重置密碼
如果忘記密碼的話,可以使用【重置密碼】功能來設置新的密碼:
2、上傳鏡像
①、倉庫認證
username 填寫你登錄騰訊雲的賬號,一般是QQ號碼
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反代服務的雲主機上進行拉取操作了。
比如,我在阿裏雲主機上拉取這個鏡像:
①、安裝docker:yum install docker
②、啟動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
[[email protected] ~]# 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
⑤、運行鏡像
這裏我們正式執行,所以加上 -d 參數:
docker run -v /data/docker:/data/wwwlogs -dti -p 443:443 -p 80:80 ccr.ccs.tencentyun.com/myspace/nginx-proxy:latest
整個過程不到5分鐘,真的非常方便!
五、小結
本文記錄了一個實際的Dokcer應用場景從創建、上傳直到部署的詳細過程,Docker為我們提供了一個新的軟件發布方式,只要將應用以及相關的依賴打包成Docker鏡像,並上傳到鏡像倉庫之後,我們就可以快速拉起一個定制服務,毫無拖泥帶水,從而極大的簡化了部署。
本文還簡單的介紹了騰訊雲的容器服務,通過容器服務,我們可以上傳自定制Docker鏡像,可以在騰訊雲主機或其他國內網服務器上快速拉起應用服務,加快了業務部署節奏,並降低了運維成本。
嗯,當然最重要的還是我通過這個實踐,熟悉了Docker的基本知識和基礎使用方法,從而實現了我的Docker入門學習目標。
相關閱讀
騰訊海量數據倉庫運維系統 : 鸚鵡螺
Qemu-KVM 網絡性能優化實踐
註意你的數據庫, 可能是勒索病毒的下一個目標 !
此文已由作者授權騰訊雲技術社區發布,轉載請註明文章出處
原文鏈接:https://cloud.tencent.com/community/article/287910
Docker 入門實踐