顯示具有 docker 標籤的文章。 顯示所有文章
顯示具有 docker 標籤的文章。 顯示所有文章

start versus restart for docker containers

Docker start vs restart:快速掌握差異

Docker 是個方便的服務部署工具,可快速安裝執行伺服軟體,供瀏覽器等前台使用。當用戶從 docker 映像檔建立 (create) 及啟動 (start) 容器時,容器將分別處於 巳建立 (created)執行 (running) 狀態。然後,遇到執行意外出錯 或 管理者故意下停止指令 (docker stop) 時,容器將進入退出 (exited) 狀態。

處於退出狀態的容器,因行程退出,將喪失記憶體狀態,但仍保有原來的可寫層 (writable layer) ,即儲存體狀態。此時,兩種指令 docker start 與 docker restart 都能讓既有容器,從現有可寫層狀態,再跑起來,效果完全一樣。以下用表格整理說明兩指令適用時機之差異。

1. 指令行為比較

指令 行為說明 適用狀態
docker start 啟動 巳建立 (created)退出 (exited) 的既有容器,直接執行其進入點命令 (entrypoint command) created / exited
docker restart 同上,但遇到執行狀態的容器會先讓其 stop,再 start created / running / exited

2. 執行期影響比較

項目 start restart
送 SIGTERM / SIGKILL
PID 改變
記憶體狀態重置
中斷連線
停機時間短暫

3. docker restart 的清理範圍

區域 是否清理
In-memory data
Processes / threads
Open sockets
TCP connections
Writable filesystem
Volumes
Env / config
Image

4. 結論:適用性與效果

docker startdocker restart 兩個指令目的都在不放棄既有容器的可寫層之下,以新記憶體,執行容器的服務。在容器處於 退出 狀態時,兩者效果完全相同,都會重新啟動容器主行程,重新分配記憶體,並執行 entrypoint command。 其適用時機摘要如下表。

適用情境 效果
容器正常退出,要再跑一次docker start
就現有可寫層,啟動既有容器
程式卡住、連線異常docker restart
保留可寫層,重新啟動既有容器
組態設定或資料壞掉docker run
放棄可寫層,重新建立啟動新容器

Use a jupyter and docker environment for learning tensorflow

想要學習Google的開源機器學習套件tensorflow,可以研讀網路上很多Python語言寫的程式範例。
但是,要讓自己的機器能跑得動這些Python寫的tensorflow範例,首先須跨越2個門檻:

1.安裝Python: 
    Python語法分Python2及Python3,IDE介面分jupyter及spyder等,套件管理分anaconda,pip等,
    在選擇眾多之下判斷及安裝皆費時。

2.安裝tensorflow: 
    除了依硬體分成CPU,GPU兩版,軟體也依Windows, Ubuntu, MacOS三種不同作業系統,而分成
    virtualenv、pip、anaconda、docker、原始碼等多種安裝法,各有不同安裝步驟及參數要設定。
    尤其安裝過程到底是使用 Python2 或 Pyhton3 也很容易因此而發生相容性問題。

以下介紹一個利用docker容器原理,快速建立執行tensoflow環境的作法:

1.安裝 docker 容器管理軟體:
    https://www.docker.com/community-edition#/download
       分成 Windows, Linux, Mac等免費版本,下載安裝合適公用版(community edition)
    其中,Windows 10可直接安裝 Docker CE for Windows,內含Windows及Linux兩種核心引擎
    若 Windows 非第10版,建議在Linux虛擬機環境下使用Docker,依序安裝如下軟體:
         VirtualBox Binaries Windows hosts + Ubuntu Desktop + Docker CE for Ubuntu

2.下載 jupyter/tensorflow-notebook 容器映像檔:
    https://hub.docker.com/r/jupyter/tensorflow-notebook/
    利用如下 docker 指令下載容器映像檔,內含Scipy Notebook + Tensorflow and Keras for Python 3.x (without GPU support)
    # docker pull jupyter/tensorflow-notebook
    註: 本映像檔可由如下github提供的 Dockerfile 從Ubuntu製成
         https://github.com/jupyter/docker-stacks/tree/master/tensorflow-notebook 
         https://github.com/jupyter/docker-stacks/tree/master/scipy-notebook
         https://github.com/jupyter/docker-stacks/tree/master/minimal-notebook
         https://github.com/jupyter/docker-stacks/tree/master/base-notebook
         Ubuntu 16.04 (xenial)

3.下載 nfmcclure/tensorflow_cookbook 程式範例:
    https://github.com/nfmcclure/tensorflow_cookbook
    利用如下 git 指令下載範例
    > git clone https://github.com/nfmcclure/tensorflow_cookbook.git
    或
    點選[Download ZIP]下載範例壓縮檔解開

    註: TensorFlow Machine Learning Cookbook範例採用 Pyhton3 撰寫

4.啟動執行範例:
    假設程式範例位於/home/user/docker/tensorflow_cookbook,網頁連線埠為8080,
    則可利用如下指令啟動容器:
    # docker run -it --rm \
        -p 8080:8888 \
        -v /home/user/docker/tensorflow_cookbook:/work \
        --name tflow jupyter/tensorflow-notebook \
        start-notebook.sh --NotebookApp.token='demo' --NotebookApp.notebook_dir='/work'

    然後開啟瀏覽器,利用網址 http://localhost:8080,密碼 demo,連到容器,執行tensorflow範例。

    註: docker run imagePath 指令可將映像檔imagePath放入容器執行,猶如虛擬機開機一般,其參數說明如下:
        -it 保留終端機供互動用,按Ctrl-C可結束容器
        --rm 容器結束時,容器也自動刪除
        -p 8080:8888 將容器內部的8888埠對應到主機的8080埠,供外部使用
        -v outerPath:innerPath 將主機的outerPath目錄掛載到容器內部的innerPath目錄,方便內外硬碟資料共享
        --name tflow 為容器命名為tflow,方便之後取用
        jupyter/tensorflow-notebook 為映像檔在docker hub的標準名稱
        start-notebook.sh  為容器啟用後執行的批次檔,主要啟動jupyter notebook,允許預設8888埠網頁連線
        --NotebookApp.token='demo' 設定網頁連線密碼 demo,以防外人取用
        --NotebookApp.notebook_dir='/work' 設定notebook初始開檔目錄,設為/work可以對應到掛載進來的外部範例目錄,方便取用

   註: 利用docker容器啟動包含jupyter notebook及tensorflow環境的容器,執行tensorflow範例程式的長相如下:

steps for setting up an osm-style map server from OsmHackTW

在 GitHub 開源平台上,OsmHackTW 提供許多台灣相關的地圖資源。
其中,openstreetmap-tiles-docker 專案利用docker容器建立本地端開放街圖標準樣式的台灣地圖服務。
以下介紹如何快速建立此服務映像檔及啟動服務的方法:

1.下載映像檔製作環境
  利用瀏覽器連線到網址 https://github.com/sekewei/openstreetmap-tiles-docker
    點選 【Clone or Download / Download ZIP】,將下載的壓縮環境檔解開

  若有安裝 git 開發環境,也可使用下列 git 指令下載製作環境
    git clone https://github.com/sekewei/openstreetmap-tiles-docker.git

2.製作地圖服務映像檔
  進入製作環境的資料夾,利用如下 docker 指令製作地圖服務映像檔
    cd openstreetmap-tiles-docker
    docker build -f ./Dockerfile -t twstd:latest .

3.初始化地圖資料庫
3.1.啟動容器,執行資料庫初始化腳本
    docker run -it -v /docker/osm-postgresql:/var/lib/postgresql --name twstd twstd:latest /bin/bash
    cd /usr/local/sbin/
    ./run initdb
    ./run startdb
    ./run createuser
    ./run createdb

3.2.下載台灣地圖資料,匯入資料庫
    wget -O /data/import.pbf http://download.geofabrik.de/asia/taiwan-latest.osm.pbf
    ./run import

3.3.含圖資存成新版映像檔
    暫時跳離容器終端機可使用 Ctrl-p + Ctrl-q
    docker commit -m full_loaded twstd twstd:latest

4.啟動地圖服務容器
  利用如下指令啟動地圖服務容器
   docker run -it -p 80:80 -v /docker/osm-postgresql:/var/lib/postgresql --name twstd twstd:latest
   cd /usr/local/sbin/
   ./run startservices

5.測試地圖服務
  利用瀏覽器連線到本地主機80號埠測試地圖服務,點選'本地街圖'選項
    http://localhost

6.更新圖資
  利用如下指令來更新台灣區地圖資料
   docker attach twstd
   cd /usr/local/sbin/
   ./run startdb       # 若執行updatemap出現資料庫連線錯誤,須先啟動資料庫
   ./run updatemap
   Ctrl-p + Ctrl-q

註: 
1. 此服務的設計,利用-v參數將容器內地圖資料庫目錄 /var/lib/postgresql 
   連結到主機目錄/docker/osm-postgresql,方便主機獨立維護圖資。

2. 如下兩個台灣地圖服務專案的差異為地圖樣式不同:
     開放街圖標準樣式: https://github.com/sekewei/openstreetmap-tiles-docker
     開放街圖明亮樣式: https://github.com/sekewei/docker-opentileserver

how to build an osm map server for taiwan on docker

最近集眾人智慧的開放街圖(OpenStreetMap)很熱門,以下介紹一個簡便架設台灣區 OSM 地圖伺服器的方法。
前提是需先安裝 docker 容器環境,例如: Windows 10 上安裝 docker for windows 容器軟體。
有了 docker 容器環境之後,取圖資及架網站的步驟如下:

0.主機打開命令列工具,例如: Windows 10 的 powershell 命令列工具。


以下分成手動及自動安裝兩種說明,手動說明方便理解安裝步驟,自動說明方便快速安裝。

A.【手動安裝法】以下利用原始映像檔,手動建立新映像檔taiwan-osmbright:v1

1.主機下載 dmakan/ubuntu-opentileserver:v1 原始映像檔,啟動容器命名 twbright
    > docker pull dmakan/ubuntu-opentileserver:v1
    > docker run -t -i -p 80:80 --name twbright dmakan/ubuntu-opentileserver:v1
    註: -t for terminal, -i for interactive 表示取得容器的終端機互動視窗,可用 Ctrl-p Ctrl-q 退回主機
    註: -p host_port:container:port for port mapping 先主機埠,後容器埠,可將容器埠對應到主機埠,對外提供服務

2.容器修改 opentileserver.sh 批次檔,讓資料庫接受 utf8 文字編碼
    # vi /opentileserver/opentileserver.sh

    原始 if [ $(psql -Upostgres -c "select datname from pg_database" | grep -m 1 -c ${OSM_DB}) -eq 0 ]; then
    之前新增一行 psql -Upostgres -c "DROP DATABASE IF EXISTS ${OSM_DB};"

    原始 psql -Upostgres -c "create database ${OSM_DB} owner=${OSM_USER};"
    修改 psql -Upostgres -c "CREATE DATABASE ${OSM_DB} TEMPLATE template0 ENCODING 'UTF8' OWNER ${OSM_USER};"

    原始 CREATE EXTENSION hstore;
    修改 CREATE EXTENSION IF NOT EXISTS hstore;

    原始 CREATE EXTENSION postgis;
    修改 CREATE EXTENSION IF NOT EXISTS postgis;

    註: 要先刪除原有資料庫,再重新建立一個接受 utf8 統一碼的資料庫
    註: OSM_USER 預設資料庫用戶名為 tile,OSM_DB 預設資料庫名稱為 gis

3.容器執行 opentileserver.sh 批次檔,下載套件及圖資
    # cd /opentileserver/
    # ./opentileserver.sh web bright http://download.geofabrik.de/asia/taiwan-latest.osm.pbf

    註: 紅色州名/國名可替換成任何想提供服務的國家,詳http://download.geofabrik.de/
    註: geofabrik每日更新一次圖資,只要再執行 opentileserver.sh 批次檔,就重新下載最新圖資,覆寫原有資料庫內容

4.容器修改 OSMBright.xml 樣式檔,讓形狀檔路徑正確
   利用串流修改指令sed進行字串取代
    # sed -ie 's/pulated_places/pulated_places_simple/g' /usr/local/share/maps/style/OSMBright/OSMBright.xml

   或者利用編輯器vi進行修改
    # vi /usr/local/share/maps/style/OSMBright/OSMBright.xml

    原始 <Parameter name="file">
          <![CDATA[/usr/local/share/maps/style/osm-bright-master/shp/
                      ne_10m_populated_places/ne_10m_populated_places.shp]]>
        </Parameter>
    修改 <Parameter name="file">
          <![CDATA[/usr/local/share/maps/style/osm-bright-master/shp/
                      ne_10m_populated_places_simple/ne_10m_populated_places_simple.shp]]>
        </Parameter>

5.容器開啟資料庫,網站,圖磚服務
    # service postgresql restart
    # service apache2 restart
    # service renderd restart

6.主機開啟瀏覽器驗證
    http://localhost/openlayers-example.html

7.主機儲存容器內容為新映像檔,供下回使用
    > docker commit twbright taiwan-osmbright:v1   # 新映像檔命名 taiwan-osmbright:v1
    > docker stop twbright     # 關閉容器
    > docker rm twbright    # 刪除容器


8.主機利用新映像檔,開啟容器,仍命名為 twbright,提供地圖服務
    > docker run -i -t -p 80:80 --name twbright taiwan-osmbright:v1
    http://localhost:80/openlayers-example.html



B.【自動安裝法】以下利用Github映像檔製作環境包快速製作新映像檔taiwan-osmbright:v1

1.下載映像檔製作環境包
  利用瀏覽器連線到網址 https://github.com/sekewei/docker-opentileserver
  點選下載映像檔製作環境包 taiwan-osmbright_v1_build.tar.gz

2.製作地圖服務映像檔
  利用如下指令製作地圖服務映像檔,其中,- 表示映像檔製作環境取自導向(<)進來的環境包檔案,
    -f ./Dockerfile 表示製作步驟檔位於映像檔製作環境之路徑
  > docker build -f ./Dockerfile -t taiwan-osmbright:v1 - < taiwan-osmbright_v1_build.tar.gz

3.啟動地圖服務容器
  利用如下指令啟動服務容器,命名twbright,介接到主機80號埠
  > docker run -it -p 80:80 --name twbright taiwan-osmbright:v1
  按Ctrl-p + Ctrl-q跳出容器終端機

4.測試地圖服務
  利用瀏覽器連線到本地主機80號埠測試地圖服務
  http://localhost:80/openlayers-example.html

  註: 如果要修改初始地圖顯示位置為(lon,lat),方法如下:
        # vi /var/www/html/openlayers-example.html
            var toProjection   = new OpenLayers.Projection("EPSG:900913"); // spherical mercator projection
            var fromProjection = new OpenLayers.Projection("EPSG:4326"); // WGS 1984
            var position       = new OpenLayers.LonLat(lon,lat).transform(fromProjection, toProjection);
            var zoom           = 15;
            map.setCenter(position, zoom);

5.更新地圖資料
  利用如下指令連入容器終端機,執行腳本下載圖資,匯入資料庫,重新啟動服務
  > docker attach twbright
  # cd /opentileserver
  # sh ./reload-opentileserver.sh
  按Ctrl-p + Ctrl-q跳出容器終端機



C.【除錯資訊】以下為自動或手動建立新映像檔,啟動容器後的除錯要點:
0.本機進入容器的終端機 > docker attach twbright 

1.圖磚前景啟動 # sudo -u tile renderd -f -c /usr/local/etc/renderd.conf
     可確認字型檔 unifont.ttf 及形狀檔 ne_10m_populated_places_simple.shp 是否載入正確

2.圖磚快取位置 # ls /var/lib/mod_tile/default/
     可確認目錄下是否有.png圖磚產生

3.字型位置必須有unifont統一碼字型
     # ls /usr/share/fonts/truetype/unifont/unifont.ttf

4.資料庫設定檔必須驗證方式為trust才不必輸入密碼,如下:
     /etc/postgresql/9.3/main/pg_hba.conf
     local all all trust

5.資料庫驗證
     # psql -d gis -Utile   # 以用戶 tile 身份連入資料庫 gis
     gis=# \d         # 列出資料表
               List of relations
   Schema |        Name        | Type  |  Owner
  --------+--------------------+-------+----------
   public | geography_columns  | view  | postgres
   public | geometry_columns   | view  | tile
   public | planet_osm_line    | table | tile
   public | planet_osm_nodes   | table | tile
   public | planet_osm_point   | table | tile
   public | planet_osm_polygon | table | tile
   public | planet_osm_rels    | table | tile
   public | planet_osm_roads   | table | tile
   public | planet_osm_ways    | table | tile
   public | raster_columns     | view  | postgres
   public | raster_overviews   | view  | postgres
   public | spatial_ref_sys    | table | tile
  (12 rows)
 
     gis=# \d planet_osm_point  # 列出欄位
  osm_id             | bigint                 |
  access             | text                   |
  addr:housename     | text                   |
  addr:housenumber   | text                   |
  addr:interpolation | text                   |
  admin_level        | text                   |
  aerialway          | text                   |
  aeroway            | text                   |
  amenity            | text                   |
  area               | text                   |
  barrier            | text                   |
  bicycle            | text                   |
  brand              | text                   |
  bridge             | text                   |
  boundary           | text                   |
  building           | text                   |
  .....
  water              | text                   |
  waterway           | text                   |
  wetland            | text                   |
  width              | text                   |
  wood               | text                   |
  z_order            | integer                |
  way                | geometry(Point,900913) |

     gis=# select osm_id, name from planet_osm_point limit 10;  # 取10個點看中文名正確否
     osm_id   |   name
  ------------+-----------
     63252122 |
   1647048653 | 青屿
   1645249987 | 五膽島
   1645249985 | 四膽島
   1645249984 | 三膽島
   1645249983 | 二膽島
   1645249988 | 大膽島
   1645251414 | 獅球
   1645249986 | 大南礁
   1645249989 | 兔嶼

     gis=# select count(*) from planet_osm_point;  # 計算總共資料庫有幾個點
  count
--------
 198300
(1 row)

     gis=# \q         # 離開

docker command line summary

docker command line summary

image: a read-only file system consisting of a base layer and a series of difference layers

container: a writable file system consisting of an image and a top writable layer with network and volume hooks

    Note:
  • an image has id, name, tag, read-only_layers, entrypoint, and cmd
  • a container has id, name, source_image, writable_layer, overwrite_cmd, cpu_limit, memory_limit, volume_hook, network_hook, and state (active/un-active)
what docker can do with images in a local image store
  -- creation --
  - import/export with docker hub
   search in a docker hub (docker search)
   pull from a docker hub (docker pull)
   push to a docker hub (docker push)
  - import/export with local filesystem
   load from a local file (docker load)
   save to a local file (docker save)
  - born from scratch
   commit an un-active container to create an image (docker commit)
   build an image with Dockerfile instructions (docker build)
 
  -- management --
  list (docker images)
  remove (docker rmi)

what docker can do with containers in a local container store
  -- creation -- 
   create an un-active container from an image (docker create)
   run from an image with an overwrite command (docker run)
   execute a command (docker exec)

  -- management
   stop an active container with a grace period (docker stop)
   kill an active container (docker kill)
   start an un-active container (docker start)
   restart an active container (docker restart = 
   		docker stop + docker start)
  -
   copy with local filesystem (docker cp)
  -
   attach the console to a container (docker attach)
  -
   commit an un-active container to create an image (docker commit)
  -
   list (docker ps [-a])
   remove (docker rm [-f])
    Note:
  • an image runs a new container with an overwrite command = an image creates a new container + the container starts with an overwrite command
  • a container is created when docker creates from an image or runs from an image with an overwrite command
  • an image is created when docker commits a container or builds from a base image and a Dockerfile
#
#
# image operation
#
#

#### search for an image
docker search image_keyword

#### download an image
docker pull [registry.hub.docker.com/]image_path[:tag] 

#### list images in local drive
docker images [image_path]

#### create new images
1.docker commit -m "submit message" -a "submit user" container_id image_path[:tag]

 $ vi ./Dockerfile
 # This is a comment
 FROM ubuntu:14.04
 MAINTAINER Docker Newbee <newbee docker.com="">
 RUN apt-get -qq update
 RUN apt-get -qqy install ruby ruby-dev
 RUN gem install sinatra
 # put my local web site in myApp folder to /var/www
 ADD myApp /var/www
 # expose httpd port
 EXPOSE 80
 # the command to run
 CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]

2.docker build -t="image_path:tag" .  

3.cat ubuntu-14.04-x86_64-minimal.tar.gz  | docker import - ubuntu:14.04

4.docker tag container_id image_path:new_tag

#### upload an image
docker push image_path # all tags

#### save and load an image as local file 
docker save -o ubuntu_14.04.tar ubuntu:14.04

docker load --input ubuntu_14.04.tar
docker load < ubuntu_14.04.tar

#### remove a local image
docker rmi image_path

#
#
# container operation
#
#

#### start and run a container with an image
docker run [-name container_name] ubuntu:14.04 /bin/echo 'Hello world'
docker run -t -i ubuntu:14.04 /bin/bash   ### start a container in interactive mode
docker start ubuntu:14.04

docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
docker ps [-a]     ### list containers, [all, inclusive of un-active containers]
docker logs insane_babbage

#### start and stop container
docker restart
docker stop
docker run -idt ubuntu
docker attach container_name

#### start a shell in a container, detach from it, and re-attach to it
docker exec -it container_name /bin/bash
# use Ctrl-p + Ctrl-q to detach from the container
docker attach container_name

#### import and export container 
docker export container_id > snapshot.tar
cat snapshot.tar | docker import - image_path[:tag]
docker import snapshot_url image_path

#### remove container
docker rm container_name
docker rm $(docker ps -aq)  ## remove all exited containers



References:
1.《Docker —— 從入門到實踐­》Run命令

2.How to use Docker without sudo on Ubuntu
  # grant docker permission to specific user 'foobar'
  > sudo setfacl -m user:foobar:rw /var/run/docker.sock
  > getfacl /var/run/docker.sock
  getfacl: 從絕對路徑名尾部去除"/"字符
  # file: var/run/docker.sock
  # owner: root
  # group: docker
  user::rw-
  user:foobar:rw-
  group::rw-
  mask::rw-
  other::---

3.Prepare docker.service.d/override.conf for the systemd drop-in service
  > sudo systemctl edit docker
  [Service]
  ExecStartPost=/bin/sh -c '/usr/bin/setfacl -m user:foobar:rw /var/run/docker.sock'
  > sudo systemctl daemon-reexec	# re-execute the systemd process
  > sudo systemctl daemon-reload	# reload the systemd manager configuration
  > sudo systemctl restart docker	# stop and start the docker service
    
4.Play With Docker provides an Alpine Linux 3.10 environment with docker and git ready for use
     CPU: Intel(R) Xeon(R) CPU E5-2673 v4 @ 2.30GHz with 8 cores
     Memory: 32GB
     Drive: 64GB with 16GB used
     Limit: Use of up to 5 nodes for up to 4 hours per session

Disable UDP to solve frequent RDP disconnection

解決 RDP 遠端桌面經常斷線問題:「關閉 UDP 傳輸」 在使用 Windows 內建的 遠端桌面(RDP, Remote Desktop Protocol) 連線時,你是否也常遇到連線突然卡死、畫面凍結,或是頻繁跳出「連線已中...

總網頁瀏覽量