Docker -- 架設與管理(未完成)

最近 Docker 很熱門啊!那 Docker 是什麼呢?感覺就是容器化(Container),這個像早期在虛擬化剛出來時有提到的一個 半虛擬化,或是 Hinet 提供的 PaaS 雲端服務一樣的方式。這個功能在 Oracle DB 12c 開始也有提供了。Container 與 全虛擬化 上有一個明顯的不同,Container 比較像的服務導向的做法與半擬化有點類似,系統資源、元件有共用性,而 全虛擬化 則是獨立資源,以效能來說 Container 會比 全擬化 好上很多,資源分配也會有彈性

CentOS 7 安裝 Docker

如果系統是 CentOS 7 直接使用 yum 安裝 docker,版本會與使用官方不同,建議使用官方方式安裝

0. 先移除其他版本

1. 取得官方 repository
 1. 先確認是否已安裝 yum-utils、device-mapper-persistent-data、lvm2 這三個套件
 2. 取得 repo 檔
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
 3. 啟用 docker-ce.repo 中 docker-ce-edge 連結
yum-config-manager --enable docker-ce-edge
註:[docker-ce-edge] 中 enabled=1
註:目前安裝完 repo 後,是會自動開啟 Docker CE Stable 這個資訊的

2. 安裝 Docker
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin

docker 官方文件 -- 安裝 Docker
https://docs.docker.com/install/linux/docker-ce/centos/

註1:安裝 docker 前,一定要到去看一下官方說明,因為早期 docker 有太多版本如 docker, docker.io , or docker-engine,目前只有兩個主要版本 docker-ce 及 docker-ee
註2:安裝完 dokcer 後,記得 enable 服務,預設為 disable

docker 官方文件 -- 安裝 Docker for ubnutn
https://docs.docker.com/engine/install/ubuntu/

-------------------------------------------------------------------------------------------------------------------------

CentOS 7 安裝 Docker

安裝相當容易,就是 yum install docker

啟動服務
安裝後,會看到以下服務,預設都是關閉的
docker-cleanup.service
docker-storage-setup.service
docker.service
docker-cleanup.timer

在執行 docker version 指令時,系統會提示連不到 docker daemon,只要開啟備 docker.server 後,就會正常,這個是啟動 docker server 的動作,如果沒啟動,docker 會提示,是不是服務在其他地方

使用這段來測試 docker 是否正常安裝、運作
docker run hello-world
註:這個動作會產生一個 Container 及一個 images(hello-world)

測試後,docker 會再請使用者執行以下指令,這個指令會啟動 ubuntu 這個 Container,如果不存在,則自動下載安裝並進入 ubuntu
docker run -it ubuntu bash
註:這個動作會產生一個 Container 及一個 images(ubuntu)

打入 exit 退出 Container


常用指令

docker info

docker version

docker images -a <== 列出所有已下載的 Images

docker ps <== 列出執行中的 Container
docker ps -a <== 列出所有的 Container

docker run hello-world <== 測試 Docker 是否正常安裝與運作

docker run -i -t [Image ID 或 Image name:version] /bin/bash <== 依 Image 產生一個 Container,執行bash,並進入 Container
註:
docker run [選項] [Image] [指令][參數]
例1:docker run -d ubuntu:latest /bin/sh -c "while true; do echo hello world; sleep 1; done"
例2:docker run -i -t nginx:latest /bin/bash
例3:docker run -idt centos:latest <== 容器會持續活著直到下 stop
例4:docker run nginx:latest --name [自定名稱]
例5:docker container --publish 10021:21 run vsftp
有使用 -i(interactive;互動)、-t(pseudo-tty;虛擬終端)並執行 /bin/bash,所產生的 Container 才能進入 Container 中互動

docker rm [Container ID] <== 刪除指定的 Container

docker rmi [Image ID] <== 刪除指定的 Image

docker search [Image name] <== 搜尋指定的 Image
例1:docker search centos
例2:docker search centos -s 30 <== 列出 Image Name 中有 centos 字串且為30個星等以上的 Image
註1:如果直接打名稱,預設會下載官方版本,如果要下載其他版本,Image Name 的部分就打 Search 出現的 Name 就會下載了
註2:-s(--starts,已經停用,官方建議使用 --filter=stars=30,-f=stars=30)

docker save [選項] IMAGE [IMAGE...] <== 匯出指定的 Image 檔
例:docker save -o nginx.tar nginx:latest

docker load [選項] <== 匯入指定的 Image 檔
例:docker load --input nginx.tar

docker start [Container ID] <== 啟動指定的 Container

docker stop [Container ID] <== 停止指定的 Container

docker attach [選項] CONTAINER
docker attach [Container ID] <== 進入指定 Container 查看執行的情形
註1:使用 attach 方式,在 run 時必需有 -i -t,並加上 /bin/bash 才行
註2:從 attach 狀態跳出,該 Container 就會停止
註3:如果要 Container 正常於背景運作,要按 Ctrl + P ==> Ctrl + Q

docker exec [選項] CONTAINER [指令][參數]
例1:docker exec -ti awesome_liskov bash
例2:docker exec -ti --user root awesome_liskov bash <== 使用 root 登入
註1:exec 可以使用參數開啟 interactive、pseudo-tty
註2:從 exec 狀態跳出,該 Container 不會停止

docker stats [Container ID] <== 查看指定 Container 的狀態(不設 Container ID 則全部列出)

docker inspect [Container(Image) ID 或 Container(Image) Name] <== 查看指定 Container(Image) 的詳細內容

docker logs [Container ID 或 Container name]  <== 查看指定 Container log 資訊。內容為所有執行、顯示的資料

docker export [選項] [Container ID] <== 匯出 CONTAINER
例:docker export a5e76bcbafbf > nginx.tar

docker import [選項] file|URL| - [REPOSITORY[:TAG]]
例:cat nginx.tar | docker import - nginx:v1.0
註:匯入後是一個 Image,不是 Container

docker pull [Image] <== 下載指定的 Image 最新版本

列出 Container 資訊
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
例:docker inspect -s 99a7c9f81ab6
這個資訊中告訴了我們所有層級檔案所存放的位置,並且說明了部分設定檔預設掛於 host 主機的位置

docker volume create --name [volume 名稱] <== 建立 host 資料匣
docker volume ls <= 列出目前有的資料匣
docker volume inspect [volume 名稱] <= 列出目前有的資料匣詳細資訊
docker volume rm [volume 名稱] <= 刪除指定資料匣
註1:volume 的用途是要在 host 上建一個特定的資料匣,讓 container 可以使用這個資料匣,在更換內容時,可以不用進入 container 中進行更換,最常用於如網頁的檔案路徑、設定檔等…
註2:資料匣建立位置預設為 /var/lib/docker/volumes/_data 中
註3:如果不知道,也可以透過列出詳細資訊看到路徑位置

參考資料:
Tsung 大文章 -- Docker 初學筆記 - 基本指令操作教學
https://blog.longwin.com.tw/2017/01/docker-learn-initial-command-cheat-sheet-2017/

flynncanfly 文章 -- Day-7 解析 Docker Volume
https://ithelp.ithome.com.tw/articles/10241922 

J.J.大文章 -- Docker - 第十三章 | 安裝Apache Server
https://morosedog.gitlab.io/docker-20190601-docker13/

Docker 初探 -- 基本指令與簡單介紹 Dockerfile 和 docker-compose
https://askie.today/docker-dockerfile-dockercompose-intro/


Image 與 Container 的關係

Image 與 Container 的關係以 Cisco switch 來說,Image 就是 start-config,而 Container 就是 running-config
Image 與 Container 的關係以 虛擬系統來說,Image 就是 OVA 檔,而 Container 就是 vdi(硬碟檔)+ vbox(設定檔)

Container 是由 Image 產生的

倉庫(Repository)存放 映像檔(Image)
映像檔(Image)產生 容器(Container)
容器(Container)一變動,要寫回 映像檔(Image),或生成 新映像檔(Image),否則下次使用"原"映像檔(Image)產生的容器(Container),將會還原為預設值

容器(Container)本身是一個檔案,他不會因為系統關閉後,就消失,除非是手動刪除了容器

參考資料:CSDN 討論串
http://bbs.csdn.net/topics/390847409 


Image 與 Container 的存放與資料匣

/var/lib/docker/

當建立過一次 Container 後,其設定檔會被放在 /var/lib/docker/containers/[container ID]/config.v2.json

記錄了映像檔名稱以及對應的Id的json檔
/var/lib/docker/image/devicemapper/repositories.json
cat repositories.json  | python -mjson.tool

參考資料:
chinaxuzw 大的文章 -- docker image是什麼,存儲在什麼位置,
http://www.aboutyun.com/thread-16811-1-1.html   


私有倉庫(Repository)建置

舊版的 Docker 使用的為 docker-registry ,新版 Docker 預設使用套件為 docker-distribution

 


docker-compose 安裝與注意事項

如果系統是 CentOS 7 直接使用 yum 安裝 docker-compose ,會無法使用 V3 版的 yml 檔,必需使用官方方式安裝

官方安裝方式

1. 從 github 直接取的檔案
curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
這個方式安裝,就只會在 /usr/local/bin/ 中產生 docker-compose 這個檔案
註:也可以直接到網址(https://github.com/docker/compose/releases)中下載檔案自行修改放入

2. 修改檔案為可執行
chmod +x /usr/local/bin/docker-compose

3. 確認版本
docker-compose --version

註1:這個做法可以確保版本是最新的,不過會有一個問題,在安裝後,記得重新登入系統讓 path 生效
註2:CentOS 防火牆預設是開啟的,記得先關閉
註3:這個方式,就不會被 RPM 管理了,必需自己記得了
註4:建議到官網看,因為版本可能會不同

4. 更新版本
修改版本後再下一次 1 的指令,將檔案覆蓋即可

參考資料:docker 官網
https://docs.docker.com/compose/install/#install-compose 

補充:docker-compose 的 指令與 docker 很類似,所以,docker-compose 有點像 docker 的 shell 


docker-compose 常用指令

docker-compose -v <== 查詢版本

docker-compose up <== 依照該 yml 內容建置並啟動容器

docker-compose up -d <== 依照該 yml 內容建置並啟動容器(於背景執行)

docker-compose down <== 停止並移除容器、網路及掛載路徑

註1:docker-compose 指令是使用在有 docker-compose.yml 檔案的路徑下
註2:docker-compose 指令只會看到 docker-compose.yml 的設定,並不會完整看到 docker 之下的資訊
註3:所為的 docker file 就是指 docker-compose.yml 這個檔案


強制刪除 images 

當使用 docker images 查看時,出現 image ID 出現重覆,這時使用 docker rmi [IMAGE ID] 發生無法刪除的錯誤訊息
Error response from daemon: conflict: unable to delete ff426288ea90 (must be forced) - image is referenced in multiple repositories
這時就必需使用 docker rmi -f [IMAGE ID] 強制將兩個 images 刪除

參考資料:willseward 回應
https://github.com/meltwater/docker-cleanup/issues/19


與容器互相複製、傳輸文件

17.05.0-ce 版本 需要使用 docker cp 指令

xiaorui 大所說的方式 3 在不同的版本中會有不同的結果,18.01.0-ce 版本可行,17.05.0-ce 版本則找不到路徑呢!

towns 一直沒辦法使用 docker inspect -f [NAME|ID] 來查找,最後是使用 docker inspect -s [NAME|ID] ,其中列出的 "DeviceName" 最後一段數字,就是容器掛載目錄的完整名稱

/var/lib/docker/devicemapper/mnt/

docker inspect -s [NAME|ID] 可以看到相當多資訊,其中可以看到很多共用檔案位置,這個可以協助設定 host 與 guest 間通用資料的資訊

參考資料:xiaorui 大的文章
http://xiaorui.cc/2015/04/12/docker%E5%AE%B9%E5%99%A8%E5%92%8C%E4%B8%BB%E6%9C%BA%E5%A6%82%E4%BD%95%E4%BA%92%E7%9B%B8%E6%8B%B7%E8%B4%9D%E4%BC%A0%E8%BE%93%E6%96%87%E4%BB%B6/   


docker 跟隨開機啟動

docker 中的 containers 預設是不會跟隨啟動的,如果要指定 container 在開機時跟啟動,必需下以下指令,之後重新啟動系統時,就會跟隨啟動了

舊版:docker update --restart=always [CONTAINER ID|NAMES]
新版:docker container update --restart=always [CONTAINER ID|NAMES]

如何確認已經加入設定
1. 設定檔路徑為:/var/lib/docker/containers/容器ID
2. 在該目錄下找到一個檔 hostconfig.json
3. 修改後配置:"RestartPolicy":{"Name":"always","MaximumRetryCount":0}
註:容器 ID 可以透過 docker ps 看 CONTAINER ID 確認

參考資料:
開始認識大的文章
https://www.cnblogs.com/kaishirenshi/p/10396446.html


在 container 中使用 root 帳號

docker exec -u 0 -it [CONTAINER ID|NAMES] bash
進入 container 後,就是 root 了

參考資料:
github 討論
https://github.com/oracle/docker-images/issues/237 


Docker for windows

安裝 Docker for Windows 後會造成 Virtualbox 無法使用全虛擬化,目前退而求其次使用 Docker Toolbox

docker-machine ls <= 列出目前啟動的 docker 虛擬機

參考資料:
天空的圾垃場
https://skychang.github.io/2017/01/06/Docker-Docker_for_Windows_10_First/ 

官方說明 -- Install Docker Desktop on Windows
https://docs.docker.com/docker-for-windows/install/

官方說明 -- Get started with Docker for Windows
https://docs.docker.com/docker-for-windows/

官方說明 -- Install Docker Toolbox on Windows
https://docs.docker.com/toolbox/toolbox_install_windows/  


IP_forwarding 功能

當 docker host 中的 container 需要與 host 的 port 對應時,必需使用到 IP_forwarding 功能

參考資料:
philipzhen g的 docker 中文說明
https://philipzheng.gitbook.io/docker_practice/advanced_network/access_control 


docker 考題

 

參考資料:
網管人 --  鄭淳尹先生文章 -- 基礎知識打底必讀 Docker面試100題(一)
https://www.netadmin.com.tw/netadmin/zh-tw/technology/4F5E8F787FCE491D9F02B1B0A41C341A?page=1


docker 網路管理

docker 的網路,是一個獨立的系統,可以透過指令去建立一個一個獨立的網段,而每一個網段可以放入多個 container,管理者需好好了解進而有效管理 docker 網路管理

相關指令
Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.

------------------------------------------------------------------------

列出 docker 網路資訊
1. 列出各網段資訊
docker network ls

註:這裡所列出的是在這台 host 中所有由 docker 建立的網段,而每個網段有一個自己專屬的 NETWORK ID,通常如果是特定功能的 container,從 name 上面可以看出來

2. 列出指定 container 網路資訊
docker network inspect [network ID 或 name]

註1:network ID 或 name,會出現在上一段指令
註2:指令會列出所有在這網段中所使用的 IP 及對應的 container

------------------------------------------------------------------------

docker 防火牆的設定

使用 docker 防火牆必需是開啟的,因為 docker 是使用 firewall 做 NAT,所以非開不可,不過,如果要限制連線呢?docker 的 container 中如果出現了弱點,而且,無法修補,這時就必需限制連入連了,docker 他有自己的 iptables 所以,必需寫在他自己的 iptables 上,在使用了 iptables-save -t filter 查看 chain,就可以看到有些 chain 是 docker 的,官方建議,如果要管理 firewall 要寫在 DOCKER-USER 這個 chain 中

範例:
限制存取
iptables -t filter -I DOCKER-USER 1 -p tcp -s 192.168.56.99 -d 172.30.0.11 --dport 8080 -j DROP
iptables -t filter -I DOCKER-USER 2 -p tcp -s 192.168.56.99 -d 172.30.0.11 --dport 8443 -j DROP

註:來源 ip 管理人會知道,可是去向 ip,則不一定知道。取得方式有兩種 1. 連入 container 下相關指令取得、2. 使用 docker 指令取得

參考資料:
白翼大的文章
https://holywhite.com/archives/489

官方說明
https://docs.docker.com/network/iptables/

ryan 教學


編輯 container 中的檔案

兩種方式
1. 將檔案取出後,再進行編輯
  $ docker cp CONTAINER:FILEPATH LOCALFILEPATH
  $ vi LOCALFILEPATH
  $ docker cp LOCALFILEPATH CONTAINER:FILEPATH

2. 將路徑放到外面,再進行編輯
  $ docker run --name="test" -v /volume-test debian echo "test"

參考資料:
zhigang、Adrian Mouat 大大回應
https://stackoverflow.com/questions/24553790/how-to-edit-docker-container-files-from-the-host


參考資料:
peihsinsu 大的文章 -- Docker學習筆記
https://peihsinsu.gitbooks.io/docker-note-book/content/

gitbook -- 這是這很多人共同提供的資訊哦!
https://philipzheng.gitbooks.io/docker_practice/content/

gitbook -- 簡中版的 docker 文件,比繁中版的新很多
https://yeasy.gitbooks.io/docker_practice/content/ 

留言

這個網誌中的熱門文章

zimbra 安裝、管理、設定

Fortigate 100D -- 管理、設定

IT 隨手記6