K8s入门必看:核心概念与实践操作

K8s入门必看:核心概念与实践操作

Kubernetes (通常简称为 K8s) 已经成为容器编排领域的事实标准。对于任何希望进入云计算、DevOps 或微服务领域的开发者和运维工程师来说,掌握 Kubernetes 都是一项必备技能。本文将深入浅出地介绍 Kubernetes 的核心概念,并通过实践操作帮助你快速入门。

一、为什么需要 Kubernetes?

在容器技术(如 Docker)普及之前,应用的部署和管理面临诸多挑战:

  • 资源利用率低: 传统虚拟机部署方式,每个应用独占一个虚拟机,资源浪费严重。
  • 环境一致性差: 开发、测试、生产环境配置差异导致“在我机器上可以运行”的问题。
  • 手动运维复杂: 应用扩容、缩容、故障恢复都需要手动操作,效率低下且容易出错。
  • 缺乏弹性伸缩: 无法根据应用负载自动调整资源,难以应对突发流量。

容器技术解决了环境一致性的问题,但随着应用规模的扩大,容器的编排和管理又成为新的难题。Kubernetes 应运而生,它提供了以下关键能力:

  • 自动化容器编排: 自动部署、调度、管理容器化应用。
  • 服务发现和负载均衡: 自动发现集群内的服务,并在多个容器实例之间分配流量。
  • 自动扩缩容: 根据应用负载自动调整容器实例数量。
  • 自我修复: 自动重启失败的容器,替换不健康的节点。
  • 滚动更新和回滚: 以零停机时间的方式更新应用,并支持快速回滚。
  • 配置管理和密钥管理: 集中管理应用的配置信息和敏感数据。
  • 存储编排: 支持多种存储方案,为容器提供持久化存储。

二、Kubernetes 核心概念

Kubernetes 的架构相对复杂,但理解其核心概念是入门的关键。下面我们将逐一介绍这些概念,并尽量用通俗易懂的语言解释。

2.1. 集群(Cluster)

Kubernetes 集群由多个节点(Node)组成,这些节点可以是物理机或虚拟机。集群是 Kubernetes 管理和运行容器化应用的平台。

  • 控制平面(Control Plane): 集群的大脑,负责管理整个集群的状态,包括调度、资源管理、故障检测等。
  • 节点(Node): 集群中的工作机器,运行容器化应用。每个节点上都运行着一些必要的组件。

2.2. 控制平面组件

控制平面由多个组件组成,每个组件负责不同的功能:

  • kube-apiserver: 集群的 API 服务器,是所有组件交互的中心。所有对集群的操作都通过 API Server 进行。
  • kube-scheduler: 调度器,负责将 Pod 调度到合适的节点上运行。调度策略考虑多种因素,如资源需求、节点负载、亲和性/反亲和性等。
  • kube-controller-manager: 控制器管理器,运行多个控制器进程。每个控制器负责监控集群的特定资源,并确保其达到期望状态。例如,节点控制器负责监控节点状态,副本控制器负责维护 Pod 的副本数量。
  • etcd: 分布式键值存储,用于保存集群的所有配置数据和状态信息。etcd 的高可用性和一致性对集群的稳定性至关重要。

2.3. 节点组件

每个节点上都运行着以下组件:

  • kubelet: 节点代理,负责与控制平面通信,管理节点上的 Pod 和容器。它接收来自 API Server 的指令,创建、启动、停止和监控容器。
  • kube-proxy: 网络代理,负责实现 Kubernetes 的服务发现和负载均衡。它通过 iptables 或 IPVS 等技术将服务的流量转发到正确的 Pod。
  • 容器运行时(Container Runtime): 负责运行容器的软件,例如 Docker、containerd 或 CRI-O。kubelet 通过容器运行时接口(CRI)与容器运行时交互。

2.4. Pod

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

  • 共享网络: Pod 内的容器共享同一个网络命名空间,它们可以通过 localhost 互相访问。
  • 共享存储: Pod 内的容器可以共享同一个存储卷(Volume),实现数据共享。
  • 生命周期一致: Pod 内的所有容器作为一个整体进行调度和管理,它们要么同时运行,要么同时停止。

通常,一个 Pod 只运行一个主容器,以及一些辅助容器(如日志收集器、监控代理等)。

2.5. ReplicaSet

ReplicaSet 用于确保指定数量的 Pod 副本始终运行。如果某个 Pod 失败或被删除,ReplicaSet 会自动创建一个新的 Pod 来替代。

ReplicaSet 通过标签选择器(Label Selector)来识别和管理 Pod。标签是附加到 Kubernetes 对象(如 Pod、Service 等)上的键值对,用于标识和分组对象。

2.6. Deployment

Deployment 是更高级别的控制器,它构建在 ReplicaSet 之上,提供了滚动更新、回滚、版本控制等功能。

通过 Deployment,你可以声明式地定义应用的期望状态,例如:

  • 运行多少个 Pod 副本
  • 使用哪个镜像版本
  • 更新策略(滚动更新或重新创建)

Deployment 会自动创建和管理 ReplicaSet,并根据你的配置逐步更新 Pod,确保应用的平滑升级。

2.7. Service

Service 为一组 Pod 提供了一个稳定的访问入口。由于 Pod 的 IP 地址可能会发生变化(例如 Pod 重启或重新调度),因此直接访问 Pod 的 IP 地址是不可靠的。

Service 通过标签选择器来关联一组 Pod,并为它们提供一个固定的虚拟 IP 地址(Cluster IP)和 DNS 名称。客户端可以通过 Service 的 IP 地址或 DNS 名称访问 Pod,而无需关心 Pod 的具体位置和数量。

Kubernetes 支持多种类型的 Service:

  • ClusterIP: 默认类型,Service 仅在集群内部可访问。
  • NodePort: 在每个节点的固定端口上暴露 Service,可以通过 <NodeIP>:<NodePort> 访问 Service。
  • LoadBalancer: 使用云提供商的负载均衡器将 Service 暴露到集群外部。
  • ExternalName: 将 Service 映射到集群外部的 DNS 名称。

2.8. Namespace

Namespace 用于将集群资源划分为多个虚拟集群,实现资源隔离和多租户管理。

通过 Namespace,你可以:

  • 将不同团队或项目的资源隔离到不同的命名空间中。
  • 对每个命名空间设置资源配额和访问控制策略。
  • 避免不同命名空间中的对象名称冲突。

Kubernetes 默认创建了几个命名空间:

  • default: 默认命名空间,未指定命名空间的对象都属于此命名空间。
  • kube-system: Kubernetes 系统组件所在的命名空间。
  • kube-public: 包含集群的公共资源,所有用户(包括未认证用户)都可以读取。

2.9. ConfigMap 和 Secret

ConfigMap 和 Secret 用于管理应用的配置信息和敏感数据。

  • ConfigMap: 用于存储非敏感的配置数据,例如应用的配置文件、环境变量等。
  • Secret: 用于存储敏感数据,例如密码、API 密钥、证书等。Secret 中的数据会进行 Base64 编码,但并非加密。

通过 ConfigMap 和 Secret,你可以将配置数据与应用代码解耦,方便配置的更新和管理。

2.10. Volume

Volume 为 Pod 提供持久化存储。Pod 中的容器可以挂载一个或多个 Volume,实现数据的持久化和共享。

Kubernetes 支持多种类型的 Volume:

  • emptyDir: 临时存储,Pod 删除时数据也会被删除。
  • hostPath: 将节点上的文件或目录挂载到 Pod 中。
  • PersistentVolume (PV) 和 PersistentVolumeClaim (PVC): 用于提供持久化存储。PV 是集群管理员预先配置的存储资源,PVC 是用户对存储资源的申请。

2.11. Ingress

Ingress 是 Kubernetes 集群的入口,它充当反向代理和负载均衡器,将外部流量路由到集群内的 Service。

Ingress 通过 Ingress Controller 实现,Ingress Controller 监听 Ingress 资源的变化,并根据规则配置负载均衡器。

常用的 Ingress Controller 有:

  • Nginx Ingress Controller
  • Traefik
  • HAProxy Ingress

三、Kubernetes 实践操作

了解了核心概念之后,让我们通过一些实践操作来加深理解。

3.1. 安装 Minikube

Minikube 是一个轻量级的 Kubernetes 发行版,可以在本地机器上快速搭建单节点的 Kubernetes 集群,非常适合学习和开发测试。

安装 Minikube 的步骤如下(以 macOS 为例):

  1. 安装 Docker Desktop
  2. 使用 Homebrew 安装 Minikube:

bash
brew install minikube

3. 启动一个 Minikube 集群, 使用的驱动是docker:

bash
minikube start --driver=docker

3.2. 部署第一个应用

我们将部署一个简单的 Nginx 应用来演示 Kubernetes 的基本操作。

  1. 创建一个名为 nginx-deployment.yaml 的文件,内容如下:

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

这个文件定义了一个名为 nginx-deployment 的 Deployment,它将创建 3 个 Nginx Pod 副本,每个 Pod 运行一个 Nginx 容器,监听 80 端口。

  1. 使用 kubectl apply 命令部署应用:

bash
kubectl apply -f nginx-deployment.yaml

  1. 查看 Deployment 状态:

bash
kubectl get deployments

  1. 查看 Pod 状态:

bash
kubectl get pods

  1. 创建一个名为 nginx-service.yaml 的文件,内容如下:

yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort

这个文件定义了一个类型为NodePort的Service。

  1. 使用 kubectl apply 命令创建服务:

bash
kubectl apply -f nginx-service.yaml

  1. 获取 Service 的访问地址:

bash
minikube service nginx-service --url

这条命令会输出service的访问地址,复制并在浏览器打开就可以访问 Nginx 默认页面了。

3.3. 滚动更新

现在,让我们尝试更新 Nginx 镜像的版本。

  1. 修改 nginx-deployment.yaml 文件,将 image 字段改为 nginx:1.23.4

  2. 再次使用 kubectl apply 命令应用更改:

bash
kubectl apply -f nginx-deployment.yaml

  1. 观察 Deployment 的更新过程:

bash
kubectl rollout status deployment/nginx-deployment

Kubernetes 会逐步更新 Pod,确保应用的平滑升级。

3.4. 扩缩容

我们可以通过修改 Deployment 的 replicas 字段来调整 Pod 的副本数量。

  1. nginx-deployment.yaml 文件中的 replicas 字段改为 5。

  2. 使用 kubectl apply 命令应用更改:

bash
kubectl apply -f nginx-deployment.yaml

Kubernetes 会自动创建新的 Pod,将副本数量扩展到 5。

同样,我们可以将 replicas 字段改回 3,Kubernetes 会自动删除多余的 Pod,实现缩容。

3.5. 使用 ConfigMap

让我们创建一个 ConfigMap 来存储 Nginx 的自定义配置。

  1. 创建一个名为 nginx-config.yaml 的文件,内容如下:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default.conf: |
server {
listen 80;
server_name localhost;

  location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    add_header Custom-Header "Hello from ConfigMap";
  }
}

```

这个 ConfigMap 包含了一个名为 default.conf 的键,其值为自定义的 Nginx 配置文件。

  1. 使用 kubectl apply 命令创建 ConfigMap:

bash
kubectl apply -f nginx-config.yaml

  1. 修改 nginx-deployment.yaml 文件,添加 volumesvolumeMounts 字段:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.23.4 # 使用之前的版本
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: nginx-config-volume
configMap:
name: nginx-config

这里我们将 ConfigMap 中的 default.conf 文件挂载到 Nginx 容器的 /etc/nginx/conf.d 目录,覆盖默认的配置文件。

  1. 再次使用 kubectl apply 命令应用更改:

bash
kubectl apply -f nginx-deployment.yaml

  1. 访问nginx页面,在响应头中就能看到自定义的header了。

四、总结

本文详细介绍了 Kubernetes 的核心概念,并通过实践操作演示了如何部署、更新、扩缩容应用,以及如何使用 ConfigMap 管理配置。希望通过这篇文章,你能够对 Kubernetes 有一个初步的了解,并能够开始你的 Kubernetes 学习之旅。

当然,Kubernetes 的内容远不止这些,还有许多高级特性和概念等待你去探索,例如:

  • StatefulSet: 用于管理有状态应用(如数据库)的部署和扩展。
  • DaemonSet: 确保每个节点上都运行一个 Pod 副本,常用于部署节点级别的代理或监控工具。
  • Job 和 CronJob: 用于运行一次性任务或定时任务。
  • Horizontal Pod Autoscaler (HPA): 根据 CPU 利用率或其他指标自动调整 Pod 副本数量。
  • RBAC (Role-Based Access Control): 基于角色的访问控制,用于管理集群的权限。
  • Network Policy: 用于控制 Pod 之间的网络访问。
  • Custom Resource Definitions (CRD): 用于扩展 Kubernetes API,自定义资源类型。

建议你继续深入学习 Kubernetes 的官方文档,并结合实际项目进行实践,不断提升你的 Kubernetes 技能。

THE END