使用kubectl实现应用滚动更新

更新应用

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

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

滚动更新概述

(1)

(2)

(3)

(4)

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

滚动更新允许以下操作:

  • 将应用从一个环境升级到另一个环境(通过容器镜像更新)
  • 回滚到之前的版本
  • 持续集成和持续交付应用的零停机

在下面的交互式教程中,我们的应用将更新到一个新的版本,并执行回滚。

K8S中文社区微信公众号

使用kubectl实现应用伸缩

伸缩应用

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

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

伸缩概述

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

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

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

K8S中文社区微信公众号

Kubernetes 使用Service暴露应用

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 服务会自动创建。通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 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。

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

Services和Labels

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

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

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

你可以在使用
--exposekubectl 创建 Deployment 的同时创建 Service 。

 

 

Label可以在创建时或以后附加到对象上,可以随时修改。

下一步:使用在线互动教程

K8S中文社区微信公众号

Kubernetes 中查看Pods和Nodes

Kubernetes Pod

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

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

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

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

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

Pod概述

 

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)。

Node概述

 

Troubleshooting with kubectl

在第2单元中,使用了Kubectl 命令管理工具。我们继续在模块3中使用它来获取有关Deployment的应用及其环境信息。常见的操作可以通过以下kubectl命令完成:

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

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

现在我们已经了解了更多关于集群组件和命令的信息,接下来让我们来探究一下应用

K8S中文社区微信公众号

使用 kubectl 创建Deployment

目标

  • 了解 Deployments 请求。
  • 使用kubectl在Kubernetes上部署应用。

Kubernetes Deployments

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

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

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

在Kubernetes上部署第一个应用程序

使用Kubernetes Kubectl(命令管理工具)创建和管理Deployment。Kubectl使用Kubernetes API与集群进行交互。在本学习模块中,学会在Kubernetes集群上运行应用所需Deployment的Kubectl常见命令。

创建Deployment时,需要为应用程序指定容器镜像以及要运行的副本数,后续可以通过Deployment更新来更改该这些信息; bootcamp的第5和第6部分讨论了如何扩展和更新Deployment。

K8S中文社区微信公众号

使用Minikube 部署 Kubernetes 集群

单机部署

创建Kubernetes cluster(单机版)最简单的方法是minikube:

首先下载kubectl

curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.6.4/bin/linux/amd64/kubectl
chmod +x kubectl

安装minikube

# install minikube
$ brew cask install minikube
$ brew install docker-machine-driver-xhyve
# docker-machine-driver-xhyve need root owner and uid
$ sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
$ sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve

最后启动minikube

# start minikube.
# http proxy is required in China
$ minikube start --docker-env HTTP_PROXY=http://proxy-ip:port --docker-env HTTPS_PROXY=http://proxy-ip:port --vm-driver=xhyve

开发版

minikube/localkube只提供了正式release版本,而如果想要部署master或者开发版的话,则可以用hack/local-up-cluster.sh来启动一个本地集群:

cd $GOPATH/src/k8s.io/kubernetes

export KUBERNETES_PROVIDER=local
hack/install-etcd.sh
export PATH=$GOPATH/src/k8s.io/kubernetes/third_party/etcd:$PATH
hack/local-up-cluster.sh

打开另外一个终端,配置kubectl:

cd $GOPATH/src/k8s.io/kubernetes
export KUBECONFIG=/var/run/kubernetes/admin.kubeconfig
cluster/kubectl.sh

//本文由 aleen42 提供 /发布在 feisky

K8S中文社区微信公众号