與生產(chǎn)運維全攻略)
第九章Docker 原理深入從會用到真正懂docker基礎自己的docker前面我們一直在講怎么使用 Docker?,F(xiàn)在開始講Docker 為什么能做到這些如果你想成為 Docker 高手這一章必須理解。1. Docker 的整體架構(gòu)先看 Docker 內(nèi)部結(jié)構(gòu)id3qz3rd 用戶 | | docker 命令 | ↓ Docker Client | | Docker API | ↓ Docker Daemon | ---------------- | | ↓ ↓ containerd 鏡像管理 | ↓ runc | ↓ Linux Kernel | ↓ Container我們逐個解釋。2. Docker Client你平時輸入docker run nginx這個docker就是客戶端。它負責例如你輸入docker ps實際上不是 docker 自己管理容器。它只是告訴 Docker 服務給我列一下容器。3. Docker Daemon核心Docker Daemon中文Docker 守護進程。它是真正干活的人。負責創(chuàng)建容器刪除容器下載鏡像管理網(wǎng)絡管理 VolumeLinux 查看systemctl status docker看到dockerd就是它。4. containerd現(xiàn)在 Docker 不直接管理容器運行。中間有containerd它負責鏡像管理容器生命周期結(jié)構(gòu)Docker ↓ containerd ↓ runc ↓ Linux5. runc 是什么runc真正創(chuàng)建容器的程序。它根據(jù) OCI 標準創(chuàng)建NamespaceCgroups文件系統(tǒng)最后產(chǎn)生Linux 進程。所以Docker 容器本質(zhì)不是 Docker 創(chuàng)建的。而是Docker ↓ containerd ↓ runc ↓ Linux進程6. Docker 為什么能隔離容器核心Linux 內(nèi)核技術(shù)。兩個最重要NamespaceCgroups7. Namespace命名空間作用隔離視圖。讓一個進程看到的是自己的世界。例如普通 Linux執(zhí)行ps aux看到PID 1 nginx PID 2 mysql PID 3 bash但是容器里面ps aux可能PID 1 nginx為什么因為Namespace 隔離了進程空間。8. Namespace 有哪些Linux 有多個 NamespacePID Namespace隔離進程。容器認為自己是 PID 1。例如宿主PID 5000 nginx容器PID 1 nginx實際上同一個進程。Network Namespace隔離網(wǎng)絡。每個容器擁有獨立網(wǎng)卡IP路由例如容器eth0 172.18.0.2Mount Namespace隔離文件系統(tǒng)。容器看到/bin /etc /usr但是和宿主不同。UTS Namespace隔離主機名。容器hostname輸出mysql-containerUser Namespace隔離用戶。例如容器 root不一定等于宿主 root。9. Cgroups資源限制Namespace解決“你看到什么”。Cgroups解決“你能用多少資源”。例如限制docker run \ --memory512m \ --cpus1 \ nginx背后就是 Cgroups。沒有 Cgroups一個容器可能吃光CPU 內(nèi)存 磁盤導致服務器崩潰。10. UnionFS 鏡像分層原理這是 Docker 鏡像核心。之前說鏡像像千層蛋糕。為什么因為Union File System。例如DockerfileFROM ubuntu RUN apt install nginx COPY index.html /生成三層Layer 3 index.html ------------ Layer 2 nginx ------------ Layer 1 ubuntu啟動容器增加一層Container Layer (可寫) -------------- Layer 3 -------------- Layer 2 -------------- Layer 1重點鏡像只讀。容器增加可寫層。11. 為什么刪除容器數(shù)據(jù)消失因為數(shù)據(jù)在Container Writable Layer刪除這一層消失。Volume為什么保存因為它在外部Container | Volume | Host Disk12. Docker 為什么啟動快虛擬機啟動BIOS ↓ 啟動內(nèi)核 ↓ 啟動系統(tǒng) ↓ 啟動程序需要幾十秒。Docker啟動進程 ↓ 隔離環(huán)境 ↓ 運行幾秒。因為沒有啟動完整操作系統(tǒng)。13. Docker 鏡像為什么下載快原因三個1. 分層例如Ubuntu已經(jīng)下載。Python鏡像復用。2. 緩存Docker 保存Layer下一次不用重新下載。3. 并行下載多個 layer同時下載。14. 容器和普通進程區(qū)別很多人問Docker 容器是不是虛擬機不是。實際上普通程序 nginx ↓ Linux進程 Docker: nginx ↓ Linux進程 Namespace Cgroups Filesystem15. Docker 安全邊界注意容器不是絕對安全。為什么因為共享Linux Kernel。如果Kernel 有漏洞可能突破。所以生產(chǎn)環(huán)境需要更新內(nèi)核最小權(quán)限非 root 用戶鏡像掃描網(wǎng)絡隔離16. Docker 和 Kubernetes 的關系很多人混淆。Docker負責運行容器。例如一臺服務器 運行10個容器Docker 很舒服。但是100臺服務器10000個容器。怎么辦需要Kubernetes。關系Kubernetes 管理 ↓ Docker / containerd 運行 ↓ Containers17. Docker 到底解決了什么總結(jié)以前開發(fā)環(huán)境 Python版本不同 依賴不同 服務器不同 部署失敗Docker程序 環(huán)境 依賴 ↓ 鏡像 ↓ 哪里都能運行18. 高手必須掌握的 Docker 排錯思路生產(chǎn)出問題不要亂試。按層排查第一層容器有沒有運行docker ps第二層日志docker logs第三層進入容器docker exec -it第四層網(wǎng)絡docker network inspect第五層資源docker stats第六層鏡像docker inspect19. 到這里你的 Docker 知識體系現(xiàn)在基礎 docker run docker ps ↓ 核心 Image Container Volume Network ↓ 開發(fā) Dockerfile Compose ↓ 生產(chǎn) 部署 日志 優(yōu)化 ↓ 原理 Namespace Cgroups containerd runc UnionFS第十章Docker 高級實戰(zhàn)工程師級現(xiàn)在你已經(jīng)不是 Docker 小白了。前面你掌握了Docker基礎 ↓ 鏡像 ↓ 容器 ↓ Volume ↓ Network ↓ Dockerfile ↓ Compose ↓ 底層原理這一章開始進入企業(yè)真實環(huán)境。目標能寫生產(chǎn)級 Dockerfile能優(yōu)化鏡像能部署、維護、排查線上 Docker 服務。一、Docker 鏡像優(yōu)化企業(yè)必做很多新人寫 DockerfileFROM ubuntu RUN apt update RUN apt install python COPY . CMD python app.py能運行。但是生產(chǎn)不合格。問題1. 鏡像巨大Ubuntu70MB安裝各種工具可能1GB2. 攻擊面增加軟件越多漏洞越多。3. 下載慢部署速度慢。生產(chǎn)目標小 快 安全二、選擇合適基礎鏡像普通FROM ubuntu大小幾百 MB。slim例如FROM python:3.12-slim特點刪除很多無用工具。推薦生產(chǎn)常用。alpine例如FROM python:3.12-alpine非常小。但是有兼容問題。例如某些 Python 庫需要 gcc。經(jīng)驗場景選擇生產(chǎn)Pythonpython-slimJavatemurin-jreNodenode-slim極致優(yōu)化alpine三、多階段構(gòu)建重點這是企業(yè)最常用技術(shù)。問題Java 項目。編譯需要JDK Maven 源碼 依賴但是運行只需要JRE jar包錯誤FROM maven COPY . RUN mvn package CMD java -jar app.jar結(jié)果鏡像包含Maven源碼編譯工具巨大。多階段# 第一階段編譯 FROM maven:3.9 AS build WORKDIR /app COPY . . RUN mvn package # 第二階段運行 FROM eclipse-temurin:17-jre WORKDIR /app COPY --frombuild /app/target/app.jar . CMD [java,-jar,app.jar]結(jié)構(gòu)階段1 Maven 源碼 ↓ app.jar 階段2 JRE app.jar結(jié)果可能1GB ↓ 200MB四、Dockerfile 最佳實踐1. 固定版本不要FROM python因為未來版本變化。推薦FROM python:3.12.5-slim2. 不使用 root默認容器root。風險攻擊后權(quán)限過高。推薦FROM nginx RUN adduser app USER app3. 不安裝無用工具不要RUN apt install vim生產(chǎn)不需要。4. 清理緩存例如錯誤RUN apt update RUN apt install nginx留下緩存。正確RUN apt update \ apt install -y nginx \ rm -rf /var/lib/apt/lists/*五、Docker 鏡像安全掃描企業(yè)不會直接使用鏡像。流程鏡像 ↓ 掃描漏洞 ↓ 上線常見工具Trivy例如掃描trivy image nginx發(fā)現(xiàn)CVE漏洞為什么因為基礎鏡像可能包含漏洞軟件。六、私有鏡像倉庫公司不會把所有鏡像放 Docker Hub。通常自己搭私有 Registry。結(jié)構(gòu)開發(fā)電腦 docker build ↓ 公司Registry ↓ 服務器pull例如鏡像nginx變registry.company.com/shop/backend:v1七、Docker Registry 工作流程開發(fā)構(gòu)建docker build -t backend:v1 .登錄docker login打標簽docker tag backend:v1 \ registry.com/backend:v1上傳docker push registry.com/backend:v1服務器docker pull registry.com/backend:v1八、Harbor企業(yè)常用Harbor很多公司使用。它比普通 Registry 強提供用戶管理權(quán)限控制鏡像掃描審計Web界面結(jié)構(gòu)開發(fā) | docker push ↓ Harbor | docker pull ↓ 生產(chǎn)服務器九、Docker CI/CD 自動化真實公司不會每天手動docker build docker push而是自動。流程開發(fā)提交代碼 ↓ Git ↓ CI系統(tǒng) ↓ 自動測試 ↓ docker build ↓ 鏡像倉庫 ↓ 服務器部署例如代碼git push自動1. 拉代碼 2. 構(gòu)建鏡像 3. 掃描 4. 上傳 5. 更新服務器十、GitLab CI 示例文件.gitlab-ci.yml例如build: script: - docker build -t app:v1 . - docker push app:v1提交代碼自動執(zhí)行。十一、Jenkins Docker傳統(tǒng)企業(yè)大量使用。流程Git ↓ Jenkins ↓ Docker Build ↓ Docker Push ↓ 服務器部署十二、Docker 生產(chǎn)監(jiān)控線上不能只看docker ps需要監(jiān)控。關注CPUCPU使用率內(nèi)存Memory網(wǎng)絡流量容器狀態(tài)是否重啟命令docker stats企業(yè)常用PrometheusGrafana組成Docker ↓ Prometheus ↓ Grafana ↓ 監(jiān)控面板十三、Docker 日志管理默認json-file長期可能撐爆磁盤。查看docker info限制daemon.json{ log-driver:json-file, log-opts:{ max-size:100m, max-file:3 } }意思單個日志最多100MB。保留3個文件。十四、Docker 健康檢查問題容器運行不代表服務正常。例如容器 alive 但是 Java死循環(huán)添加DockerfileHEALTHCHECK CMD curl http://localhost:8080Composehealthcheck: test: - CMD - curl - localhost:8080效果Docker知道服務健康狀態(tài)。十五、自動恢復生產(chǎn)一定restart: always例如服務器重啟服務器開機 ↓ Docker啟動 ↓ 容器自動啟動常見restart: unless-stopped意思除非人為停止。十六、Docker 網(wǎng)絡生產(chǎn)設計不要所有服務一個網(wǎng)絡。推薦分層公網(wǎng)網(wǎng)絡 | ↓ Nginx 內(nèi)部網(wǎng)絡 | ↓ Backend 數(shù)據(jù)庫網(wǎng)絡 | ↓ MySQL例如networks: frontend: backend: database:隔離。十七、Docker 數(shù)據(jù)備份策略數(shù)據(jù)庫不能只靠 Volume。生產(chǎn)至少每日備份例如凌晨3點 mysqldump ↓ 備份文件異地備份例如服務器↓對象存儲。十八、Docker 常見線上事故事故1磁盤爆滿原因日志。解決docker system prune事故2容器不停重啟查看docker ps然后docker logs事故3數(shù)據(jù)庫數(shù)據(jù)丟失原因沒有 Volume。事故4服務訪問不了檢查順序docker psdocker logsdocker network inspect端口docker port十九、Docker 運維黃金流程上線代碼提交 ↓ CI構(gòu)建 ↓ Docker鏡像 ↓ 漏洞掃描 ↓ 推送倉庫 ↓ 服務器拉取 ↓ Compose更新 ↓ 監(jiān)控觀察二十、現(xiàn)在你的 Docker 能力等級大概初級會docker run docker ps docker pull中級會Dockerfile Volume Network Compose高級會鏡像優(yōu)化 安全 CI/CD 私有倉庫 監(jiān)控 生產(chǎn)部署你現(xiàn)在已經(jīng)進入高級 Docker 使用者。