一、Kubernetes介绍

Kubernetes是一款容器编排工具,以下简称k8s(k到s中间有8个字母所以是k8s),为了更快的入门k8s我们首先要对k8s的一些概念有所了解。

K8s介绍

官方定义的k8s是能够对容器化软件进行部署和管理,也就是可以在不停机的情况下提供简单快速的发布和更新方式。简单点来说,**如果项目需要多机器节点的微服务架构,并且采用的是Docker进行容器化部署的,那么k8s就可以帮我们屏蔽集群的复杂性,自动选择最优资源分配方式进行部署。**k8s提供简单的多实例部署及更新方案,几个命令就可以实现。

回顾

为了理解Kubernetes的用处,我们先回顾部署应用的历史。

image-20221001142600457

在部署应用上经历了以上三个时代:

  • 传统部署:应用直接部署到物理机上,缺陷很明显!有的应用占用资源多,有的占用资源少,这就造成了资源分配不均、利用率不足的情况。

  • 虚拟机部署:针对上述问题,虚拟化技术应运而生。用户可以在单台物理机的cpu上运行多个虚拟机。

    • 虚拟化技术使应用程序被虚拟机分开了,限制了应用程序之间的非法访问,进而提供了一定程序的安全
    • 提高了物理机的资源利用率,降低了硬件成本。
    • 每一个虚拟机可认为自己是被虚拟化的物理机上的一台完整机器。
  • 容器化部署时代:容器与虚拟机类似,它降低了隔离层级,共享了OS。所以,容器可以认为是轻量级的

    • 与虚拟机相似,每个容器都有自己的文件系统、CPU、内存、进程空间等。
    • 运行应用程序需要的资源都被容器包装
    • 容器化的应用可以跨OS发行版进行部署

k8s功能

  • 服务发现和负载均衡

k8s可以通过ip地址暴露容器的的访问方式,在同组容器中可实现负载均衡

  • 存储编排

k8s可以自动挂在指定的存储系统,nfs、云存储…

  • 自动发布和回滚

我们可以在k8s中声明应用程序容器应该达到的状态,K8s将以合适的速率调整容器的状态,并自动达到期望的效果

  • 自愈
    • 重新启动已经停机的容器
    • 在容器没有准备完成之前,不会让调用者发现该容器
    • 替换、kill掉不健康的容器

k8s的组件

Master组件

  • master组件是负责集群中的全局决策
  • master 组件探测并响应集群事件(当 Deployment 的实际 Pod 副本数未达到 replicas 字段的规定时,启动一个新的 Pod)

为了简介性,master组件运行在同一台机器上(master)

kube-apiserver

这个组件提供K8s的API。它属于k8s平台的前端,可以水平扩展也就是加服务器数量以提高性能。像后面会用到的kubectl/ kubernetes dashboard / kuboard 等k8s的管理工具其本质上就是调用了k8s的api实现了对k8s集群的管理。

etcd

存储组件,k8s集群相关的配置信息都存储在etcd里。更多信息可以看官方文档

kube-scheduler

此组件监控所有新创建尚未分配到节点上的 Pod,而且自动的为pod选择一个合适的节点运行

kube-controller-manager

就像它的名字一样,所有的控制器都被它管理

它包含的控制器有:

  • 节点控制器: 负责监听节点停机的事件并作出对应响应
  • 副本控制器: 负责为集群中每一个 副本控制器对象(Replication Controller Object)维护期望的 Pod 副本数
  • 端点(Endpoints)控制器:负责为端点对象(Endpoints Object,连接 Service 和 Pod)赋值
  • Service Account & Token控制器: 负责为新的名称空间创建 default Service Account 以及 API Access Token
cloud-controller-manager

cloud-controller-manager 中运行了与具体云基础设施供应商互动的控制器。

Node组件

Node 组件运行在每一个节点上(包括 master 节点和 worker 节点),负责维护运行中的 Pod 并提供 Kubernetes 运行时环境

kubelet

此组件是运行在每一个集群节点上的代理程序。它确保 Pod 中的容器处于运行状态。

kube-proxy

kube-proxy 是一个网络代理程序,运行在集群中的每一个节点上,是实现 Kubernetes Service 概念的重要部分。

kube-proxy 在节点上维护网络规则。这些网络规则使得您可以在集群内、集群外正确地与 Pod 进行网络通信。

容器引擎

容器引擎负责运行容器。

Addons

Addons 使用 Kubernetes 资源(DaemonSet、Deployment等)实现集群的功能特性。由于他们提供集群级别的功能特性,addons使用到的Kubernetes资源都放置在 kube-system 名称空间下。

DNS

除了 DNS Addon 以外,其他的 addon 都不是必须的,所有 Kubernetes 集群都应该有 Cluster DNS

Cluster DNS 是一个 DNS 服务器,是对您已有环境中其他 DNS 服务器的一个补充,存放了 Kubernetes Service 的 DNS 记录。

如果安装过K8s集群的话对这个组件会有印象

Web UI(Dashboard)

Dashboard (opens new window)是一个Kubernetes集群的 Web 管理界面。用户可以通过该界面管理集群。

ContainerResource Monitoring

将容器的度量指标(metrics)记录在时间序列数据库中,并提供了 UI 界面查看这些数据

Cluster-level Logging

将容器的日志存储到一个统一存储中,并提供搜索浏览的界面

Kuboard

Kuboard是一款基于Kubernetes的微服务管理界面,相较于 Dashboard,Kuboard 强调:

  • 无需手工编写 YAML 文件
  • 微服务参考架构
  • 上下文相关的监控
  • 场景化的设计
    • 导出配置
    • 导入配置
KubeSphere

KubeSphere 是在 Kubernetes 之上构建的面向云原生应用的分布式操作系统

提供全栈的 IT 自动化运维能力,简化企业的 DevOps 工作流。

二、Kubenetes入门

k8s集群简单介绍

image-20221001141119460

上图意思就是一个master(主)6个node(工作)节点的k8s集群

image-20221001141226655

Master 负责管理集群 负责协调和管理集群中的所有的活动,比如调用应用程序啊、维护应用的状态、扩展和更新应用程序等。

Worker节点(即图中的Node)是VM或服务器,它们充当k8s集群中的工作计算机。 每个Worker节点都有一个Kubelet,它管理该Worker节点并负责与Master节点通信。每个Worker节点还具有处理容器操作的工具,例如Docker。

简单了解下这些概念即可,让我们继续!

k8s集群搭建

参考

https://blog.csdn.net/qq_45714272/article/details/127049336?spm=1001.2014.3001.5501

部署第一个应用程序

在 k8s 上进行部署前,首先需要了解一个基本概念 Deployment

Deployment 译名为 部署。在k8s中,通过发布 Deployment,可以创建应用程序 (docker image) 的实例 (docker container),这个实例会被包含在称为 Pod 的概念中,Pod 是 k8s 中最小可管理单元。

在 k8s 集群中发布 Deployment 后,Deployment 将指示 k8s 如何创建和更新应用程序的实例,master 节点将应用程序实例调度到集群中的具体的节点上。

创建应用程序实例后,Kubernetes Deployment Controller 会持续监控这些实例。如果运行实例的 worker 节点关机或被删除,则 Kubernetes Deployment Controller 将在群集中资源最优的另一个 worker 节点上重新创建一个新的实例。**这提供了一种自我修复机制来解决机器故障或维护问题,**这个特性在下面的实验中将有所体现。

在容器编排之前的时代,各种安装脚本通常用于启动应用程序但是不能够使应用程序从机器故障中恢复。通过创建应用程序实例并确保它们在集群节点中的运行实例个数,Kubernetes Deployment 提供了一种完全不同的方式来管理应用程序

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

image-20221001164640289

上图是在第一篇文章的基础上,添加上了Deployment、Pod和Container。

Deployment 处于 master 节点上,通过发布 Deployment,master 节点会选择合适的 worker 节点创建 Container(即图中的正方体),Container 会被包含在 Pod (即蓝色圆圈)里。

使用yml文件部署应用
[root@master ~]# vim nginx.yml 
apiVersion: apps/v1	#与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment	#该配置的类型,我们使用的是 Deployment
metadata:	        #译名为元数据,即 Deployment 的一些基本属性和信息
  name: nginx-deployment	#Deployment 的名称
  labels:	    #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
    app: nginx	#为该Deployment设置key为app,value为nginx的标签
spec:	        #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
  replicas: 1	#使用该Deployment创建一个应用程序实例
  selector:	    #标签选择器,与上面的标签共同作用,目前不需要理解
    matchLabels: #选择包含标签app:nginx的资源
      app: nginx
  template:	    #这是选择或创建的Pod的模板
    metadata:	#Pod的元数据
      labels:	#Pod的标签,上面的selector即选择包含标签app:nginx的Pod
        app: nginx
    spec:	    #期望Pod实现的功能(即在pod中部署)
      containers:	#生成container,与docker中的container是同一种
      - name: nginx	#container的名称
        image: nginx:1.7.9	#使用镜像nginx:1.7.9创建container,该container默认80端口可访问

        
[root@master ~]# kubectl apply -f nginx.yml 
deployment.apps/nginx-deployment created
[root@master ~]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           2m45s
[root@master ~]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-85658cc69f-n9bl9   1/1     Running   0          2m53s
自动生成yml文件

自动生成之和,我们可以在进行自定义

[root@master ~]# kubectl create deployment web --image=nginx:nginx:1.7.9 -o yaml --dry-run > my1.ymlW0930 18:38:07.329663   78660 helpers.go:622] --dry-run is deprecated and can be replaced with --dry-run=client.
[root@master ~]# ll
-rw-------. 1 root root 1324 Sep 25 04:24 anaconda-ks.cfg
-rw-r--r--  1 root root  388 Sep 30 18:38 my1.yml

[root@master ~]# kubectl apply -f my1.yml 
deployment.apps/web created
[root@master ~]# kubectl get pods
NAME                                READY   STATUS             RESTARTS   AGE
nginx-deployment-85658cc69f-n9bl9   1/1     Running            0          26m
web-57b577675-lblh2                 0/1     InvalidImageName   0          12s
[root@master ~]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           26m
web                0/1     1            0           21s
使用命令直接部署
[root@master ~]# kubectl create deploy tomcat --image=tomcat6.0.53-jre8
deployment.apps/tomcat created
    
[root@master ~]# kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP               NODE    NOMINATED NODE   READINESS GATES
tomcat6-fd99d4dd6-q6f7k   1/1     Running   0          3m26s   100.66.209.239   node1   <none>           <none>

了解Pods/Nodes

Kubernetes Pods

部署第一个应用程序中创建 Deployment 后,k8s创建了一个 Pod(容器组) 来放置应用程序实例(container 容器)

Pods概述

image-20221001183830670

Pod 容器组 是一个k8s中一个抽象的概念,用于存放一组 container(可包含一个或多个 container 容器,即图上正方体),以及这些 container (容器)的一些共享资源。这些资源包括:

  • 共享存储,称为卷(Volumes),即图上紫色圆柱
  • 网络,每个 Pod(容器组)在集群中有个唯一的 IP,pod(容器组)中的 container(容器)共享该IP地址
  • container(容器)的基本信息,例如容器的镜像版本,对外暴露的端口等

例如,Pod可能既包含带有Node.js应用程序的 container 容器,也包含另一个非 Node.js 的 container 容器,用于提供 Node.js webserver 要发布的数据。Pod中的容器共享 IP 地址和端口空间(同一 Pod 中的不同 container 端口不能相互冲突),始终位于同一位置并共同调度,并在同一节点上的共享上下文中运行。(同一个Pod内的容器可以使用 localhost + 端口号互相访问)。

Pod(容器组)是 k8s 集群上的最基本的单元。当我们在 k8s 上创建 Deployment 时,会在集群上创建包含容器的 Pod (而不是直接创建容器)。每个Pod都与运行它的 worker 节点(Node)绑定,并保持在那里直到终止或被删除。如果节点(Node)发生故障,则会在群集中的其他可用节点(Node)上运行相同的 Pod(从同样的镜像创建 Container,使用同样的配置,IP 地址不同,Pod 名字不同)。

重要:

  • Pod 是一组容器(可包含一个或多个应用程序容器),以及共享存储(卷 Volumes)、IP 地址和有关如何运行容器的信息。
  • 如果多个容器紧密耦合并且需要共享磁盘等资源,则他们应该被部署在同一个Pod(容器组)中。

Node(节点)

下图显示一个 Node(节点)上含有4个 Pod(容器组)

image-20221001184227389

Pod(容器组)总是在 Node(节点) 上运行。Node(节点)是 kubernetes 集群中的计算机,可以是虚拟机或物理机。每个 Node(节点)都由 master 管理。一个 Node(节点)可以有多个Pod(容器组),kubernetes master 会根据每个 Node(节点)上可用资源的情况,自动调度 Pod(容器组)到最佳的 Node(节点)上。

每个 Kubernetes Node(节点)至少运行:

  • Kubelet,负责 master 节点和 worker 节点之间通信的进程;管理 Pod(容器组)和 Pod(容器组)内运行的 Container(容器)。
  • 容器运行环境(如Docker)负责下载镜像、创建和运行容器等。

实战:故障排除

kubectl get - 显示资源列表

kubectl get 资源类型

  • kubectl get deployments 获取类型为Deployment的资源列表
  • kubectl get pods 获取类型为Pod的资源列表
  • kubectl get nodes 获取类型为Node的资源列表
名称空间

在命令后增加 -A--all-namespaces 可查看所有 名称空间中 的对象,使用参数 -n 可查看指定名称空间的对象,例如

# 查看所有名称空间的 Deployment
kubectl get deployments -A
kubectl get deployments --all-namespaces
# 查看 kube-system 名称空间的 Deployment
kubectl get deployments -n kube-system

并非所有对象都在名称空间里

kubectl describe - 显示有关资源的详细信息

kubectl describe 资源类型 资源名称

  • kubectl describe pod nginx-XXXXXX 查看名称为nginx-XXXXXX的Pod的信息
  • kubectl describe deployment nginx 查看名称为nginx的Deployment的信息
kubectl logs - 查看pod中的容器的打印日志

和命令docker logs 类似

kubectl logs -f nginx-pod-XXXXXXX

kubectl exec - 在pod中的容器环境内执行命令

和命令docker exec 类似

kubectl exec -it nginx-pod-xxxxxx /bin/bash

公布应用程序

Kubernetes Service(服务)概述

事实上,pod(容器组)有自己的生命周期。当work node故障时,节点上运行的pod(容器组)也会消失。然后,Deployment可以通过创建新的Pod(容器组)来动态调整集群的原来的状态,以使应用程序保持运行。

虽然pod有自己的ip,但是如果这个pod发生故障了,那pod的ip不就发生变化了吗,那咋办呢?我们需要一种机制,为前端系统屏蔽后端系统的 Pod(容器组)在销毁、创建过程中所带来的 IP 地址的变化。

Kubernetes 中的 Service(服务) 提供了这样的一个抽象层,它选择具备某些特征的 Pod(容器组)并为它们定义一个访问方式。Service(服务)使 Pod(容器组)之间的相互依赖解耦(原本从一个 Pod 中访问另外一个 Pod,需要知道对方的 IP 地址)。一个 Service(服务)选定哪些 Pod(容器组) 通常由 LabelSelector(标签选择器) 来决定。

在创建Service的时候,通过设置配置文件中的 spec.type 字段的值,可以以不同方式向外部暴露应用程序:

  • ClusterIP(默认)

在群集中的内部IP上公布服务,这种方式的 Service(服务)只在集群内部可以访问到

  • NodePort

使用 NAT 在集群中每个的同一端口上公布服务。这种方式下,可以通过访问集群中任意节点+端口号的方式访问服务 <NodeIP>:<NodePort>。此时 ClusterIP 的访问方式仍然可用。

  • LoadBalancer

在云环境中(需要云供应商可以支持)创建一个集群外部的负载均衡器,并为使用该负载均衡器的 IP 地址作为服务的访问地址。此时 ClusterIP 和 NodePort 的访问方式仍然可用。

Service是一个抽象层,它通过 LabelSelector 选择了一组 Pod(容器组),把这些 Pod 的指定端口公布到到集群外部,并支持负载均衡和服务发现。

  • 公布 Pod 的端口以使其可访问
  • 在多个 Pod 间实现负载均衡
  • 使用 Label 和 LabelSelector

服务和标签

下图中有两个服务Service A(黄色虚线)和Service B(蓝色虚线) Service A 将请求转发到 IP 为 10.10.10.1 的Pod上, Service B 将请求转发到 IP 为 10.10.10.2、10.10.10.3、10.10.10.4 的Pod上。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jrk3IerI-1664673404248)(https://raw.githubusercontent.com/YuyanCai/imagebed/main/module_04_services.11cdc7bc.svg)]

Service 将外部请求路由到一组 Pod 中,它提供了一个抽象层,使得 Kubernetes 可以在不影响服务调用者的情况下,动态调度容器组(在容器组失效后重新创建容器组,增加或者减少同一个 Deployment 对应容器组的数量等)。

Service使用 Labels、LabelSelector(标签和选择器) (opens new window)匹配一组 Pod。Labels(标签)是附加到 Kubernetes 对象的键/值对,其用途有多种:

  • 将 Kubernetes 对象(Node、Deployment、Pod、Service等)指派用于开发环境、测试环境或生产环境
  • 嵌入版本标签,使用标签区别不同应用软件版本
  • 使用标签对 Kubernetes 对象进行分类

下图体现了 Labels(标签)和 LabelSelector(标签选择器)之间的关联关系

  • Deployment B 含有 LabelSelector 为 app=B 通过此方式声明含有 app=B 标签的 Pod 与之关联
  • 通过 Deployment B 创建的 Pod 包含标签为 app=B
  • Service B 通过标签选择器 app=B 选择可以路由的 Pod
    在这里插入图片描述

Labels(标签)可以在创建 Kubernetes 对象时附加上去,也可以在创建之后再附加上去。任何时候都可以修改一个 Kubernetes 对象的 Labels(标签)

实战:为nginx Deployment创建一个Service

[root@master ~]# vim nginx-service.yml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service	#Service 的名称
  labels:     	#Service 自己的标签
    app: nginx	#为该 Service 设置 key 为 app,value 为 nginx 的标签
spec:	    #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问
  selector:	    #标签选择器
    app: nginx	#选择包含标签 app:nginx 的 Pod
  ports:
  - name: nginx-port	#端口的名字
    protocol: TCP	    #协议类型 TCP/UDP
    port: 80	        #集群内的其他容器组可通过 80 端口访问 Service
    nodePort: 32600   #通过任意节点的 32600 端口访问 Service
    targetPort: 80	#将请求转发到匹配 Pod 的 80 端口
  type: NodePort	#Serive的类型,ClusterIP/NodePort/LoaderBalancer


[root@master ~]# kubectl apply -f nginx-service.yml
service/nginx-service created

[root@master ~]# kubectl get services -o wide
NAME            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE     SELECTOR
kubernetes      ClusterIP   10.96.0.1     <none>        443/TCP        5d12h   <none>
nginx-service   NodePort    10.96.3.195   <none>        80:32600/TCP   53s     app=nginx

测试

image-20221001193401475

使用命令暴露service端口

参数说明

tomcat已经在k8s中的pod中运行了,如果要对外能够访问的话还需要对外暴露端口

  1. –port pod的端口
  2. –target-port pod里面的tomcat容器的端口
  3. –type指定以何种方式暴露端口

封装成的service模式为NodePort,随机分配一个端口进行暴露

执行完会自动随机一个端口对外暴露,也就是说k8s最后是通过service端口暴露给外部来访问的

测试

kubectl expose deployment tomcat6 --port=80 --target-port=8080 --type=NodePort 
[root@master ~]# kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE     SELECTOR
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        5d8h    <none>
tomcat6      NodePort    10.96.3.240   <none>        80:31975/TCP   9m56s   app=tomcat6

通过k8s集群中的任何一个节点+端口号都可访问

image-20221001105124456

伸缩应用程序

Scaling(伸缩)应用程序

在之前我们说过,我们创建了一个 Deployment (opens new window)提供访问 Pod 的方式。我们发布的 Deployment 只创建了一个 Pod 来运行我们的应用程序。当流量增加时,我们需要对应用程序进行伸缩操作以满足系统性能需求。

伸缩 的实现可以通过更改 nginx-deployment.yaml 文件中部署的 replicas(副本数)来完成

spec:
  replicas: 2    #使用该Deployment创建两个应用程序实例

Scaling(伸缩)概述

下图中,Service A 只将访问流量转发到 IP 为 10.0.0.5 的Pod上

在这里插入图片描述

修改了 Deployment 的 replicas 为 4 后,Kubernetes 又为该 Deployment 创建了 3 新的 Pod,这 4 个 Pod 有相同的标签。因此Service A通过标签选择器与新的 Pod建立了对应关系,将访问流量通过负载均衡在 4 个 Pod 之间进行转发。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0gJeZm6Q-1664673404258)(https://raw.githubusercontent.com/YuyanCai/imagebed/main/module_05_scaling2.3f74dfba.svg)]

通过更改部署中的 replicas(副本数)来完成扩展

实战:将 nginx Deployment 扩容到 4 个副本

[root@master ~]# vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
        
[root@master ~]# kubectl apply -f nginx-deployment.yaml


[root@master ~]# watch kubectl get pods -o wide
Every 2.0s: kubectl get pods -o wide                                                                                                                                Fri Sep 30 20:06:58 2022

NAME                                READY   STATUS             RESTARTS   AGE    IP               NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-85658cc69f-n9bl9   1/1     Running            0          108m   100.66.209.249   node1   <none>           <none>
web-57b577675-lblh2                 0/1     InvalidImageName   0          82m    100.66.209.250   node1   <none>           <none>
使用命令伸缩应用

扩容

一个容器不行?k8s提供扩容机制,一个命令即可在多台节点启动同样的容器

这些容器,我们在任何一个节点+端口号都可访问

[root@master ~]# kubectl get deployment
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
tomcat6   1/1     1            1           5h30m
[root@master ~]# kubectl scale --replicas=3 deployment tomcat6
deployment.apps/tomcat6 scaled
[root@master ~]# kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS   AGE    IP               NODE    NOMINATED NODE   READINESS GATES
tomcat6-fd99d4dd6-5lmnd   1/1     Running   0          23s    100.66.209.245   node1   <none>           <none>
tomcat6-fd99d4dd6-8bnv5   1/1     Running   0          5h5m   100.108.11.237   node2   <none>           <none>
tomcat6-fd99d4dd6-bzbcz   1/1     Running   0          23s    100.66.209.244   node1   <none>           <none>

缩容

资源浪费,用不了这么多?

K8s还有缩容机制,通过–replicas=1可指定启动容器的个数

[root@master ~]# kubectl scale --replicas=1 deployment tomcat6
deployment.apps/tomcat6 scaled
[root@master ~]# kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS   AGE    IP               NODE    NOMINATED NODE   READINESS GATES
tomcat6-fd99d4dd6-8bnv5   1/1     Running   0          5h8m   100.108.11.237   node2   <none>           <none>
删除资源

查看所有的资源

[root@master ~]# kubectl get all
NAME                          READY   STATUS    RESTARTS   AGE
pod/tomcat6-fd99d4dd6-8bnv5   1/1     Running   0          5h12m

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        5d8h
service/tomcat6      NodePort    10.96.3.240   <none>        80:31975/TCP   20m

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/tomcat6   1/1     1            1           5h38m

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/tomcat6-fd99d4dd6   1         1         1       5h38m

删除指定资源

这里是删除了一个部署,那就意味着该部署所用到的pod将全部都被删除

kubectl delete deployment.apps/tomcat6
删除该资源对应的service

资源想要对外访问都是通过service来访问的,所以我们要把资源对应的service也删除掉

[root@master ~]# kubectl get  all
NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        5d8h
service/tomcat6      NodePort    10.96.3.240   <none>        80:31975/TCP   22m
[root@master ~]# kubectl delete service/tomcat6
service "tomcat6" deleted
模拟意外情况

容器停止

image-20220930221149522

image-20220930221439619

可以看到当容器宕机宕机的时候,k8s检测到以后,又会重新启动一个新的容器。

服务器宕机

image-20220930223647679

等待一段时间,k8s会在node2节点重新生成tomcat容器

image-20220930223633620

Ok,K8s第一个特性说完了,某个节点宕机了,它会帮我们自动恢复在该节点上的容器到其他可用节点上

执行滚动更新

更新应用程序

用户期望应用程序始终可用,为此开发者/运维者在更新应用程序时要分多次完成。在 Kubernetes 中,这是通过 Rolling Update 滚动更新完成的。Rolling Update滚动更新 通过使用新版本的 Pod 逐步替代旧版本的 Pod 来实现 Deployment 的更新,从而实现零停机。新的 Pod 将在具有可用资源的 Node(节点)上进行调度。

Kubernetes 更新多副本的 Deployment 的版本时,会逐步的创建新版本的 Pod,逐步的停止旧版本的 Pod,以便使应用一直处于可用状态。这个过程中,Service 能够监视 Pod 的状态,将流量始终转发到可用的 Pod 上。

在上一个模块中,我们学习了将应用程序 Scale Up(扩容)为多个实例,这是执行更新而不影响应用程序可用性的前提(如果只有 1 个实例那还玩啥)。默认情况下,Rolling Update 滚动更新 过程中,Kubernetes 逐个使用新版本 Pod 替换旧版本 Pod(最大不可用 Pod 数为 1、最大新建 Pod 数也为 1)。这两个参数可以配置为数字或百分比。在Kubernetes 中,更新是版本化的,任何部署更新都可以恢复为以前的(稳定)版本。

滚动更新概述

  1. 原本 Service A 将流量负载均衡到 4 个旧版本的 Pod (当中的容器为 绿色)上

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UxMMVu6G-1664673404265)(https://raw.githubusercontent.com/YuyanCai/imagebed/main/module_06_rollingupdates1.3f74dfba.svg)]

  1. 更新完 Deployment 部署文件中的镜像版本后,master 节点选择了一个 worker 节点,并根据新的镜像版本创建 Pod(紫色容器)。新 Pod 拥有唯一的新的 IP。同时,master 节点选择一个旧版本的 Pod 将其移除。

此时,Service A 将新 Pod 纳入到负载均衡中,将旧Pod移除

在这里插入图片描述

  1. 同步骤2,再创建一个新的 Pod 替换一个原有的 Pod

在这里插入图片描述

  1. 如此 Rolling Update 滚动更新,直到所有旧版本 Pod 均移除,新版本 Pod 也达到 Deployment 部署文件中定义的副本数,则滚动更新完成

在这里插入图片描述

滚动更新允许以下操作:

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

实战:更新 nginx Deployment

修改 nginx-deployment.yaml 文件

image-20221001200409813

image-20221001200443303

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐