网络研讨会系列:仔细观察Kubernetes

在本教程中,您将学习Kubernetes基元如何在Kubernetes中部署Pod,向其公开一个Service并通过复制控制器对其进行扩展。

本文补充了关于在云中部署和管理容器化工作负载网络研讨会系列 该系列涵盖容器的基本要素,包括管理容器生命周期,部署多容器应用程序,扩展工作负载以及使用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
NAME                  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
NAME                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上公开。 请注意,该定义包含标签nameenv 我们将使用这些标签来识别和配置特定的Pod。

简单Pod.yaml
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
pod "web-pod" created

我们来验证Pod的创建。

kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
web-pod   1/1       Running   0          2m

在接下来的步骤中,我们将使这个Pod可供公共互联网访问。

第4步 - 通过服务暴露豆荚

服务在内部或外部公开一组Pod。 让我们定义一个使Nginx窗格公开可用的服务。 我们将通过NodePort公开一个Nginx,这个方案使Pod可以通过群集中每个节点上打开的任意端口访问。

创建一个名为Simple-Service.yaml的新文件,其中包含定义Nginx服务的代码:

简单Service.yaml
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

你会看到这个输出表明服务已成功创建:

service "web-svc" created

让我们来获取Pod可用的端口。

kubectl get services
NAME         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

从这个输出中,我们看到该服务在端口3209732097 我们尝试连接到其中一个工作节点。

使用DigitalOcean控制台获取其中一个工作节点的IP地址。

DigitalOcean控制台中的Droplet与您的Kubernetes群集相关联。

使用curl命令向端口31930上的其中一个节点发出HTTP请求。

curl http://your_worker_1_ip_address:32097

您将看到包含Nginx默认主页的响应:

<!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
pod "web-pod" deleted

现在创建一个新的副本集声明。 副本集的定义与Pod相同。 关键的区别在于它包含定义需要运行的Pod数量的副本元素。 与Pod一样,它也包含标签作为帮助进行服务发现的元数据。

创建Simple-RS.yml文件并将下面的代码添加到文件中:

简单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
replicaset "web-rs" created

然后检查豆荚的数量:

kubectl get pods
NAME           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
pod "web-rs-p5lzg" deleted

再看看豆荚:

kubectl get pods
NAME           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
replicaset "web-rs" deleted

现在定义一个新的部署。 创建Simple-Deployment.yaml文件并添加以下代码:

简单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
deployment "web-dep" created

查看部署:

kubectl get deployments
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
web-dep   3         3         3            3           1m

由于部署导致创建Pod,因此在YAML文件中将有三个Pod按照副本声明运行。

kubectl get pods
NAME                       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
deployment "web-dep" deleted
kubectl delete service web-svc
service "web-svc" deleted

有关部署的更多详细信息,请参阅Kubernetes文档

结论

在本教程中,您将探索使用Pod,服务,副本集和部署部署Nginx Web服务器时Kubernetes的基本构建块。

在本系列的下一部分中,您将学习如何打包,部署,扩展和管理多容器应用程序。


分享按钮