1.背景介绍
1.1 谈一谈docker容器优缺点
1.1.1 docker 容器概述
** **容器是一种轻量级、独立的可执行软件包,包含了运行应用程序所需的所有必要组件,包括代码、运行时、库和配置文件。容器与虚拟机不同,它们共享主机操作系统的内核,因此占用的资源更少,启动速度更快。
** 容器是一种特殊的进程,它通过约束和修改进程的动态表现,让容器表现出类似虚拟机的功能。其中Cgroups技术用来约束CPU、内存、磁盘、网络带宽等大小 ;Namespace技术则用来修改进程视图,让运行在容器中的进程只能看到Namespace里挂载的目录、文件和网络设备;**
** **在 Docker 中,rootfs是指容器的根文件系统,它包含了运行容器所需的所有文件和目录,用来为容器进程提供隔离后执行环境的文件系统 。rootfs 是由 Docker 镜像中的各个层次叠加而成的。Docker 使用联合文件系统(如 OverlayFS、AUFS 或 Btrfs)来实现 rootfs ,rootfs 的存在实现了无论在本地、云端,还是在一台任何地方的机器上,用户只需要解压打包好的容器镜像,那么这个应用运行所需要的完整的执行环境就被重现出来了。
** **从上可见,docker 容器是由Linux Namespace、Linux Cgroups和rootfs三种技术构建出来的进程的隔离环境,它的最大的优点就是解决开发人员打包应用及其依赖管理问题,并在任何环境中一致地运行。
1.1.2 Docker 的局限性
Docker 在开发和单机环境中非常高效,但在生产环境中运行和管理大量容器时会遇到一些问题
- 隔离性导致需要协作的一些应用工作较为困难。
- 容器数量增加时,手动管理复杂,成本加大
- 编排能力较弱,docker-compose 主要用于单个主机上定义和管理多个容器的应用程序,适用于小规模部署
- 缺乏一些自动扩展、负载均衡、故障恢复等高级功能。
1.2 Kubernetes 概述
Kubernetes,简称 K8S,是由 Google 开发并开源的容器编排平台。它用于自动化部署、扩展和管理容器化应用程序。Kubernetes 提供了一个灵活的架构,使得应用程序可以在不同的环境中运行,包括物理机、虚拟机和云环境。
** 相对于Docker的局限性,k8s 是为用户提供一个具有普遍意义的容器编排工具,是按照用户的意愿和整个系统的规则,完全自动化地处理好容器之间的各种关系,另外还给用户提供了路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。
2. kubernetes基本架构
Kubernetes 采用主从架构,主要组件包括:
2.1. Master 组件
- API Server\:处理所有的 RESTful API 请求,是集群的入口。**
- Controller Manager:负责集群状态的管理,例如故障检测、自动修复、伸缩等。**
- Scheduler:负责将 Pod 分配到合适的 Node 上运行。**
- etcd:分布式键值存储,用于保存集群的所有配置信息和状态数据。**
2.2. Node 组件
- Kubelet**:负责与 Master 组件通信,管理 Pod 的生命周期。**
- Kube-Proxy**:实现 Kubernetes Service 的网络代理和负载均衡。**
- Container Runtime**:用于运行容器,例如 Docker、containerd 等。**
3.Kubernetes 的核心概念
3.1 K8s 中节点与集群
3.1.1 Node
Node 是 Kubernetes 集群中的工作节点,它可以是物理机或虚拟机。每个 Node 上都运行着一个 Kubelet 进程,用于与 Kubernetes 控制平面通信,以及容器运行时(如 Docker)用于管理容器。
3.1.2. Cluster
Cluster 是一组 Node 的集合,它们共同工作以运行容器化应用程序。Kubernetes 集群通常由一个或多个 Master 节点和若干 Worker 节点组成。
3.1.3. Namespace
Namespace 是 Kubernetes 中用于资源隔离的机制。它允许在同一个集群中创建多个隔离的环境,每个环境可以包含独立的资源、对象和策略。
3.2 K8s 中 API对象
Kubernetes(k8s) API 对象是 Kubernetes 系统中的核心概念。它们是以资源的形式定义的,可以通过 Kubernetes API 进行操作。这些对象使得 Kubernetes 可以以声明式的方式管理和编排容器化应用,以下是 Kubernetes 中一些常见的 API 对象及其详细介绍
3.2.1 Pod
Pod 是 Kubernetes 中的最小部署单元,一个 Pod 可以包含一个或多个容器,这些容器共享网络和存储资源。Pod 通常用于运行一个应用或一个应用的一个实例。****pod 主要解决多应用联合运行的问题,同时还要不破坏容器的隔离
3.2.2 ReplicaSet
ReplicaSet 确保指定数量的 Pod 副本在任何时间点都在运行,它可以自动替换失败的 Pods 以保持所需的副本数。
3.2.3. Deployment
Deployment 是 Kubernetes 中用于管理应用程序部署的控制器。它定义了应用的期望状态,并确保集群中的实际状态与期望状态一致。Deployment 支持滚动更新、回滚等操作。
3.2.4 Service
Service 是 Kubernetes 中用于定义一组 Pod 的访问策略的抽象。它为一组 Pod 提供一个单一的访问入口,并实现负载均衡。
3.2.5 Ingress
Ingress 是一种 API 对象,用于管理外部访问到集群中服务的 HTTP 和 HTTPS 路由。它提供了基于规则的路由能力,使用户可以使用单一 IP 地址来暴露多个服务
3.2.6 Job
Job 是一种 Kubernetes 对象,负责创建一个或多个 Pods,并确保这些 Pods 成功完成指定的任务。Job 通常用于一次性任务和批处理任务。
3.2.7 StatefulSet
StatefulSet 是一种工作负载 API 对象,用于管理有状态应用程序。与 Deployment 不同,StatefulSet 为每个 Pod 维护唯一标识,使其在重启、升级等操作中保持稳定的网络标识和存储
3.2.8 DaemonSet
DaemonSet 是一种工作负载 API 对象,确保每个(或指定的)节点上运行一个 Pod 副本。它通常用于运行集群范围的系统守护进程,例如日志收集器、监控代理等。
3.2.9 ConfigMap
ConfigMap 是一种 Kubernetes API 对象,用于在 Pod 中存储和管理配置数据。它可以将配置数据以环境变量、命令行参数或配置文件的形式注入到容器中。
3.2.10 Secret
Secret 是一种 Kubernetes API 对象,用于存储和管理敏感信息,例如密码、令牌和密钥。与 ConfigMap 类似,但 Secret 数据是以 base64 编码存储的,确保其在传输和存储过程中得到保护
4.Kubernetes 工作流程
1.用户提交应用配置:用户通过命令行工具(如 **kubectl
)或者 lens 控制台提交应用程序的配置文件(YAML 或 JSON 格式),这些文件定义了应用程序的期望状态。
2.API Server 接收请求:API Server 是 Kubernetes 集群的主要管理组件,负责接收、验证和处理所有的 REST API 请求。**
3.存储到 etcd:API Server 将应用程序的期望状态存储到 **etcd
中,etcd
是一个分布式键值存储,用于保存集群的所有配置信息和状态数据。
4.调度器调度 Pod:调度器(Scheduler)监控未被分配的 Pods,根据资源需求和策略将 Pods 分配到合适的节点上。**
5.Kubelet 管理 Pod 生命周期:每个节点上运行的 Kubelet 负责与 API Server 交互,获取该节点上需要运行的 Pod 配置,并管理 Pod 的创建、更新和销毁。
6.容器运行时启动容器:Kubelet 与容器运行时(如 Docker、containerd)交互,拉取容器镜像并启动容器。
7.持续监控和调整:控制器管理器(Controller Manager)持续监控集群状态,确保实际状态符合期望状态,并在必要时进行调整,例如重启失败的容器、扩展/缩减副本等
5.Kubernetes 网络
5.1Kubernetes 网络模型
Kubernetes 网络模型定义了网络的基本原则
每个 Pod 都有一个唯一的 IP 地址:Pod 在其生命周期内拥有一个独立的 IP 地址,Pod 之间可以通过 IP 地址直接通信,不需要使用 NAT(网络地址转换)。
所有 Pod 都在一个扁平的网络空间中:Pod 可以直接相互访问,无需通过中间代理。
容器之间共享一个网络命名空间: 同一 Pod 中的容器共享一个网络命名空间,包括 IP 地址和端口。
5.2 服务发现和负载均衡
Kubernetes 中的服务(Service)提供了一种抽象,定义了一组逻辑上相关的 Pod,并且能够在 Pod 之间实现负载均衡。
- ClusterIP**:默认类型的服务,分配一个集群内部可访问的虚拟 IP 地址,供集群内部使用。**
- NodePort**:将服务暴露在每个节点的固定端口上,供集群外部访问。**
- LoadBalancer**:使用云提供商的负载均衡器,将服务暴露给外部(通常用于公有云环境)。**
- ExternalName**:将服务映射到 DNS 名称。**
5.3 DNS服务
5.3 DNS 服务
**Kubernetes 内置了 DNS 服务,通过 DNS 自动解析服务名称,简化服务之间的访问。例如,一个服务名为 **my-service
,在命名空间 my-namespace
中,其 DNS 名称将是 my-service.my-namespace.svc.cluster.local
。
5.4 Service 工作原理
Service 通过一个虚拟 IP(ClusterIP)和 DNS 名称,将流量负载均衡到后端的 Pod 上。kube-proxy
组件负责维护这些规则,确保流量正确地路由到目标 Pod。
5.5 Ingress 工作原理
Ingress 是一种 API 对象,管理外部访问 HTTP 和 HTTPS 服务的路由规则。它提供了基于名称的虚拟主机、多域名、SSL/TLS 终止等功能。
- 定义了一组规则,指定外部如何访问集群内的服务
- 需要部署 Ingress 控制器来实现这些规则。常用的 Ingress 控制器包括:NGINX Ingress Controller 一个功能丰富、使用广泛的 Ingress 控制器;haproxy 一个高性能的 TCP/HTTP 负载均衡器.
6 Kubernetes 存储
6.1 Kubernetes 存储资源
Kubernetes 存储通过多种机制来管理和持久化数据,主要包括以下几种资源:
- Volumes(卷):在 Pod 内部挂载存储。
- Persistent Volumes(PV,持久卷):集群范围内的持久存储。
- Persistent Volume Claims(PVC,持久卷声明):用户对持久存储的请求。
- Storage Classes(存储类):用于动态创建 PV 的模板。
6.2 Volumes
Volumes用于在 Pod 内部挂载存储。不同于容器的临时文件系统,Volumes 可以提供持久化的存储,即使容器重启,数据也不会丢失。
- emptyDir**:在 Pod 生命周期内存在的临时存储,Pod 删除时数据会丢失**
- hostPath**:挂载主机文件系统的路径到 Pod 中,Pod 删除时数据不会丢失**
- configMap 和 secret**:将配置文件和敏感信息挂载到 Pod 中**
6.3 Persistent Volumes(PV)和 Persistent Volume Claims(PVC)
- PV 是集群范围内的持久存储资源,由管理员配置和管理。PVC 是用户对存储的请求,PVC 可以绑定到 PV。
- PV描述的,是持久化存储数据卷。这个API对象主要定义的是一个持久化存储在宿主机上的目录,比如一个NFS的挂载目录
- PVC描述的,则是Pod所希望使用的持久化存储的属性。比如,Volume存储的大小、可读写权限等等
PVC可以理解为持久化存储的“接口”,它提供了对某种持久化存储的描述,但不提供具体的实现;而这个持久化存储的实现部分则由PV负责完成,绑定 PVC 和 PV 后,Pod 可以使用 PVC 来挂载存储
6.4 Storage Classes
Storage Classes 提供了一种动态创建 PV 的方法,定义了存储的属性和配置。不同存储类可以映射到不同的存储后端,例如 AWS EBS、GCE PD、NFS 等
7 k8s 安装
7.1 本地环境搭建
- 使用 Minikube 或 Kind 快速创建单节点集群
- 使用 kubeadm 创建高可用集群
7.2生产环境部署
- ** 建议使用二进制文件来进行安装**
7.3客户端工具
- Kubectl 命令行操作
- Lens 图形界面控制台
8 操作示例
下列操作是在单机 Minikube 环境进行执行。
8.1 创建yaml文件
- **创建 PV **
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /mnt/data
- 创建 PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
- 创建Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
volumes:
- name: myvolume
persistentVolumeClaim:
claimName: my-pvc
- 上述yaml 定义了一个Pod模版(spec.template),这个模版描述了我想要创建的Pod的细节
- API对象的定义,大多可以分为Metadata和Spec两个部分。Metadata的字段,这个字段就是API对象的“标识”
- Deployment会把所有正在运行的、携带“app: nginx”标签的Pod识别为被管理的对象,并确保这些Pod的总数严格等于两个:过滤规则的定义,是在Deployment的“spec.selector.matchLabels”字段。我们一般称之为:Label Selector
8.2 资源创建
pingguo@pingguodeMacBook-Pro % kubectl apply -f first.yml -n cfp
deployment.apps/nginx-deployment created
8.3 资源查看
- 创建一个Deployment
- 创建一个Replica set
- 创建2个pod
pingguo@pingguodeMacBook-Pro % kubectl get pod -n cfp
NAME READY STATUS RESTARTS AGE
nginx-deployment-7f89d7585d-5kj7v 0/1 ErrImagePull 0 3m49s
nginx-deployment-7f89d7585d-9z2fw 0/1 ErrImagePull 0 3m49s
pingguo@pingguodeMacBook-Pro % kubectl get deploy -n cfp
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/2 2 0 4m24s
pingguo@pingguodeMacBook-Pro % kubectl get rs -n cfp
NAME DESIRED CURRENT READY AGE
nginx-deployment-7f89d7585d 2 2 0 4m44s
由于网络原因,导致镜像没有下载下来。
9 总结与后续规划
Kubernetes 是一个强大的容器编排平台,用于自动化部署、扩展和管理容器化应用。 本文对比了Docker容器、K8s适应场景,介绍K8s的基础架构与核心组件,详细阐述了k8s的各个API对象,其中对网络与存储两方面进行重点展开说明,最后写了一个简单的示例介绍k8s的基本命令。k8s 通过其强大的编排能力、自动化管理、扩展性和灵活的存储解决方案,极大地简化了容器化应用的部署和管理。理解 Kubernetes 的核心概念和组件,并结合具体实践,可以有效提升应用的部署效率和运维水平。
由于mac环境下,minikube的NodePort端口无法访问,目前无法样例演示k8s 的网络请求,计划放在后续分享中去解决。