控排查的完整路徑)
Docker 和 K8S 一直是 Linux 運維繞不開的兩個關(guān)鍵詞。如果你剛接觸運維崗位或者正準備從傳統(tǒng)虛擬機轉(zhuǎn)向容器化部署大概率會在面試和日常工作中被這兩個詞反復(fù)轟炸。很多人在學習時最大的問題不是找不到資料而是資料太多不知道先裝哪個、先學哪個、跑到哪一步算學會。這篇文章按我實際帶人的順序來寫先搞清楚 Docker 和 K8S 各自解決了什么問題再把環(huán)境裝起來跑通第一個容器然后進入 K8S 的 Pod、Service、監(jiān)控和故障排查最后給一份可以直接照著做的學習落地清單。如果你只有一臺普通機器甚至 Windows 筆記本也可以跟著走完大部分流程。1. 先理清概念Docker 和 K8S 到底解決什么問題很多新手一上來就急著裝環(huán)境結(jié)果被一堆鏡像、容器、YAML 文件繞暈。我建議先花 20 分鐘把概念理順因為后面所有操作都建立在“為什么要用它們”這個基礎(chǔ)上。1.1 沒有容器之前運維最頭疼的是什么傳統(tǒng)的部署方式是直接在服務(wù)器上裝環(huán)境。Java 應(yīng)用要裝 JDKPython 應(yīng)用要裝特定版本的依賴數(shù)據(jù)庫要單獨維護實例。第一次部署還好第二次、第三次只要機器環(huán)境稍微不一樣就會出現(xiàn)“開發(fā)環(huán)境能跑測試環(huán)境跑不起來生產(chǎn)環(huán)境更跑不起來”的問題。這種“環(huán)境不一致”是最消耗時間的事情。你可能為了一個依賴版本差異排查一整天。虛擬機能解決一部分問題但虛擬機很重一個基礎(chǔ)系統(tǒng)鏡像要幾個 GB啟動要幾十秒甚至幾分鐘每臺虛擬機還要單獨分配 CPU、內(nèi)存和磁盤資源。容器化解決的就是“把應(yīng)用和它的運行環(huán)境一起打包”。Docker 把程序、依賴、配置文件、啟動命令都寫進一個鏡像鏡像在任何裝有 Docker 的機器上都能以同樣的方式啟動。啟動一個容器通常只需要一兩秒比虛擬機輕量得多。隔離性是有的但不是完整的操作系統(tǒng)級隔離而是共享宿主機內(nèi)核。用一句話理解Docker 的核心價值是“一次構(gòu)建到處運行”。它把過去繁瑣的環(huán)境配置工作提前打包好了。1.2 容器多了以后為什么需要 K8S單機環(huán)境下Docker 管理幾十個容器還勉強可以。容器少的時候你用docker run一條一條啟動再配合 docker compose 編排基本夠用。但一旦應(yīng)用到多臺服務(wù)器問題就來了某臺機器掛了容器怎么自動遷移到另一臺機器流量高峰期需要擴容是手動再啟動幾個容器還是能自動伸縮多個容器分布在多臺機器上它們之間怎么互相訪問發(fā)布新版本的時候能不能滾動更新且不中斷服務(wù)這些問題 Docker 單機版都給不了完整答案。K8S 就是用來解決“多機環(huán)境下容器怎么調(diào)度、怎么管理、怎么恢復(fù)”的編排系統(tǒng)。K8S 里有一個核心思想叫“聲明式管理”你告訴它期望的狀態(tài)比如“我要運行 3 個 nginx 副本”它會自己去創(chuàng)建 Pod、調(diào)度到合適的節(jié)點、保持副本數(shù)始終是 3。節(jié)點掛了它會自動在另一臺節(jié)點上重新創(chuàng)建 Pod直到集群恢復(fù)期望狀態(tài)。一個容易理解的比喻是Docker 像打包和拉貨的車負責把貨物打包成標準箱子并啟動運輸K8S 像物流調(diào)度中心它不負責造箱子但負責決定箱子放哪臺車、怎么分配路線、車壞了以后怎么補貨。1.3 Docker 和 K8S 的關(guān)系與區(qū)別很多資料會把 Docker 和 K8S 放在一起講導(dǎo)致新手誤以為它們是替代關(guān)系學了 K8S 就不需要 Docker。實際不是這樣。Docker 是一個容器管理工具負責構(gòu)建鏡像、啟動容器、管理容器生命周期。K8S 是一個容器編排平臺負責管理多個節(jié)點上的容器調(diào)度。K8S 本身不直接啟動容器它需要一個容器運行時來執(zhí)行真正的容器操作。早期 K8S 經(jīng)常用 Docker 作為運行時所以“Docker K8S”成了默認組合。但現(xiàn)在 K8S 默認使用 containerd 作為運行時這是 Kubernetes 社區(qū)逐步演進出來的方向。containerd 更輕量專門為容器運行時設(shè)計而 Docker 更偏向端到端的開發(fā)者體驗。學習時建議從 Docker 入手因為 Docker 的命令足夠直觀能幫你快速理解鏡像、容器、數(shù)據(jù)卷、端口映射這些基礎(chǔ)概念。進入 K8S 后再逐步切換到 containerd、Pod、Service 這些新的表達方式。記住一點K8S 和 Docker 是不同層級的東西不是同一類工具的替代而是“編排調(diào)度”和“容器管理”的分工關(guān)系。2. Docker 落地裝好環(huán)境、跑通 MySQL 和 Redis概念清楚后進入動手環(huán)節(jié)。Docker 的落地路徑比較固定安裝、配置鏡像源、跑容器、管理容器。這里我按不同系統(tǒng)分別說明并給出兩個常見生產(chǎn)任務(wù)的完整案例。2.1 不同系統(tǒng)的安裝路徑如果你用的是 Windows 或 macOS最簡單的方案是安裝 Docker Desktop。Docker Desktop 自帶圖形界面適合學習階段使用。但它對系統(tǒng)版本有要求安裝前先確認兩點系統(tǒng)版本是否在支持范圍內(nèi)。Windows 上如果提示 incompatible version of windows說明當前系統(tǒng)版本太舊要么升級系統(tǒng)要么換用 Linux 環(huán)境練習。是否開啟虛擬化。Windows 常見報錯是virtualization support not detectedDocker Desktop 無法啟動錯誤信息里會直接提示沒有檢測到虛擬化支持。這時去 BIOS/UEFI 里找 Intel VT-x 或 AMD SVM 開關(guān)開啟后重啟。Linux 環(huán)境下安裝 Docker 更直接。Ubuntu 上可以用 apt 安裝docker.io也可以用 Docker 官方倉庫安裝推薦用官方倉庫版本更新更及時。CentOS 7 想升級到新版 Docker不能只靠yum update docker一般需要先卸載舊包再配置 Docker 官方或鏡像站倉庫然后裝新版本。這里給的是通用排查順序?qū)嶋H命令要以當前系統(tǒng)的官方文檔為準。安裝完先跑一次驗證docker --version docker run hello-worlddocker run hello-world會拉取一個很小的測試鏡像并打印一段成功信息。如果這一步能跑通說明 Docker 守護進程和命令行都能正常工作。如果卡在拉取鏡像說明鏡像下載網(wǎng)絡(luò)有問題先進入下一步配置鏡像源。2.2 安裝之后先配鏡像源Docker Hub 是默認鏡像倉庫但拉取慢是很多新手遇到的第一個問題。一個常見解決辦法是在 Docker 配置里設(shè)置鏡像加速源。在 Linux 下修改/etc/docker/daemon.json{ registry-mirrors: [ https://your-mirror-source.example.com ] }修改后重啟 Dockersudo systemctl restart docker在 Docker Desktop 里設(shè)置項中一般有 registry mirrors 配置填入可用地址后應(yīng)用并重啟。注意事項不同云廠商的鏡像源地址可能變化落地時以你所用環(huán)境對應(yīng)的官方文檔為準不要照抄幾年前文章里的地址。配置鏡像源不保證所有鏡像都能加速個別鏡像可能仍然很慢或者不穩(wěn)定。如果鏡像拉取失敗先看報錯是超時、連接拒絕還是 404。超時優(yōu)先檢查鏡像源連通性404 優(yōu)先確認鏡像名和 tag 是否正確。配好之后重新執(zhí)行docker run hello-world能正常輸出版本信息說明鏡像源生效了。2.3 用 Docker 部署 MySQL 8.0MySQL 是運維中最高頻的中間件之一。Docker 部署 MySQL 8.0 特別適合本地開發(fā)、測試環(huán)境快速起實例。先拉鏡像并運行docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDyourpassword \ mysql:8.0參數(shù)含義-d后臺運行。--name mysql8容器名稱方便后續(xù)用 docker 命令管理。-p 3306:3306宿主機 3306 端口映射到容器 3306 端口。-e MYSQL_ROOT_PASSWORDyourpassword設(shè)置 root 密碼。這是 MySQL 官方鏡像支持的初始化環(huán)境變量。mysql:8.0鏡像名和標簽表示 MySQL 8.0 系列。啟動后先不要急著連庫先看狀態(tài)和日志docker ps docker logs mysql8如果docker ps里沒有這個容器說明容器啟動后立刻退出了這時必須看日志。常見情況是密碼策略、端口被占用、初始化腳本報錯。日志會給出線索。進入容器執(zhí)行命令驗證docker exec -it mysql8 mysql -uroot -p輸入上面設(shè)置的密碼能進入 MySQL Shell 說明服務(wù)正常。一個容易踩的坑是數(shù)據(jù)持久化。如果直接用上面的命令啟動容器刪除后/var/lib/mysql里的數(shù)據(jù)也會一起刪除。正確做法是掛載數(shù)據(jù)卷docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDyourpassword \ -v $PWD/mysql-data:/var/lib/mysql \ mysql:8.0這樣數(shù)據(jù)會落到宿主機當前目錄的mysql-data文件夾里。容器重建后只要掛載到同一個目錄數(shù)據(jù)就不會丟。另一個常見問題是 3306 端口沖突。如果本機已經(jīng)裝了 MySQL或者別的主機占用該端口可以換個端口docker run -d \ --name mysql8 \ -p 3307:3306 \ -e MYSQL_ROOT_PASSWORDyourpassword \ -v $PWD/mysql-data:/var/lib/mysql \ mysql:8.0連接時就要連127.0.0.1:3307連接工具和代碼里的端口都要跟著改。2.4 用 docker compose 部署 Redis 主從單個 MySQL 用 docker run 還能接受如果要用 Docker 部署一整套 Redis 主從我建議直接上 docker compose。compose 把多個容器的配置寫進一個 YAML 文件一條命令就能啟動和停止整套服務(wù)。先創(chuàng)建一個工作目錄比如redis-cluster里面放一個docker-compose.ymlservices: redis-master: image: redis:7.0 container_name: redis-master ports: - 6379:6379 command: redis-server --appendonly yes redis-slave: image: redis:7.0 container_name: redis-slave ports: - 6380:6379 command: redis-server --slaveof redis-master 6379 depends_on: - redis-master這個配置里有兩個服務(wù)master 和 slave。slave 啟動時通過--slaveof redis-master 6379指定主節(jié)點地址和端口。在 compose 網(wǎng)絡(luò)里服務(wù)名redis-master可以直接作為域名訪問。啟動整套服務(wù)docker compose up -d查看運行狀態(tài)docker compose ps驗證主從關(guān)系docker exec -it redis-master redis-cli info replication看到role:master并且有slave0連接信息說明主節(jié)點正常。再檢查從節(jié)點docker exec -it redis-slave redis-cli info replication看到role:slave并且master_link_status:up說明主從同步正常。這里有一個版本差異問題老版本 compose 使用獨立的docker-compose命令新版本 Docker 直接支持docker compose子命令。如果你執(zhí)行docker compose報錯先確認 Docker 和 Docker Compose 的安裝版本不要強行套命令。數(shù)據(jù)掛載在 Redis 集群里同樣重要。可以在每個服務(wù)下加volumes配置把/data目錄掛載到宿主機避免容器重建后數(shù)據(jù)丟失。除此之外Redis 主從只解決讀擴展問題不解決自動故障切換生產(chǎn)環(huán)境要考慮哨兵或 Redis Cluster這是另一個話題。3. K8S 入門從集群搭建到 Pod、Service 和啟動命令Docker 跑順之后開始進入 K8S。K8S 的入門曲線比 Docker 陡因為它引入了一批新概念。不要試圖一次全看懂先掌握最常見的幾個再通過實際操作加深理解。3.1 先記住核心概念K8S 里的最小調(diào)度單元不是容器而是 Pod。Pod 是“一組容器的集合”通常一個 Pod 里放一個主容器也可以放邊車容器。Pod 里的容器共享網(wǎng)絡(luò)命名空間和存儲卷所以它們之間可以通過 localhost 通信。Deployment 負責管理 Pod 的副本數(shù)。它告訴你“我要運行幾個副本”實際創(chuàng)建、更新和刪除 Pod 都是 Deployment 去做。Service 是服務(wù)入口。Pod 的 IP 會隨著重啟變化直接訪問 Pod IP 不現(xiàn)實。Service 提供一個固定虛擬 IP 和域名把流量轉(zhuǎn)發(fā)到后端一組 Pod 上。Namespace 用于隔離資源。團隊多、項目多的時候用 Namespace 區(qū)分環(huán)境或團隊。不指定時默認在 default 命名空間??刂破矫娼M件里你最先要理解 API Server、etcd 和 kubelet。API Server 是所有請求的入口etcd 保存集群狀態(tài)kubelet 負責在節(jié)點上管理 Pod。理解這三個后面看任何報錯都會更容易定位。一個關(guān)鍵思維方式是“聲明式”你聲明的不是一個動作而是一個期望狀態(tài)。比如你寫清楚“副本數(shù) 3”K8S 會自己判斷當前有幾個副本不夠就去創(chuàng)建多了就回收。3.2 本地或測試環(huán)境怎么搭學習 K8S 有兩類路徑。如果只有一臺筆記本或者只想體驗基礎(chǔ)功能推薦 minikube。minikube 會在本地創(chuàng)建一個小型 K8S 集群可以是單節(jié)點常用作學習環(huán)境。啟動命令一般類似minikube start啟動后可以用kubectl get nodes查看節(jié)點狀態(tài)。如果你對資源要求不高minikube 是成本最低的入門方式。如果想模擬真實集群建議準備三臺 Linux 虛擬機或云主機一臺 master兩臺 worker。系統(tǒng)建議選擇較新的長期支持版本。搭建流程大致是關(guān)閉 swap保證 kubelet 能正常工作。加載內(nèi)核模塊調(diào)整網(wǎng)絡(luò)參數(shù)讓容器流量能正常轉(zhuǎn)發(fā)。安裝 kubeadm、kubelet、kubectl 三個核心組件。master 節(jié)點執(zhí)行kubeadm init初始化集群。初始化完成后按提示配置 kubeconfig并記錄生成的 join token。worker 節(jié)點執(zhí)行kubeadm join加入集群。安裝一個容器網(wǎng)絡(luò)插件讓不同節(jié)點上的 Pod 能互相通信。這里有一個容易忽略的點不同網(wǎng)絡(luò)插件對--pod-network-cidr參數(shù)的要求不同。不要盲目照搬某個教程里的 CIDR 值一定要看你實際選擇的網(wǎng)絡(luò)插件文檔。我在實際測試中見過很多次初始化失敗不是因為集群配置錯而是 CIDR 和網(wǎng)絡(luò)插件對不上。初始化完成后驗證kubectl get nodes能看到 master 和 worker 節(jié)點狀態(tài)為Ready說明集群基礎(chǔ)可用。3.3 用 YAML 描述 Pod 和 ServiceK8S 里最常用的是 YAML 文件。下面是一個最簡單的 nginx Pod 示例apiVersion: v1 kind: Pod metadata: name: my-nginx spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80執(zhí)行kubectl apply -f pod-nginx.yaml kubectl get pods kubectl describe pod my-nginxkubectl describe是排查問題的第一入口。它會把 Pod 的事件、容器狀態(tài)、鏡像拉取情況全部列出來。如果 Pod 一直 Pending先看 describe 輸出里有沒有節(jié)點資源不足、鏡像拉取失敗等提示。直接訪問 Pod IP 不方便所以通常再創(chuàng)建一個 ServiceapiVersion: v1 kind: Service metadata: name: my-nginx-service spec: selector: app: my-nginx ports: - port: 80 targetPort: 80 type: ClusterIP如果你想在本地瀏覽器直接訪問可以把 Service 類型改成NodePort或者用kubectl port-forward做端口轉(zhuǎn)發(fā)。學習階段我常用kubectl port-forward不用改 Service 類型也不用關(guān)心集群外的防火墻規(guī)則。kubectl port-forward service/my-nginx-service 8080:80然后訪問http://localhost:8080看到 nginx 默認頁面說明 Pod 和 Service 都通了。3.4 entrypoint 和 cmd 在 K8S 中代表什么Dockerfile 里有 ENTRYPOINT 和 CMDK8S 的容器定義里有 command 和 args。很多人會混淆它們。Dockerfile 中的 CMD 是默認啟動命令ENTRYPOINT 是固定入口。運行時最終執(zhí)行的命令是 ENTRYPOINT 加上 CMD 作為默認參數(shù)。K8S 里可以通過command覆蓋 Dockerfile 的 ENTRYPOINT通過args覆蓋 Dockerfile 的 CMD。它們的關(guān)系是K8S 的command對應(yīng) Dockerfile 的 ENTRYPOINT。K8S 的args對應(yīng) Dockerfile 的 CMD。舉個例子鏡像默認通過 ENTRYPOINT 啟動某個腳本你希望在 K8S 里加一個額外參數(shù)就可以在 Pod 的 YAML 里只寫args不寫command這樣保留鏡像里的 ENTRYPOINT只覆蓋默認參數(shù)spec: containers: - name: my-app image: my-app:latest args: [--config-file/etc/my-app/config.yaml]如果你同時寫了command和args就會完全覆蓋鏡像里的默認設(shè)置。遇到啟動命令不生效先看容器的啟動命令和日志再確認是 command 寫錯了還是 args 里的路徑、參數(shù)名不對。4. 監(jiān)控告警與故障排查進入真實運維場景后不能只會在命令行里跑 pod、看日志。容器集群一旦多起來你更需要一套監(jiān)控體系來發(fā)現(xiàn)資源問題而不是等用戶報障才知道服務(wù)掛了。4.1 常用命令速查我不建議背命令而是建議按“查狀態(tài)、查日志、查資源”三個動作去記命令。Linux 系統(tǒng)層面查系統(tǒng)運行狀態(tài)top、free -h、df -h、du -sh *查服務(wù)和日志systemctl status 服務(wù)名、journalctl -u 服務(wù)名 -f查端口和連接ss -tlnp、netstat -tlnpDocker 層面查容器狀態(tài)docker ps -a查日志docker logs -f 容器名進入容器docker exec -it 容器名 bash查資源占用docker stats查鏡像和容器詳情docker inspect 容器名K8S 層面查集群節(jié)點kubectl get nodes查資源對象kubectl get pods -A查詳細事件kubectl describe pod 名稱查容器日志kubectl logs -f pod名稱進容器調(diào)試kubectl exec -it pod名稱 -- bash查資源用量kubectl top nodes、kubectl top pods實際排查時我發(fā)現(xiàn)很多新手會在命令本身上浪費時間比如糾結(jié)kubectl logs和kubectl describe該用哪個。原則很簡單先 describe 看事件再 logs 看應(yīng)用輸出。事件負責告訴你“K8S 層面發(fā)生了什么”日志負責告訴你“應(yīng)用內(nèi)部發(fā)生了什么”。4.2 監(jiān)控告警體系node-exporter Prometheus Grafana容器化環(huán)境里靠 ssh 到每臺機器去看top和df不現(xiàn)實。標準做法是搭建一套監(jiān)控告警體系常見組合是 node-exporter、Prometheus 和 Grafana。node-exporter 負責在每臺節(jié)點上采集系統(tǒng)指標比如 CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)。Prometheus 負責定時抓取這些指標并存儲。Grafana 負責把指標可視化并配置告警規(guī)則。這套體系可以用 docker compose 在單機跑通也可以部署進 K8S 集群。學習階段我建議先用 docker compose 跑一遍理解“采集、存儲、展示”三個環(huán)節(jié)再考慮部署到 K8S。一個最簡單的鏈路是在目標機器運行 node-exporter默認監(jiān)聽 9100 端口。Prometheus 配置文件里添加這個 node-exporter 作為 scrape target。打開 Prometheus 的 targets 頁面看到該節(jié)點狀態(tài)為 UP。Grafana 添加 Prometheus 數(shù)據(jù)源導(dǎo)入一個 Node Exporter 的儀表盤。在 Grafana 里配置告警規(guī)則或者通過 Alertmanager 發(fā)送通知。驗證鏈路是否正常先看兩個地方Prometheus 的 targets 是否 UPGrafana 的 Dashboard 是否有數(shù)據(jù)。如果 target 是 DOWN先檢查 node-exporter 進程和 9100 端口而不是急著改 Grafana。4.3 磁盤告警規(guī)則怎么寫磁盤告警是最常見的需求因為鏡像、容器日志、數(shù)據(jù)卷都會迅速消耗磁盤空間。只靠人工巡檢很被動最好配置自動告警。在 Prometheus 或 Grafana 里寫告警規(guī)則時核心是判斷“磁盤剩余空間是否低于閾值”。下面是 Prometheus 告警規(guī)則的常見寫法示例groups: - name: node-disk-alert rules: - alert: DiskUsageHigh expr: (1 - (node_filesystem_avail_bytes{fstype!~tmpfs|overlay} / node_filesystem_size_bytes{fstype!~tmpfs|overlay})) 0.9 for: 10m labels: severity: warning annotations: summary: 磁盤使用率超過 90%這段規(guī)則的作用是篩選出非 tmpfs、非 overlay 的文件系統(tǒng)計算磁盤使用率是否超過 90%持續(xù) 10 分鐘就觸發(fā)告警。需要提醒的是node-exporter 的指標名會隨版本變化。有些版本里相關(guān)指標可能叫node_filesystem_avail_bytes還有可能存在node_filesystem_avail之類的歷史指標。寫規(guī)則前先在 Prometheus 的 Graph 頁面用 PromQL 查詢確認指標名否則規(guī)則可能永遠不會觸發(fā)。告警通知渠道取決于你的部署方式。Grafana 支持郵件、釘釘、企業(yè)微信、Webhook 等Alertmanager 也能做更復(fù)雜的路由和收斂。關(guān)鍵是先保證“規(guī)則能觸發(fā)、通知能發(fā)出去”不要一開始就追求復(fù)雜的告警路由。4.4 常見故障排查鏈路K8S 和 Docker 的故障很多但排查思路是固定的先看現(xiàn)象再查輸入再查環(huán)境最后查參數(shù)。Docker Desktop 虛擬化報錯。如果啟動時提示virtualization support not detected優(yōu)先檢查 BIOS/UEFI 里的 CPU 虛擬化開關(guān)再檢查 Windows 虛擬機平臺功能是否開啟。報錯信息本身一般已經(jīng)給了修復(fù)方向。容器啟動后立刻退出。先docker logs看日志再docker ps -a看退出狀態(tài)。常見原因是端口被占、數(shù)據(jù)目錄權(quán)限不足、啟動命令依賴的配置不存在。不要反復(fù)重啟容器先看退出前的日志。K8S Pod 一直 Pending。用kubectl describe pod看事件常見原因是節(jié)點 CPU 或內(nèi)存不足或者節(jié)點有 taint 導(dǎo)致沒有可用節(jié)點。先解決資源問題或調(diào)整調(diào)度配置。K8S Pod 進入 CrashLoopBackOff。說明容器啟動后又崩潰了看kubectl logs是最直接的排查方式。常見原因是啟動命令參數(shù)錯誤、依賴服務(wù)沒就緒、環(huán)境變量缺失。K8S CPU throttling。這是一個比較隱蔽的問題。表現(xiàn)是 Pod 的 CPU 使用率看起來不高但接口響應(yīng)很慢日志里有大量延遲提升。原因是 Pod 設(shè)置了 CPU limit但業(yè)務(wù)在實際運行時超過了 limit導(dǎo)致 CPU 被限流。排查時可以查看 Prometheus 里container_cpu_cfs_throttled_periods_total相關(guān)指標判斷是否存在大量 throttled 周期。解決思路不是簡單地取消 limit而是根據(jù)業(yè)務(wù)真實負載合理設(shè)置 requests 和 limits并在容量規(guī)劃時留出緩沖。權(quán)限問題。比如想給團隊成員只讀權(quán)限查看 K8S 資源很多人會直接把管理員 kubeconfig 發(fā)出去這是非常危險的。正確做法是創(chuàng)建一個只讀用戶或 ServiceAccount綁定只包含get、list、watch權(quán)限的 RBAC 角色。最小化權(quán)限是運維的基本功。5. 學習落地清單和邊界最后這部分給新手一條可以照著走的路徑也把最容易踩的坑集中說一遍。5.1 建議的學習順序我的建議是分四個階段走不要跳級。第一階段Linux 基礎(chǔ)。至少會用cd、ls、top、free、df、journalctl、systemctl能看懂系統(tǒng)報錯。沒有這個基礎(chǔ)Docker 和 K8S 的很多問題會卡在系統(tǒng)層面。第二階段Docker 單機。從安裝、拉鏡像、跑容器開始理解鏡像、容器、數(shù)據(jù)卷、端口映射。重點練習docker run、docker exec、docker logs、docker inspect。第三階段docker compose 和多服務(wù)編排。把 MySQL、Redis、Nginx 等常見組件用 docker compose 編排起來理解容器之間的網(wǎng)絡(luò)通信和數(shù)據(jù)持久化。第四階段K8S。先掌握 Pod、Deployment、Service、Namespace再往上加監(jiān)控、日志、持久化存儲。不要一開始就去研究 Operator、service mesh 這些進階內(nèi)容。5.2 典型踩坑記錄鏡像下載慢配置鏡像源確認網(wǎng)絡(luò)連通性不要反復(fù)重試同一個失敗任務(wù)。容器數(shù)據(jù)丟失沒有掛載數(shù)據(jù)卷。無論 MySQL、Redis 還是業(yè)務(wù)應(yīng)用只要需要持久化都要先規(guī)劃數(shù)據(jù)目錄。端口沖突啟動前先看端口占用不要等bind failed才去改端口。版本不匹配Docker Compose 新老命令差異、MySQL 8.0 初始化參數(shù)變化、K8S 鏡像版本過多都會導(dǎo)致照搬教程失敗。遇到版本報錯第一反應(yīng)是核對版本。權(quán)限問題K8S 不要隨便發(fā) admin kubeconfig云主機不要隨意放行所有端口。權(quán)限最小化操作留日志。資源耗盡容器不設(shè)置 requests/limitsK8S 集群容易被某個異常服務(wù)拖垮。學習階段可以不調(diào)但生產(chǎn)環(huán)境一定要設(shè)置。5.3 學習環(huán)境和生產(chǎn)環(huán)境的邊界學習環(huán)境可以用單節(jié)點、可以不開資源限制、可以隨便刪除重建。生產(chǎn)環(huán)境要考慮的東西更多etcd 備份、Master 高可用、網(wǎng)絡(luò)插件選型、Ingress 規(guī)劃、數(shù)據(jù)持久化、日志采集、監(jiān)控告警、權(quán)限審計、鏡像倉庫安全。低配置機器能跑 K8S不代表它能扛住生產(chǎn)流量。學習時用 minikube 或單節(jié)點集群沒問題放到生產(chǎn)環(huán)境要按實際負載和可用性要求設(shè)計。默認配置適合入門不適合生產(chǎn)。很多教程里的“一鍵部署”只是為了教學生產(chǎn)環(huán)境必須有明確的參數(shù)、容量、監(jiān)控和回滾方案。如果只是學習默認配置夠用。如果要長期維護就要把日志、輸出目錄、任務(wù)隊列、監(jiān)控規(guī)則提前整理好。不是等出事之后才補而是第一天就把基礎(chǔ)打牢。踩過幾次之后我發(fā)現(xiàn)很多問題不是工具能力不夠而是前置環(huán)境和輸入材料沒有處理干凈。先把 Docker 單機跑順再進入 K8S 編排先把監(jiān)控鏈路搭通再談告警閾值先學會看日志和事件再去找參數(shù)和配置。這套順序看起來慢但實際落地時能省下大量返工時間。