Kubernetes(3)——逐个解析kubernetes基础操作代码

  写在前面

从这节课开始我们正式进入以minikube为基础的K8S的实验部分。这部分其实大体上可以分为,创建集群,部署应用,查看应用,发布应用,伸缩应用以及更新应用这6个部分,本文将会逐一对这6个部分进行讲解。本文的基本概念和实验代码全部copy自kubernetes官方文档,首先感谢我们前面伟大的工程师的对K8S的贡献。写本文的动机是因为菜白自己在学习的时候遇到了很多confuse,就是针对上述的confuse进行的解释大家可以和原本的教程对照着学习,希望对各位读者有帮助。

创建Minikube集群

1. 了解 Kubernetes 集群

Kubernetes 协调一个高可用计算机集群,每个计算机作为独立单元互相连接工作。 Kubernetes 中的抽象允许您将容器化的应用部署到群集,而无需将它们绑定到某个特定的独立计算机。为了使用这种新的部署模型,应用需要以将应用与单个主机分离的方式打包:它们需要被容器化。与过去的那种应用直接以包的方式深度与主机集成的部署模型相比,容器化应用更灵活、更可用。 Kubernetes 以更高效的方式跨群集自动分发和调度应用容器。 Kubernetes 是一个开源平台,并且可应用于生产环境。Kubernetes(3)——逐个解析kubernetes基础操作代码_第1张图片

Kubernetes 分成了Node和Master两个部分。

Master负责管理整个集群。 Master协调集群中的所有活动,例如调度应用、维护应用的所需状态、应用扩容以及推出新的更新。

 

Node是一个虚拟机或者物理机,它在Kubernetes集群中充当工作机器的角色每个Node都有 Kubelet , 它管理 Node而且是Node与Master通信的代理。Node 还应该具有用于​​处理容器操作的工具,例如Docker或rkt。处理生产级流量的Kubernetes集群至少应具有三个Node。

Master 管理集群,Node 用于托管正在运行的应用。

在 Kubernetes上部署应用时,您告诉Master启动应用容器。Master 就编排容器在群集的 Node 上运行。Node使用Master暴露的Kubernetes API与Master通信。终端用户也可以使用 Kubernetes API 与集群交互。

2. 了解Minikube

minikube quickly sets up a local Kubernetes cluster on macOS, Linux, and Windows. We proudly focus on helping application developers and new Kubernetes users.

3. 开启一个 Kubernetes 集群

使用minikube 命令查看minikube的版本

minikube version

使用minikube命令启用minikube

minikube start

使用kubectl命令查看kubectl客户端和Kubernetes服务端的版本

kubectl version

使用这个命令可以查看cluster的详细信息

kubectl cluster-info

使用这个命令可以查看系欸但的数量状态等信息

kubectl get nodes

使用 kubectl 创建Deployment

1. 了解 Deployments 请求

为了实现在Kubernetes集群上部署容器化应用程序。需要创建一个Kubernetes Deployment,Deployment负责创建和更新应用。创建Deployment后,Kubernetes master 会将Deployment创建好的应用实例调度到集群中的各个节点。

应用实例创建完成后,Kubernetes Deployment Controller会持续监视这些实例。如果管理实例的节点被关闭或删除,那么 Deployment Controller将会替换它们,实现自我修复能力。

“在旧的世界中” ,一般通常安装脚本来启动应用,但是便不会在机器故障后自动恢复。通过在Node节点上运行创建好的应用实例,使 Kubernetes Deployment 对应用管理提供了截然不同的方法。

Kubernetes(3)——逐个解析kubernetes基础操作代码_第2张图片

2. 使用kubectl在Kubernetes上部署应用

在开始练习前,教程涉及了一个关键的知识点。

Kubernetes内部运行的Pod在私有的隔离网络上运行。 默认情况下,它们在同一kubernetes集群中的其他Pod和服务中可见,但在该网络外部不可见。 当使用kubectl时,我们通过API端点进行交互以与我们的应用程序进行通信。

你可以使用下面的命令对部署镜像,部署时需要提供镜像的位置和部署的名称。

kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1

你可以使用下面的命令来罗列之前的部署

kubectl get deployments

下面我们需要创建另外的一个终端

echo -e "\n\n\n\e[92mStarting Proxy. After starting it will not output a response. Please click the first Terminal Tab\n";

kubectl proxy

但是在教程当中出现一段Linux代码,出现在这里非常的突兀,看了很多遍这个代码我都非常的迷惑,我来翻译下这一段帮大家理清一下思路。

                                                                             

                                                                             

                                                                             

 Starting Proxy. After starting it will not output a response. Please click the first Terminal Tab                                              

                                                                             

所以这里其实就是输出一段绿色文字,关键的部分是最后一句,生成一个代理,这个API代理会基于pod的名称自动为每一个pod创建端点。但是这里不会自动生成,需要手动在Terminal2手动输入。

kubectl proxy

使用下面的命令测试代理

curl http://localhost:8001/version

使用下面的命令将pod名称导出,然后存储在环境变量当中;最后输出这个变量。这里涉及到了get pods这个命令的用法,get pods -o后面的部分其实是输出的格式,详细请输入kubectl get pods --help查看。

export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

echo Name of the Pod: $POD_NAME

 

Kubernetes 中查看Pods和Nodes

1. 了解Kubernetes Pod, Node的概念

Kubernetes Pod

在模块2中创建Deployment时,Kubernetes会创建了一个Pod来托管应用。Pod是Kubernetes中一个抽象化概念,由一个或多个容器组合在一起得共享资源。这些资源包括:

  • 共享存储,如 Volumes 卷
  • 网络,唯一的集群IP地址
  • 每个容器运行的信息,例如:容器镜像版本

Pod模型是特定应用程序的“逻辑主机”,并且包含紧密耦合的不同应用容器。

Pod中的容器共享IP地址和端口。

Pod是Kubernetes中的最小单位,当在Kubernetes上创建Deployment时,该Deployment将会创建具有容器的Pods(而不会直接创建容器),每个Pod将被绑定调度到Node节点上,并一直保持在那里直到被终止(根据配置策略)或删除。在节点出现故障的情况下,群集中的其他可用节点上将会调度之前相同的Pod。

Kubernetes(3)——逐个解析kubernetes基础操作代码_第3张图片

Node

一个Pod总是在一个(Node)节点上运行,Node是Kubernetes中的工作节点,可以是虚拟机或物理机。每个Node由 Master管理,Node上可以有多个pod,Kubernetes Master会自动处理群集中Node的pod调度,同时Master的自动调度会考虑每个Node上的可用资源。

 

每个Kubernetes Node上至少运行着:

  • Kubelet,管理Kubernetes Master和Node之间的通信; 管理机器上运行的Pods和containers容器。
  • container runtime(如Docker,rkt)。

Kubernetes(3)——逐个解析kubernetes基础操作代码_第4张图片

Kubectl 指令的功能

  • kubectl get - 列出资源
  • kubectl describe - 显示资源的详细信息
  • kubectl logs - 打印pod中的容器日志
  • kubectl exec - pod中容器内部执行命令

可以使用这些命令来查看应用程序何时部署、它们当前的状态是什么、它们在哪里运行以及它们的配置是什么。

2. 浏览我的app

我们可以通过下面的代码查看我们的pods

kubectl get pods

如果是重新启动pods,命令行会提示

NAME                                   READY   STATUS    RESTARTS   AGE

kubernetes-bootcamp-765bf4c7b4-2xwnn   1/1     Running   0          2m26s

这时候我们不需要做其他额外的操作,只需要稍作等待

我们可以通过下面命令获取pods当中的状态IP 地址,端口号,以及使用的pod的生命周期和image

kubectl describe pods

下面我们用上面提到的代码创建一个新的终端,并且获取Pod的名称。

echo -e "\n\n\n\e[92mStarting Proxy. After starting it will not output a response. Please click the first Terminal Tab\n"; kubectl proxy
export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') echo Name of the Pod: $POD_NAME

用下面的命令测试一下刚刚创建的代理

curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/

用下面的命令获取Pod的日志信息

kubectl logs $POD_NAME

用下面的命令来列出环境变量

kubectl exec $POD_NAME env

用下面的命令进入pod当中的容器,并且开启了一个运行NodeJS应用的控制台。

kubectl exec -ti $POD_NAME bash

用下面的命令可以测试一下啊应用程序

curl localhost:8080

最后退出

exit

 

Kubernetes 使用Service暴露应用

1. Kubernetes Services概述

(凡人皆有一死来描述pod,没有比这跟准确的了)。事实上,Pod是有生命周期的。当一个工作节点(Node)销毁时,节点上运行的Pod也会销毁,然后通过ReplicationController动态创建新的Pods来保持应用的运行。作为另一个例子,考虑一个图片处理 backend,它运行了3个副本,这些副本是可互换的 —— 前端不需要关心它们调用了哪个 backend 副本。也就是说,Kubernetes集群中的每个Pod都有一个独立的IP地址,甚至是同一个节点上的Pod,因此需要有一种方式来自动协调各个Pod之间的变化,以便应用能够持续运行。

Enter Services。Kubernetes中的Service 是一个抽象的概念,它定义了Pod的逻辑分组和一种可以访问它们的策略,这组Pod能被Service访问,使用YAML(优先)或JSON来定义Service,Service所针对的一组Pod通常由LabelSelector实现(参见下文,为什么可能需要没有 selector的Service)。

可以通过type在ServiceSpec中指定一个需要的类型的 Service,Service的四种type:

  • ClusterIP(默认)- 在集群中内部IP上暴露服务。此类型使Service只能从群集中访问。
  • NodePort - 通过每个 Node上的IP和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP服务,这个ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个NodePort 服务。
  • LoadBalancer - 使用云提供商的负载均衡器(如果支持),可以向外部暴露服务。外部的负载均衡器可以路由到NodePort 服务和 ClusterIP 服务。
  • ExternalName - 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容,没有任何类型代理被创建。这种类型需要v1.7版本或更高版本kube-dnsc才支持。

更多不同类型Service的信息,请参考“Using Source IP”教程,Connecting Applications with Services。

使用ExternalName类型可以实现一种情况,在创建Service涉及未定义selector的示例,创建的Service selector不创建相应的Endpoints对象,可以通过手动将Service映射到特定Endpoints。

2. Services和Labels

Kubernetes Service 是一个抽象层,它定义了一组逻辑的Pods,借助Service,应用可以方便的实现服务发现与负载均衡。

Kubernetes(3)——逐个解析kubernetes基础操作代码_第5张图片

如上图,A中Service 路由一组Pods的流量。Service允许pod在Kubernetes中被销毁并复制pod而不影响应用。相关Pod之间的发现和路由(如应用中的前端和后端组件)由Kubernetes Services处理。

Service 使用label selectors来匹配一组Pod,允许对Kubernetes中的对象进行逻辑运算,Label以key/value 键/值对附加到对象上。以多种方式使用:

  • 指定用于开发,测试和生产的对象
  • 嵌入版本Label
  • 使用Label分类对象

Kubernetes(3)——逐个解析kubernetes基础操作代码_第6张图片

3. Expose your app publicly

使用下面的命令获取Pod状态信息

kubectl get pods

使用下面的命令列出正在的Cluster当中运行的服务

kubectl get services

使用下面的命令创建一个新的服务并将其公开出Node的端口给外部流量

kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080

再次运行获取获取服务的命令

kubectl get services

我们发现除了刚刚的ClusterIP,NodePort也被罗列出来,接下来使用下面的命令找到被暴露出来的服务。

kubectl describe services/kubernetes-bootcamp

使用下面的命令创建一个名为“NODE_PORT”的变量

export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}') echo NODE_PORT=$NODE_PORT

然后使用下面的命令测试

curl $(minikube ip):$NODE_PORT

使用下面的命令为Pod自动创建标签

kubectl describe deployment

使用下面的命令查看pod当中值为“run=kubernetes-bootcamp”的标签

kubectl get pods -l run=kubernetes-bootcamp

使用下面的命令查看services当中值为“run=kubernetes-bootcamp”的标签

kubectl get services -l run=kubernetes-bootcamp

使用下面的命令创建一个名为“POD_NAME”的环境变量

export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') echo Name of the Pod: $POD_NAME

使用下面的命令创建新标签,我们使用label命令,后跟对象类型,对象名称和新标签:

kubectl label pod $POD_NAME app=v1

然后使用下面的命令检查刚刚创建好的标签

kubectl describe pods $POD_NAME

可以看到在一个Pod上面打了很多的标签,然后使用下面的命令来获取标签为“app=v1”的pod

kubectl get pods -l app=v1

使用下面的命令删除标签为“run=kubernetes-bootcamp”服务

kubectl delete service -l run=kubernetes-bootcamp

然后使用下面的命令验证

kubectl get services

使用下面的命令来double confirm服务被删除了

最后使用下面的命令来验证app通过内部Curl依旧可以访问

kubectl exec -ti $POD_NAME curl localhost:8080

使用kubectl实现应用伸缩

1. 伸缩应用

在之前模块中,我们创建了一个Deployment,然后通过Service暴露,Deployment创建的Pod来运行应用,当流量增加时,我们需要扩展应用来满足用户需求。

通过Deployment更改副本数可以实现伸缩。

2. 伸缩概述

Kubernetes(3)——逐个解析kubernetes基础操作代码_第7张图片

Kubernetes(3)——逐个解析kubernetes基础操作代码_第8张图片

使用Deployment扩展能确保在新的可用Node资源上创建Pods,缩小比例将减少Pod的数量到理想状态。如果伸缩需求是0,将会终止Deployment指定的所有Pod。Kubernetes还支持自动缩放 Pods,本节将不做介绍。

运行应用将要考虑一些情况,需要将流量分配给所有实例。Service集成了负载均衡器,可以将网络流量分配到Deployment暴露的所有Pod中。Service将使用Endpoints持续监控运行的Pod,以确保仅将流量分配到可用的Pod

下节将讨论如何在不停机的情况下进行滚动更新。现在让我们进入在线终端进行伸缩我们的应用。

3. Scaling a deployment

首先使用下面的命令查看部署的状态,返回的参数包括:名称-name,当前副本数/所需副本-ready,已更新以达到所需状态的副本数- UP-TO-DATE,应用程序的副本数-available,应用程序的运行时间-age

kubectl get deployments

使用下面的命令查看Deployment的副本数量,返回的参数包括:应用程序副本数-desired,当前运行多少个副本-current

kubectl get rs

使用下面的命令来自动扩展部署的数量,在kubectl scale后面需要的参数有,部署的种类,名称和实例的需求数量。

kubectl scale deployments/kubernetes-bootcamp --replicas=4

再次使用下面的命令查看部署的状态

kubectl get deployments

使用下面的命令来查看pod的状态。

kubectl get pods -o wide

使用下面的命令查看暴露的公网IP和端口号

kubectl describe services/kubernetes-bootcamp

使用下面的命令创建一个名为“NODE_PORT”的环境变量

export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}') echo NODE_PORT=$NODE_PORT

使用下面的命令测试

curl $(minikube ip):$NODE_PORT

使用下面的命令将服务缩减到两个副本

kubectl scale deployments/kubernetes-bootcamp --replicas=2

再次使用下面的命令查看部署的状态

kubectl get deployments

再次使用下面的命令来查看pod的状态

kubectl get pods -o wide

使用kubectl实现应用滚动更新

1. 更新应用

用户需求:需要应用始终正常运行,开发人员每天需要部署新的版本(一个简单例子,大家在玩游戏时常常碰到这类公告:8月8日凌晨:2点-6点服务升级,暂停所有服务.....)。在Kubernetes中可以通过滚动更新(Rolling updates )来完成。滚动更新通过Deployments实现应用实例在不中断、不停机情况下更新,新的Pod会逐步调度到可用的资源Node节点上。

 

在前面的模块中,我们对应用进行了伸缩,以运行多个实例。这是在不影响应用可用性的情况下执行更新的需求。更新时的Pod数量可以是数字或百分数(pod)来表示。在Kubernetes更新中,支持升级 / 回滚(恢复)更新。

2. 滚动更新概述

Kubernetes(3)——逐个解析kubernetes基础操作代码_第9张图片

Kubernetes(3)——逐个解析kubernetes基础操作代码_第10张图片

Kubernetes(3)——逐个解析kubernetes基础操作代码_第11张图片

Kubernetes(3)——逐个解析kubernetes基础操作代码_第12张图片

与应用伸缩相似,滚动更新是实现流量负载均衡方式。

  • 滚动更新允许以下操作:
  • 将应用从一个环境升级到另一个环境(通过容器镜像更新)
  • 回滚到之前的版本

持续集成和持续交付应用的零停机

3. Updating Your App

使用下面的命令查看部署的状态

kubectl get deployments

使用下面的命令来查看pod的状态。

kubectl get pods

使用下面的命令来更新pod当中的应用版本

kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2

使用下面的命令查看pod的状态,这里我建议快速多运行几次,可以清晰的看到pod变化。

kubectl get pods

使用下面的命令查看暴露的公网IP和端口号

kubectl describe services/kubernetes-bootcamp

使用下面的命令创建一个名为“NODE_PORT”的环境变量

export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}') echo NODE_PORT=$NODE_PORT

使用下面的命令测试

curl $(minikube ip):$NODE_PORT

使用下面的命令查看资源的状态

kubectl rollout status deployments/kubernetes-bootcamp

使用下面的命令描述所有的pod

kubectl describe pods

使用下面的命令来更新pod当中的应用版本到一个不存在的版本号V10

kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10

使用下面的命令查看部署的状态,会发现“READY”的数量不足

kubectl get deployments

使用下面的命令来查看pod的状态,会发现“STATUS”里面有些虚机状态是Error

kubectl get pods

使用下面的命令来回滚到之前的版本

kubectl rollout undo deployments/kubernetes-bootcamp

使用下面的命令查看部署的状态

kubectl get deployments

使用下面的命令来查看pod的状态。

kubectl get pods

结语

至此,所有的基础教学就完成了,在这里面读者可能会因为Linux当中的Go语法而困扰,因此我会在下一篇当中给大家详细介绍Go-template  

你可能感兴趣的:(kubernetes,docker)