一、Kubernetes概述

1、K8s介绍

Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,方便进行声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统,其服务、支持和工具的使用范围广泛。

2、K8s能做什么

Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移你的应用、提供部署模式等。 例如,Kubernetes 可以轻松管理系统的 Canary 部署。

应用部署架构分类:

  1. 无中心节点架构:GlusterFS
  2. 有中心节点架构:HDFS(Yarn) 和 K8S

Kubernetes 为你提供:

  • 服务发现和负载均衡

    Kubernetes 可以使用 DNS 名称或自己的 IP 地址来曝露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。

  • 存储编排

    Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。

  • 自动部署和回滚

    你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。

  • 自动完成装箱计算

    你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。 你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。 Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。

  • 自我修复

    Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。

  • 密钥与配置管理

    Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

3、K8s不能做什么

Kubernetes 不是传统的、包罗万象的 PaaS(平台即服务)系统。 由于 Kubernetes 是在容器级别运行,而非在硬件级别,它提供了 PaaS 产品共有的一些普遍适用的功能, 例如部署、扩展、负载均衡,允许用户集成他们的日志记录、监控和警报方案。 但是,Kubernetes 不是单体式(monolithic)系统,那些默认解决方案都是可选、可插拔的。 Kubernetes 为构建开发人员平台提供了基础,但是在重要的地方保留了用户选择权,能有更高的灵活性。

Kubernetes:

  • 不限制支持的应用程序类型。 Kubernetes 旨在支持极其多种多样的工作负载,包括无状态、有状态和数据处理工作负载。 如果应用程序可以在容器中运行,那么它应该可以在 Kubernetes 上很好地运行。

  • 不部署源代码,也不构建你的应用程序。 持续集成(CI)、交付和部署(CI/CD)工作流取决于组织的文化和偏好以及技术要求。

  • 不提供应用程序级别的服务作为内置服务,例如中间件(例如消息中间件)、 数据处理框架(例如 Spark)、数据库(例如 MySQL)、缓存、集群存储系统 (例如 Ceph)。这样的组件可以在 Kubernetes 上运行,并且/或者可以由运行在 Kubernetes 上的应用程序通过可移植机制 (例如开放服务代理)来访问。

  • 不是日志记录、监视或警报的解决方案。 它集成了一些功能作为概念证明,并提供了收集和导出指标的机制。

  • 不提供也不要求配置用的语言、系统(例如 jsonnet),它提供了声明性 API, 该声明性 API 可以由任意形式的声明性规范所构成。

  • 不提供也不采用任何全面的机器配置、维护、管理或自我修复系统

  • 此外,Kubernetes 不仅仅是一个编排系统,实际上它消除了编排的需要。 编排的技术定义是执行已定义的工作流程:首先执行 A,然后执行 B,再执行 C。 而 Kubernetes 包含了一组独立可组合的控制过程,可以连续地将当前状态驱动到所提供的预期状态。 你不需要在乎如何从 A 移动到 C,也不需要集中控制,这使得系统更易于使用 且功能更强大、系统更健壮,更为弹性和可扩展。

4、K8s集群节点主要组件和功能

4.1 控制平面组件(Control Plane Components)

控制平面组件也叫Master组件,对集群进行资源调度、以及检测响应集群事件。

Master节点主要由kube-apiserveretcdkube-schedulerkube-controller-managercloud-controller-manager所组成。

4.2 Node 组件

集群工作节点,负责维护运行的 Pod 并提供 Kubernetes 运行环境。

Node节点主要由kubeletkube-proxy、容器运行时环境(Container Runtime)组成。

二、K8s集群搭建

K8s常见安装方式有工具部署和二进制包部署,本教程以官方部署工具Kubeadm进行部署。

  1. 工具部署:Kubeadm(官方工具)、Kops、Kubespray
  2. 二进制包部署:官方下载二进制包手动编译部署。

1、搭建准备

  • 准备多台机器(操作系统Centos7)
  • 配置好网络(可以翻墙,国内太慢)
  • 禁止swap分区

2、系统初始化

2.1 关闭防火墙

1
2
$ systemctl stop firewalld
$ systemctl disable firewalld

2.2 关闭selinux

1
2
$ sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久关闭 
$ setenforce 0 # 临时关闭

2.3 关闭swap

1
2
$ vim /etc/fstab  # 永久
$ swapoff -a # 临时

2.4 设置主机名

1
$ hostnamectl set-hostname <hostname>

2.5 添加hosts

1
2
3
4
5
$ cat >> /etc/hosts << EOF
192.168.31.61 k8s-master
192.168.31.62 k8s-node1
192.168.31.63 k8s-node2
EOF

2.6 将桥接的 IPv4 流量传递到 iptables 的链

1
2
3
4
5
$ cat > /etc/sysctl.d/k8s.conf << EOF 
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sysctl --system # 生效

2.7 时间同步

1
2
$ yum install ntpdate -y
$ ntpdate time.windows.com

3、安装Docker、Kubeadm、Kubelet

所有机器都需要安装

3.1 安装Docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Step 1: 卸载旧版本
$ sudo yum remove docker docker-client docker-client-latest docker-common docker-latest \
docker-latest-logrotate docker-logrotate \
docker-engine
# Step 2: 安装依赖包并设置仓库源
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
$ sudo yum-config-manager --add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 阿里云源
$ sudo yum-config-manager --add-repo \
https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo # 清华源
# Step 3:安装Docker CE
$ sudo yum install -y docker-ce docker-ce-cli containerd.io
# Step 4: 设置开机自启
$ sudo systemctl enable docker
$ sudo systemctl start docker
# Step 5: 验证是否安装成功
$ docker --version

# 配置阿里云Docker加速(可选)
$ sudo cat > /etc/docker/daemon.json << EOF {
"registry-mirrors": ["https://xxx.mirror.aliyuncs.com"] } # 登陆自己的阿里云复制链接
EOF
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

# 配置阿里云yum源(可选)
$ sudo cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

3.2 安装kubeadm,kubelet 和 kubectl

1
2
3
$ yum install -y kubelet kubeadm kubectl     
$ sudo systemctl enable kubelet
$ sudo systemctl start kubelet

Mac 部署K8s注意调大Docker Desktop资源,网速不好可以手动拉取K8s镜像,但需要注意版本。

4、部署K8s Master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Step 1:在Master节点安装
# 如果直接执行命令出错或者太慢,可以先手动把镜像拉下来在执行的命令
$ kubeadm init \
--apiserver-advertise-address=10.0.2.15 \ # 注意apiserver地址
--image-repository registry.aliyuncs.com/google_containers \ # aliyun源
--kubernetes-version v1.17.3 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16
# Step 2:启用kubectl
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
# Step 3:安装Pod网站插件(CNI)
$ kubectl apply –f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
$ watch kubectl get pod -n kube-system -o wide # 监控pod进度
# Step 4:使用kubectl工具
$ kubectl get nodes # 获取所有节点
$ kubectl get namespaces # 获取所有namespaces
$ kubectl get pods -n <namespaces> # 获取所有Pod,可以添加 <--all-namespaces> 参数。

# 手动拉取镜像
#!/bin/bash
images=(
kube-apiserver:v1.17.3
kube-proxy:v1.17.3
kube-controller-manager:v1.17.3
kube-scheduler:v1.17.3
coredns:1.6.5
etcd:3.4.3-0
pause:3.1
)
for imageName in ${images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
# docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
done

如果直接执行Step 1 命令出错或者太慢,可以先手动把镜像拉下来在执行Step 1 的命令;

更多拓展插件:https://kubernetes.io/zh-cn/docs/concepts/cluster-administration/addons/

Step 3安装网络插件如果image拉不下来可以取Docker hub上找一个并修改kube-flannel.yml文件地址;

5、部署Node节点,并加入K8s集群

1
2
3
4
5
# 部署Node节点,并将新节点添加到K8s集群,注意修改 IP地址
$ kubeadm join <Master节点IP>:6443 --token esce21.q6hetwm8si29qxwn \
--discovery-token-ca-cert-hash sha256:00603a05805807501d7181c3d60b478788408cfe6cedefedb1f97569708be9c5
# 如果token过期,手动生成token
$ kubeadm token create --print-join-command

6、测试集群(部署一个应用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Step 1:使用 kubectl 创建Deployment
$ kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8
# Step 2:查看Pods和Nodes
$ kubectl get pods <namespaces>
$ kubectl get nodes -o wide # -o wide 打印详细信息
# Step 3:使用Service暴露应用
$ kubectl expose deployment tomcat6 --port=80 --target-port=8080 --type=NodePort
$ kubectl get service # 查看访问端口
# Step 4:应用伸缩
$ kubectl scale --replicas=3 deployment tomcat6
# Step 5:应用更新
# kubectl set image deployment.apps/<deployment名称> <容器名称>=<镜像>:<版本>
$ kubectl set image deployment.apps/tomcat7 tomcat7=tomcat:7.0.53-jre8
# Step 6:回滚应用
$ kubectl get deployment
$ kubectl rollout history deployment tomcat7 # 查看deployment记录
$ kubectl rollout history deployment tomcat7 --revision=<版本号> # 查看版本详细信息
$ kubectl rollout undo deployment tomcat7 --to-revision=<版本号> # 回退到某个版本

# Step 7:其他命令
$ kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8 --dry-run -o yaml # 预执行并打印yaml

7、常用命令

1
2
3
4
5
6
$ kubectl get node -o wide                           # 获取集群节点
$ kubectl get ns # 获取namespaces
$ kubectl get all --all-namespaces
$ kubectl get pods --all-namespaces # 获取pod
$ kubectl get pod -n kube-system
$ kubectl get svc -n kube-system # 获取services

到此K8s集群已经搭建完成。

TUDO

部署可视化界面、部署helm、部署KubeSphere

三、核心架构

K8s 中文文档: http://docs.kubernetes.org.cn/251.html

1、K8s架构

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

一个 Kubernetes 集群包含两种类型的资源:

  • Master 调度整个集群
  • Nodes 负责运行应用

architecture

Kubernetes主要由以下几个核心组件组成:

  • etcd保存了整个集群的状态;
  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;

除了核心组件,还有一些推荐的Add-ons:

  • kube-dns负责为整个集群提供DNS服务
  • Ingress Controller为服务提供外网入口
  • Heapster提供资源监控
  • Dashboard提供GUI
  • Federation提供跨可用区的集群
  • Fluentd-elasticsearch提供集群日志采集、存储与查询

img

img

分层架构

Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示

img

  • 核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
  • 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
  • 接口层:kubectl命令行工具、客户端SDK以及集群联邦
  • 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
    • Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等
    • Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

2、部署一个应用

在K8s中部署一个应用的整个过程

官方文档教学: https://kubernetes.io/zh-cn/docs/tutorials/kubernetes-basics/

1、使用 kubectl 创建Deployment

1
2
3
4
# 创建Deployment
$ kubectl create deployment <deployment名称> --image=<镜像名称>:<镜像版本>
# 查看Deployment
$ kubectl get deployment

Kubernetes Deployments

一旦运行了 Kubernetes 集群,就可以在其上部署容器化应用程序。 为此,你需要创建 Kubernetes Deployment 配置。Deployment 指挥 Kubernetes 如何创建和更新应用程序的实例。创建 Deployment 后,Kubernetes master 将应用程序实例调度到集群中的各个节点上。

创建应用程序实例后,Kubernetes Deployment 控制器会持续监视这些实例。 如果托管实例的节点关闭或被删除,则 Deployment 控制器会将该实例替换为集群中另一个节点上的实例。 这提供了一种自我修复机制来解决机器故障维护问题。

在没有 Kubernetes 这种编排系统之前,安装脚本通常用于启动应用程序,但它们不允许从机器故障中恢复。通过创建应用程序实例并使它们在节点之间运行, Kubernetes Deployments 提供了一种与众不同的应用程序管理方法。

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

img

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

Node 是一个虚拟机或者物理机,它在 Kubernetes 集群中充当工作机器的角色 每个Node都有 Kubelet , 它管理 Node 而且是 Node 与 Master 通信的代理。 Node 还应该具有用于处理容器操作的工具,例如 Docker 或 rkt 。处理生产级流量的 Kubernetes 集群至少应具有三个 Node,因为如果一个 Node 出现故障其对应的 etcd 成员和控制平面实例都会丢失,并且冗余会受到影响。 你可以通过添加更多控制平面节点来降低这种风险 。

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

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

Kubernetes 既可以部署在物理机上也可以部署在虚拟机上。你可以使用 Minikube 开始部署 Kubernetes 集群。 Minikube 是一种轻量级的 Kubernetes 实现,可在本地计算机上创建 VM 并部署仅包含一个节点的简单集群。 Minikube 可用于 Linux , macOS 和 Windows 系统。Minikube CLI 提供了用于引导集群工作的多种操作,包括启动、停止、查看状态和删除。

2、Pod和Node

1
$ kubectl apply -f pod.yaml

Kubernetes Pods

在创建 Deployment 时, Kubernetes 添加了一个 Pod 来托管你的应用实例。Pod 是 Kubernetes 抽象出来的,表示一组一个或多个应用程序容器(如 Docker),以及这些容器的一些共享资源。这些资源包括:

  • 共享存储,当作卷
  • 网络,作为唯一的集群 IP 地址
  • 有关每个容器如何运行的信息,例如容器镜像版本或要使用的特定端口。

Pod 为特定于应用程序的“逻辑主机”建模,并且可以包含相对紧耦合的不同应用容器。例如,Pod 可能既包含带有 Node.js 应用的容器,也包含另一个不同的容器,用于提供 Node.js 网络服务器要发布的数据。Pod 中的容器共享 IP 地址和端口,始终位于同一位置并且共同调度,并在同一工作节点上的共享上下文中运行。

Pod是 Kubernetes 平台上的原子单元。 当我们在 Kubernetes 上创建 Deployment 时,该 Deployment 会在其中创建包含容器的 Pod (而不是直接创建容器)。每个 Pod 都与调度它的工作节点绑定,并保持在那里直到终止(根据重启策略)或删除。 如果工作节点发生故障,则会在集群中的其他可用工作节点上调度相同的 Pod。

img

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

img

使用 kubectl 进行故障排除

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

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

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

3、Service

1
2
3
4
# 创建一个service
$ kubectl apply -f service.yaml
# 查看service
$ kubectl get service

Kubernetes Pod 是转瞬即逝的。 Pod 实际上拥有 生命周期。 当一个工作 Node 挂掉后, 在 Node 上运行的 Pod 也会消亡。 ReplicaSet 会自动地通过创建新的 Pod 驱动集群回到目标状态,以保证应用程序正常运行。 换一个例子,考虑一个具有3个副本数的用作图像处理的后端程序。这些副本是可替换的; 前端系统不应该关心后端副本,即使 Pod 丢失或重新创建。也就是说,Kubernetes 集群中的每个 Pod (即使是在同一个 Node 上的 Pod )都有一个唯一的 IP 地址,因此需要一种方法自动协调 Pod 之间的变更,以便应用程序保持运行。

Kubernetes 中的服务(Service)是一种抽象概念,它定义了 Pod 的逻辑集和访问 Pod 的协议。Service 使从属 Pod 之间的松耦合成为可能。 和其他 Kubernetes 对象一样, Service 用 YAML (更推荐) 或者 JSON 来定义. Service 下的一组 Pod 通常由 LabelSelector (请参阅下面的说明为什么你可能想要一个 spec 中不包含selector的服务)来标记。

尽管每个 Pod 都有一个唯一的 IP 地址,但是如果没有 Service ,这些 IP 不会暴露在集群外部。Service 允许你的应用程序接收流量。Service 也可以用在 ServiceSpec 标记type的方式暴露

  • ClusterIP (默认) - 在集群的内部 IP 上公开 Service 。这种类型使得 Service 只能从集群内访问。
  • NodePort - 使用 NAT 在集群中每个选定 Node 的相同端口上公开 Service 。使用<NodeIP>:<NodePort> 从集群外部访问 Service。是 ClusterIP 的超集。
  • LoadBalancer - 在当前云中创建一个外部负载均衡器(如果支持的话),并为 Service 分配一个固定的外部IP。是 NodePort 的超集。
  • ExternalName - 通过返回带有该名称的 CNAME 记录,使用任意名称(由 spec 中的externalName指定)公开 Service。不使用代理。这种类型需要kube-dns的v1.7或更高版本。

更多关于不同 Service 类型的信息可以在使用源 IP 教程。 也请参阅 连接应用程序和 Service

另外,需要注意的是有一些 Service 的用例没有在 spec 中定义selector。 一个没有selector创建的 Service 也不会创建相应的端点对象。这允许用户手动将服务映射到特定的端点。没有 selector 的另一种可能是你严格使用type: ExternalName来标记。

Kubernetes 的 Service 是一个抽象层,它定义了一组 Pod 的逻辑集,并为这些 Pod 支持外部流量暴露、负载平衡和服务发现。

Services和Labels

img

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

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

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

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

img

标签(Label)可以在创建时或之后附加到对象上。他们可以随时被修改。现在使用 Service 发布我们的应用程序并添加一些 Label 。

4、扩缩应用程序

1
2
$ kubectl set image deployment.apps/<deployment名称> <容器名称>=<镜像>:<版本>
$ kubectl set image deployment.apps/tomcat7 tomcat6=tomcat:6.0.53-jre8

在之前的模块中,我们创建了一个 Deployment,然后通过 Service让其可以开放访问。Deployment 仅为跑这个应用程序创建了一个 Pod。 当流量增加时,我们需要扩容应用程序满足用户需求。

扩缩 是通过改变 Deployment 中的副本数量来实现的。

在运行 kubectl run 命令时,你可以通过设置 –replicas 参数来设置 Deployment 的副本数。

img

img

扩展 Deployment 将创建新的 Pods,并将资源调度请求分配到有可用资源的节点上,收缩 会将 Pods 数量减少至所需的状态。Kubernetes 还支持 Pods 的自动缩放,但这并不在本教程的讨论范围内。将 Pods 数量收缩到0也是可以的,但这会终止 Deployment 上所有已经部署的 Pods。

运行应用程序的多个实例需要在它们之间分配流量。服务 (Service)有一种负载均衡器类型,可以将网络流量均衡分配到外部可访问的 Pods 上。服务将会一直通过端点来监视 Pods 的运行,保证流量只分配到可用的 Pods 上。

一旦有了多个应用实例,就可以没有宕机地滚动更新。

扩缩是通过改变 Deployment 中的副本数量来实现的。

5、更新应用程序

1
2
3
4
$ kubectl get deployment
$ kubectl rollout history deployment tomcat7 # 查看deployment记录
$ kubectl rollout history deployment tomcat7 --revision=<版本号> # 查看版本详细信息
$ kubectl rollout undo deployment tomcat7 --to-revision=<版本号> # 回退到某个版本

用户希望应用程序始终可用,而开发人员则需要每天多次部署它们的新版本(一个简单例子,大家在玩游戏时常常碰到这类公告:8月8日凌晨:2点-6点服务升级,暂停所有服务…..)*。在 Kubernetes 中,这些是通过滚动更新(Rolling Updates)完成的。 滚动更新 允许通过使用新的实例逐步更新 Pod 实例,零停机进行 Deployment 更新。新的 Pod 将在具有可用资源的节点上进行调度。

在前面的模块中,我们将应用程序扩展为运行多个实例。这是在不影响应用程序可用性的情况下执行更新的要求。默认情况下,更新期间不可用的 pod 的最大值和可以创建的新 pod 数都是 1。这两个选项都可以配置为(pod)数字或百分比。 在 Kubernetes 中,更新是经过版本控制的,任何 Deployment 更新都可以恢复到以前的(稳定)版本,支持升级 / 回滚(恢复)更新。

滚动更新允许通过使用新的实例逐步更新 Pod 实例从而实现 Deployments 更新,停机时间为零。

img

img

img

img

与应用程序扩展类似,如果 Deployment 是公开的,服务将在更新期间仅对可用的 pod 进行负载均衡。可用 Pod 是应用程序用户可用的实例。

滚动更新允许以下操作:

  • 将应用程序从一个环境提升到另一个环境(通过容器镜像更新)
  • 回滚到以前的版本
  • 持续集成和持续交付应用程序,无需停机

如果 Deployment 是公开的,则服务将仅在更新期间对可用的 pod 进行负载均衡。

参考