声明: 本文翻译自Kubernetes Tutorial for Beginners: Basic Concepts
Kubernetes是部署和扩展容器化系统的最流行的编排器。你可以使用Kubernetes可靠地构建和分发你的应用程序在云中。
在这个初学者指南中,你将了解Kubernetes的功能以及如何开始运行你自己的容器化解决方案。
什么是k8s?
Kubernetes是一个开源系统,可以自动执行容器部署任务。它最初由谷歌开发,但现在作为云原生计算基金会(CNCF)的一部分进行维护。
Kubernetes之所以声名鹊起,是因为它解决了在生产中使用容器的许多挑战。它可以轻松地启动无限的容器副本,将它们分布在多个物理主机上,并设置网络,以便用户可以访问您的服务。
大多数开发人员从Docker开始他们的容器之旅。虽然这是一个全面的工具,但它的级别相对较低,并且依赖于一次与一个容器交互的CLI命令。Kubernetes提供了更高级别的抽象,用于使用您可以协作的声明性模式来定义应用程序及其基础设施。
Kubernetes 特性
Kubernetes拥有一个全面的功能集,包括用于运行容器及相关基础设施的全谱能力:
- 自动化部署、扩展和回滚: Kubernetes自动创建指定数量的副本,将它们分布到合适的硬件上,并在节点故障时采取行动以重新安排您的容器。您可以根据需要或响应诸如CPU使用率等变化即时扩展副本数量。
- 服务发现、负载均衡和网络入口: Kubernetes提供了一个完整的网络解决方案,涵盖了内部服务发现和公共容器暴露。
- 无状态和有状态应用: 虽然Kubernetes最初专注于无状态容器,但现在它还内置了用于表示有状态应用的对象。您可以在Kubernetes中运行任何类型的应用程序。
- 存储管理: 持久存储通过一致的接口进行抽象,可跨提供商使用,无论是在云中、网络共享上,还是在本地文件系统上。
- 声明式状态: Kubernetes使用YAML文件中的对象清单来定义您想要在集群中创建的状态。应用清单会指示Kubernetes自动将集群转换为目标状态。您无需手动编写脚本来实现所需的更改。
- 跨环境工作: Kubernetes可在云中、边缘设备上或开发者工作站上使用。有许多不同的发行版可用以匹配不同的用例。主要云提供商如AWS和Google Cloud提供托管的Kubernetes服务,而像Minikube和K3s这样的单节点发行版非常适用于本地使用。
- 高度可扩展: Kubernetes内置了许多功能,但您可以通过扩展添加更多功能。您可以创建自定义对象类型、控制器和运算符来支持您自己的工作负载。
由于Kubernetes提供了如此多的功能,因此它非常适合在您希望使用声明性配置部署容器的任何情况下使用。
Kubernetes工作原理
Kubernetes因为涉及多个组件,被认为较为复杂。理解它们基本的工作方式将有助于您开始学习Kubernetes。
一个Kubernetes环境被称为一个集群。它包括一个或多个节点,节点简单来说就是将运行您的容器的机器,可以是物理硬件或虚拟机。
除了节点,集群还包括一个控制平面。控制平面协调整个集群的操作。它调度新的容器到可用的节点,并提供您与之交互的API服务器。可以运行具有多个控制平面实例的集群,以创建具有更高可用性和更强韧性的设置。
以下是最重要的Kubernetes组件:
- kube-apiserver(API服务器): 控制平面的一部分,运行API服务器。这是与运行中的Kubernetes集群交互的唯一方式。您可以使用Kubectl CLI或HTTP客户端向API服务器发出命令。
- kube-controller-manager(控制器管理器): 控制器管理器启动并运行Kubernetes内置的控制器。控制器实际上是一个事件循环,在集群发生变化后执行操作。它们根据事件(如API请求或负载增加)创建、扩展和删除对象。
- kube-scheduler(调度器): 调度器将新的Pod(容器)分配到集群中的节点。它确定哪些节点可以满足Pod的要求,然后选择最优的位置以最大程度地提高性能和可靠性。
- kubelet: Kubelet是在每个节点上运行的工作进程。它与Kubernetes控制平面保持通信以接收其指令。Kubelet负责拉取容器镜像,并响应调度请求启动容器。
- kube-proxy(代理): 代理是在各个节点上的另一个组件。它配置主机的网络系统,以便流量能够到达集群中的服务。
Kubectl通常是一个运行中的Kubernetes环境中的最后一块拼图。您需要这个CLI与集群及其对象进行交互。一旦集群设置完成,您还可以安装官方仪表板或第三方解决方案以通过GUI控制Kubernetes。
安装与设置
由于提供的发行版范围广泛,因此有许多不同的方式开始使用Kubernetes。使用官方发行版创建集群相对复杂,因此大多数人使用Minikube、MicroK8s、K3s或Kind等打包解决方案。
在本教程中,我们将使用K3s。它是一个超轻量级的Kubernetes发行版,将所有Kubernetes组件捆绑到一个单一的二进制文件中。与其他选项不同,它无需安装依赖项或运行繁重的虚拟机。它还包括您将用于发出Kubernetes命令的Kubectl CLI。
运行以下命令将在您的计算机上安装K3s:
$ curl -sfL https://get.k3s.io | sh -
...
[INFO] systemd: Starting k3s
它会自动下载最新版本的Kubernetes并为K3s注册一个系统服务。
安装后,运行以下命令将自动生成的Kubectl配置文件复制到您的.kube目录中:
$ mkdir -p ~/.kube
$ sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
$ sudo chown $USER:$USER ~/.kube/config
现在通过运行以下命令告诉K3s使用此配置文件:
$ export KUBECONFIG=~/.kube/config
您可以将此行添加到您的~/.profile或~/.bashrc文件中,以在登录后自动应用更改。
接下来运行此命令:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ubuntu22 Ready control-plane,master 102s v1.24.4+k3s1
您应该会看到一个名为您计算机主机名的单个节点。节点显示为Ready,因此您现在可以使用您的Kubernetes集群了!
Kubernetes基本术语和概念
您的集群正在运行,但您可以对其进行哪些操作呢?在继续之前,熟悉一些关键的Kubernetes术语是值得的。
Nodes(节点): 节点代表形成Kubernetes集群的物理机器,它们运行您创建的容器。Kubernetes跟踪节点的状态并将每个节点公开为一个对象。在上面的示例中,您使用Kubectl检索了节点列表。
虽然您的新集群只有一个节点,但Kubernetes支持多达5000个节点的理论扩展。
Namespaces(命名空间): 命名空间隔离了不同组资源,通过为资源提供作用域,避免了名称冲突。
在同一命名空间中禁止使用相同名称创建两个对象。例如,在默认命名空间中,您不能创建两个都称为database的Pod。通过提供资源的逻辑分离,命名空间解决了这个问题。两个名为app-1和app-2的命名空间可以分别包含一个名为database的Pod,而不会发生冲突。
命名空间是灵活的,可以以许多不同的方式使用。为集群中的每个工作负载创建一个命名空间是一个好主意。您还可以使用命名空间通过应用基于角色的访问控制,将资源在用户和团队之间划分。
Pods(Pod): Pod是Kubernetes中的基本计算单元。Pod类似于容器,但存在一些关键区别。Pod可以包含多个容器,每个容器共享一个上下文。整个Pod将始终被调度到相同的节点上。Pod内的容器紧密耦合,因此您应该为应用程序的每个不同部分(例如API和数据库)创建一个新的Pod。
在简单的情况下,Pods通常会一对一地映射到应用程序运行的容器。在更高级的情况下,Pods可以通过使用初始化容器和临时容器进行增强,以定制启动行为并提供详细的调试。
ReplicaSets(ReplicaSet): ReplicaSets用于一致地复制一个Pod。它们提供了一个保证,在任何时候都会运行一定数量的副本。如果节点下线或Pod变得不健康,Kubernetes将自动安排一个新的Pod实例以维护指定的副本计数。
Deployments(部署): Deployments通过支持声明性更新和回滚来包装ReplicaSets。它们是更容易控制的更高抽象级别。
部署对象允许您指定一组Pod的期望状态,包括要运行的副本数量。修改部署将自动检测所需的更改并根据需要扩展ReplicaSet。您可以暂停部署或恢复到先前的版本,这是普通ReplicaSets不具备的功能。
学习如何创建Kubernetes部署YAML文件。
Services(服务): 服务用于将Pod暴露到网络。它们允许在集群内或外部定义对Pod的访问。
Ingresses是紧密相关的对象。它们用于通过负载均衡器设置到服务的HTTP路由。Ingress还支持通过TLS证书保护的HTTPS流量。
Jobs(作业): Kubernetes作业是一个创建一组Pod并等待它们终止的对象。它将重试任何失败的Pod,直到指定数量成功退出。然后标记作业为完成。
作业提供了在集群内运行临时任务的机制。Kubernetes还提供了使用类似cron的调度支持包装作业的CronJobs。这使您可以自动定期运行作业以适应批处理活动、备份和应用程序所需的任何其他定期任务。
Volumes(卷): 卷将外部文件系统存储挂载到Pod内。它们抽象了不同云提供商的存储实现之间的差异。
卷可以在Pod之间共享。这使得Kubernetes能够运行状态应用程序,其中数据必须在Pod终止或重新安排后保留。在集群中运行数据库或文件服务器时,您需要使用卷。
Secrets和ConfigMaps(密钥和配置映射): Secrets用于将敏感数据注入到集群中,例如API密钥、证书和其他类型的凭据。它们可以作为环境变量或挂载到卷中的文件提供给Pod。
ConfigMaps是非敏感信息的类似概念。这些对象应存储应用程序所需的任何通用设置。
DaemonSets(守护进程集): Kubernetes DaemonSets用于可靠地在集群中的每个节点上运行一个Pod的副本。
使用Kubectl与Kubernetes交互
现在您已经熟悉了基础知识,可以开始使用Kubectl向您的集群添加工作负载。以下是一些关键命令的快速参考。
列出Pods 这显示您集群中的Pods:
$ kubectl get pods
No resources found in default namespace
使用-n或--namespace标志指定命名空间:
$ kubectl get pods -n demo
No resources found in demo namespace
或者,通过指定--all-namespaces,从所有命名空间获取Pods:
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-b96499967-4xdpg 1/1 Running 0 114m
...
这包括Kubernetes系统组件。
创建一个Pod 使用以下命令创建一个Pod:
$ kubectl run nginx --image nginx:latest
pod/nginx created
这将启动一个名为nginx的Pod,该Pod将运行nginx:latest容器映像。
创建一个Deployment 创建一个Deployment允许您扩展容器的多个副本:
$ kubectl create deployment nginx --image nginx:latest --replicas 3
deployment.apps/nginx created
您将看到创建了三个Pods,每个Pod都运行nginx:latest映像:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-7597c656c9-4qs55 1/1 Running 0 51s
nginx-7597c656c9-gdjl9 1/1 Running 0 51s
nginx-7597c656c9-7sxrc 1/1 Running 0 51s
扩展Deployment 现在使用此命令增加副本计数:
$ kubectl scale deployment nginx --replicas 5
deployment.apps/nginx scaled
Kubernetes创建了两个额外的Pods,以提供额外的容量:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-7597c656c9-4qs55 1/1 Running 0 2m26s
nginx-7597c656c9-gdjl9 1/1 Running 0 2m26s
nginx-7597c656c9-7sxrc 1/1 Running 0 2m26s
nginx-7597c656c9-kwm6q 1/1 Running 0 2s
nginx-7597c656c9-nwf2s 1/1 Running 0 2s
暴露一个Service 现在让我们让这个NGINX服务器可访问。
运行以下命令创建一个服务,该服务在运行Pods的节点上的一个端口上公开:
$ kubectl expose deployment/nginx --port 80 --type NodePort
service/nginx exposed
通过运行此命令发现分配的端口:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 121m
nginx NodePort 10.43.149.39 <none> 80:30226/TCP 3s
端口是30226。在浏览器中访问:30226将显示默认的NGINX欢迎页面。
如果您一直遵循本教程中创建的单节点K3s集群,则可以使用localhost作为。否则,运行get nodes命令并使用显示的INTERNAL-IP。
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP
ubuntu22 Ready control-plane,master 124m v1.24.4+k3s1 192.168.122.210
使用端口转发 您可以使用Kubectl的集成端口转发功能在不绑定到节点端口的情况下访问服务。删除您的第一个服务,并创建一个没有--type标志的新服务:
$ kubectl delete service nginx
service/nginx deleted
$ kubectl expose deployment/nginx --port 80
service/nginx exposed
这将创建一个可以在集群内部访问的ClusterIP服务。
通过运行此命令检索服务的详细信息:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 10.100.191.238 <none> 80/TCP 2s
该服务可以在集群内的10.100.191.238:80上访问。
您可以使用以下命令从本地计算机访问此地址:
$ kubectl port-forward service/nginx 8080:80
在浏览器中访问localhost:8080将显示NGINX欢迎页面。Kubectl正在将流量重定向到集群内部的服务。完成后,您可以按Ctrl+C停止端口转发会话。
端口转发也适用于没有服务的情况。您可以直接使用此命令连接到部署中的Pod:
$ kubectl port-forward deployment/nginx 8080:80
在浏览器中访问localhost:8080将再次显示NGINX欢迎页面,这次不经过服务。
应用YAML文件 最后,让我们看看如何将声明性YAML文件应用于您的集群。首先,为您的Pod编写一个简单的Kubernetes清单:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:latest
将此清单保存到nginx.yaml,并运行kubectl apply以自动创建您的Pod:
$ kubectl apply -f nginx.yaml
pod/nginx created
你可以在修改文件后重复执行命令,以应用对你的集群的任何更改。
现在你已经熟悉使用 Kubectl 与 Kubernetes 进行交互的基础知识了!
本文使用 markdown.com.cn 排版