Docker 与 Kubernetes 学习笔记

Docker 与 Kubernetes 学习笔记

——从容器基础到集群编排的系统梳理

整理范围:K8s 与 Docker 的区别、Docker 三件套、docker-compose
多容器编排、K8s 核心对象与进阶四件套(ConfigMap / Secret / Ingress /
Volume),并附命令对照表与学习路线。

目录

一、先搞懂:K8s 是什么,和 Docker 什么关系

1.1 一句话定义

K8s 就是
Kubernetes,一个开源的容器编排系统——它是帮你自动部署、扩缩容和管理大量容器化应用的”自动驾驶管家”。

名字由来:Kubernetes 源自希腊语,意为”舵手、飞行员”;K 和 s 之间正好 8
个字母,故简称 K8s。它 2014 年由 Google
开源,基于其十几年大规模生产运维经验。

1.2 它解决什么问题

用 Docker
能把应用打包成容器,但线上往往是几十上百个容器一起跑:半夜某个容器挂了谁去重启?流量暴涨怎么从
3 个扩到 30 个?发版怎么做到用户无感?K8s 就是来自动干这些脏活累活的。

1.3 核心思想:声明式 + 自愈

你不用一步步下命令(命令式),而是只描述”我想要什么状态”,K8s
自己想办法达成并一直维持。比如你说”这个应用永远保持 3
个副本在线”,真掉到 2 个它会立刻拉起第 3 个——这叫自愈,是 K8s
最迷人的能力。

1.4 必懂的三个概念

概念 一句话 比喻
Pod 最小调度单位,包着一个或几个容器 豌豆荚(豆子=容器)
Deployment 声明副本数,自动维持、滚动更新、回滚 staffing 经理,有人请假就补人
Service 给会变的 Pod 一个固定入口 + 负载均衡 公司总机号,员工换了号码不变

1.5 整体架构:大脑 + 工人

控制平面(大脑):API
Server(统一入口)、etcd(存状态的数据库)、Scheduler(决定 Pod
放哪台机器)、Controller Manager(监工,不停对比”期望 vs 现实”)。

工作节点(工人):真正跑容器的地方,上面有
kubelet(听指挥、照看本机容器)、kube-proxy(网络转发)、容器运行时(containerd
/ CRI-O)。

1.6 一句话总结

你负责描述目标(写 YAML),K8s 负责让现实一直等于目标。

二、K8s 和 Docker 有什么区别

2.1 核心区别对照

维度 Docker Kubernetes
定位 容器引擎(造容器、跑容器) 容器编排系统(管一群容器)
关注点 单个容器的构建与运行 多个容器的部署、调度、自愈、扩缩容
规模 适合单机、几到几十个容器 设计目标就是集群,几十到上万节点
高可用 容器挂了得你自己重启 自动重启、自动迁移、自动补齐副本
典型工具 docker build / run / ps kubectl apply / get / logs

2.2 比喻与配合关系

Docker 是造集装箱的工厂 +
货轮上的工人,负责把货装进箱、运到指定位置;K8s
是港口调度中心,决定哪个箱子放哪条船、船超载了要不要加船、船沉了货怎么转到别的船上。

典型误解”K8s 要取代 Docker?”——没有。准确说是 K8s 在 2020 年移除了对
Docker 作为容器运行时的直接支持(去掉了 dockershim),改用兼容 CRI
标准的 containerd。你用 Docker 构建的镜像,K8s
照常能跑,镜像格式完全通用。

2.3 实际开发里怎么配合

写 Dockerfile → docker build 出镜像 → 推到镜像仓库 → kubectl apply -f
deploy.yaml → K8s 从仓库拉镜像,调度到节点跑起来。Docker
是你的开发/打包工具,K8s 是线上的运行平台。

2.4 到底学哪个

只跑一两个小项目、单机部署 → Docker + Docker Compose
就够了,轻量好上手。

团队协作、要上线、要高可用、要弹性扩缩 → 上 K8s。

初学者路线:先 Docker 入门(1-2 天)→ 再 K8s(概念多,慢慢啃)。

三、Docker 三件套:镜像 / 容器 / 仓库

3.1 镜像(Image)= 模板 / 安装盘

只读的模板,里面打包了代码、运行环境、系统库、配置文件。同一份镜像可以启动出
N 个一模一样的容器。

Dockerfile 示例:

FROM node:18-alpine # 基础镜像

WORKDIR /app

COPY package*.json ./

RUN npm install # 构建时安装依赖

COPY . .

EXPOSE 3000

CMD \”node\”, \”server.js\” # 容器启动命令

关键理解:RUN 是在构建镜像时执行;CMD 是在启动容器时执行。

3.2 容器(Container)= 镜像的运行实例

就像”类 vs 对象”的关系。容器是可写、有生命周期的(运行 / 停止 / 删除)。

docker build -t myapp:1.0 . # 用 Dockerfile 造镜像

docker run -d -p 8080:3000 myapp:1.0 # 启动容器,端口映射

docker ps # 看正在跑的容器

docker logs <容器id> # 看日志

docker exec -it <容器id> sh # 进容器里看看

3.3 仓库(Registry)= 镜像的”应用商店”

本地 build 好的镜像推上去,别人(和 K8s)就能拉下来用。公共仓库有 Docker
Hub(默认)、阿里云容器镜像服务(国内快);公司内网可用 Harbor。

docker tag myapp:1.0 registry.cn-chengdu.aliyuncs.com/myteam/myapp:1.0

docker push registry.cn-chengdu.aliyuncs.com/myteam/myapp:1.0

3.4 主线口诀

写 Dockerfile → build 出镜像 → run 成容器 → push 到仓库。Docker
的活就干完了,剩下的交给 K8s。

四、docker-compose:一条命令拉起一整套服务

4.1 为什么需要它

docker run 手动起容器,遇到”Web + 数据库 + 缓存 +
消息队列”就得敲四五条命令、记一堆参数。docker-compose
就是把它们写进一个文件,一条命令全起来。

4.2 典型场景:Node.js + MySQL + Redis

docker-compose.yml

version: “3.9”

services:

web:

build: . # 用当前目录 Dockerfile 构建

ports:

– “8080:3000”

environment:

– DB_HOST=mysql

– REDIS_HOST=redis

depends_on:

– mysql

– redis

restart: unless-stopped

mysql:

image: mysql:8.0

environment:

MYSQL_ROOT_PASSWORD: root123

MYSQL_DATABASE: myapp

volumes:

– mysql-data:/var/lib/mysql # 数据持久化

ports:

– “3306:3306”

redis:

image: redis:7-alpine

command: redis-server –requirepass redis123

volumes:

mysql-data: # 声明命名卷

4.3 四条救命命令

docker-compose up -d # 后台启动全部服务

docker-compose ps # 看状态

docker-compose logs -f web # 跟某个服务的日志

docker-compose down -v # 全停掉 + 顺带清掉卷

4.4 新手必踩的三个坑

depends_on 只管启动顺序,不管”就绪”。MySQL
容器起来了但数据库还没初始化完,Web
就连不上——解决:应用里加重试逻辑,或用 healthcheck。

容器之间用服务名当域名:mysql、redis 就是主机名,不用 IP。

数据一定要挂卷,否则 down 一次数据全没。

适用场景:docker-compose 适合开发环境、单机部署、CI
测试;一旦要多机、高可用、弹性伸缩,就该上 K8s。

五、K8s 部署一个真实项目(全流程)

假设要把一个 Node.js 服务部署成 3 个副本 + 对外可访问。

5.1 用 Deployment 声明”我要什么”

deploy.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

name: myapp

spec:

replicas: 3 # 要 3 个副本

selector:

matchLabels:

app: myapp

template: # Pod 模板

metadata:

labels:

app: myapp

spec:

containers:

– name: web

image: myapp:1.0

ports:

– containerPort: 3000

resources:

requests: {cpu: “100m”, memory: “128Mi”}

limits: {cpu: “500m”, memory: “512Mi”}

5.2 用 Service 给 Pod 一个固定入口

svc.yaml

apiVersion: v1

kind: Service

metadata:

name: myapp-svc

spec:

selector:

app: myapp # 自动找到带这个标签的 Pod

ports:

– port: 80 # 服务对外端口

targetPort: 3000 # 转发到 Pod 的端口

type: NodePort # 简单起见用 NodePort

5.3 三条命令搞定上线

kubectl apply -f deploy.yaml # 创建/更新部署

kubectl apply -f svc.yaml

kubectl get pods -l app=myapp # 看 3 个 Pod 是不是都 Running

kubectl get svc myapp-svc # 拿到端口,比如 8080

5.4 滚动更新 & 回滚

改了代码,build 出新镜像 myapp:2.0

kubectl set image deployment/myapp web=myapp:2.0

默认一个一个替换,用户全程无感知

kubectl rollout status deployment/myapp # 看更新进度

kubectl rollout undo deployment/myapp # 翻车了?一秒回滚

提示:标签(label)是 K8s 的粘合剂——Deployment 靠标签找 Pod
模板,Service 靠标签找后端 Pod,你靠标签筛选查看。搞懂 label,K8s
就通了一半。

六、K8s 进阶四件套

6.1 ConfigMap / Secret:把配置和镜像解耦

核心思想:镜像一份跑遍所有环境,变的是配置。开发 / 测试 /
生产用同一个镜像,只是数据库地址、日志级别不同。

ConfigMap 存非敏感配置(如环境变量、配置文件);Secret
存密码、token——注意它只是 Base64 编码,不是加密,kubectl get secret
-o yaml 就能看到明文。生产环境一定要开 RBAC
限制访问、加密静态存储,或对接外部密钥管理(如腾讯云 KMS、HashiCorp
Vault)。

6.2 Ingress:给 K8s 装个”智能路由器”

之前用 NodePort 访问,问题很多:端口随机、每个服务一个端口、没
HTTPS、没域名。Ingress 是集群入口的 7 层负载均衡 + 反向代理(相当于
Nginx)。

架构:用户浏览器 → 域名 → Ingress Controller(通常是 Nginx Pod)→
Ingress 规则(路由表)→ Service → Pod。前提:集群里得先装好 Ingress
Controller。

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

name: myapp-ingress

spec:

ingressClassName: nginx

tls:

– hosts: myapp.commyapp.commyapp.com

secretName: myapp-tls # TLS 证书存在 Secret 里

rules:

– host: myapp.com

http:

paths:

– path: /api

pathType: Prefix

backend:

service: {name: api-svc, port: {number: 80}}

– path: /

pathType: Prefix

backend:

service: {name: web-svc, port: {number: 80}}

6.3 Volume:容器的”硬盘”

容器本身是临时的——重启、重建就没了。数据库、日志、上传文件必须挂外部存储。

类型 用途 特点
emptyDir Pod 内多容器共享临时数据 Pod 删就没,纯临时
hostPath 挂宿主机目录 单机能用,不跨节点,不推荐生产
PersistentVolumeClaim 生产标准做法 用云盘/NAS,跟节点解耦

说明:PV 是”供给”,PVC 是”申请”,Pod 用 PVC。云环境里你只需要写
PVC,云厂商的 CSI 驱动会自动帮你把云盘接上。

七、kubectl vs docker 命令对照表

想做什么 Docker K8s(kubectl)
启动 docker run -d nginx kubectl run nginx –image=nginx
查看列表 docker ps kubectl get pods
看详情 docker inspect <id> kubectl describe pod <名>
看日志 docker logs <id> kubectl logs <pod名>
进容器 docker exec -it <id> sh kubectl exec -it <pod名> — sh
删掉 docker rm -f <id> kubectl delete pod <名>
构建 docker build -t app . (K8s 不负责构建,用 Docker)
状态监控 docker stats kubectl top pod

本质区别:Docker 命令操作的是”一个容器”,K8s
命令操作的是”一个期望状态”——你删掉一个 Pod,K8s
会立刻再建一个补上,因为 Deployment 说要 3 个。

八、学习路线与知识地图

8.1 完整知识地图

Docker:镜像 / 容器 / 仓库 → Dockerfile → docker-compose 多容器编排。

K8s 核心:Pod / Deployment / Service → ConfigMap / Secret → Ingress →
Volume / PVC → 下一步安全 / 运维 / 上云。

进阶(按需):RBAC 权限控制、HPA
自动伸缩、三种探针(liveness/readiness/startup)、资源配额、上云(腾讯云
TKE / 阿里云 ACK)。

8.2 推荐练习环境

本地:kind(Kubernetes IN Docker,轻量、起得快)或
minikube(单节点,官方 Basics 教程就用它)。

在线:Killercoda(浏览器里的交互式 K8s 场景)、Play with
Kubernetes(免费临时集群,无需安装)。

官方教程:Kubernetes Basics
六个浏览器模块,覆盖部署、探索、暴露、扩缩、更新,边学边敲真实 kubectl
命令。

8.3 学习建议

先跑通”镜像→容器→compose”,再上 K8s 核心对象,最后用真实项目走一遍
deploy + service + ingress + PVC 全流程。

命令别死记,重点是理解”期望状态 + 调和循环”这一设计思想,它解释了 K8s
大部分行为。

作者:ZCNIX
本文链接:https://blog.zcnix.com/docker-kubernetes-notes/
许可协议:CC BY-NC-SA 4.0
上一篇
下一篇