Skip to content
第 6 章 运维 ⏱ 13 分钟阅读

第 6 章:Kubernetes 入门 ​

学习目标 ​

  • 理解 Pod / Deployment / Service 模型
  • 学会 kubectl 基础命令
  • 部署第一个 Deployment 并暴露访问
  • 避开 YAML 陷阱和镜像拉取坑

一、核心概念速览 ​

资源作用
Pod最小调度单位,封装 1~N 个容器,共享网络和卷
DeploymentPod 的声明式控制器,管副本、滚动更新
Service给一组 Pod 固定 IP + DNS,负责负载均衡
Namespace集群内逻辑分区(类似文件夹)
ConfigMap / Secret配置 / 敏感配置
Ingress七层路由(类似 nginx server)
Node工作节点(运行 Pod 的机器)
Cluster一组 Node 的集合

二、安装 minikube(本地体验) ​

bash
# Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

minikube start --driver=docker    # 用 docker 驱动
minikube status
minikube dashboard                 # 开 Web 面板

# 装 kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install kubectl /usr/local/bin/

kubectl version --client

⚠️ 坑 1:Windows 上 minikube 用 --driver=hyperv 或 virtualbox 性能差,推荐 WSL2 + --driver=docker。Mac 用 hyperkit 或 docker。

三、kubectl 核心命令 ​

bash
kubectl get nodes                      # 看节点
kubectl get pods                       # 当前 namespace 的 Pod
kubectl get pods -A                    # 所有 namespace
kubectl get svc                        # 看 Service
kubectl get deploy                     # 看 Deployment

kubectl apply -f app.yaml              # 声明式部署
kubectl delete -f app.yaml             # 按文件删
kubectl delete pod myapp-xxx           # 删 Pod(自动重建)

kubectl describe pod myapp-xxx         # 详情(events 必看)
kubectl logs myapp-xxx                 # 日志
kubectl logs -f myapp-xxx              # 实时
kubectl logs myapp-xxx -c sidecar      # 多容器时指定
kubectl exec -it myapp-xxx -- bash     # 进 Pod

kubectl scale deploy/myapp --replicas=5    # 扩缩容
kubectl rollout status deploy/myapp       # 看滚动更新状态
kubectl rollout undo deploy/myapp         # 回滚上一版
kubectl rollout history deploy/myapp      # 历史

# 常用 -o
kubectl get pods -o wide               # 看 IP 和所在 Node
kubectl get pods -o yaml               # YAML 格式
kubectl get pods -o jsonpath='{...}'   # 提取字段

⚠️ 坑 2:kubectl 默认读 ~/.kube/config 找集群。切多集群用 kubectl config use-context minikube 或环境变量 KUBECONFIG=other-config。

四、第一个 Deployment ​

yaml
# app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 3                          # 3 个副本
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: web
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 64Mi
          limits:
            cpu: 500m
            memory: 256Mi
        readinessProbe:                # 就绪探针
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 5
bash
kubectl apply -f app.yaml
kubectl get pods -o wide              # 3 个 Running
kubectl describe deploy myapp         # 看 Events

五、暴露 Service ​

yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  type: ClusterIP                    # 仅集群内访问
  selector:
    app: myapp                        # 匹配 Pod 标签
  ports:
  - port: 80
    targetPort: 80
bash
kubectl apply -f service.yaml
kubectl get svc myapp                 # 看 CLUSTER-IP 和 PORT
kubectl get endpoints myapp           # 看后端 Pod 列表

# 集群内访问
kubectl run tmp --rm -it --image=alpine -- wget -qO- myapp.default.svc.cluster.local

⚠️ 坑 3:selector 写错 → Endpoints 为空,流量没人接,curl 超时。labels 必须跟 Pod template 的 labels 完全一致。 ⚠️ 坑 4:Service type: ClusterIP 仅集群内可达,集群外访问不了。要外网用 NodePort、LoadBalancer 或 Ingress。

六、ConfigMap 和 Secret ​

bash
# ConfigMap
kubectl create configmap app-config \
  --from-literal=DB_HOST=mysql \
  --from-literal=DB_PORT=3306

# Secret(自动 base64)
kubectl create secret generic app-secret \
  --from-literal=DB_USER=admin \
  --from-literal=DB_PWD=secret123
yaml
# 用环境变量注入
spec:
  containers:
  - name: web
    env:
    - name: DB_HOST
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: DB_HOST
    - name: DB_PWD
      valueFrom:
        secretKeyRef:
          name: app-secret
          key: DB_PWD

⚠️ 坑 5:Secret 默认只是 base64 编码,不是加密。真正高安全要开 EncryptionConfiguration + KMS。看 kubectl get secret xxx -o yaml 是 base64 不是明文,容易误以为加密。

七、Namespace 与上下文 ​

bash
kubectl create ns dev
kubectl create ns prod

# 在指定 namespace
kubectl -n dev get pods
kubectl config set-context --current --namespace=dev    # 切默认

# 限额(默认 namespace 必须有,否则 Pod 跑不起来)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: dev
spec:
  limits:
  - default:
      cpu: 500m
      memory: 512Mi
EOF

⚠️ 坑 6:建 namespace 不设 LimitRange,Pod 写了 resources: {} 或根本没写,可能被调度到无资源的 Node 上。生产每个 namespace 必须设。

八、NodePort 暴露外网 ​

yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-nodeport
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080                  # 范围 30000-32767
bash
minikube service myapp-nodeport    # minikube 快捷打开浏览器
# 或 curl http://$(minikube ip):30080

九、本章小结 ​

操作命令 / 资源
看资源kubectl get
改配置kubectl apply -f
排查describe / logs
副本数Deployment.spec.replicas
访问Service (ClusterIP / NodePort / LoadBalancer)
配置ConfigMap / Secret

动手练习 ​

  1. minikube start 并 kubectl get nodes 看到 Ready
  2. 部署 nginx Deployment(replicas=3),get pods 看到 3 个 Running
  3. 创建 Service ClusterIP,集群内用 wget 访问成功
  4. 改成 NodePort,浏览器通过 minikube ip:30080 访问成功
  5. 用 kubectl scale deploy/myapp --replicas=5 扩容,验证 Pod 数变化

下一章:第 7 章:K8s 部署实战 →

本站基于 VitePress 构建 · 由 StackHub 团队维护