SlideShare a Scribd company logo
1 of 29
Download to read offline
Docker In-Depth
David Hsu
Docker History
PaaS to Docker
TimeLine
2015 OCI 出現,Docker 捐出 libcontainer,改名 RunC
OCI 的出現是⼀一些⼤大廠想要避免 Container 技術如同 Android ⼀一樣碎片化
(表⾯面上是這樣講,實際上是要限制 Docker 獨⼤大)。
CNCF 出現
CNCF 背後可以理理解為 Google 要以 Kubernetes 打 Docker 的基⾦金金會,所以該基⾦金金會的專案很多
都會跟 Kubernetes 密切整合,或者是建置在 Kubernetes 之上。比如說 CNI、CoreDNS 與 gRPC 等。
CNCF 確保兩兩件事
k8s 必須能在容器編排取得競爭優勢。
CNCF 社群 將以 k8s 為 CNCF 的核⼼心專案,擴展⾄至更更多使⽤用場景。
Docker vs k8s == 獨裁 vs ⺠民主化
k8s 開放很多 plugin api 讓使⽤用者得以介入 k8s
2017 Docker 投降
k8s and CNCF全⾯面獲勝
runC
⽽而 Docker 在 2015 年年的⾼高速迭代與版本更更新更更令許多使⽤用者苦不堪⾔言,
因此,幾個容器界的⼤大佬就出來來成立中立的基⾦金金會,以切割與 docker 公司的權威。
這個項⽬目就是著名的 RunC,是由 docker 公司領頭將項⽬目 Libcontainer 提供給⼀一個中立的基
⾦金金會,然後⼤大家以 RunC 為基礎,建立⼀一套屬於容器和鏡像的標準和規範。
⽽而這個規範標準就是 Open Containers Initiative(OCI),
規範標準的提出使得容器鏡像與容器 runtime 得以與 Docker 項⽬目分離,
也造就了了現在可以不依賴 Docker 項⽬目也能做出容器平台的成果。
Docker != VM ?
docker is only a process. 依賴rootfs去
提供docker所需的⽬目錄結構,才會讓⼈人
以為他是VM的錯覺 但本質上container
依賴host上的kernel
Docker 为什什么资源的隔离和限制在云时代更更加重要?在默认情
况下,⼀一个操作系统⾥里里所有运⾏行行的进程共享CPU和内存
资源,如果程序设计不当,最极端的情况,某进程出现
死循环可能会耗尽CPU资源,或者由于内存泄漏消耗掉
⼤大部分系统资源,这在企业级产品场景下是不可接受
的,所以进程的资源隔离技术是非常必要的。
Linux OS 本⾝身就⽀支援虛擬化技術,稱為 Linux Container,
也就是常聽到的 LXC 技術。
LXC 有三個特⾊色技術
namespace, cGroup, unionFS
也就是構成現在 Docker 的重要底層技術
Namespace
Example:
Container 裡主要 process PID=1,
但回到 Host 上,會有另外的 PID。
————
Container 裡所使⽤用的是 root 權限,
但對於 Host 來來說,
只不過是⼀一個普通user。
如果CGroup设计出来的⽬目的是为了了隔
离上⾯面描述的物理理资源,那么
namespace则⽤用来隔离PID(进程
ID),IPC,Network等系统资源。
Linux Namespace
Namespace 也有不能隔離的資源: 時間
cGroup
cGroups 全名 control group,⽤用來來限定⼀一個 process 的物理理資源使⽤用,
並由 Linux kernel 原⽣生⽀支援,
可以限制與隔離 Linux process groups 所使⽤用的 “物理理” 資源。
Ex. CPU / MEM / Disk IO / Networking IO
Linux Namespace 帮助进程隔离出⾃自⼰己的单独空
间,⽽而 Cgroups 则可以限制每个空间的⼤大⼩小。
Cgroups 提供了了对⼀一组进程及将来⼦子进程的资源
限制、控制和统计的能⼒力力。
unionFS
Linux ⽂文件結構由
bootfs and rootfs 構成。
bootfs 主要負責引導 kernel 啟動系
統後就會 unmount.
⽽而 rootfs (root file system) 包含典
型⽬目錄結構
 /dev, /proc, /bin, /etc, /lib, /usr,
and /tmp
Union File System 就是將不同⽬目錄 mount 在⼀一個資料夾的⼀一個技術。
unionFS
Docker 將 rootfs 做為 read-only layer 放
在最底層 layer,
並在上⾯面掛載⼀一層 writable layer 提供
Container 內寫入。
所以結合在⼀一起的結果,會讓⼈人誤以為可
以直接寫入 rootfs.
但其實兩兩者是分開的,也就是爲什什麼重啟
Container 後,所做的更更變會遺失,是因
為 writable layer 遺失了了。
Review
namespace -> 提供與 Host 隔離的環境
cGroup -> 提供 container 內 CPU / MEM / IO 使⽤用限制,以免 overload 影響 Host
unionFS -> 提供資料夾的分離,讓 container 內也能有 rootfs
Docker FAQ
EXPOSE / docker run -p
Docker中有兩兩個概念念,EXPOSE and PUBLISH。
EXPOSE 是 Image / Container 聲明要暴暴露並可以提供其他容器使⽤用的 port。
但這個聲明,只要沒有設定 —icc=false,實際上沒有意義,因為並不強制。
也就是說沒有聲明 EXPOSE 的 port 其他容器也能訪問。
反之,使⽤用 —icc=false 的話,就只有 EXPOSE 的 port 可以被其他 Container 訪問。
PUBLISH 會直接映射 Host 的 Port ,將 Container 的 Port 對外公開,也就是說其他主機也可
以透過訪問 Host IP 來來訪問 Container。
docker-compose / docker run 裡⾯面的 ports / -p 實際上是指 PUBLISH
EXPOSE 的端⼝口可以不 PUBLISH,这样只有容器间可以访问,
宿主之外⽆无法访问。⽽而 PUBLISH 的端⼝口,可以不事
先 EXPOSE,换句句话说 PUBLISH 等于同时隐式定义了了该端⼝口
要 EXPOSE。

補充:docker run -p 可以指定範圍

ex. -p 1000-2000:1000-2000

開 terminal demo expose and publish
Container 互連?
不使⽤用 —link ?
因為使⽤用 link 的⽅方式下是通過修改 /etc/hosts 來來達成的,
所有網路路沒有適當隔離,安全度不佳。也容易易在頻繁重啟 container 的狀狀況下造成對檔案有
race condiction 的問題,以及 container 內 cache /etc/hosts 的問題。
所以⽬目前普遍使⽤用 docker network 為最好的⽅方式
修改 /etc/hosts ⽂文件有很多弊病。比如,⾼高频繁的容器启停环境时,容易易产⽣生竞争冒
险,导致 /etc/hosts⽂文件损坏,出现访问故障;或者有些应⽤用发现是来⾃自于 /etc/
hosts ⽂文件后,就假定其为静态⽂文件,⽽而缓存结果不再查询,从⽽而导致容器启停 IP 变更更
后,使⽤用旧的条⽬目⽽而⽆无法连接到正确的容器等等
docker-compose network
Docker 裡使⽤用 top / free 看到的
是主機還是容器的資源使⽤用?
A : 主機上
因為 top / free / df…etc 會去抓取 /etc 內的檔案來來顯⽰示資源使⽤用情況,
⽽而 container 內的 /etc 其實並不是真的獨立的 /etc
Volume / docker run -v
docker run -v 是掛載⽂文件 / 檔案 ,建議寫為絕對路路徑,雖然在 docker-compose 裡會⾃自動補
全相對路路徑為絕對路路徑,但使⽤用 docker run 指令時不會。
⽽而 docker volume 是數據卷
數據卷⼀一般設計是為了了裡⾯面內容還能夠被再次使⽤用,
不過使⽤用不當將會造成 Host 上存有⼤大量量 volumes ⽽而造成 full disk。
數據卷 ( Data Volumes )
分為 匿名卷 以及 命名卷。
在 Dockerfile 裡宣告 Volume /data
匿名卷: docker run -itd nginx:latest
=> /data 會被掛在為匿名卷,當 container 死亡後數據會消失
命名卷: docker run -v mydata:/data -itd nginx:latest
=> /data 被掛載為 mydata 命名卷,container 死亡後數據會被保留留在本地
(⼀一般來來說會是 /var/lib/docker/volumes)
所以 docker run -v / Volumes 到
底哪裡不⼀一樣?
掛載⽬目錄是由⽤用⼾戶⾃自⾏行行維護權限 ( Permission ) 像是 uid / gid / SELinux 等問
題,容易易遇到 container 內與 Host 上 Permission Denied 問題 。
⽽而 Docker Volumes 由 docker engine 維護以上問題,docker 會在建立 volume
時加入 rules 以調整權限問題。
在外⾯面Host修改了了容器內的檔案,
在容器內卻遺失了了? 使⽤用dw常⾒見見問題

可以demo ( ls -i 秀出file index number
)
因為當你使⽤用掛載⽬目錄⽅方式的時候 (docker run -v ) 如果只掛載單⼀一檔案,使⽤用 vim 或其他 IDE
時會出現問題。
容器內跑 cronjob
根據 Docker Best Practice , ⼀一個 container 只應該做⼀一件事,
⽽而 Cronjob 算是另⼀一個服務了了,應該另起 container 來來做 cronjob 才是正確做法。
Database 不適合放在 Docker 上
運⾏行行嗎?
使⽤用 Docker Volume 的狀狀態下,是可以的。
但如果沒有使⽤用 Docker Volume ,資料將會遺失,
所以建議先了了解 Docker Volume 再來來考慮是否在 Docker 上運⾏行行 Database
Docker 禁術
docker commit
docker save
docker load
docker export
docker import
docker commit / import / export 俗稱⿊黑箱 Docker 。
除了了本⼈人之外沒有⼈人知道裡⾯面發⽣生過什什麼,
可能創造者本⼈人過⼀一段時間也忘了了 (?)
並不是正常使⽤用 docker 會⽤用的⽅方式。
這樣的⽅方式實際上是將 container 保存為 tar 檔,然後再變成 Image。
除了了正常操作會有⼀一層⼀一層的 layer 會被壓縮為⼀一層以外,原有層裡⾯面的配置也可能遺失。
如果遺失的是 CMD 就會造成無法正常啟動。
所以不建議使⽤用 commit / import / export.
如何寫好 Dockerfile
Dockerfile 的每⼀一⾏行行指令都是⼀一層 layer , layer 越多當然 Image 也會越⼤大。
應該要盡量量減少 layer 的產⽣生。
把 Dockerfile 當 Shell Script 來來寫
Node.js official Dockerfile
利利⽤用 Docker 分層概念念,
使建構過程更更為順利利與快速
=> docker pull 的時候是分層下載的
已經存在的層,就不會再次 pull
如果只有改 code 沒有更更改 package.json
就不⽤用重跑 npm install,節省了了很多時間。
縮⼩小 docker image : multiple stage
ENTRYPOINT / CMD
docker run -it nginx:latest [ ENTRYPOINT ] [ CMD ]
ENTRYPOINT 不指定的話預設是 sh -c
Docker logs
docker logs 有很多種 logging driver
Ex. CloudwatchLogs 使⽤用的是 awslogs driver
所以你在 ECS 上使⽤用 cloudwatchlogs 的 container 使⽤用 docker logs
=> 是絕對看不到 log 的
Docker ⼀一跑就停⽌止
要觀察停⽌止的 Exit Code
通常為以下情況:
Exited (127) : 很有可能是 Out of Memory
Exited (0) : Docker 主進程退出了了 ( PID=1 的 Process 做完事情或失敗了了 )
其他情況請看 log
Windows Docker
Windows Docker 其實是在 windows 上跑 hyper-v 再運⾏行行 Linux kernel
( Docker for Windows )
Docker on Windows 是 windows 原⽣生⽀支援,但不能與 Linux 平台互通。

More Related Content

What's hot

Docker workshop
Docker workshopDocker workshop
Docker workshopWei Tung
 
容器式軟體開發介紹
容器式軟體開發介紹容器式軟體開發介紹
容器式軟體開發介紹Philip Zheng
 
K8s removes dockershime
K8s removes dockershimeK8s removes dockershime
K8s removes dockershimePhilip Zheng
 
從軟體開發角度
談 Docker 的應用
從軟體開發角度
談 Docker 的應用從軟體開發角度
談 Docker 的應用
從軟體開發角度
談 Docker 的應用謝 宗穎
 
Introduction to Golang final
Introduction to Golang final Introduction to Golang final
Introduction to Golang final Paul Chao
 
企業導入容器經驗分享與開源技能培養
企業導入容器經驗分享與開源技能培養企業導入容器經驗分享與開源技能培養
企業導入容器經驗分享與開源技能培養Philip Zheng
 
Rancher: 建立你的牧場艦隊
Rancher: 建立你的牧場艦隊Rancher: 建立你的牧場艦隊
Rancher: 建立你的牧場艦隊Miles Chou
 
Docker容器微服務 x WorkShop
Docker容器微服務 x WorkShopDocker容器微服務 x WorkShop
Docker容器微服務 x WorkShopPhilip Zheng
 
Docker初识
Docker初识Docker初识
Docker初识hubugui
 
AWS EC2 for beginner
AWS EC2 for beginnerAWS EC2 for beginner
AWS EC2 for beginnerazole Lai
 
前端工程師一定要知道的 Docker 虛擬化容器技巧
前端工程師一定要知道的 Docker 虛擬化容器技巧前端工程師一定要知道的 Docker 虛擬化容器技巧
前端工程師一定要知道的 Docker 虛擬化容器技巧Chu-Siang Lai
 
Hello world 的一生
Hello world 的一生Hello world 的一生
Hello world 的一生Wen Liao
 
Docker tutorial
Docker tutorialDocker tutorial
Docker tutorialazole Lai
 
Docker
DockerDocker
DockerNCUDSC
 
Software Engineer Talk
Software Engineer TalkSoftware Engineer Talk
Software Engineer TalkLarry Cai
 
Dev-Ops与Docker的最佳实践 QCon2016 北京站演讲
Dev-Ops与Docker的最佳实践 QCon2016 北京站演讲Dev-Ops与Docker的最佳实践 QCon2016 北京站演讲
Dev-Ops与Docker的最佳实践 QCon2016 北京站演讲ChinaNetCloud
 
Docker + CI pipeline 的高效率 ChatBot 開發方法
Docker + CI pipeline 的高效率 ChatBot 開發方法Docker + CI pipeline 的高效率 ChatBot 開發方法
Docker + CI pipeline 的高效率 ChatBot 開發方法Philip Zheng
 

What's hot (20)

Docker workshop
Docker workshopDocker workshop
Docker workshop
 
容器式軟體開發介紹
容器式軟體開發介紹容器式軟體開發介紹
容器式軟體開發介紹
 
K8s removes dockershime
K8s removes dockershimeK8s removes dockershime
K8s removes dockershime
 
Docker 101
Docker 101Docker 101
Docker 101
 
從軟體開發角度
談 Docker 的應用
從軟體開發角度
談 Docker 的應用從軟體開發角度
談 Docker 的應用
從軟體開發角度
談 Docker 的應用
 
Introduction to Golang final
Introduction to Golang final Introduction to Golang final
Introduction to Golang final
 
企業導入容器經驗分享與開源技能培養
企業導入容器經驗分享與開源技能培養企業導入容器經驗分享與開源技能培養
企業導入容器經驗分享與開源技能培養
 
Rancher: 建立你的牧場艦隊
Rancher: 建立你的牧場艦隊Rancher: 建立你的牧場艦隊
Rancher: 建立你的牧場艦隊
 
Docker容器微服務 x WorkShop
Docker容器微服務 x WorkShopDocker容器微服務 x WorkShop
Docker容器微服務 x WorkShop
 
Docker應用
Docker應用Docker應用
Docker應用
 
Docker初识
Docker初识Docker初识
Docker初识
 
AWS EC2 for beginner
AWS EC2 for beginnerAWS EC2 for beginner
AWS EC2 for beginner
 
前端工程師一定要知道的 Docker 虛擬化容器技巧
前端工程師一定要知道的 Docker 虛擬化容器技巧前端工程師一定要知道的 Docker 虛擬化容器技巧
前端工程師一定要知道的 Docker 虛擬化容器技巧
 
Hello world 的一生
Hello world 的一生Hello world 的一生
Hello world 的一生
 
Docker tutorial
Docker tutorialDocker tutorial
Docker tutorial
 
Docker
DockerDocker
Docker
 
Software Engineer Talk
Software Engineer TalkSoftware Engineer Talk
Software Engineer Talk
 
Dev-Ops与Docker的最佳实践 QCon2016 北京站演讲
Dev-Ops与Docker的最佳实践 QCon2016 北京站演讲Dev-Ops与Docker的最佳实践 QCon2016 北京站演讲
Dev-Ops与Docker的最佳实践 QCon2016 北京站演讲
 
Docker基礎
Docker基礎Docker基礎
Docker基礎
 
Docker + CI pipeline 的高效率 ChatBot 開發方法
Docker + CI pipeline 的高效率 ChatBot 開發方法Docker + CI pipeline 的高效率 ChatBot 開發方法
Docker + CI pipeline 的高效率 ChatBot 開發方法
 

Similar to Docker In-Depth

桃園市教育局Docker技術入門與實作
桃園市教育局Docker技術入門與實作桃園市教育局Docker技術入門與實作
桃園市教育局Docker技術入門與實作Philip Zheng
 
docker intro
docker introdocker intro
docker introkoji lin
 
Docker open stack
Docker open stackDocker open stack
Docker open stackGuangya Liu
 
快速上手 Windows Containers 容器技術 (Docker Taipei)
快速上手 Windows Containers 容器技術 (Docker Taipei)快速上手 Windows Containers 容器技術 (Docker Taipei)
快速上手 Windows Containers 容器技術 (Docker Taipei)Will Huang
 
開發人員不可不知的 Windows Container 容器技術預覽
開發人員不可不知的 Windows Container 容器技術預覽開發人員不可不知的 Windows Container 容器技術預覽
開發人員不可不知的 Windows Container 容器技術預覽Will Huang
 
Docker 最佳实践
Docker 最佳实践Docker 最佳实践
Docker 最佳实践YuLing Liu
 
使用 Docker 建置 END OF LIFE 的 Ruby 開發環境
使用 Docker 建置 END OF LIFE 的 Ruby 開發環境使用 Docker 建置 END OF LIFE 的 Ruby 開發環境
使用 Docker 建置 END OF LIFE 的 Ruby 開發環境俊明 吳
 
Hyper 基于hypervisor的docker引擎.pptx
Hyper 基于hypervisor的docker引擎.pptxHyper 基于hypervisor的docker引擎.pptx
Hyper 基于hypervisor的docker引擎.pptxXu Wang
 
Azure Container Service 使用 DC / OS 管理 docker 容器
Azure Container Service 使用 DC / OS 管理 docker 容器Azure Container Service 使用 DC / OS 管理 docker 容器
Azure Container Service 使用 DC / OS 管理 docker 容器Ch Rick
 
Docker一期培训
Docker一期培训Docker一期培训
Docker一期培训青帅 常
 
Docker 基礎介紹與實戰
Docker 基礎介紹與實戰Docker 基礎介紹與實戰
Docker 基礎介紹與實戰Bo-Yi Wu
 
Introduction to Docker
Introduction to DockerIntroduction to Docker
Introduction to DockerChris Chen
 
Cloud Foundry Introduction
Cloud Foundry IntroductionCloud Foundry Introduction
Cloud Foundry Introduction家弘 周
 
From docker hub to bluemix catalog
From docker hub to bluemix catalogFrom docker hub to bluemix catalog
From docker hub to bluemix catalogJoseph Chang
 
使用Lua提高开发效率
使用Lua提高开发效率使用Lua提高开发效率
使用Lua提高开发效率gowell
 
Docker進階探討
Docker進階探討Docker進階探討
Docker進階探討國昭 張
 
Docker - 30秒生出100台伺服器
Docker - 30秒生出100台伺服器Docker - 30秒生出100台伺服器
Docker - 30秒生出100台伺服器升煌 黃
 

Similar to Docker In-Depth (20)

桃園市教育局Docker技術入門與實作
桃園市教育局Docker技術入門與實作桃園市教育局Docker技術入門與實作
桃園市教育局Docker技術入門與實作
 
docker intro
docker introdocker intro
docker intro
 
Docker實務
Docker實務Docker實務
Docker實務
 
Docker open stack
Docker open stackDocker open stack
Docker open stack
 
快速上手 Windows Containers 容器技術 (Docker Taipei)
快速上手 Windows Containers 容器技術 (Docker Taipei)快速上手 Windows Containers 容器技術 (Docker Taipei)
快速上手 Windows Containers 容器技術 (Docker Taipei)
 
開發人員不可不知的 Windows Container 容器技術預覽
開發人員不可不知的 Windows Container 容器技術預覽開發人員不可不知的 Windows Container 容器技術預覽
開發人員不可不知的 Windows Container 容器技術預覽
 
Docker
DockerDocker
Docker
 
Docker 最佳实践
Docker 最佳实践Docker 最佳实践
Docker 最佳实践
 
使用 Docker 建置 END OF LIFE 的 Ruby 開發環境
使用 Docker 建置 END OF LIFE 的 Ruby 開發環境使用 Docker 建置 END OF LIFE 的 Ruby 開發環境
使用 Docker 建置 END OF LIFE 的 Ruby 開發環境
 
Hyper 基于hypervisor的docker引擎.pptx
Hyper 基于hypervisor的docker引擎.pptxHyper 基于hypervisor的docker引擎.pptx
Hyper 基于hypervisor的docker引擎.pptx
 
Azure Container Service 使用 DC / OS 管理 docker 容器
Azure Container Service 使用 DC / OS 管理 docker 容器Azure Container Service 使用 DC / OS 管理 docker 容器
Azure Container Service 使用 DC / OS 管理 docker 容器
 
Docker一期培训
Docker一期培训Docker一期培训
Docker一期培训
 
Docker 基礎介紹與實戰
Docker 基礎介紹與實戰Docker 基礎介紹與實戰
Docker 基礎介紹與實戰
 
Introduction to Docker
Introduction to DockerIntroduction to Docker
Introduction to Docker
 
Cloud Foundry Introduction
Cloud Foundry IntroductionCloud Foundry Introduction
Cloud Foundry Introduction
 
From docker hub to bluemix catalog
From docker hub to bluemix catalogFrom docker hub to bluemix catalog
From docker hub to bluemix catalog
 
使用Lua提高开发效率
使用Lua提高开发效率使用Lua提高开发效率
使用Lua提高开发效率
 
Docker進階探討
Docker進階探討Docker進階探討
Docker進階探討
 
Docker - 30秒生出100台伺服器
Docker - 30秒生出100台伺服器Docker - 30秒生出100台伺服器
Docker - 30秒生出100台伺服器
 
Docker基礎
Docker基礎Docker基礎
Docker基礎
 

Docker In-Depth

  • 3. TimeLine 2015 OCI 出現,Docker 捐出 libcontainer,改名 RunC OCI 的出現是⼀一些⼤大廠想要避免 Container 技術如同 Android ⼀一樣碎片化 (表⾯面上是這樣講,實際上是要限制 Docker 獨⼤大)。 CNCF 出現 CNCF 背後可以理理解為 Google 要以 Kubernetes 打 Docker 的基⾦金金會,所以該基⾦金金會的專案很多 都會跟 Kubernetes 密切整合,或者是建置在 Kubernetes 之上。比如說 CNI、CoreDNS 與 gRPC 等。 CNCF 確保兩兩件事 k8s 必須能在容器編排取得競爭優勢。 CNCF 社群 將以 k8s 為 CNCF 的核⼼心專案,擴展⾄至更更多使⽤用場景。 Docker vs k8s == 獨裁 vs ⺠民主化 k8s 開放很多 plugin api 讓使⽤用者得以介入 k8s 2017 Docker 投降 k8s and CNCF全⾯面獲勝
  • 4. runC ⽽而 Docker 在 2015 年年的⾼高速迭代與版本更更新更更令許多使⽤用者苦不堪⾔言, 因此,幾個容器界的⼤大佬就出來來成立中立的基⾦金金會,以切割與 docker 公司的權威。 這個項⽬目就是著名的 RunC,是由 docker 公司領頭將項⽬目 Libcontainer 提供給⼀一個中立的基 ⾦金金會,然後⼤大家以 RunC 為基礎,建立⼀一套屬於容器和鏡像的標準和規範。 ⽽而這個規範標準就是 Open Containers Initiative(OCI), 規範標準的提出使得容器鏡像與容器 runtime 得以與 Docker 項⽬目分離, 也造就了了現在可以不依賴 Docker 項⽬目也能做出容器平台的成果。
  • 5. Docker != VM ? docker is only a process. 依賴rootfs去 提供docker所需的⽬目錄結構,才會讓⼈人 以為他是VM的錯覺 但本質上container 依賴host上的kernel
  • 7. Namespace Example: Container 裡主要 process PID=1, 但回到 Host 上,會有另外的 PID。 ———— Container 裡所使⽤用的是 root 權限, 但對於 Host 來來說, 只不過是⼀一個普通user。 如果CGroup设计出来的⽬目的是为了了隔 离上⾯面描述的物理理资源,那么 namespace则⽤用来隔离PID(进程 ID),IPC,Network等系统资源。
  • 9. cGroup cGroups 全名 control group,⽤用來來限定⼀一個 process 的物理理資源使⽤用, 並由 Linux kernel 原⽣生⽀支援, 可以限制與隔離 Linux process groups 所使⽤用的 “物理理” 資源。 Ex. CPU / MEM / Disk IO / Networking IO Linux Namespace 帮助进程隔离出⾃自⼰己的单独空 间,⽽而 Cgroups 则可以限制每个空间的⼤大⼩小。 Cgroups 提供了了对⼀一组进程及将来⼦子进程的资源 限制、控制和统计的能⼒力力。
  • 10. unionFS Linux ⽂文件結構由 bootfs and rootfs 構成。 bootfs 主要負責引導 kernel 啟動系 統後就會 unmount. ⽽而 rootfs (root file system) 包含典 型⽬目錄結構  /dev, /proc, /bin, /etc, /lib, /usr, and /tmp Union File System 就是將不同⽬目錄 mount 在⼀一個資料夾的⼀一個技術。
  • 11. unionFS Docker 將 rootfs 做為 read-only layer 放 在最底層 layer, 並在上⾯面掛載⼀一層 writable layer 提供 Container 內寫入。 所以結合在⼀一起的結果,會讓⼈人誤以為可 以直接寫入 rootfs. 但其實兩兩者是分開的,也就是爲什什麼重啟 Container 後,所做的更更變會遺失,是因 為 writable layer 遺失了了。
  • 12. Review namespace -> 提供與 Host 隔離的環境 cGroup -> 提供 container 內 CPU / MEM / IO 使⽤用限制,以免 overload 影響 Host unionFS -> 提供資料夾的分離,讓 container 內也能有 rootfs
  • 14. EXPOSE / docker run -p Docker中有兩兩個概念念,EXPOSE and PUBLISH。 EXPOSE 是 Image / Container 聲明要暴暴露並可以提供其他容器使⽤用的 port。 但這個聲明,只要沒有設定 —icc=false,實際上沒有意義,因為並不強制。 也就是說沒有聲明 EXPOSE 的 port 其他容器也能訪問。 反之,使⽤用 —icc=false 的話,就只有 EXPOSE 的 port 可以被其他 Container 訪問。 PUBLISH 會直接映射 Host 的 Port ,將 Container 的 Port 對外公開,也就是說其他主機也可 以透過訪問 Host IP 來來訪問 Container。 docker-compose / docker run 裡⾯面的 ports / -p 實際上是指 PUBLISH EXPOSE 的端⼝口可以不 PUBLISH,这样只有容器间可以访问, 宿主之外⽆无法访问。⽽而 PUBLISH 的端⼝口,可以不事 先 EXPOSE,换句句话说 PUBLISH 等于同时隐式定义了了该端⼝口 要 EXPOSE。 補充:docker run -p 可以指定範圍 ex. -p 1000-2000:1000-2000 開 terminal demo expose and publish
  • 15. Container 互連? 不使⽤用 —link ? 因為使⽤用 link 的⽅方式下是通過修改 /etc/hosts 來來達成的, 所有網路路沒有適當隔離,安全度不佳。也容易易在頻繁重啟 container 的狀狀況下造成對檔案有 race condiction 的問題,以及 container 內 cache /etc/hosts 的問題。 所以⽬目前普遍使⽤用 docker network 為最好的⽅方式 修改 /etc/hosts ⽂文件有很多弊病。比如,⾼高频繁的容器启停环境时,容易易产⽣生竞争冒 险,导致 /etc/hosts⽂文件损坏,出现访问故障;或者有些应⽤用发现是来⾃自于 /etc/ hosts ⽂文件后,就假定其为静态⽂文件,⽽而缓存结果不再查询,从⽽而导致容器启停 IP 变更更 后,使⽤用旧的条⽬目⽽而⽆无法连接到正确的容器等等
  • 17. Docker 裡使⽤用 top / free 看到的 是主機還是容器的資源使⽤用? A : 主機上 因為 top / free / df…etc 會去抓取 /etc 內的檔案來來顯⽰示資源使⽤用情況, ⽽而 container 內的 /etc 其實並不是真的獨立的 /etc
  • 18. Volume / docker run -v docker run -v 是掛載⽂文件 / 檔案 ,建議寫為絕對路路徑,雖然在 docker-compose 裡會⾃自動補 全相對路路徑為絕對路路徑,但使⽤用 docker run 指令時不會。 ⽽而 docker volume 是數據卷 數據卷⼀一般設計是為了了裡⾯面內容還能夠被再次使⽤用, 不過使⽤用不當將會造成 Host 上存有⼤大量量 volumes ⽽而造成 full disk。
  • 19. 數據卷 ( Data Volumes ) 分為 匿名卷 以及 命名卷。 在 Dockerfile 裡宣告 Volume /data 匿名卷: docker run -itd nginx:latest => /data 會被掛在為匿名卷,當 container 死亡後數據會消失 命名卷: docker run -v mydata:/data -itd nginx:latest => /data 被掛載為 mydata 命名卷,container 死亡後數據會被保留留在本地 (⼀一般來來說會是 /var/lib/docker/volumes)
  • 20. 所以 docker run -v / Volumes 到 底哪裡不⼀一樣? 掛載⽬目錄是由⽤用⼾戶⾃自⾏行行維護權限 ( Permission ) 像是 uid / gid / SELinux 等問 題,容易易遇到 container 內與 Host 上 Permission Denied 問題 。 ⽽而 Docker Volumes 由 docker engine 維護以上問題,docker 會在建立 volume 時加入 rules 以調整權限問題。
  • 21. 在外⾯面Host修改了了容器內的檔案, 在容器內卻遺失了了? 使⽤用dw常⾒見見問題 可以demo ( ls -i 秀出file index number ) 因為當你使⽤用掛載⽬目錄⽅方式的時候 (docker run -v ) 如果只掛載單⼀一檔案,使⽤用 vim 或其他 IDE 時會出現問題。
  • 22. 容器內跑 cronjob 根據 Docker Best Practice , ⼀一個 container 只應該做⼀一件事, ⽽而 Cronjob 算是另⼀一個服務了了,應該另起 container 來來做 cronjob 才是正確做法。
  • 23. Database 不適合放在 Docker 上 運⾏行行嗎? 使⽤用 Docker Volume 的狀狀態下,是可以的。 但如果沒有使⽤用 Docker Volume ,資料將會遺失, 所以建議先了了解 Docker Volume 再來來考慮是否在 Docker 上運⾏行行 Database
  • 24. Docker 禁術 docker commit docker save docker load docker export docker import docker commit / import / export 俗稱⿊黑箱 Docker 。 除了了本⼈人之外沒有⼈人知道裡⾯面發⽣生過什什麼, 可能創造者本⼈人過⼀一段時間也忘了了 (?) 並不是正常使⽤用 docker 會⽤用的⽅方式。 這樣的⽅方式實際上是將 container 保存為 tar 檔,然後再變成 Image。 除了了正常操作會有⼀一層⼀一層的 layer 會被壓縮為⼀一層以外,原有層裡⾯面的配置也可能遺失。 如果遺失的是 CMD 就會造成無法正常啟動。 所以不建議使⽤用 commit / import / export.
  • 25. 如何寫好 Dockerfile Dockerfile 的每⼀一⾏行行指令都是⼀一層 layer , layer 越多當然 Image 也會越⼤大。 應該要盡量量減少 layer 的產⽣生。 把 Dockerfile 當 Shell Script 來來寫 Node.js official Dockerfile 利利⽤用 Docker 分層概念念, 使建構過程更更為順利利與快速 => docker pull 的時候是分層下載的 已經存在的層,就不會再次 pull 如果只有改 code 沒有更更改 package.json 就不⽤用重跑 npm install,節省了了很多時間。 縮⼩小 docker image : multiple stage
  • 26. ENTRYPOINT / CMD docker run -it nginx:latest [ ENTRYPOINT ] [ CMD ] ENTRYPOINT 不指定的話預設是 sh -c
  • 27. Docker logs docker logs 有很多種 logging driver Ex. CloudwatchLogs 使⽤用的是 awslogs driver 所以你在 ECS 上使⽤用 cloudwatchlogs 的 container 使⽤用 docker logs => 是絕對看不到 log 的
  • 28. Docker ⼀一跑就停⽌止 要觀察停⽌止的 Exit Code 通常為以下情況: Exited (127) : 很有可能是 Out of Memory Exited (0) : Docker 主進程退出了了 ( PID=1 的 Process 做完事情或失敗了了 ) 其他情況請看 log
  • 29. Windows Docker Windows Docker 其實是在 windows 上跑 hyper-v 再運⾏行行 Linux kernel ( Docker for Windows ) Docker on Windows 是 windows 原⽣生⽀支援,但不能與 Linux 平台互通。