docker可以說給我們的部署帶來極大的方便和可逢凶化吉性!(懂的同學自然懂)
在初步了解之后,我們就能簡單使用docker了。
剛開始玩docker時,可以基於系統級別的鏡像做定制,比如基於 centos 鏡像使用docker;
docker pull centos:7 # 把鏡像拉下來 docker run -it centos:7 # 創建一個容器即可運行
你可以在拉下來的容器里安裝任何需要的應用(必要的);然后,一切都看起來很美好!
但是,這時,我們最擔心一個問題,那就是docker掛了怎么辦?機器重啟后怎么辦?
是的,這個擔心是有道理的,如果你沒有去查細細看過官方文檔,那么多半你是吃過這虧,才會清楚其中的坑!
所以,我們來提幾個問題? 簡單而不簡約!
1. 如何備份當前容器的修改?備份是可靠性的一個保證!
1. 使用commit 命令保存到本地
docker commit -m "msg" abcommitid myimage:1.0
其好處是操作方便,本機永久保存,方便下次快速操作。壞處,也不算,就是你如果想放到遠程,你必須注冊一個docker hub 賬號,然后保存過去。而且這樣的鏡像,一般只適合自己使用,不適合團隊傳播!(不過也不是絕對的)
2. 使用docker save 保存壓縮包到本地
docker save -o myimage_save.tar abcontainerid
這樣備份好之后,就可以將改該容器到處分發到其他機器或者做備份了。這樣做都好處是,傳播方便,不會導致隱私泄露。壞處是都是本地包,沒有存儲在雲端,必須到處攜帶該包。
導入時使用 docker load 即可!
docker load -i myimage_save.tar
然后就可以看到鏡像了,使用docker run 運行。操作步驟稍微繁瑣了點。注意: 只有 docker run 才能自定義各種參數哦。(docker run 聚合了 create 和 start 的功能)
在部署應用時可能存在需要將新應用部署好后,再刪除原容器的操作,所以容器重命名就很有必要的, 使用 docker rename
docker rename 原容器名 新容器名
3. 使用 docker export 保存到本地, 操作如同 docker save, 但是功能受限,個人不是很喜歡使用
docker export -o mycontainer_save.tar tmp_container
2. 如何設置應用開機啟動?只要啟動容器就夠了!
應用場景可以說是剛需: 我把第一個鏡像安裝好后,希望下次創建容器之后就能自動運行,而不是還要操作N多繁雜步驟,從而降低移植性帶來的方便性!
1. 能想得最簡單的是,使用系統的開機啟動功能
比如在 /etc/rc.d/rc.local 中添加相應的啟動,但是這里有個前提,那就是你必須先把容器啟起來; (啟不啟得來另說)
2. 使用docker的開機自動運行功能,使用簡單;
這里說的簡單是指使用,而在操作的時候則看個人了。在docker創建時,使用啟動腳本,自動運行。主要的命令有: CMD, RUN, ADD . 創建一個start.sh,可以定復雜的啟動邏輯;但是這在后期中,就很難更改其邏輯了哦!
CMD ["sh", "-c", "service httpd start;bash"] # 開機啟動 apache 服務
3. 如何自定義端口映射?容器需要與外部通信!
Docker 自帶了端口映射功能,使用docker run -p 進行操作!
docker run -d -p 81:80 --name container_name myimage:1.0
多個端口映射使用多個-p即可;
4. 如何自定義hostname?訂制你的機器名而不是隨機數!
自定義host也很有用,比如我想看我當前氣息環境,hostname就很有用,還有hostname的固定可以不致讓自己迷失; 只需要使用-h參數就可以了。
docker run -d -h myapi1 myimage:1.0
5. 如何插入host的解析?容器內訂制自己的 hosts !
這種應用場景是,比如你其他應用的服務,為了防止ip經常變更導致的麻煩性,這種服務一般是以內網域名形式出現,所以需要加入域名解析。
方法一是,你給每個容器定義一個通用的域名解析器dns;
方法二是,為各自的hosts里加入解析。而這在docker中,則操作是不會被保存的,每個新容器老是新 hosts. 可以通過 --add-host 添加自定義hosts解析:
docker run --add-host a.com:1.2.3.4 myimage:1.0
這種方式僅用於學習,其中更有用的是加入一個dns; 其操作步驟就是安裝個bind 軟件,然后配制 named.conf 即可。使用時,vim /etc/resolv.conf
nameserver 100.1.1.1
6. 如何自定義自己都的變量以滿足容器內動態修改的需求?特殊場景定制化!
其實如上的配置基本能滿足大部分情況下的生產需求了。但是難免還是個性的,比如我想定義nginx訪問某個的另外端口,這時使用dns 就不好搞了。在不改變外部環境的情況下,我們只能自定義修改了。最直接的方式是在 nginx 中直接改掉即可。但是這樣做還有個,如果我想讓同一個容器靈活地指向任意端口怎么辦?那就只能自定義變量操作了,在創建容器的時候指定該端口即可。
這樣的自定義變量可以用於設置 nginx 的自定義端口, java 堆大小,日志目錄設置等等.
具體做法步驟如下:
# 1. docker run -it myimage:1.0, 修改 nginx 配置文件,使其可以方便被替換,如下 # vim /usr/local/nginx/conf/conf.d/www.conf server { listen 80; server_name localhost; access_log /var/log/nginx/host.access.log main; location / { root /www/webapp/html/app1; try_files $uri $uri/ /index.html; index index.html index.htm; } location /api { # 設置點位符使外部可替換 set $API_HOST 192.168.1.1; set $API_PORT 8083; proxy_pass http://$API_HOST:$API_PORT; index index.html index.htm; } } # 2. 自己嘗試啟動無誤后,將新變更提交到原鏡像, docker commit docker commit -m 'conf update' abcommitid myimage:1.0 # 3. vim Dockerfile, 設置啟動腳本 FROM myimage:1.0 MAINTAINER xxx <abc@abc.com> ENV NGINX_CONFD_PATH /usr/local/nginx/conf/conf.d ENV PATH /usr/local/nginx/sbin:$PATH ADD ./start.sh /usr/local/bin/start.sh RUN chmod +x /usr/local/bin/start.sh EXPOSE 80 # 設置啟動腳本,腳本來源本機,可隨時修改 CMD [ "/usr/local/bin/start.sh" ] # 4. 縮寫啟動腳本,使在啟動時執行動態配置變更 awk # vim start.sh #!/bin/bash # override port variable if set if [ ! -z "$API_PORT" ]; then echo "------- api port replacing to $API_PORT -----------"; awk -v PORT="set \$API_PORT $API_PORT;" '{ sub(/set.*\$API_PORT.*/, PORT); print; }' ${NGINX_CONFD_PATH}/default.conf \ > ${NGINX_CONFD_PATH}/default.conf.new && mv ${NGINX_CONFD_PATH}/default.conf.new ${NGINX_CONFD_PATH}/default.conf fi if [ ! -z "$API_HOST" ]; then echo "------- api host replacing to $API_HOST -----------"; awk -v HOST="set \$API_HOST $API_HOST;" '{ sub(/set.*\$API_HOST.*/, HOST); print; }' ${NGINX_CONFD_PATH}/default.conf \ > ${NGINX_CONFD_PATH}/default.conf.new && mv ${NGINX_CONFD_PATH}/default.conf.new ${NGINX_CONFD_PATH}/default.conf fi # start nginx /bin/sh -c 'nginx -g "daemon off;" ' # 5. 都操作好后,重新構建一個新的鏡像,使用就可以了 docker build -t myimage:1.1 . # 6. 使用時,用 --env 來指定自定義變量 docker run --env API_HOST=192.168.1.112 --env API_PORT=8090 -it myimage:1.1 # 此時,進入查看時,nginx已經運行在不同的api端口下了
注意: 本處使用的是比較原始的 docker 版本,如果使用到 docker-compose 等高級工具,可能就不需要這么麻煩了!
7. 如何將宿主機目錄與容器內目錄進行交換?可視化你的容器內容!
這樣的場景是比較多的:
比如為了統一管理安裝包,不讓所有安裝包散亂在各個容器的各個目錄;
比如為了讓容器的數據存儲使用一塊新買的磁盤;
比如我想復制同一份代碼到新容器使用,從而方便后續獨立修改;
比如你無法進入你的容器,卻想拿到其中的數據等等;
所以,我們需要使用到目錄映射功能,這是 docker 自帶的功能,方便實用: -v 參數設置即可:
docker run -d -v /opt/docker/webapps:/www/webapp myimage:1.0
經過上面這些問答,相信你已經能簡單應付docker常用運維場景了,盡情享受docker帶來的可移植性方便以及其隔離性吧。