一、Kubernetes 简介

Kubernetes(简称 K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它旨在提供一个跨主机集群的容器调度、编排、高可用及自动化的平台,让开发者可以更专注于应用程序的开发,而无需过多关注底层基础设施的管理。

Kubernetes 具有强大的自愈能力、弹性伸缩、服务发现与负载均衡等特性,能够有效保障应用在复杂环境中的稳定运行。

图解 1:Kubernetes 作用示意

二、Kubernetes 核心组件

Kubernetes 集群由控制平面组件和节点组件组成,各组件协同工作以实现集群的各项功能。

(一)控制平面组件

  • kube-apiserver:所有操作的统一入口,提供 RESTful API,是集群中各个组件之间通信的枢纽。
  • etcd:集群数据的存储中心,保存着集群的所有状态信息。
  • kube-scheduler:负责 Pod 的调度,根据预定的调度策略为 Pod 选择合适的节点。
  • kube-controller-manager:运行各种控制器进程,如节点控制器、副本控制器等,确保集群的状态与期望状态一致。
  • cloud-controller-manager:与云服务提供商集成,用于管理云服务相关的资源。

(二)节点组件

  • kubelet:运行在每个节点上,确保容器按照 Pod 规范运行,负责与控制平面通信,汇报节点和容器的状态。
  • kube-proxy:维护节点网络规则,实现 Pod 之间以及 Pod 与外部网络的通信。
  • 容器运行时:负责运行容器,如 containerd、CRI-O 等,是 Kubernetes 与容器交互的接口。

图解 2:Kubernetes 核心组件架构

三、Kubernetes 安装方式

(一)使用 kubeadm 安装 Kubernetes 集群

前置条件
  • 至少 2 台 Ubuntu/CentOS 服务器(1 台 master,1 台或多台 node)
  • 每台服务器至少 2GB 内存,2 个 CPU
  • 服务器之间可以相互通信
  • 禁用 swap
  • 安装容器运行时(如 containerd)
在所有节点上执行

        1. 禁用 swap:

sudo swapoff -a
# 永久禁用 swap(重启生效)
sudo sed -i '/swap/s/^/#/' /etc/fstab

        2. 安装 containerd:

sudo apt-get update && sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd

        3. 安装 kubeadm、kubelet 和 kubectl:

sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
在 master 节点上执行

        1. 初始化集群:

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

        2. 配置 kubectl

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

        3. 安装网络插件(这里使用 flannel):

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.17.0/Documentation/kube-flannel.yml
在 worker 节点上执行

使用 kubeadm init 输出的 kubeadm join 命令,例如:

sudo kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
  --discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

如果忘记了 join 命令,可以在 master 节点上执行:

kubeadm token create --print-join-command

图解 3:kubeadm 安装集群流程

(二)安装 Minikube(单节点测试环境)

        1. 安装 Minikube:

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

        2. 启动 Minikube:

minikube start

        3. 验证集群状态:

minikube status

图解 4:Minikube 安装流程

四、kubectl 常用命令

kubectl 是 Kubernetes 的命令行工具,用于与 Kubernetes 集群进行交互。

        1. 查看集群信息:

kubectl cluster-info

        2. 查看节点:

kubectl get nodes
kubectl get nodes -o wide

        3. 查看命名空间:

kubectl get namespaces

        4. 查看所有资源:

kubectl get all --all-namespaces

        5. 查看 Pod:

kubectl get pods
kubectl get pods -n <namespace>

        6. 查看 Deployment:

kubectl get deployments

        7. 查看 Service:

kubectl get services

        8. 查看日志:

kubectl logs <pod-name>
kubectl logs -f <pod-name>  # 实时查看日志

        9. 进入 Pod:

kubectl exec -it <pod-name> -- /bin/bash

        10. 描述资源:

kubectl describe pod <pod-name>
kubectl describe deployment <deployment-name>

        11. 创建资源:

kubectl create -f <yaml-file>

        12. 应用资源配置:

kubectl apply -f <yaml-file>

        13. 删除资源:

kubectl delete pod <pod-name>
kubectl delete -f <yaml-file>

图解 5:kubectl 命令分类

五、核心资源对象

(一)Pod

Pod 是 Kubernetes 最小的部署单元,包含一个或多个容器,这些容器共享网络和存储资源。

创建 pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
spec:
  containers:
  - name: my-container
    image: nginx:alpine
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

应用配置:

kubectl apply -f pod.yaml

图解 6:Pod 结构示意

(二)Deployment

Deployment 用于管理 Pod 的创建和扩展,确保指定数量的 Pod 副本运行,并支持滚动更新和回滚。

创建 deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:alpine
        ports:
        - containerPort: 80

应用配置:

kubectl apply -f deployment.yaml

图解 7:Deployment 与 Pod 关系

(三)Service

Service 为 Pod 提供稳定的网络访问点,实现 Pod 之间的通信,即使 Pod 发生重建,Service 也能通过标签选择器找到新的 Pod。

创建 service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 80
  type: NodePort

应用配置:

kubectl apply -f service.yaml

图解 8:Service 工作原理

(四)ConfigMap 和 Secret

ConfigMap 用于存储非敏感的配置信息,Secret 用于存储敏感信息,如密码、密钥等。

创建 configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  app.properties: |
    environment=production
    log_level=info
  max_connections: "100"

创建 secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  username: YWRtaW4=  # base64 编码的 "admin"
  password: cGFzc3dvcmQ=  # base64 编码的 "password"

应用配置:

kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml

在 Pod 中使用:

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app-container
    image: my-app-image
    env:
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: username
    - name: LOG_LEVEL
      valueFrom:
        configMapKeyRef:
          name: my-config
          key: log_level
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
  - name: config-volume
    configMap:
      name: my-config

图解 9:ConfigMap 和 Secret 在 Pod 中的使用

六、存储配置

(一)PersistentVolume 和 PersistentVolumeClaim

PersistentVolume(PV)是集群中的一块存储,由管理员配置;PersistentVolumeClaim(PVC)是用户对存储的请求,PVC 可以绑定到 PV 上,实现存储的动态分配。

创建 pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /data/my-pv

创建 pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

在 Pod 中使用:

apiVersion: v1
kind: Pod
metadata:
  name: pv-pod
spec:
  containers:
  - name: pv-container
    image: nginx
    volumeMounts:
    - name: pv-storage
      mountPath: /data
  volumes:
  - name: pv-storage
    persistentVolumeClaim:
      claimName: my-pvc

图解 10:PV、PVC 与 Pod 关系

七、实际应用部署案例

部署一个完整的 Web 应用(前端 + 后端 + 数据库):

        1. 创建 mysql-secret.yaml(存储 MySQL 密码):

apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
type: Opaque
data:
  root-password: cGFzc3dvcmQxMjM=  # base64编码的"password123"

        2. 创建 mysql-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /data/mysql-pv

        3. 创建 mysql-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

        4. 创建 mysql-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: root-password
        - name: MYSQL_DATABASE
          value: myappdb
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql
  ports:
  - port: 3306
    targetPort: 3306
  clusterIP: None  # Headless service

        5. 创建 backend-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: my-backend-image:latest
        env:
        - name: DB_HOST
          value: mysql-service
        - name: DB_USER
          value: root
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: root-password
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: backend
  ports:
  - port: 8080
    targetPort: 8080

        6. 创建 frontend-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: my-frontend-image:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  selector:
    app: frontend
  ports:
  - port: 80
    targetPort: 80
  type: LoadBalancer

        7. 应用所有配置

kubectl apply -f mysql-secret.yaml
kubectl apply -f mysql-pv.yaml
kubectl apply -f mysql-pvc.yaml
kubectl apply -f mysql-deployment.yaml
kubectl apply -f backend-deployment.yaml
kubectl apply -f frontend-deployment.yaml

图解 11:完整 Web 应用部署架构

图解 12:Kubernetes 多环境部署架构图

八、Kubernetes 常见问题及解决方法

(一)节点状态为 NotReady

  • 问题现象:执行 kubectl get nodes 显示节点状态为 NotReady。
  • 可能原因:网络插件未安装或运行异常、kubelet 服务未启动、节点资源不足。
  • 解决方法
    • 检查网络插件状态,如 flannel 插件:kubectl get pods -n kube-system | grep flannel。
    • 重启 kubelet 服务:sudo systemctl restart kubelet。
    • 检查节点资源使用情况,确保内存和 CPU 未耗尽。

(二)Pod 处于 Pending 状态

  • 问题现象:Pod 长时间处于 Pending 状态,不调度到节点。
  • 可能原因:节点资源不足、节点亲和性设置不当、没有满足条件的节点。
  • 解决方法
    • 查看 Pod 事件:kubectl describe pod <pod-name> 寻找具体原因。
    • 检查节点资源是否充足:kubectl top nodes。
    • 调整 Pod 的资源请求或节点亲和性配置。

(三)Service 无法访问 Pod

  • 问题现象:通过 Service 无法访问后端 Pod。
  • 可能原因:Service 选择器与 Pod 标签不匹配、Pod 未就绪、网络策略限制。
  • 解决方法
    • 检查 Service 选择器和 Pod 标签是否一致:kubectl get service <service-name> -o yaml 和 kubectl get pods --show-labels。
    • 查看 Pod 状态是否为 Running 且就绪:kubectl get pods。
    • 检查是否有网络策略阻止访问:kubectl get networkpolicy。

九、总结

Kubernetes 作为容器编排领域的主流工具,为大规模容器化应用的管理提供了强大的支持。本文详细介绍了 Kubernetes 的核心组件、安装方式、kubectl 命令、核心资源对象、存储配置、实际应用部署案例以及常见问题解决方法,并通过 Mermaid 图解直观展示了相关概念和架构。

掌握 Kubernetes 需要不断实践,在实际使用中深入理解其设计理念和工作原理,才能更好地应对复杂的容器管理场景,充分发挥其自动化、高可用、可扩展的优势,为应用的稳定运行提供有力保障。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐