下面的内容是基于你已经了解了 Docker 容器的前提下的,如果还不了解什么是容器,可以先看看之前的文章

https://www.ryanzoe.top/category/docker/

k8s 是什么

Kubernetes 也称为 K8s,是用于自动部署、扩缩和管理容器化应用程序的开源系统。Google 在 2014 年开源了 Kubernetes 项目。

在生产环境中, 你需要管理运行着应用程序的容器,并确保服务不会下线。 例如,如果一个容器发生故障,则你需要启动另一个容器。 如果此行为交由给系统处理,是不是会更容易一些?这就是 Kubernetes 要来做的事情! Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移你的应用、提供部署模式等。

Kubernetes 为你提供:

  1. 服务发现和负载均衡
  2. 存储编排
  3. 自动部署和回滚
  4. 自动完成装箱计算
  5. 自我修复
  6. 密钥与配置管理
  7. 批处理执行
  8. 水平扩缩 
  9. IPv4/IPv6 双栈 
  10. 为可扩展性设计 

集群架构

集群主要分为两部分,Control Plane 和 Node 节点,Control Plane 负责控制和管理各个 Node,Node 是实际的工作节点,可以是裸机服务器、虚拟机或云服务器等,负责实际运行服务,多个服务共享一台 Node 上的资源

etcd

etcd是一个分布式键值存储系统,用于存储整个集群的状态信息,包括节点、Pods、配置、secrets、账户权限、角色、角色绑定和其他重要的元数据。Kubernetes的控制平面组件,如API服务器、调度器和控制器管理器,都依赖于etcd来保持集群状态的一致性。

API Server

API Server(kube-apiserver)是集群的中心管理实体,它提供了Kubernetes API的实现。API Server充当了集群内部各种组件以及外部用户与集群交互的接口。

由于API Server是与Kubernetes集群交互的主要入口点,因此它通常配置有适当的安全措施,如TLS加密、API速率限制和审计日志,以确保集群的安全性和稳定性。

Scheduler

Scheduler(调度器)是控制平面的一个关键组件,负责将Pods(容器的集合)分配到集群中的节点上。Scheduler的主要任务是根据多种调度策略和约束条件,为新创建的Pods选择最合适的节点,以确保集群资源的有效利用和Pods的高可用性。

Kubernetes允许自定义调度策略,并且可以运行多个调度器以满足不同类型的工作负载需求。此外,还可以使用第三方调度器或开发自定义调度器插件来扩展调度功能。

Controller Manager

Controller Manager是一个控制平面组件,它负责运行各种控制器进程。这些控制器是后台进程,它们负责监视集群的状态,并确保当前状态与期望状态一致。如果当前状态与期望状态不一致,控制器会采取行动来调整状态,以达到期望状态。

Controller Manager具体负责以下几个方面的任务:

  1. 监控&维护集群状态
  2. 自动修复
  3. 管理资源的生命周期
  4. 调度辅助

Controller Manager的设计允许它灵活地扩展和引入新的控制器,而无需修改核心代码。这种模块化的设计使得Kubernetes能够适应不断变化的需求和工作负载。在高级别上,Controller Manager的作用是持续地将集群的实际状态推向期望状态,这是Kubernetes自动化管理的核心。

kubelet

是Kubernetes集群中每个节点上的主要“节点代理”,它负责维护和管理该节点上的容器。Kubelet的工作是确保容器都按照PodSpec(Pod的规格说明)运行。每个Kubernetes节点上都运行着一个Kubelet进程,它是节点自动化的关键组件。

Kubelet通过与API Server的通信来接收PodSpecs,并根据这些规格来管理本地节点上的容器。此外,Kubelet还会定期向API Server发送心跳,以表明节点的健康状态。

  1. Pod生命周期管理
  2. 资源监控
  3. 容器健康检查
  4. 报告节点状态
  5. 管理容器的生命周期
  6. 管理存储资源
  7. 收集和管理容器日志

Container runtime

容器运行时(Container Runtime)是负责运行容器的软件。在Kubernetes集群中,容器运行时是节点上的关键组件,它负责拉取容器镜像、创建容器、执行容器以及管理容器的生命周期。它为Kubernetes提供了底层技术,使得Kubernetes能够管理和编排容器化应用程序。

Kubernetes支持多种容器运行时,包括:Docker、CRI-O等

容器运行时的主要职责包括:

  1. 镜像管理
  2. 容器启动和运行
  3. 生命周期管理
  4. 资源管理
  5. 健康
  6. 日志管理

kube-proxy

kube-proxy 是 Kubernetes 网络的核心部分,它确保了集群内服务的高可用性和可扩展性。通过kube-proxy,Kubernetes 能够实现复杂的服务发现和负载均衡策略,而无需在Pods中运行额外的网络代理。

  1. 服务发现
  2. 维护网络规则
  3. 负载均衡
  4. 网络代理

ingress

Ingress 是 Kubernetes 中的一个 API 对象,它管理着外部到集群内服务的访问规则。Ingress 充当反向代理,将进入的 HTTP 和 HTTPS 流量路由到集群内的多个服务。它允许你将不同的外部主机名和路径映射到不同的服务上,从而实现虚拟托管和基于路径的路由。

kubectl

kubectl 是 Kubernetes 集群的命令行工具,它允许用户与 Kubernetes 集群进行交互。使用 kubectl,你可以部署应用程序、检查和管理集群资源以及查看日志等。kubectl 通过与 Kubernetes API Server 通信来执行各种操作。

持声明式和命令式两种操作方式:

  • 声明式(Declarative):用户提供包含资源状态的 YAML 或 JSON 文件,使用 kubectl apply 命令来创建或更新资源。
  • 命令式(Imperative):用户直接在命令行中指定操作和资源,如 kubectl createkubectl runkubectl expose 等。

核心概念

节点(Node)

通过将容器放入在节点(Node)上运行的 Pod 中,来执行你的工作负载。 节点可以是一个虚拟机或者物理机器,取决于所在的集群配置。 每个节点包含运行 Pod 所需的服务,这些节点由Control Plane负责管理。

通常集群中会有若干个节点,节点上的组件包括 kubelet、 容器运行时以及 kube-proxy。

添加节点的方式主要有两种:

  1. 节点上的 kubelet 向控制面执行自注册
  2. 手动添加一个 Node 对象

在你创建了 Node 对象或者节点上的 kubelet 执行了自注册操作之后,控制面会检查新的 Node 对象是否合法。 例如,如果你尝试使用下面的 JSON 对象来创建 Node 对象:

{
  "kind": "Node",
  "apiVersion": "v1",
  "metadata": {
    "name": "10.240.79.157",
    "labels": {
      "name": "my-first-k8s-node"
    }
  }
}

Kubernetes 会在内部创建一个 Node 对象作为节点的表示。Kubernetes 检查 kubelet 向 API 服务器注册节点时使用的 metadata.name 字段是否匹配。 如果节点是健康的(即所有必要的服务都在运行中),则该节点可以用来运行 Pod。 否则,直到该节点变为健康之前,所有的集群活动都会忽略该节点。

Pod

Pod是最小的可部署的计算单元,它代表了集群中的一个运行过程。一个Pod通常包含一个或多个容器(例如Docker容器),这些容器共享存储、网络和运行配置。Pod中的容器总是在同一个节点上一起调度,并且在同一个上下文中运行。

Pod 也被视为短暂的,这意味着它们被设计为易于创建、销毁和替换。Kubernetes 推荐使用控制器(如 Deployments 或 DaemonSets)来管理 Pods 的生命周期,而不是直接管理单个 Pods。控制器可以确保应用程序的期望状态被维护,例如在 Pod 失败时自动替换它。

Deployments

Deployment是一个高级的API对象,它帮助你声明性地管理Pod和ReplicaSet(Pod的副本集)。Deployment允许你定义应用的期望状态,Kubernetes系统负责将实际状态改变为期望状态。你可以使用Deployment来创建新的资源,或者替换现有的资源,例如在升级或回滚应用时。

通常会将Deployment与Service一起使用,Service为Pod提供一个稳定的网络接口,而Deployment确保Pod的数量和配置是正确的。这样,即使在更新和故障恢复期间,应用也可以持续对外提供服务。

服务(Service)

在 Kubernetes 中,Service 是一种抽象,它定义了一种访问 Pod 的方式,无论这些 Pod 如何变化,Service 都保持不变。Service 使得 Pod 可以被外部世界发现和访问,同时 Service 还支持负载均衡,可以分发网络流量到多个 Pod。

Namespaces

命名空间(Namespaces)是一种将集群资源划分为多个独立的逻辑分区的机制。命名空间允许你在同一个物理集群中运行多个组织或应用程序的资源,而这些资源彼此隔离,不会互相干扰。

Kubernetes提供了几个默认的命名空间:

  • default:如果你不指定命名空间,资源默认会被创建在这个命名空间中。
  • kube-system:Kubernetes系统创建的资源所在的命名空间,这些资源是Kubernetes集群运行所必需的。
  • kube-public:这个命名空间是自动创建的,它是公开的,所有用户(甚至是未经认证的用户)都可以访问。
  • kube-node-lease:这个命名空间包含每个节点的租约对象,用于确定节点的可用性。

ConfigMaps

ConfigMap是一种API资源,它用于将非机密性的配置数据存储为键值对。这些数据可以是配置文件、命令行参数或其他配置项。ConfigMap允许你将配置与容器镜像分离,从而使得应用程序的配置更加灵活和可移植。

ConfigMap的主要用途包括:

  1. 配置解耦:将配置信息从应用代码中分离出来,使得应用更容易移植和配置。
  2. 环境配置:为不同的环境(如开发、测试和生产)提供不同的配置,而无需修改应用代码。
  3. 配置共享:在多个Pod或容器之间共享配置信息。
  4. 动态配置:在不重启容器的情况下更新配置信息。

ConfigMap可以以多种方式使用:

  • 环境变量:将ConfigMap中的键值对作为环境变量注入到Pod中。
  • 命令行参数:在启动容器时,使用ConfigMap中的数据作为命令行参数。
  • 配置文件:将ConfigMap作为文件或卷挂载到Pod中,容器可以读取这些文件中的配置数据。
  • Pod命令和参数:使用ConfigMap中的数据来设置Pod规格中的命令和参数。

创建ConfigMap的方法通常有两种:

  1. 命令行:使用kubectl create configmap命令,可以直接从命令行参数或从文件中创建ConfigMap。
  2. 配置文件:编写一个ConfigMap的YAML或JSON配置文件,然后使用kubectl apply命令来创建它。

ConfigMap是Kubernetes中用于管理配置数据的有用工具,但它不应该用于敏感信息的存储,对于敏感信息,应该使用Secrets。

Persistent Volumes

持久卷(Persistent Volumes,简称PV)是一种由管理员预先配置的存储,它提供了一种与Pod生命周期无关的存储解决方案。PV是集群中的资源,就像节点是集群中的资源一样。PV允许用户存储数据,即使容器停止运行,数据也不会丢失。

PV是一种抽象层,它封装了底层的存储细节,比如NFS、iSCSI或云提供商的存储系统(如AWS的EBS、Google Cloud的Persistent Disk或Azure的Disk Storage)。管理员可以预先创建一系列的PV,或者配置动态供应(Dynamic Provisioning),后者允许自动创建PV以满足用户的PersistentVolumeClaim(PVC)请求。

通过创建PersistentVolumeClaim(PVC)来请求存储资源。PVC指定了存储的大小、访问模式和可能的StorageClass。Kubernetes会匹配一个合适的PV给PVC,或者通过动态供应创建一个新的PV来满足PVC的要求。

一旦PVC与PV绑定,PVC就可以像使用本地节点存储一样在Pod中使用。Pods通过在其规格中引用PVC来使用持久存储,而不是直接引用PV。

持久卷提供了一种在Kubernetes中使用持久存储的标准化方式,使得应用程序可以轻松地迁移到不同的环境和云提供商,而无需修改对存储的引用。

基本操作

接下会演示如何创建、更新、删除资源,查看日志,调试 Pods 等一些基本操作

安装 k8s 环境

本地开发环境

  1. Minikube: Minikube是一个轻量级的Kubernetes实现,它创建了一个虚拟机,并在这个虚拟机上部署一个简单的集群。Minikube适合用于学习和开发目的。
    • 安装Minikube:Minikube安装指南
    • 启动Minikube集群:minikube start
  2. Kind (Kubernetes IN Docker): Kind使用Docker容器作为Kubernetes集群的节点。它主要用于测试Kubernetes本身,但也适合开发和CI环境。
    • 安装Kind:Kind安装指南
    • 创建一个Kind集群:kind create cluster
  3. Docker Desktop: Docker Desktop的边缘版支持一键启用Kubernetes集群。
    • 安装Docker Desktop:Docker Desktop安装指南
    • 在Docker Desktop设置中启用Kubernetes。

云服务

许多云服务提供商提供了托管的Kubernetes服务,这些服务简化了集群的创建和管理过程。

  1. Google Kubernetes Engine (GKE)GKE快速入门
  2. Amazon Elastic Kubernetes Service (EKS)EKS入门
  3. 腾讯云容器服务 (TKE)TKE 入门
  4. 阿里云容器服务(ACK)ACK 入门

对于初学者和开发者来说,Minikube和Kind是快速开始的好选择。对于生产环境,托管服务或使用kubeadm、Kubespray等工具在自己的服务器上搭建可能更合适。

基础操作

  1. 查看集群中的所有 Podkubectl get pods
  2. 查看特定命名空间中的所有 Podkubectl get pods --namespace=<namespace-name>
  3. 查看 Pod 的详细信息kubectl describe pod <pod-name>
  4. 查看 Pod 的日志kubectl logs <pod-name>
  5. 在集群中创建一个新的 Deploymentkubectl apply -f <deployment-file.yaml>这里 <deployment-file.yaml> 是包含 Deployment 定义的 YAML 文件。
  6. 删除一个 Deploymentkubectl delete deployment <deployment-name>
  7. 扩展 Deployment 中的 Pod 数量kubectl scale deployment <deployment-name> --replicas=<number-of-replica>
  8. 查看集群中的所有 Servicekubectl get svc
  9. 创建一个新的 Servicekubectl apply -f <service-file.yaml>这里 <service-file.yaml> 是包含 Service 定义的 YAML 文件。
  10. 删除一个 Servicekubectl delete svc <service-name>
  11. 查看集群中的所有 Namespacekubectl get namespaces
  12. 创建一个新的 Namespacekubectl create namespace <namespace-name>
  13. 删除一个 Namespacekubectl delete namespace <namespace-name>
  14. 将 Pod 从一个节点调度到另一个节点kubectl cordon <node-name>
  15. 取消节点的调度kubectl uncordon <node-name>
  16. 查看集群的状态kubectl cluster-info
  17. 获取当前上下文信息kubectl config current-context
  18. 切换到不同的 Kubernetes 集群kubectl config use-context <context-name>
  19. 查看集群中的 Persistent Volumeskubectl get pv
  20. 查看集群中的 Persistent Volume Claims:复制kubectl get pvc

网络

  1. Pod之间的通信:集群内的每个Pod都应该能够与其他Pod通信,无论它们位于哪个节点上。
  2. 节点之间的通信:集群内的节点应该能够相互通信,以便Pods能够跨节点通信。
  3. Pod与服务之间的通信:Pods应该能够通过服务发现机制访问服务,服务可以作为负载均衡器分发流量到后端的Pods。
  4. 外部访问:应该能够从集群外部访问集群内的服务。

安全特性

Kubernetes提供了多种安全特性来保护集群和管理访问控制,这些特性可以分为几个主要领域:

  1. 认证(Authentication)
    • 用户账号和服务账号:Kubernetes区分用户账号(供人使用)和服务账号(供在Pods中运行的应用程序使用)。
    • 证书认证:使用客户端证书进行用户认证是Kubernetes支持的一种方式。
    • 静态令牌文件:通过配置文件提供的静态Bearer令牌。
    • OpenID Connect Tokens:支持使用OIDC(OpenID Connect)进行身份验证。
    • Webhook Token Authentication:使用HTTP回调(webhook)来进行身份验证。
  2. 授权(Authorization)
    • RBAC(Role-Based Access Control):基于角色的访问控制,允许管理员通过角色来定义用户和服务账号的权限。
    • ABAC(Attribute-Based Access Control):基于属性的访问控制,可以定义复杂的策略。
    • Node Authorization:一个特殊的授权模式,用于控制节点可以访问的API资源。
    • Webhook Authorization:使用HTTP回调(webhook)来进行授权决策。
  3. 准入控制(Admission Control)
    • Admission Controllers:在资源请求到达API服务器,但在对象被持久化之前,准入控制器可以修改或拒绝请求。
    • Pod Security Policies:定义一组条件,Pods必须在这些条件下运行,否则会被拒绝创建。
  4. 网络策略(Network Policies)
    • 允许管理员控制Pod之间的通信规则,限制哪些Pod可以相互通信。
  5. 秘密管理(Secret Management)
    • Secrets:用于存储和管理敏感信息,如密码、OAuth令牌和SSH密钥。
    • 加密配置数据:在etcd中存储时,可以对Secrets进行加密。
  6. Pod安全标准(Pod Security Standards)
    • 一组定义了Pod应该如何安全运行的标准。
  7. TLS
    • Kubernetes各组件之间的通信可以通过TLS进行加密。
  8. 审计日志(Audit Logging)
    • 记录API服务器接收到的每个请求的详细信息,以便进行安全审计。
  9. 容器安全
    • 容器运行时安全:确保容器运行时(如containerd、CRI-O)遵循最佳安全实践。
    • 镜像安全:使用镜像签名、镜像扫描来确保容器镜像的安全。
  10. API服务器安全
    • API速率限制:限制对API服务器的请求速率,以防止拒绝服务攻击。
    • API请求大小限制:限制请求的大小,以防止拒绝服务攻击。

其他

官方文档:

https://kubernetes.io/zh-cn/

https://kubernetes.io/zh-cn/docs/tutorials/kubernetes-basics/