第三章 部署第一个应用程序

本章包括

  • 在笔记本电脑上运行单节点Kubernetes集群
  • 在谷歌Kubernetes引擎上设置Kubernetes集群
  • 设置和使用kubectl命令行工具
  • 在Kubernetes中部署应用程序,并使其在全球范围内可用
  • 水平扩展应用程序

本章的目标是向您展示如何运行一个用于开发的本地单节点Kubernetes集群,或者在云中建立一个适当的、受管理的多节点集群。一旦集群运行,使用它来运行在前一章中创建的容器。

3.1部署Kubernetes集群

部署一个成熟的、多节点的Kubernetes集群并不是一项简单的任务,特别是如果您不熟悉Linux和网络管理的话。正确的Kubernetes安装跨越多个物理机或虚拟机,需要适当的网络设置来允许集群中的所有容器彼此通信。您可以在笔记本电脑上、公司的基础设施上或云提供商(谷歌计算引擎、Amazon EC2、Microsoft Azure等)提供的虚拟机上安装Kubernetes。另外,大多数云提供商现在都提供托管的Kubernetes服务,为您省去了安装和管理的麻烦。以下是对主流云提供商所提供Kubernetes服务的简要概述:

  • 谷歌提供GKE -谷歌Kubernetes引擎,
  • 亚马逊有Amazon Elastic Kubernetes服务,
  • 微软有AKS Azure Kubernetes服务,
  • IBM有IBM云服务,
  • 阿里巴巴提供阿里巴巴云容器服务。

安装和管理Kubernetes要比使用它困难得多,特别是在您非常熟悉它的体系结构和操作之前。由于这个原因,我们将从获得一个工作的Kubernetes集群的最简单方法开始。了解在本地计算机上运行单节点Kubernetes集群的几种方法,以及如何使用运行在谷歌Kubernetes引擎(GKE)上的托管集群。第三个选项涉及使用kubeadm工具安装集群,附录b对此进行了解释。该教程将向您展示如何使用虚拟机设置三个节点的Kubernetes集群。但是您可能希望在熟悉使用Kubernetes之后再进行尝试。还有许多其他的选择,但它们超出了本书的范围。请参考kubernetes.io网站了解更多信息。如果您已经被授予访问其他人部署的现有集群的权限,那么可以跳过本节,转到第3.2节,在第3.2节中,您将学习如何与Kubernetes集群交互。

3.1.1使用Docker桌面内置的Kubernetes集群

如果你使用macOS或Windows,你很可能已经安装了Docker Desktop来运行前一章的练习。它包含一个单节点的Kubernetes集群,您可以通过它的设置对话框启用它。这可能是开始Kubernetes之旅的最简单方法,但请记住,在使用下一节中描述的可选选项时,对应的Kubernetes的版本可能不是最新的。请注意虽然在技术上不是一个集群,Docker Desktop提供的单节点Kubernetes系统应该足以探索本书中讨论的大多数主题。当一个练习需要一个多节点集群时,我将指出这一点。在Docker桌面启用Kubernetes假设您的计算机上已经安装了Docker Desktop,您可以通过单击系统托盘中的whale图标并打开设置对话框来启动Kubernetes集群。单击Kubernetes选项卡并确保选中了Enable Kubernetes复选框。组成控制平面的组件作为Docker容器运行,但是当您调用Docker ps命令时,它们不会显示在正在运行的容器列表中。要显示它们,选择“显示系统容器”复选框。请注意集群的初始安装需要几分钟时间,因为必须下载Kubernetes组件的所有容器镜像。图片图3.1 Windows Docker桌面设置对话框
如果您希望重置集群以删除在其中部署的所有对象,请记住Reset Kubernetes集群按钮。可视化系统要了解组成Kubernetes集群的各种组件在Docker Desktop中运行的位置,请看下图。图片图3.2 在Docker桌面运行的Kubernetes
Docker Desktop设置了一个Linux虚拟机,它承载Docker守护进程和所有容器。这个VM还运行Kubelet——管理节点的Kubernetes代理。控制平面的组件在容器中运行,您部署的所有应用程序也是如此。要列出正在运行的容器,您不需要登录VM,因为主机OS中可用的docker CLI工具会显示这些容器。从内部探索虚拟机在撰写本文时,如果您想从内部探索VM, Docker Desktop不提供登录到VM的命令。但是,您可以运行一个配置为使用VM的命名空间来运行远程shell的特殊容器,这实际上与使用SSH访问远程服务器完全相同。要运行容器,执行以下命令:

$ docker run --net=host --ipc=host --uts=host --pid=host --privileged 
 --security-opt=seccomp=unconfined -it --rm -v /:/host alpine chroot /host

这个长命令需要解释:

  • 容器是从alpine镜像创建的。
  • --net, --ipc, --uts 和--pid标志使容器使用主机的命名空间,而不是sandbox,--privileged 和--security-opt 标志使容器可以不受限制地访问所有系统调用。
  • -it标志运行容器交互模式,而--rm标志确保容器在终止时被删除。
  • -v标志将主机的根目录挂载到容器中的/host目录。然后,chroot /host命令将此目录作为容器中的根目录。

运行该命令之后,您就进入了一个shell,它与使用SSH进入VM时的shell是相同的。使用这个shell来探索虚拟机——尝试通过执行ps aux命令来列出进程,或者通过运行ip addr来探索网络接口。

3.1.2 使用Minikube运行本地集群

创建Kubernetes集群的另一种方法是使用Kubernetes社区维护的工具Minikube。Minikube部署的Kubernetes版本通常比Docker Desktop部署的版本更新。集群由单个节点组成,适合测试Kubernetes和本地开发应用程序。它通常在Linux VM中运行Kubernetes,但是如果您的计算机是基于Linux的,它也可以通过Docker直接在您的主机OS中部署Kubernetes。请注意如果将Minikube配置为使用VM,则不需要Docker,但需要像VirtualBox这样的管理程序。在另一种情况下,您需要Docker,但不需要hypervisor。安装MinikubeMinikube支持macOS、Linux和Windows。它有一个二进制可执行文件,您可以在GitHub上的Minikube存储库中找到(http://github.com/kubernetes/minikube)。最好按照那里发布的当前安装说明进行安装,但大致来说,您可以按照以下方式进行安装。在macOS上,你可以使用Brew包管理器安装它,在Windows上有一个安装程序,你可以下载,在Linux上,你可以下载.deb或.rpm包,或者简单地下载二进制文件,并使用以下命令使其可执行:

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

有关具体操作系统的详细信息,请参阅在线安装指南。使用Minikube启动Kubernetes集群安装了Minikube之后,启动Kubernetes集群,如下面的清单所示。

Listing 3.1 Starting Kubernetes with Minikube
$ minikube start
minikube v1.11.0 on Fedora 31
Using the virtualbox driver based on user configuration
Downloading VM boot image ...
> minikube-v1.11.0.iso.sha256: 65 B / 65 B [-------------] 100.00% ? p/s 0s
> minikube-v1.11.0.iso: 174.99 MiB / 174.99 MiB [] 100.00% 50.16 MiB p/s 4s
Starting control plane node minikube in cluster minikube
Downloading Kubernetes v1.18.3 preload ...
> preloaded-images-k8s-v3-v1.18.3-docker-overlay2-amd64.tar.lz4: 526.01 MiB
Creating virtualbox VM (CPUs=2, Memory=6000MB, Disk=20000MB) ...
Preparing Kubernetes v1.18.3 on Docker 19.03.8 ...
Verifying Kubernetes components...
Enabled addons: default-storageclass, storage-provisioner
Done! kubectl is now configured to use "minikube"

这个过程可能需要几分钟,因为必须下载Kubernetes组件的VM镜像和容器镜像。提示如果使用Linux,可以通过创建不需要VM的集群来减少Minikube所需的资源。使用这个命令:minikube start --vm-driver none检查Minikube的状态当minikube start命令完成时,您可以通过运行minikube status来检查集群的状态,如下面的清单所示。

Listing 3.2 Checking Minikube’s status
$ minikube status
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

命令的输出显示Kubernetes主机(托管Kubernetes的VM)正在运行,Kubelet(负责管理节点的代理)和Kubernetes API服务器也在运行。最后一行显示,kubectl命令行工具(CLI)被配置为使用Minikube提供的Kubernetes集群。Minikube并不安装CLI工具,但是它会创建它的配置文件。在第3.2节中解释了CLI工具的安装。可视化系统系统的架构,如下图所示,实际上与Docker桌面中的架构相同。图片图3.3 使用Minikube运行单节点Kubernetes集群
控制平面组件在VM中的容器中运行,如果使用--vm-driver none选项创建集群,则可以直接在主机OS中运行。Kubelet直接在VM或主机的操作系统中运行。它通过Docker守护进程运行您在集群中部署的应用程序。您可以运行minikube ssh登录到minikube VM并从内部进行探索。例如,您可以通过运行ps aux列出正在运行的进程或docker ps列出正在运行的容器来查看VM中正在运行的内容。提示如果希望使用本地docker CLI实例列出容器,就像在docker桌面的情况一样,运行以下命令:eval $(minikube docker-env)。

3.1.3 使用kind (Docker中的Kubernetes)运行本地集群

Minikube的另一个替代方案是kind (Kubernetes-in-Docker),尽管它还不够成熟。与在虚拟机上或直接在主机上运行Kubernetes不同,kind在容器中运行每个Kubernetes集群节点。与Minikube不同,这允许它通过启动几个容器来创建多节点集群。部署到Kubernetes的实际应用程序容器然后在这些节点容器中运行。系统如下图所示。图片图3.4 使用kind运行多节点Kubernetes集群
在前一章中,我提到在容器中运行的进程实际上是在宿主操作系统中运行的。这意味着当您使用kind运行Kubernetes时,所有Kubernetes组件都运行在您的主机操作系统中。部署到Kubernetes集群的应用程序也可以在主机操作系统中运行。这使得kind成为开发和测试的完美工具,因为一切都在本地运行,而且您可以像在容器外运行它们一样轻松地调试正在运行的进程。当我在Kubernetes上开发应用程序时,我更喜欢使用这种方法,因为它允许我做一些神奇的事情,比如在运行我的应用程序的容器中运行网络流量分析工具(如Wireshark),甚至运行我的web浏览器。我使用一个名为nsenter的工具,它允许我在网络或容器的其他名称空间中运行这些工具。如果你是Kubernetes的新手,最安全的选择是从Minikube开始,但如果你想冒险,这里是如何从kind开始。安装kind就像Minikube一样,kind由单个二进制可执行文件组成。要安装它,请参考https://kind.sigs.k8s.io/docs/user/quick-start/上的安装说明。在macOS和Linux上,安装命令如下:

$ curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(uname)-amd64 && chmod +x ./kind && mv ./kind /some-dir-in-your-PATH/kind

检查文档以了解最新版本是什么,并使用它代替上面示例中的v0.7.0。另外,用路径中的实际目录替换/some-dir-in-your-PATH/。注意  Docker必须安装在你的系统上才能使用。用kind启动Kubernetes集群启动一个新的集群和使用Minikube一样简单。执行以下命令:

$ kind create cluster

与Minikube一样,kind将kubectl配置为使用它创建的集群。用kind启动多节点集群默认情况下,Kind运行单节点集群。如果希望运行具有多个工作节点的集群,必须首先创建名为kind-multi-node的配置文件。包含以下内容的yaml(您可以在本书的代码归档目录Chapter03/中找到该文件):

Listing 3.3 Config file for running a three-node cluster with kind
kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
nodes:
- role: control-plane
- role: worker
- role: worker

文件就位后,使用以下命令创建集群:

$ kind create cluster --config kind-multi-node.yaml

列出工作节点在撰写本文时,kind没有提供检查集群状态的命令,但是您可以使用kind get nodes列出集群节点,如下面的清单所示。

Listing 3.4 Listing nodes using kind get nodes
$ kind get nodes
kind-worker2
kind-worker
kind-control-plane

请注意由于宽度的限制,本书中使用了节点名control-plane、worker1和worker2,而不是实际的节点名。由于每个节点都作为容器运行,所以您还可以通过使用docker ps列出正在运行的容器来查看节点,如下面的清单所示。

Listing 3.5 Displaying kind nodes running as containers
$ docker ps
CONTAINER ID   IMAGE                   ...   NAMES
45d0f712eac0   kindest/node:v1.18.2   ...   kind-worker2
d1e88e98e3ae   kindest/node:v1.18.2   ...   kind-worker
4b7751144ca4   kindest/node:v1.18.2   ...   kind-control-plane

登录到kind提供的集群节点与Minikube不同的是,如果您想探究运行在节点中的进程,则使用Minikube ssh登录到节点,而kind则使用docker exec。例如,要进入kind-control-plane节点,运行:

$ docker exec -it kind-control-plane bash

与使用Docker运行容器不同,kind创建的节点使用CRI-O容器运行时环境,它是我在前一章提到的Docker的轻量级替代品。crictl CLI工具用于与CRI-O交互。它的使用与docker工具非常相似。登录到节点后,通过运行crictl ps列出其中运行的容器下面的清单显示了该命令的输出示例:

Listing 3.6 Listing containers inside a cluster node provisioned with kind
root@kind-control-plane:/# crictl ps
CONTAINER ID   IMAGE           CREATED     STATE     NAME
c7f44d171fb72   eb516548c180f   15 min ago   Running   coredns       ...
cce9c0261854c   eb516548c180f   15 min ago   Running   coredns       ...
e6522aae66fcc   d428039608992   16 min ago   Running   kube-proxy     ...
6b2dc4bbfee0c   ef97cccdfdb50   16 min ago   Running   kindnet-cni   ...
c3e66dfe44deb   be321f2ded3f3   16 min ago   Running   kube-apiserver ...

3.1.4 使用谷歌Kubernetes引擎创建托管集群

3.1.5使用Amazon Elastic Kubernetes服务创建集群

3.1.6 从零开始部署多节点集群

在对Kubernetes有更深入的理解之前,我强烈建议您不要尝试从头安装多节点集群。如果您是一名有经验的系统管理员,那么您可以轻松地完成此任务,但是大多数人可能希望首先尝试前面几节中描述的方法。正确地管理Kubernetes集群是非常困难的。安装本身就是一项不可低估的任务。如果您喜欢冒险,可以从附录B中的说明开始,其中解释了如何使用VirtualBox创建虚拟机,以及如何使用kubeadm工具安装Kubernetes。您还可以使用这些说明在裸机上或在云中运行的vm中安装Kubernetes。一旦你成功地使用kubeadm部署了一到两个集群,你就可以尝试完全手动部署它,在github.com/kelseyhightower/kubernetes-the-hard-Way上遵循Kelsey Hightower的Kubernetes the Hard Way教程。虽然你可能会遇到一些问题,但找出如何解决它们可以是一个很好的学习经验。

3.2与Kubernetes交互

现在,您已经了解了部署Kubernetes集群的几种可能的方法。现在来学习如何使用集群。要与Kubernetes交互,需要使用一个名为kubectl的命令行工具,发音为kube-control、kube-C-T-L或kube-cuddle。如图所示,该工具与Kubernetes API服务器通信,后者是Kubernetes控制平面的一部分。然后,控制平面触发其他组件根据您通过API所做的更改执行需要执行的操作。图片图3.6如何与Kubernetes集群交互

3.2.1安装kubectl—Kubernetes命令行客户端

Kubectl是一个单独的可执行文件,您必须将其下载到您的计算机并放置到您的路径中。它从一个名为kubeconfig的配置文件加载配置信息。要使用kubectl,您必须安装它并准备kubeconfig文件,以便kubectl知道要与哪个集群对话。下载和安装kubectl可以使用以下命令下载和安装最新的Linux稳定版本:

$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/

要在macOS上安装kubectl,您可以运行相同的命令,但是在URL中将linux替换为darwin,或者通过运行brew install kubectl通过Homebrew安装该工具。在Windows上,从https://storage.googleapis.com/kubernetes-release/release/v1.18.2/bin/windows/amd64/kubectl.exe下载kubectl.exe。要下载最新版本,首先访问https://storage.googleapis.com/kubernetes-release/release/stable.txt,查看最新的稳定版本是什么,然后用这个版本替换第一个URL中的版本号。要检查是否正确安装,请运行kubectl --help。注意,kubectl可能被配置为与Kubernetes集群通信,也可能还没有配置,这意味着大多数命令可能还不能工作。提示您可以随时向任何kubectl命令追加--help,以获得关于它的功能和如何使用它的信息。为kubectl设置一个别名你会经常使用kubectl。必须每次输入完整的命令是不必要的时间浪费,可以通过设置别名和TAB键来加快速度。大多数Kubernetes用户使用k作为kubectl的别名。如果您还没有使用别名,下面将介绍如何在Linux和macOS中定义别名。将以下行添加到~/.bashrc或等效文件:

alias k=kubectl

在Windows上,如果使用命令提示符,可以执行doskey k=kubectl $*来定义别名。如果使用PowerShell,请执行set-alias -name k -value kubectl。请注意 如果使用gcloud设置集群,则可能不需要别名。除了kubectl之外,它还安装k二进制文件。为kubectl配置TAB补全功能即使使用像k这样的短别名,您仍然需要输入很多内容。幸运的是,kubectl命令还可以为bash和zsh shell输出shell补全代码。它不仅支持命令名,还支持对象名的TAB补全。例如,稍后您将学习如何通过执行以下命令查看特定集群节点的详细信息:

$ kubectl describe node gke-kubia-default-pool-9bba9b18-4glf

这是大量的输入,你会一直重复。有了tab补全功能,事情就简单多了。你只需在输入每个标记的前几个字符后按TAB键:

$ kubectl desc<TAB> no<TAB> gke-ku<TAB>

要在bash中启用TAB补全功能,必须首先安装一个名为bash-completion的包,然后运行以下命令(还可以将其添加到~/.bashrc或同等文件):

$ source <(kubectl completion bash)

但有一点需要注意。只有在使用完整的kubectl命令名时,才会补全命令。用k的别名是不行的。要使它与别名一起工作,必须使用sed工具转换kubectl补全命令的输出:

$ source <(kubectl completion bash | sed s/kubectl/k/g)

3.2.2 配置kubectl以使用特定的Kubernetes集群

kubeconfig配置文件位于~/.kube/config。如果您使用Docker Desktop、Minikube或GKE部署集群,则会为您创建该文件。如果您已经获得了对现有集群的访问权,那么您应该已经收到了该文件。其他工具,比如kind,可能已经将文件写入了不同的位置。不需要将文件移动到默认位置,您还可以通过设置KUBECONFIG环境变量使kubectl指向此文件,如下所示:

$ export KUBECONFIG=/path/to/custom/kubeconfig

要了解更多关于如何管理kubectl的配置并从头创建配置文件,请参阅附录a。请注意如果您想使用几个Kubernetes集群(例如,同时使用Minikube和GKE),请参阅附录A以获得在不同kubectl上下文之间切换的信息。

3.2.3 使用kubectl

假设您已经安装并配置了kubectl,现在可以使用它与集群通信。验证集群是否启动,kubectl是否可以与之对话要验证您的集群是否在工作,使用kubectl集群-info命令,如下面的清单所示。清单3.9 显示集群信息

$ kubectl cluster-info

Kubernetes master is running at https://192.168.99.101:8443

KubeDNS is running at https://192.168.99.101:8443/api/v1/namespaces/...

这表明API服务器处于活动状态并响应请求。输出内容中,列出了集群中运行的各种Kubernetes集群服务的url。上面的示例表明,除了API服务器之外,在集群中提供域名服务的KubeDNS服务是在集群中运行的另一个服务。列出集群节点现在使用kubectl命令列出集群中的所有节点。下面的清单显示了在有三个节点的GKE集群上执行kubectl时生成的输出。清单3.10列出使用kubectl的集群节点

$ kubectl get nodes

NAME           STATUS ROLES   AGE   VERSION

control-plane   Ready   <none> 12m   v1.18.2

worker1         Ready   <none> 12m   v1.18.2

worker2         Ready   <none> 12m   v1.18.2

Kubernetes中的所有内容都由对象表示,可以通过RESTful API检索和操作。kubectl get命令从API检索指定类型的对象列表。您将一直使用这个命令,但它只显示有关列出的对象的摘要信息。检索对象的其他详细信息要查看一个对象的更多详细信息,可以使用 kubectl describe 命令,它会显示更多信息:

$ kubectl describe node gke-kubia-85f6-node-0rrx

我省略了describe命令的实际输出,因为它很宽,在本书中完全不可读。如果您自己运行该命令,您将看到它显示节点的状态、关于其CPU和内存使用情况的信息、系统信息、节点上运行的容器等等。如果运行kubectl describe命令而不指定资源名称,则将打印所有节点的信息。提示当只有一个特定类型的对象存在时,执行描述命令而不指定对象名称是有用的。您不必键入或复制/粘贴对象名称。您将在本书中了解更多关于其他kubectl命令的信息。

3.2.4 通过web仪表板与Kubernetes交互

如果您更喜欢使用图形化的web用户界面,那么您会很高兴地听到Kubernetes还提供了一个漂亮的web仪表板。但是请注意,仪表板的功能可能会明显落后于kubectl,后者是与Kubernetes交互的主要工具。不过,仪表板显示了上下文中的不同资源,可以很好地帮助您了解Kubernetes中的主要资源类型以及它们之间的关系。仪表板还提供了修改已部署对象的可能性,并为每个操作显示等效的kubectl命令——这是大多数初学者都会喜欢的特性。图3.7显示了集群中部署了两个工作负载的仪表板。图片

尽管可能不会使用本书中展示的仪表板,但在通过kubectl创建集群后,可以打开它来快速查看部署在集群中的对象的图形化视图。

访问Docker桌面中的仪表板

不幸的是,默认情况下Docker桌面不会安装Kubernetes仪表板。访问它也不是一件容易的事情,下面是具体操作步骤。首先,需要使用以下命令安装它:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc5/aio/deploy/recommended.yaml

访问github.com/kubernetes/dashboard可以找到最新的版本号。安装仪表板后,运行的下一个命令:

$ kubectl proxy

该命令运行API服务器的本地代理,允许通过它访问服务。让代理进程运行,并使用浏览器打开仪表板(URL如下):

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

您将看到一个身份验证页面。然后必须运行以下命令来获取身份验证令牌。

$ kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | sls admin-user | ForEach-Object { $_ -Split 's+' } | Select -First 1)

请注意

此命令必须在Windows PowerShell中运行。

找到kubernetes-dashboard-token-xyz下面列出的令牌,并将其粘贴到浏览器中显示的身份验证页面的令牌字段中。完成此操作后,应该能够使用仪表板。当使用完它时,使用Control-C终止kubectl代理进程。

使用Minikube时访问仪表板

如果使用的是Minikube,那么访问仪表板就容易得多了。运行以下命令,仪表盘将在默认浏览器中打开:

$ minikube dashboard

在其他地方运行Kubernetes时访问仪表板

谷歌Kubernetes引擎不再提供对开源Kubernetes仪表板的访问,但它提供了一个基于web的替代控制台。这同样适用于其他云提供商。有关如何访问仪表盘的信息,请参阅各自提供程序的文档。

如果您的集群运行在您自己的基础设施上,您可以按照kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard的指南部署仪表板。

3.3 在Kubernetes上运行第一个应用程序

现在终于可以在集群中部署一些东西了。通常,要部署应用程序,需要准备一个JSON或YAML文件来描述由应用程序组成的所有组件,并将该文件应用于集群。这就是声明式方法。

因为这可能是您第一次将应用程序部署到Kubernetes,所以让我们选择一种更简单的方法。我们将使用简单的一行命令来部署应用程序。

3.3.1 部署应用程序

部署应用程序的必要方法是使用kubectl create deployment命令。正如命令本身所暗示的,它创建一个Deployment对象,该对象表示部署在集群中的应用程序。通过使用命令式命令,可以避免像编写YAML或JSON清单时那样需要了解部署对象的结构。

创建一个Deployment

在前一章中,您创建了一个Node.js应用程序,并将其打包为一个容器映像,并将其推到Docker Hub,从而使其可以轻松地分发到任何计算机上。让我们将该应用程序部署到Kubernetes集群。下面是您需要执行的命令:

$ kubectl create deployment kubia --image=luksa/kubia:1.0
deployment.apps/kubia created

你在这里指定了三件事:

  • 需要创建一个deployment对象。

  • 希望该对象被称为kubia。

  • 希望deployment使用容器镜像luksa/kubia:1.0。

默认情况下,镜像是从Docker Hub提取的,但是也可以在镜像名称中指定镜像注册中心(例如,quay.io/luksa/kubia:1.0)。

请注意

确保镜像存储在公共注册中心,并且可以在没有访问授权的情况下提取。在第8章中,您将学习如何为获取私有镜像提供凭据。

Deployment对象现在存储在Kubernetes API中。这个对象的存在告诉Kubernetes:luksa/kubia:1.0容器必须在您的集群中运行。你已经表明了想要的状态。Kubernetes现在必须确保实际情况符合期望。

部署对象列表

与Kubernetes的交互主要包括通过其API创建和操作对象。Kubernetes存储这些对象,然后执行操作以赋予它们生命。例如,当创建一个部署Deployment时,Kubernetes会运行一个应用程序。然后,Kubernetes通过将状态写入对应的部署对象,让您了解应用程序的当前状态。您可以通过回读对象来查看状态。一种方法是列出所有部署对象,如下:

$ kubectl get deployments
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
kubia   0/1     1            0           6s

kubectl get Deployment命令列出集群中当前存在的所有Deployment对象。您的当前集群中只有一个部署。它运行应用程序的一个实例,如UP-TO-DATE列所示,但是AVAILABLE列指示该应用程序尚不可用。这是因为容器还没有准备好,如READY列中所示。可以看到,一个容器中没有一个准备好了。

您可能想知道是否可以通过运行kubectl get containers来要求Kubernetes列出所有正在运行的容器。让我们试一下。

$ kubectl get containers
error: the server doesn't have a resource type "containers"

该命令失败,因为Kubernetes没有“Container”对象类型。这可能看起来很奇怪,因为Kubernetes完全是关于运行容器的,但是有一个特别的地方。容器不是Kubernetes中最小的部署单元。那么,最小的部署单元是什么?

Pods简介

在Kubernetes中,部署的不是单独的容器,而是一组位于同一位置的容器——即所谓的pods。你可以理解成一个豌豆荚。

pod是一组紧密相关的容器(与豌豆荚中的豌豆类似),它们在同一个工作节点上运行,需要共享特定的Linux命名空间,以便它们能够比其他pod更紧密地交互。

在上一章中,我展示了一个两个进程使用相同命名空间的例子。通过共享网络名称空间,两个进程使用相同的网络接口,共享相同的IP地址和端口空间。通过共享UTS命名空间,两者可以看到相同的系统主机名。这正是在同一个pod中运行容器时所发生的情况。它们使用相同的网络和UTS命名空间,以及其他命名空间,具体取决于pod的规范。

图片

图3.8容器、pods和工作节点之间的关系

如图3.8所示,可以将每个pod看作包含一个应用程序的单独逻辑计算机。应用程序可以由运行在容器中的单个进程组成,也可以由运行在单独容器中的主应用程序进程和其他支持进程组成。Pods分布在集群的所有工作节点上。

每个pod都有自己的IP、主机名、进程、网络接口和其他资源。属于同一pod的容器认为它们是计算机上唯一运行的容器。它们不会看到任何其他pod的进程,即使它们位于同一个节点。

由于容器不是顶级的Kubernetes对象,所以不能列出它们。但是你可以列出pods。如下一个清单所示,通过创建Deployment对象,您已经部署了一个pod。

Listing 3.11 Listing pods
$ kubectl get pods
NAME                     READY     STATUS   RESTARTS   AGE
kubia-9d785b578-p449x    0/1       Pending   0         1m

这是容纳运行应用程序的容器的pod。确切地说,由于状态仍然是挂起,应用程序,或者更确切地说,容器还没有运行。这也在READY列中表示,它表示pod有一个容器没有准备好。

pod挂起的原因是,分配pod的工作节点必须首先下载容器镜像,然后才能运行它。下载完成后,将创建pod的容器,并进入运行状态。

如果Kubernetes不能从注册中心提取镜像,那么kubectl get pods命令将在STATUS列中指出这一点。如果您正在使用自己的镜像,请确保它在Docker Hub上标记为public。尝试在另一台计算机上使用docker pull命令手动拉镜像。

如果其他问题导致pod不能运行,或者您只是想查看有关pod的更多信息,还可以使用kubectl describe pod命令,就像前面所做的那样,查看工作节点的详细信息。如果pod有任何问题,应该通过这个命令显示。查看其输出底部显示的事件。对于正在运行的pod,它们应该类似于下面的清单所示。

Listing 3.12 The events displayed by kubectl describe pod
Events:
Type   Reason     Age   From               Message
----    ------     ----  ----               -------
Normal Scheduled 25s   default-scheduler Successfully assigned
                                          default/kubia-9d785b578-p449x
                                          to worker2
Normal Pulling   23s   kubelet, worker2   Pulling image "luksa/kubia:1.0"
Normal Pulled     21s   kubelet, worker2   Successfully pulled image
Normal Created   21s   kubelet, worker2   Created container kubia
Normal Started   21s   kubelet, worker2   Started container kubia

理解幕后发生的事情

为了帮助您可视化创建Deployment时发生的情况,请参见图3.9。

图片

图3.9 创建Deployment对象如何引起一个运行的应用程序容器

当运行kubectl create命令时,它通过向Kubernetes API服务器发送HTTP请求,在集群中创建了一个新的Deployment对象。然后Kubernetes创建了一个新的Pod对象,然后将其分配或调度到一个工作节点。工作节点(Kubelet)上的Kubernetes代理识别到新创建的Pod对象,看到它被调度到自己的节点,就指示Docker从注册中心中提取指定的镜像,从镜像创建容器,并执行它。

定义

术语调度指的是将pod分配到节点。pod立即运行,而不是在未来的某个时间点运行。就像操作系统中的CPU调度器选择在哪个CPU上运行进程一样,Kubernetes中的调度器也决定应该执行每个容器的哪个工作节点。与操作系统进程不同,一旦将一个pod分配给一个节点,它就只在那个节点上运行。即使失败,这个pod实例也不会移动到其他节点,就像CPU进程那样,但是可以创建一个新的pod实例来替换它。

根据您用于运行Kubernetes集群的内容,集群中的工作节点数量可能有所不同。图中只显示了pod调度到的工作节点。在多节点集群中,此过程中不涉及其他工作节点。

3.3.2 向世界展示您的应用程序

您的应用程序现在正在运行,因此要回答的下一个问题是如何访问它。我提到过,每个pod都有自己的IP地址,但是这个地址是集群内部的,不能从外部访问。为了使pod在外部可访问,将通过创建一个服务对象来公开它。

3.3.2 向世界展示您的应用程序

您的应用程序现在正在运行,因此要回答的下一个问题是如何访问它。我提到过,每个pod都有自己的IP地址,但是这个地址是集群内部的,不能从外部访问。为了使pod在外部可访问,将通过创建一个服务对象来公开它。存在几种类型的服务对象。你决定你需要什么类型。有些仅在集群内公开pods,而另一些则在外部公开。具有LoadBalancer类型的服务提供一个外部负载均衡器,它使服务可以通过公共IP访问。这就是您现在要创建的服务类型。创建一个服务创建服务最简单的方法是使用以下命令:

$ kubectl expose deployment kubia --type=LoadBalancer --port 8080
service/kubia exposed

您前面运行的create deployment命令创建一个部署对象,而expose deployment命令创建一个服务对象。运行上面的命令告诉Kubernetes:

  • 您希望将属于kubia Deployment的所有pods公开为一个新服务。
  • 您希望通过负载均衡器从集群外部访问pods。
  • 应用程序在端口8080上侦听,因此您希望通过该端口访问它。

您没有为服务对象指定名称,因此它继承Deployment的名称。服务列表Services是API对象,就像Pods、Deployments、Nodes和Kubernetes中的几乎所有其他东西一样,因此可以通过执行kubectl get services来列出它们,如下列表所示。

Listing 3.13 Listing Services
$ kubectl get svc
NAME         TYPE         CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
kubernetes   ClusterIP     10.19.240.1   <none>        443/TCP         34m
kubia       LoadBalancer  10.19.243.17   <pending>     8080:30838/TCP 4s

请注意注意这里使用了缩写svc而不是services。大多数资源类型都有一个简短的名称,您可以使用它来代替完整的对象类型(例如,po是pods的缩写,no是nodes的缩写,deploy是deployments的缩写)。该列表显示了两个服务及其类型(IPs和它们公开的端口)。现在先忽略kubernetes服务,仔细看看kubia服务。它还没有外部IP地址。它是否会得到一个IP,依赖于您如何部署集群。使用kubectl api-resources列出可用的对象类型您已经使用kubectl get命令列出了集群中的各种内容:Nodes, Deployments, Pods 和 Services.。这些都是Kubernetes对象类型。通过运行kubectl api-resources,可以显示所有受支持类型的列表。该列表还显示了每种类型的简短名称,以及在JSON/YAML文件中定义对象所需的其他一些信息,您将在接下来的章节中学习这些内容。理解负载均衡器(load balancer)服务虽然Kubernetes允许您创建所谓的LoadBalancer服务,但它本身并不提供负载均衡器。如果集群部署在云中,Kubernetes可以要求云基础设施提供一个负载均衡器,并配置它将流量转发到集群。基础设施告诉Kubernetes负载均衡器的IP地址,这将成为服务的外部地址。创建服务对象、配置负载均衡器以及它如何将连接转发到集群的过程如下图所示。

图片

图3.10 LoadBalancer类型服务对象是如何工作的
负载均衡器的配置需要一些时间,因此让我们再等待几秒钟,再次检查是否已经分配了IP地址。这一次,不是列出所有服务,而是只使用名称显示kubia服务,如下一个清单所示。

Listing 3.14 Getting a single service
$ kubectl get svc kubia
NAME       TYPE         CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kubia       LoadBalancer  10.19.243.17  35.246.179.22  8080:30838/TCP 82s

外部IP现在显示出来了。这意味着负载均衡器已经准备好为世界各地的客户端将请求转发到您的应用程序。请注意如果您使用Docker Desktop部署集群,那么负载平衡器的IP地址将显示为localhost,指的是您的Windows或macOS机器,而不是Kubernetes和应用程序运行的VM。如果您使用Minikube创建集群,则不会创建负载均衡器,但是您可以以另一种方式访问该服务。稍后将对此进行更多介绍。通过负载均衡器访问应用程序您现在可以通过外部IP和端口的服务发送请求到您的应用程序:

$ curl 35.246.179.22:8080
Hey there, this is kubia-9d785b578-p449x. Your IP is ::ffff:1.2.3.4.

请注意如果您使用Docker Desktop,该服务可以在localhost:8080获得。使用curl或浏览器访问它。恭喜你!如果您使用谷歌Kubernetes引擎,那么您已经成功地向全球的用户发布了您的应用程序。任何知道它的IP和端口的人现在都可以访问它。如果不计算部署集群本身所需的步骤,那么部署应用程序只需要两个简单的命令:

  • kubectl create deployment
  • kubectl expose deployment.

当负载均衡器不可用时,访问应用程序并不是所有的Kubernetes集群都具有提供负载均衡器的机制。Minikube提供的集群就是其中之一。如果您创建了LoadBalancer类型的服务,该服务本身可以工作,但没有负载均衡器。Kubectl总是将外部IP显示为<pending>,您必须使用另一种方法来访问服务。存在几种访问服务的方法。您甚至可以绕过服务,直接访问各个pods,但这主要用于故障排除。你将在第5章中学习如何做到这一点。现在,如果没有可用的负载均衡器,让我们探索下一种更简单的方法来访问您的服务。如下面的清单所示,Minikube可以告诉你在哪里访问该服务:

Listing 3.15 Getting the service URL when using Minikube
$ minikube service kubia --url
http://192.168.99.102:30838

该命令打印出服务的URL。现在你可以将curl或浏览器指向那个URL来访问你的应用程序:

$ curl http://192.168.99.102:30838
Hey there, this is kubia-9d785b578-p449x. Your IP is ::ffff:172.17.0.1.

提示如果在运行minikube service命令时省略了--url选项,那么浏览器将打开并加载服务url。您可能想知道这个IP地址和端口来自哪里。这是Minikube虚拟机的IP。可以执行minikube ip命令来确认这一点。Minikube VM也是您的单一工作节点。端口30838是所谓的节点端口。工作节点上的端口将连接转发到您的服务。当你运行kubectl get svc命令时,你可能已经注意到服务端口列表中的端口:

$ kubectl get svc kubia
NAME       TYPE         CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kubia       LoadBalancer  10.19.243.17 <pending>      8080:30838/TCP 82s

无论您使用的是Minikube还是任何其他Kubernetes集群,您的服务都可以通过这个端口号在所有工作节点上访问。请注意如果您使用Docker Desktop,运行Kubernetes的VM不能通过VM的IP从您的主机OS到达。您只能在VM中通过节点端口访问该服务,方法是使用3.1.1节中描述的特殊容器登录到该服务。如果您知道至少一个工作节点的IP,那么您应该能够通过这个IP:port组合访问您的服务,前提是防火墙规则不阻止您访问该端口。下图显示了外部客户端如何通过节点端口访问应用程序。

图片

图3.11 通过服务节点端口的连接路由
为了连接到我之前提到的负载均衡器,将连接转发到节点,节点再将它们转发到容器:节点端口正是负载均衡器将传入请求发送到的位置。然后Kubernetes确保它们被转发到容器中运行的应用程序。您将在第10章中了解它是如何做到这一点的,因为我们将更深入地研究服务。在此之前不要花太多时间去想它。相反,让我们用集群多做一些工作,看看Kubernetes还能做什么。

3.3.3 横向扩展应用程序

您现在有了一个运行中的应用程序,该应用程序由Deployment表示,并通过Service对象向外界公开。现在让我们创建一些额外的魔法。

在容器中运行应用程序的主要好处之一是可以轻松扩展应用程序部署。当前正在运行应用程序的单个实例。假设您突然看到更多用户使用您的应用程序。单个实例不再能够处理负载。需要运行其他实例来分配负载并为用户提供服务。这被称为水平扩展。对于Kubernetes,这是很简单的。

增加正在运行的应用程序实例的数量

要部署应用程序,需要创建一个Deployment对象。默认情况下,它运行应用程序的单个实例。要运行其他实例,只需使用以下命令扩展Deployment对象:

$ kubectl scale deployment kubia --replicas=3deployment.apps/kubia scaled

现在,您已经告诉Kubernetes想要运行您的pod的三个副本。请注意,您还没有指示Kubernetes做什么。你没有告诉它再加两个pod。您只设置了新的所需副本数量,并让Kubernetes决定它必须采取什么操作才能达到新的所需状态。这是Kubernetes最基本的原则之一。您不必告诉Kubernetes要做什么,只需设置系统的一个新的理想状态,并让Kubernetes实现它。为此,它检查当前状态,将其与期望状态进行比较,识别差异,并确定必须采取哪些措施来协调它们。查看扩展的结果虽然 kubectl scale deployment 命令看起来是必须的,因为它显然是告诉Kubernetes扩展您的应用程序,但是该命令实际上做的是修改指定的Deployment对象。正如您将在后面的章节中看到的,您可以简单地编辑对象,而不是给出命令式命令。让我们再次查看Deployment对象,看看scale命令是如何影响它的:

$ kubectl get deployNAME    READY   UP-TO-DATE   AVAILABLE   AGEkubia   3/3     3            3           18m

现在有三个实例是可用的,三个容器中的三个已经准备好了。从命令输出中不能清楚地看出这一点,但是这三个容器不是同一个pod实例的一部分。有三个pod,每个都有一个容器。可以通过列出pods来确认这一点:

$ kubectl get podsNAME                    READY   STATUS    RESTARTS   AGEkubia-9d785b578-58vhc   1/1     Running   0          17skubia-9d785b578-jmnj8   1/1     Running   0          17skubia-9d785b578-p449x   1/1     Running   0          18m

正如所看到的,现在存在三个pods。如READY列中所示,每行都有一个容器,而且所有容器都已准备好。所有的pod都是Running。

在列出pods时显示pods的主机节点

如果使用单节点集群,那么所有pods都运行在同一个节点上。但是在多节点集群中,这三个pods应该分布在整个集群中。要查看pod分布到哪个节点,可以使用-o wide选项来显示更详细的pod列表:

$ kubectl get pods -o wideNAME                   ...  IP          NODEkubia-9d785b578-58vhc  ...  10.244.1.5  worker1kubia-9d785b578-jmnj8  ...  10.244.2.4  worker2kubia-9d785b578-p449x  ...  10.244.2.3  worker2

请注意

在列出其他对象类型时,还可以使用-o wide 输出选项查看附加信息。

输出表明一个pod被调度到一个节点,而其他两个pod都被调度到另一个节点。调度器通常均匀地分配pods,但这取决于如何配置它。你将在第21章中学习更多关于调度安排的内容。理解pod为什么被调度到worker节点并不重要无论在哪个节点上运行,应用程序的所有实例都具有相同的OS环境,因为它们运行在从相同容器镜像创建的容器中。您可能还记得,在上一章中,唯一不同的是操作系统内核,但这只会在不同节点使用不同的内核版本或加载不同的内核模块时发生。此外,每个pod都有自己的IP,并且可以以相同的方式与任何其他pod通信——不管其他pod是在相同的worker节点、位于相同服务器机架的另一个节点,还是在完全不同的数据中心。到目前为止,您还没有为pods设置资源需求,但是如果您设置了资源需求,那么将为每个pod分配所需的计算资源。对于pod来说,由哪个节点提供这些资源并不重要,只要pod的需求得到满足。因此,您不应该关心pod被调度到何处。这也是为什么默认的kubectl get pods命令不显示所列出的pods的worker节点的信息。在Kubernetes的世界里,这并不是那么重要。如您所见,扩展应用程序非常简单。一旦您的应用程序进入生产环境,并且需要对其进行扩展,就可以使用单个命令添加其他实例,而不必手动安装、配置和运行其他副本。

请注意

应用程序本身必须支持水平伸缩。Kubernetes不会神奇地让你的应用程序可伸缩;复制它只会让它变得微不足道。

在使用该服务时,观察访问三个pods的请求

现在应用程序的多个实例都在运行,让我们看看当您再次点击服务URL时会发生什么。响应是否每次都来自相同的实例?下一个清单显示了发生了什么。

Listing 3.16 Requests sent to the service are spread across all the pods$ curl 35.246.179.22:8080Hey there, this is kubia-9d785b578-58vhc. Your IP is ::ffff:1.2.3.4.//请求到达一个pod$ curl 35.246.179.22:8080Hey there, this is kubia-9d785b578-p449x. Your IP is ::ffff:1.2.3.4.//请求到达第三个pod$ curl 35.246.179.22:8080Hey there, this is kubia-9d785b578-jmnj8. Your IP is ::ffff:1.2.3.4.//请求到达第二个pod$ curl 35.246.179.22:8080Hey there, this is kubia-9d785b578-p449x. Your IP is ::ffff:1.2.3.4.//请求再次到达第三个pod

如果你仔细观察它们的响应,会发现它们与pod的名字相对应。每个请求以随机的顺序到达不同的pod。这就是Kubernetes中的服务在后台有多个pod实例时所做的事情。它们在pod前面充当负载平衡器。让我们使用下面的图来可视化这个系统。

图片

图3.12支持相同服务的多个pods之间的负载平衡

如图所示,不应该将Kubernetes服务本身提供的负载平衡机制与运行在GKE或运行在云中的另一个集群中的基础设施提供的额外负载平衡器混淆。即使使用了Minikube并且没有外部负载均衡器,请求仍然由服务本身分布在这三个pods中。如果您使用GKE,实际上有两个负载平衡器。图中显示了由基础设施提供的负载均衡器跨节点分发请求,然后服务跨pods分发请求。我知道这现在可能会让人很困惑,但是在第10章中会变得很清楚。

3.3.4 了解已部署的应用程序

作为本章的结尾,让我们回顾一下您的系统是由什么组成的。有两种方法来观察你的系统--逻辑视图和物理视图。您刚刚看到了图3.12中的物理视图。有三个正在运行的容器部署在三个工作节点上(使用Minikube时是单个节点)。如果您在云中运行Kubernetes,那么云基础设施还为您创建了一个负载平衡器。Docker Desktop还创建了一种本地负载均衡器。Minikube不创建负载均衡器,但是可以通过节点端口直接访问服务。尽管不同集群中的系统的物理视图存在差异,但逻辑视图总是相同的,无论您使用的是小型开发集群还是具有数千个节点的大型生产集群。如果您不是管理集群的人,甚至不需要担心集群的物理视图。如果一切都如预期的那样工作,那么只需担心逻辑视图。让我们仔细看看这个视图。理解表示应用程序的API对象逻辑视图由在Kubernetes API中创建的对象(直接或间接)组成。下图显示了对象之间是如何相互关联的。

图片

图3.13 部署的应用程序由一个Deployment、几个Pods和一个Service组成。
对象如下所示:

  • 创建的Deployment对象,

  • 根据部署自动创建的Pod对象和

  • 手动创建的Service对象。

在刚才提到的三个对象之间还有其他对象,但你还不需要知道它们。你将在接下来的章节中了解它们。

还记得我在第一章中解释过Kubernetes对基础结构进行了抽象吗?应用程序的逻辑视图就是一个很好的例子。没有节点,没有复杂的网络拓扑,没有物理负载平衡器。只是一个简单的视图,只包含您的应用程序和支持对象。让我们看看这些对象是如何组合在一起的,以及它们在您的小设置中扮演什么角色。Deployment对象表示应用程序部署。它指定哪个容器镜像包含您的应用程序,以及Kubernetes应用程序应该运行多少个副本。每个副本都由一个Pod对象表示。Service对象表示这些副本的单个通信入口点。理解pods系统最基本和最重要的部分是pods。每个pod定义包含一个或多个组成pod的容器。当Kubernetes启动pod时,它将运行其定义中指定的所有容器。只要存在一个Pod对象,Kubernetes就会尽力确保其容器继续运行。它只在Pod对象被删除时关闭容器。理解Deployment角色当您第一次创建Deployment对象时,只创建了一个Pod对象。但是当您在Deployment中增加所需的副本数量时,Kubernetes会创建额外的副本。Kubernetes确保实际的pods数量总是与期望的数量匹配。
如果一个或多个pods消失,或者它们的状态未知,Kubernetes将替换它们,使实际的pods数量恢复到所需的副本数量。当某人或某物删除pod时,pod会消失,而当运行它的节点由于网络或节点故障不再报告其状态时,pod的状态是未知的。严格地说,Deployment的结果不过是创建一定数量的Pod对象。您可能想知道是否可以直接创建Pods,而不是让Deployment为您创建它们。当然可以这样做,但是如果您想要运行多个副本,就必须单独手动创建每个pod,并确保为每个pod指定一个惟一的名称。然后,您还必须时刻关注您的pods,以便在它们突然消失或运行它们的节点失败时替换它们。这就是为什么您几乎从不直接创建pods,而是使用Deployment的原因。理解为什么需要Service系统的第三个组件是Service对象。通过创建它,您可以告诉Kubernetes您需要一个到pods的通信入口点。无论当前部署了多少副本,该服务都为您提供一个单独的IP地址来与pods进行通信。如果服务由多个pods支持,它就充当一个负载均衡器。但是,即使只有一个pod,您仍然希望通过服务公开它。要理解其中的原因,需要了解有关pods的一个重要细节。pod是短暂的。一个pod可能会在任何时候消失。当它的主机节点发生故障、有人无意中删除了pod,或者将pod从正常的节点中清除,以便为其他更重要的pod腾出空间时,就会发生这种情况。如前一节所述,当通过Deployment创建pods时,丢失的pod会立即被新的pod替换。这个新的pod和它取代的那个不一样。这是一个全新的pod,具有新的IP地址。如果您没有使用service,并且已经将客户机配置为直接连接到原始pod的IP,那么现在需要重新配置所有这些客户机来连接到新pod的IP。在使用service时,这是不必要的。与pods不同,service不是短暂的。当创建一个服务时,将分配一个静态IP地址,该地址在服务的生命周期中不会改变。客户机应该连接到service的IP,而不是直接连接到pod。这确保了它们的连接始终被路由到正常的pod,即使服务背后的pod集一直在变化。当决定水平扩展部署时,它还确保负载均匀地分布在所有pods上。3.4  总结在这个章节中,你会学到:

  • 实际上,所有的云提供商都提供托管Kubernetes选项。它们承担了维护Kubernetes集群的责任,而您只需使用它的API来部署应用程序。
  • 您也可以自己在云中安装Kubernetes,但在您掌握了管理Kubernetes的所有方面之前,这通常不是最好的主意。
  • 您可以在本地安装Kubernetes,甚至在您的笔记本电脑上,使用Docker Desktop或Minikube等工具,它们在Linux虚拟机中运行Kubernetes,或kind,它们将master节点和worker节点作为Docker容器运行,并在这些容器中运行应用程序容器。
  • 命令行工具Kubectl是与Kubernetes交互的常用方式。也存在基于web的仪表板,但不像CLI工具那样稳定和最新。
  • 为了更快地使用kubectl,为它定义一个简短的别名并启用shell补全功能是很有用的。
  • 可以使用kubectl create deployment部署应用程序。然后可以通过运行kubectl expose deployment将其公开给客户端。水平扩展应用程序非常简单:kubectl scale deployment指示Kubernetes添加新的副本或删除现有副本,以达到您指定的副本数量。
  • 部署的基本单元不是容器,而是pod,它可以包含一个或多个相关容器。
  • Deployments、Services、Pods和Nodes都是Kubernetes对象/资源。你可以用kubectl get列出它们,用kubectl describe检查它们。
  • Deployment对象部署所需数量的Pods,而Service对象使它们可以在一个稳定的IP地址下访问。
  • 每个Service都在集群中提供内部负载平衡,但是如果您将服务类型设置为LoadBalancer, Kubernetes将要求它运行的云基础设施提供额外的负载平衡器,以使您的应用程序在一个公共可访问的地址上可用。

现在你已经完成了第一次在导游的带领下游览海湾。现在是时候开始学习缆绳了,这样你就能独立航行了。本书的下一部分着重于不同的Kubernetes对象以及如何/何时使用它们。您将从最重要的一个开始——Pod。

原文地址:https://www.cnblogs.com/lanblogs/p/15162817.html