docker少挖坑

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 <[email protected]>
    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

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章