深圳幻海软件技术有限公司 欢迎您!

彻底搞懂K8S相关知识

2023-03-20

相信很多人对他的名字都不陌生,但是很多人却把他和docker相关的关系分不清,也没有搞懂它到底是用来做什么的,能帮助我们解决哪些问题,今天我就给大家详细的讲一下。K8S,它的全称,是kubernetes,Kubernetes这个单词来自于希腊语,含义是舵手或领航员。K8S是它的缩写,用“8”字替代了

相信很多人对他的名字都不陌生,但是很多人却把他和docker相关的关系分不清,也没有搞懂它到底是用来做什么的,能帮助我们解决哪些问题,今天我就给大家详细的讲一下。

K8S,它的全称,是kubernetes,Kubernetes 这个单词来自于希腊语,含义是舵手或领航员。K8S是它的缩写,用“8”字替代了“ubernete”这8个字符,所有我们一般都会叫它k8s,和Docker不同,K8S的创造者,是大名鼎鼎行业巨头谷歌,K8S并不是一件全新的发明。它的前身,是Google自己捣鼓了十多年的Borg系统,K8S是2014年6月由Google公司正式公布出来并宣布开源的。

k8s和docker有什么关系

我们都知道随着docker人气迅速攀升,越来越多的公司和开发者都把自己公司的业务迁移到docker容器平台,这样以来很多人就发现一个问题,自己公司业务一台docker容器根本没有办法满足当前需求,这时候我们首先想到的就是增加服务器,在每台服务器都安装docker容器,如果你的服务拆分不是很多这样的确可以解决当前问题,但是如果有上百个微服务,你还是用以前方式管理docker那就非常吃力了,这时候我们可能会想,有没有一款能把所有docker容器进行统一管理的平台,没错k8s是为容器服务而生的一个可移植容器的编排管理工具,越来越多的公司正在拥抱k8s,并且当前k8s已经主导了云业务流程,推动了微服务架构等热门技术的普及和落地。

说白了k8s就是用来管理docker容器的,以前我们运行一个容器都是直接调用docker创建容器的,这样以来随着docker实力越来越多我们维护就非常困难了,假设我现在有30多个服务,如果没有用容器编排工具我们就需要自己计算每个服务占用多少空间,一个docker容器部署多少个服务,这些都是需要提前计算好的,但是随着我们系统访问量不断增加,可能以前只4g运行内存的现在可能需要调整到8g,那以前节点明显就不够用了,我们就需要手动部署到新机器上去,如果你使用了k8s,你只需要把新的节点加入k8s集群,剩下的工作就都是交给k8s来帮你完成了。

k8s能帮我们做什么

版本回退

我们都知道只要是程序就可能存在bug,如果发现新发布的程序版本有问题,我们可以立即回退到原来的版本。

服务自愈

k8s默认会有监控检查机制,说白了就是不断的curl你服务的端口发现不通或者其他异常问题,一旦某一个容器崩溃,能够快速速启动新的容器。

弹性伸缩

当我们某个服务访问量比较高的时候发现一个节点已经无法正常处理我们业务请求了,我们可以动态的调整pod数量达实现扩容效果,如果某个服务访问不高我们就可以减少pod数量实现动态扩容,而且k8s实现扩容和缩容是非常简单的只需要一条命令即可搞定。

负载均衡

如果由于某个服务访问量比较高,那么相当于一个服务起动了多个容器,如果我们用传统方式肯定还需要使用nginx相关的负载均衡中间件,但是如果使用了k8s能自动实现请求的负载均衡。

存储卷挂载

如果你项目中有使用nfs或者其它文件系统存储文件,我们可以直接在k8s创建存储卷挂着nfs了,比较常见的就是我们服务是微服务项目我们的文件存储系统和文件分析系统是两个服务这时候我们就可以挂着nfs,两个服务使用同一个文件系统效果。

再带大家认识一下k8s基本架构

​一个k8s集群主要是由控制节点(master)、工作节点(node)构成,每个节点上都会安装不同的组件。

master节点主要负责集群的管理 ,master节点包含以下组件。

  • ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制。
  • Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上。
  • ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等。
  • Etcd :负责存储集群中各种资源对象的信息。

node节点负责为容器提供运行环境,也就是正在干活的节点。

  • Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器
  • KubeProxy : 负责提供集群内部的服务发现和负载均衡
  • Docker : 负责节点上容器的各种操作

以部署一个Nginx服务来说明Kubernetes系统各个组件调用关系。

  1. 首先需要明确,一旦Kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中。
  2. 一个Nginx服务的安装请求首先会被发送到master节点上的API Server组件。
  3. API Server组件会调用Scheduler组件来决定到底应该把这个服务安装到那个node节点上。此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知API Server。
  4. API Server调用Controller-Manager去调用Node节点安装Nginx服务。
  5. Kubelet接收到指令后,会通知Docker,然后由Docker来启动一个Nginx的Pod。Pod是Kubernetes的最小操作单元,容器必须跑在Pod中。
  6. 一个Nginx服务就运行了,如果需要访问Nginx,​就需要通过kube-proxy来对Pod产生访问的代理,这样,外界用户就可以访问集群中的Nginx服务了

最后我们再来了解一下k8s核心概念

官网提供架构图

Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控。

Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行。

Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器。

Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等。

Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod。

Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签。

NameSpace:命名空间,用来隔离pod的运行环境。

Linux常用命令

查看节点信息

kubectl get node
  • 1.

namespace创建/删除

kubectl create ns ${空间名称}
kubectl delete ns ${空间名称}
  • 1.
  • 2.

在k8s运行pod

Pod运行中的一组容器,Pod是kubernetes中应用的最小单位。

示例:运行一个名称为nginx,副本数为3,标签为app=example,镜像为nginx:1.10,端口为80的容器实例。

kubectl run nginx --replicas=3 --labels="app=example" --image=nginx:1.10 --port=80
  • 1.

查看容器内所有pod

kubectl get pod -A
  • 1.

显示pod节点的标签信息

kubectl get pod --show-labels
  • 1.

根据指定标签匹配到具体的pod

kubectl get pods -l app=example
  • 1.

查看pod创建详细过程

kubectl describe pod ${pod名称} -n ${空间名称}
  • 1.

查看指定pod的信息

kubectl get pod ${pod名称} -n ${空间名称}
  • 1.

查看pod详细信息

kubectl get pod -o wide
  • 1.

查看pod日志,其实就查看服务本身日志,类似docker logs

kubectl logs ${pod名称} -n ${空间名称}
  • 1.

指定时间段输出日志

kubectl logs ${pod名称} --since=1h
  • 1.

指定时间戳输出日志

kubectl logs ${pod名称} --since-time=2022-12-01T15:00:00Z
  • 1.

进入容器里面里面

kubectl exec -ti ${pod名称} /bin/bash
  • 1.

Service概念

我们已经能够利用Deployment来创建一组Pod来提供具有高可用性的服务,虽然每个Pod都会分配一个单独的Pod的IP地址,但是却存在如下的问题:

Pod的IP会随着Pod的重建产生变化。

Pod的IP仅仅是集群内部可见的虚拟的IP,外部无法访问。

创建集群内部可访问的Service

kubectl expose deployment xxx --name=服务名 --type=ClusterIP --port=暴露的端口 --target-port=指向集群中的Pod的端口 [-n 命名空间]。

会产生一个CLUSTER-IP,这个就是service的IP,在Service的生命周期内,这个地址是不会变化的。

kubectl expose deployment nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n test
  • 1.

查看Service

kubectl get svg [-n 命名空间] [-o wide]
  • 1.

创建集群外部可访问的Service

kubectl expose deployment xxx --name=服务名 --type=NodePort --port=暴露的端口 --target-port=指向集群中的Pod的端口 [-n 命名空间]

kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n test
  • 1.

扩缩容

kubectl scale --replicas=5 deployment/my-nginx
kubectl edit deployment my-nginx
  • 1.
  • 2.

更新镜像

将deployment中的nginx容器镜像设置为“nginx:1.9.1”。

kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
  • 1.

版本回退

历史记录。

kubectl rollout history deployment ${pod名称}
  • 1.

查看某个历史详情。

kubectl rollout history deployment my-nginx--revision=2
  • 1.

回滚(回到上次)。

kubectl rollout undo deployment ${pod名称}
  • 1.

回滚(回到指定版本)。

kubectl rollout undo deployment my-nginx--to-revision=2
  • 1.