本文补充了关于在云中部署和管理容器化工作负载的网络研讨会系列 。 该系列涵盖容器的基本要素,包括管理容器生命周期,部署多容器应用程序,扩展工作负载以及使用Kubernetes。 它还突出显示了运行有状态应用程序的最佳实践。
本文补充了系列中的第四部分,Kubernetes近距离观察 。
介绍
Kubernetes是一款用于管理容器化应用程序的开源容器编排工具。 在本系列的前一个教程中 ,您将在DigitalOcean上配置Kubernetes。 现在集群已启动并运行,您可以在其上部署容器化的应用程序。
在本教程中,您将学习如何在Kubernetes中部署Pod,将其作为服务公开并通过复制控制器进行扩展时,这些基元如何协同工作。
先决条件
要完成本教程,您应该先完成本系列中的前一个教程,即Kubernetes入门 。
第1步 - 了解Kubernetes基元
Kubernetes公开了客户端用于创建,缩放和终止应用程序的API。 每个操作都针对Kubernetes管理的其中一个对象。 这些对象构成了Kubernetes的基本构建块。 它们是您管理容器化应用程序的原始程序。
以下是Kubernetes关键API对象的摘要:
- 集群 :计算,存储和网络资源池。
- 节点 :在集群内运行的主机。
- 命名空间 :集群的逻辑分区。
- Pods :部署单位。
- 标签和选择器 :用于标识和服务发现的键值对。
- 服务 :属于同一应用程序的Pod的集合。
- 副本集 :确保可用性和可扩展性。
- 部署 :管理应用程序生命周期。
让我们更详细地看看这些。
运行Kubernetes集群的节点也被视为对象。 它们可以像Kubernetes的任何其他API对象一样进行管理。 为了实现应用程序的逻辑分离,Kubernetes支持名称空间的创建。 例如,一个组织可以在逻辑上对Kubernetes集群进行分区,以运行开发,测试,分段和生产环境。 每个环境都可以放置在独立管理的专用命名空间中。 Kubernetes通过主节点公开其API。
尽管Kubernetes运行Docker容器,但这些容器不能直接部署。 相反,应用程序需要以Kubernetes能够理解的格式进行打包。 这种格式使Kubernetes能够高效地管理容器化的应用程序。 这些应用程序可能包含需要一起工作的一个或多个容器。
Kubernetes包装和部署的基本单位称为Pod 。 每个Pod可能包含一个或多个需要一起管理的容器。 例如,Web服务器(Nginx)容器和缓存(Redis)容器可以作为Pod一起打包。 Kubernetes将属于Pod的所有容器视为逻辑单元。 每次创建一个新的Pod时,都会创建Pod定义中声明的所有容器。 Pod中的所有容器共享相同的上下文,如IP地址,主机名和存储。 它们通过进程间通信(IPC)相互通信,而不是远程调用或REST API。
一旦容器被打包并部署在Kubernetes上,他们需要暴露内部和外部访问。 像数据库和缓存这样的容器不需要暴露于外部世界。 由于API和Web前端将被其他消费者和最终用户直接访问,因此必须向公众公开。 在Kubernetes中,容器根据策略在内部或外部暴露。 该机制将降低向公众公开诸如数据库的敏感工作负载的风险。
通过服务暴露Kubernetes中的豆荚。 每个服务被声明为内部或外部端点以及端口和协议信息。 内部消费者(包括其他Pod)和外部消费者(如API客户端)依靠Kubernetes Services进行基本交互。 服务支持TCP和UDP协议。
Kubernetes中的每个对象(如Pod或Service)都与称为标签和选择器的附加元数据相关联。 标签是连接到Kubernetes对象的键/值对。 这些标签唯一标识一个或多个API对象。 选择器将一个Kubernetes对象与另一个对象关联。 例如,服务中定义的选择器可帮助Kubernetes找到所有具有与选择器的值匹配的标签的窗格。 这种关联可以动态发现对象。 使用相同标签在运行时创建的新对象将立即发现并与相应的选择器关联。 此服务发现机制支持高效的动态配置,如扩展和扩展操作。
切换到容器的优点之一是快速扩展。 因为与虚拟机相比,容器很轻便,所以您可以在几秒钟内缩放它们。 要获得高可用性和可伸缩性的设置,您需要部署多个应用程序实例,并确保这些应用程序的最小数量的实例始终在运行。 为了解决容器化应用的这种配置,Kubernetes引入了副本集的概念,该副本集的设计始终是为了运行一个或多个Pod。 当多个Pod实例需要在群集中运行时,它们将打包为副本集。 Kubernetes将确保副本集中定义的Pod的数量始终处于运行模式。 如果Pod由于硬件或配置问题而终止,则Kubernetes控制面板将立即启动另一个Pod。
部署对象是Pod和副本集的组合。 该原语为Kubernetes应用程序带来类PaaS功能。 它可让您以最少的停机时间对现有部署进行滚动升级。 部署还可实现金丝雀部署和蓝/绿部署等模式。 他们处理容器化应用程序的应用程序生命周期管理(ALM)的基本部分。
第2步 - 列出Kubernetes节点和命名空间
假设您已按照步骤在DigitalOcean中设置Kubernetes群集 ,请运行以下命令以列出所有节点和可用名称空间:
kubectl get nodes
OutputNAME STATUS ROLES AGE VERSION
spc3c97hei-master-1 Ready master 10m v1.8.7
spc3c97hei-worker-1 Ready <none> 4m v1.8.7
spc3c97hei-worker-2 Ready <none> 4m v1.8.7
kubectl get namespaces
OutputNAME STATUS AGE
default Active 11m
kube-public Active 11m
kube-system Active 11m
stackpoint-system Active 4m
当没有指定名称空间时, kubectl
默认名称空间为目标。
现在让我们启动一个应用程序。
第3步-创建和部署Pod
Kubernetes对象在YAML文件中声明并通过kubectl
CLI提交给Kubernetes。 我们来定义一个Pod并部署它。
创建一个名为Simple-Pod.yml
的新YAML文件:
nano Simple-Pod.yaml
添加下面的代码,它定义了一个基于Nginx Web服务器的容器。 它通过TCP协议在端口80
上公开。 请注意,该定义包含标签name
和env
。 我们将使用这些标签来识别和配置特定的Pod。
apiVersion: "v1"
kind: Pod
metadata:
name: web-pod
labels:
name: web
env: dev
spec:
containers:
- name: myweb
image: nginx
ports:
- containerPort: 80
name: http
protocol: TCP
运行以下命令来创建一个Pod。
kubectl create -f Simple-Pod.yml
Outputpod "web-pod" created
我们来验证Pod的创建。
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE
web-pod 1/1 Running 0 2m
在接下来的步骤中,我们将使这个Pod可供公共互联网访问。
第4步 - 通过服务暴露豆荚
服务在内部或外部公开一组Pod。 让我们定义一个使Nginx窗格公开可用的服务。 我们将通过NodePort公开一个Nginx,这个方案使Pod可以通过群集中每个节点上打开的任意端口访问。
创建一个名为Simple-Service.yaml
的新文件,其中包含定义Nginx服务的代码:
apiVersion: v1
kind: Service
metadata:
name: web-svc
labels:
name: web
env: dev
spec:
selector:
name: web
type: NodePort
ports:
- port: 80
name: http
targetPort: 80
protocol: TCP
该服务发现相同名称空间中与name: web
匹配的标签中的所有窗格。 YAML文件的选择器部分明确定义了这种关联。
我们通过type:NodePort声明指定服务是类型NodePort。
然后使用kubectl将其提交给群集。
kubectl create -f Simple-Service.yml
你会看到这个输出表明服务已成功创建:
Outputservice "web-svc" created
让我们来获取Pod可用的端口。
kubectl get services
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.3.0.1 <none> 443/TCP 28m
web-svc NodePort 10.3.0.143 <none> 80:32097/TCP 38s
从这个输出中,我们看到该服务在端口32097
上32097
。 我们尝试连接到其中一个工作节点。
使用DigitalOcean控制台获取其中一个工作节点的IP地址。
使用curl
命令向端口31930
上的其中一个节点发出HTTP请求。
curl http://your_worker_1_ip_address:32097
您将看到包含Nginx默认主页的响应:
Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
您已定义Pod和Service。 现在我们来看看使用Replica Sets进行缩放。
第5步 - 通过副本集缩放荚
副本集可确保群集中至少运行最少数量的Pod。 让我们删除当前的Pod并通过副本集重新创建三个Pod。
首先,删除现有的Pod。
kubectl delete pod web-pod
Outputpod "web-pod" deleted
现在创建一个新的副本集声明。 副本集的定义与Pod相同。 关键的区别在于它包含定义需要运行的Pod数量的副本元素。 与Pod一样,它也包含标签作为帮助进行服务发现的元数据。
创建Simple-RS.yml
文件并将下面的代码添加到文件中:
apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
name: web-rs
labels:
name: web
env: dev
spec:
replicas: 3
selector:
matchLabels:
name: web
template:
metadata:
labels:
name: web
env: dev
spec:
containers:
- name: myweb
image: nginx
ports:
- containerPort: 80
name: http
protocol: TCP
保存并关闭文件。
现在创建副本集:
kubectl create -f Simple-RS.yml
Outputreplicaset "web-rs" created
然后检查豆荚的数量:
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE
web-rs-htb58 1/1 Running 0 38s
web-rs-khtld 1/1 Running 0 38s
web-rs-p5lzg 1/1 Running 0 38s
当我们通过NodePort访问服务时,请求将被发送到由副本集管理的一个Pod中。
让我们通过删除其中一个Pod来测试副本集的功能,并查看发生了什么:
kubectl delete pod web-rs-p5lzg
Outputpod "web-rs-p5lzg" deleted
再看看豆荚:
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE
web-rs-htb58 1/1 Running 0 2m
web-rs-khtld 1/1 Running 0 2m
web-rs-fqh2f 0/1 ContainerCreating 0 2s
web-rs-p5lzg 1/1 Running 0 2m
web-rs-p5lzg 0/1 Terminating 0 2m
一旦Pod被删除,Kubernetes创建了另一个来确保所需计数得以维持。
现在让我们看看部署。
第6步 - 处理部署
虽然可以将容器部署为Pod和Replica集,但部署可以更轻松地升级和修补应用程序。 您可以使用部署来就地升级Pod,这是副本集无法实现的。 这使得可以以最少的停机时间推出新版本的应用程序。 他们将类PaaS功能带入应用程序管理。
在创建部署之前删除现有的副本集。 这也将删除关联的Pod:
kubectl delete rs web-rs
Outputreplicaset "web-rs" deleted
现在定义一个新的部署。 创建Simple-Deployment.yaml
文件并添加以下代码:
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: web-dep
labels:
name: web
env: dev
spec:
replicas: 3
selector:
matchLabels:
name: web
template:
metadata:
labels:
name: web
spec:
containers:
- name: myweb
image: nginx
ports:
- containerPort: 80
创建一个部署并验证创建。
kubectl create -f Simple-Deployment.yml
Outputdeployment "web-dep" created
查看部署:
kubectl get deployments
OutputNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
web-dep 3 3 3 3 1m
由于部署导致创建Pod,因此在YAML文件中将有三个Pod按照副本声明运行。
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE
web-dep-8594f5c765-5wmrb 1/1 Running 0 2m
web-dep-8594f5c765-6cbsr 1/1 Running 0 2m
web-dep-8594f5c765-sczf8 1/1 Running 0 2m
我们之前创建的服务将继续将请求路由到由部署创建的Pod。 这是因为包含与原始Pod定义相同的值的标签。
通过删除部署和服务来清理资源。
kubectl delete deployment web-dep
Outputdeployment "web-dep" deleted
kubectl delete service web-svc
Outputservice "web-svc" deleted
有关部署的更多详细信息,请参阅Kubernetes文档 。
结论
在本教程中,您将探索使用Pod,服务,副本集和部署部署Nginx Web服务器时Kubernetes的基本构建块。
在本系列的下一部分中,您将学习如何打包,部署,扩展和管理多容器应用程序。