Kind

2020-10-03T14:11:02+08:00 | 5分钟阅读 | 更新于 2020-10-03T14:11:02+08:00

@

学习目标

学完本章你应该能够:

  1. 讲清 kind 是什么:用 Docker 容器当节点的「伪集群」,适合资源有限的本地学习环境。
  2. 写一份 kind.yaml 配置:多节点(1 control-plane + 2 worker)、ingress 端口映射、私有镜像仓库接入。
  3. 用 kind 起集群并把一个本地镜像(如 nginx)跑起来,通过 NodePort 从宿主机访问。
  4. 在同事面前把「为什么本地要用 kind 而不是 minikube」讲清楚取舍。

前置知识

  • 已安装 Docker 与 kubectl
  • 知道 Pod / Deployment / Service 是 K8s 基本资源(哪怕只在别处看过)
  • 建议配合「容器和 k8s 入门」一起看,那里讲了 kind 的完整搭建脚本

本章你会动手做的事

  1. 用文末 kind.yaml kind create cluster 起一个 3 节点集群。
  2. 把 nginx 的 Deployment + NodePort Service apply 起来,从宿主机 curl 通。
  3. 故意多映射一个端口,观察 extraPortMappings 怎么把节点容器端口暴露到宿主机。

一、Kind 集群长什么样

类比:kind 就像「用乐高积木拼出一座 mini 城市」——每个 Docker 容器是一块积木,kind 把它们拼成 control-plane(市政府)和 worker(各个街区),外面用 extraPortMappings 打通「城市道路」让你从宿主机的浏览器进城。比起真在云上开几台虚拟机,这城市零成本、说拆就拆。

下面这张图把「1 个 control-plane + 2 个 worker + 端口映射」的拓扑画出来:

flowchart LR
    CP[control-plane
ingress-ready=true] --> W1[worker] CP --> W2[worker] subgraph 端口映射[extraPortMappings] M[80 / 443 / 30080-30090 / 31272
容器端口 → 宿主机端口] end CP --- M

二、Kind 的 yaml 配置文件

下面这份是完整的 kind.yaml。逐行看可能晕,先抓主干:nodes 定义几个节点、containerdConfigPatches 给节点配镜像加速、extraPortMappings 把节点内端口暴露到宿主机。

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
containerdConfigPatches:
  - |-
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
      endpoint = ["https://ustc-edu-cn.mirror.aliyuncs.com", "https://ccr.ccs.tencentyun.com", "https://docker.m.daocloud.io"]    
nodes:
  - role: control-plane
    kubeadmConfigPatches:
      - |
        kind: InitConfiguration
        nodeRegistration:
          kubeletExtraArgs:
            node-labels: "ingress-ready=true"        
    extraPortMappings:
      - containerPort: 30080
        hostPort: 30080
        protocol: TCP
      - containerPort: 30081
        hostPort: 30081
        protocol: TCP
      - containerPort: 30082
        hostPort: 30082
        protocol: TCP
      - containerPort: 30083
        hostPort: 30083
        protocol: TCP
      - containerPort: 30084
        hostPort: 30084
        protocol: TCP
      - containerPort: 30085
        hostPort: 30085
        protocol: TCP
      - containerPort: 30086
        hostPort: 30086
        protocol: TCP
      - containerPort: 30087
        hostPort: 30087
        protocol: TCP
      - containerPort: 30088
        hostPort: 30088
        protocol: TCP
      - containerPort: 30089
        hostPort: 30089
        protocol: TCP
      - containerPort: 30090
        hostPort: 30090
        protocol: TCP
      - containerPort: 31272
        hostPort: 31272
        protocol: TCP
      - containerPort: 80
        hostPort: 80
        protocol: TCP
      - containerPort: 443
        hostPort: 443
        protocol: TCP
  - role: worker
  - role: worker

几个关键点(按「步骤」拆开看):

  • 步骤 1:control-plane 打 ingress-ready=true 标签 —— 这是给 ingress-nginx 用的;ingress controller 只会调度到带这个标签的节点上当「入口」。
  • 步骤 2:extraPortMappings 端口映射 —— 把节点容器里的端口(如 30080)映射到宿主机同号端口,这样你在本机浏览器 localhost:30080 就能访问到集群内的服务。
  • 步骤 3:containerdConfigPatches 镜像加速 —— 给容器运行时配国内镜像源,拉 docker.io 的镜像更快,否则 kind 起集群会卡在拉镜像。
  • 步骤 4:2 个 worker —— 加上 control-plane,凑成「1 控制面 + 2 工作节点」的真实多节点感,才能演练调度。

起集群的命令(同样按步骤拆):

# 步骤 1:用上面的配置创建名为 dev 的集群
kind create cluster --config kind.yaml --name dev

# 步骤 2:验证节点都就绪
kubectl get nodes

# 步骤 3:装 ingress-nginx(它会找 ingress-ready 标签的节点)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

三、安装 nginx 测试集群

先用一个最朴素的 nginx 验证「镜像能跑、端口能通」。

类比:NodePort 像是给每栋楼(节点)统一开了一个「对外营业的旁门」——你不用知道楼里哪个房间(Pod)在处理,只要敲这个固定门牌号(30080),请求就会被转发进去。

下面把「宿主机 → NodePort → Pod」的转发链画出来:

flowchart LR
    U[宿主机浏览器
curl localhost:30080] --> NP[NodePort 30080
Service nginx-nodeport] NP --> P1[Pod nginx] NP --> P2[Pod nginx]
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.22
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080 # 可以指定一个端口号,如果不指定,会自动分配一个

⚠️ 新手必踩的坑:NodePort 端口范围 + extraPortMappings 是两回事。K8s 的 NodePort 默认只允许 30000–32767 区间,本文 nodePort: 30080 落在区间里没问题。但 extraPortMappings 是把节点容器的端口映射到宿主机(kind 特有),和 Service 的 nodePort 是两个不同层面——前者让「宿主机↔节点容器」通,后者让「集群内 Service↔Pod」通,别混为一谈。另外 M1/M2 Mac 上要 docker buildx build --platform linux/arm64 构建镜像,否则跑 amd64 镜像会因 QEMU 模拟很慢。

跑起来后验证:

# 步骤 1:部署 Deployment + Service
kubectl apply -f nginx.yaml

# 步骤 2:等 Pod 都 Running
kubectl get pods -l app=nginx

# 步骤 3:从宿主机访问 NodePort
curl localhost:30080

自测题与动手练习

自测题(合上书能答出来,才算懂)

  1. kind 用的是什么来模拟 K8s 节点?为什么它比在云上开真虚拟机更适合本地学习?
  2. extraPortMappings 把端口映射到了哪一层(宿主机 ↔ 节点容器),它和 Service 的 nodePort 是一回事吗?
  3. control-plane 上打的 ingress-ready=true 标签是给谁用的?为什么 ingress controller 需要它?
  4. 文末 nginx 用 NodePort 暴露,nodePort: 30080 落在 K8s 允许的端口区间里吗?
  5. 起完集群后 kubectl get nodes 看到 worker 是 Ready,但 Pod 一直 Pending,最可能缺什么(提示:看本文资源声明与调度)?

动手练习(建议真做一遍)

  1. 用文末 kind.yaml 起集群,kubectl get nodes 确认 1 个 control-plane + 2 个 worker 都 Ready。
  2. apply nginx 的 Deployment + NodePort Service,从宿主机 curl localhost:30080 验证能拿到 nginx 默认页。
  3. kind.yaml 多加一个 extraPortMappings(比如 30091→30091),kind delete cluster 重建后 curl 新端口,理解映射机制。

本章小结

  • kind 用 Docker 容器模拟 K8s 节点,1 个 control-plane + 2 个 worker 即可在笔记本上跑出「多节点调度」的真实感,零成本、易销毁。
  • extraPortMappings 负责把节点容器端口暴露到宿主机,和 Service 的 nodePort 是两个不同层面,调试时别混淆。
  • ingress 需要 control-plane 打 ingress-ready=true 标签,再 apply ingress-nginx 才能接管 80/443。
  • 下一步可回到「容器和 k8s 入门」用这份 kind 集群跑通 Helm / Kustomize 交付的应用。
About Me

没什么想介绍的,一个很大众的码农…

喜欢代码,车,马,真的是 🐎

讨厌别人让我给自己的代码写注释 最厌烦别人的程序没有写注释

目标

学AI,加油!加油!