K8s

2023-09-13  本文已影响0人  追风还是少年

云计算

云计算从狭义上讲,指IT基础设施的交付和使用模式,即通过网络以按需、易扩展的方式获取所需资源。
广义上则指服务的交付和使用模式,通过网络以按需、易扩展的方式获取所需服务。
提供资源的网络被形象地比喻成“云”,其计算能力通常是由分布式的大规模集群和虚拟化技术提供的。而“云”中的计算资源在用户看来是可以扩展,并且可以随时获取、按需使用的。

根据云计算提供服务资源的类型:

image.png

Kubernetes 的基本概念和术语

Kubernetes 的基本概念和术语大多是围绕资源对象 Resource Object 来说的,而资源对象在总体上可分为以下两类:

资源对象一般包括几个通用属性:版本 、类 Kind 、名称、标签、注解:
(1)资源对象的名称要唯一
(2)资源对象的标签是很重要的数据,也是 Kubernetes 的一大设计特性,比如通过标签来表明资源对象 的特征 、类别,以及通过标签筛选不同的资源对象并实现对象之间的关联控制或协作功能
(3)注解可被理解为一种特殊的标签,不过更多地是与程序挂钩,通常用于实现资源对象属性的自定义扩展。

集群类

集群 (Cluster) 表示一个由 Master Node 组成的 Kubernetes 集群

在Master 上运行着以下关键进程:
(1)Kubemetes API Server(kube-apiserver) :提供 HTTP RESTful API 接口的主要服务,是Kubernetes 里对所有资源进行增、删、查等操作的唯一入口,也是集群控制的入口进程。
(2)Kubernetes Controller Manager ( kube-controller-manager): Kubernetes 里所有资源对象的自动化控制中心 ,可以将其理解为资源对象的“大总管”。
(3)Kubemetes Scheduler (kube-scheduler) :负责资源调度(Pod 调度)的进程,相当千公交公司的调度室。

在默认情况下, kubelet 会向 Master 注册自己,这也是Kubernetes 推荐的 Node 管理方式 。一 Node 被纳入集群管理范畴, kubelet 进程就会定时向 Master 汇报自身的情报,例如操作系统、主机 CPU 和内存使用情况,以及当前有哪些Pod 在运行等,这样 Master 就可以获知每个 Node 的资源使用情况,并实现高效均衡的资源调度策略。而某个 Node 在超过指定时间不上报信息时,会被 Master 判定为“失联”,该Node 的状态就被标记为不可用 (Not Ready), Master 随后会触发”工作负载大转移”的自动流程
我们可以运行以下命令查看在集群中有多少个 Node:

kubectl get nodes

然后通过 kubectl describe node <node_name>命令查看某个 Node 的详细信息:

kubectl describe node k8s-node-l

在集群类里还有一个重要的基础概念一命名空间,它在很多情况下用于实现多租户的资源隔离,典型的一种思路就是给每个租户都分配 个命名空间,命名空间属于Kubernetes 集群范畴的资源对象,在一个集群里可以创建多个命名空间,每个命名空间都是相互独立的存在,属于不同命名空间的资源对象从逻辑上相互隔离,在每个 Kubernetes集群安装完成且正常运行之后, Master 会自动创建两个命名空间,一个是默认的 (default),一个是系统级的 (kube-systern), 用户创建的资源对象如果没有指定命名空间,则被存放在 default 命名空间中;而系统相关的资源对象如网络组件 DNS 组件、监控类组件等,都被安装在 kube-systern 命名空间中

定义命名空间:

apiVersion: vl 
kind: Namespace 
metadata: 
  name: development

一旦创建 命名空间 ,我们在 建资源对象 就可以指定这个资源对象属于哪个命名空间。

apiVersion: vl 
kind: Pod 
metadata: 
  name: busybox 
  namespace: development 
spec: 
  containers: 
  - image: busybox 
    command: 
      - sleep 
      - " 3600 " 
     name: busybox

如果不加参数 kubectlet 命令将仅显示属于 default 命名空间的资源对象。
可以在 kubectl get 命令中加入-- namespace 参数来操作某个命名空间中的对象。

kubectl get pods
kubectl get pods --namespace=development

应用类

Kubernete 为每个 Pod 分配了唯一 IP 地址,称之为 Pod IP, 一个 Pod 里的 多个容器共享 Pod IP 地址,Kubernetes 要求底层网络支待集群内任意两个 Pod之间的 TCP/IP直接通信,这通常采用虚拟二层网络技术实现,例如 Flannel Open vSwitch 等,因此我们需要牢记一点在 Kubernetes 里, 一个 Pod 里的容器与另外主机上的 Pod 容器能够直接通信。

Pod 其实有两种类型:普通的 Pod 及静态 Pod (Static Pod) 。后者比较特殊,它并没被存放在 Kubernetes etcd 中,而是被存放在某个具体的 Node 上的 一个具体文件中,并且只能在此 Node 启动、运行,而普通的 Pod 一旦被创建,就会被放入 etcd 中存储,随后被Kubernetes Master 调度到某个具体的 Node 上并绑定(Binding),该Pod 技对应的Node上的 kubelet 进程实例化成一组相关的 Docker 容器并启动。在默认情况下,当 里的某个容器停止时, Kubernetes 会自动检测到这个问题并且重新启动这个 Pod (重启 Pod 里的所有容器),如果 Pod 所在的 Node 宕机,就会将这个 Node 上的所有 Pod 都重新调度到其他节点上。
Endpoint, 代表此 Pod 里的 一个服务进程的对外通信地址,一个 Pod也存在具有多个 Endpoint 的情况,比如 当我们把 Tomcat 定义为一个 Pod时,可以对外暴露管理端口与服务端口这两个 Endpoint.

当前有两种 Label Selector 表达式:基于等式的Selector 表达式和基于集合的Selector 表达式。
基于等式的 Selector 表达式采用等式类表达式匹配标签:
name = redis-slave: 匹配所有具有 name=redis-slave 标签的资源对象
env 1= production: 匹配所有不具有 env=production 标签的资源对象,比如 “env=test"就是满足此条件的标签之一。

基于集合的 Selector 表达式则使用集合操作类表达式匹配标签:
name in ( redis-master,redis-slave) :匹配所有具有 name=redis-master 签或者name= redis-slave 标签的资源对象。
name not in (php-fronlend) :匹配所有不具有 name=php-frontend 标签的 资源对象。

可以通过多个 Label Selector 表达式的组合来实现复杂的条件选择 ,多个表达式之间用“,”进行分隔即可,几个条件之间是 “AND" 的关系,即同时满足多个条件,比如下面的例子:
name=redis-slave,env!=preduction
name not in (php-frontend),env !=production

查看 Deploment 信息:

kubectl get deployments

Deployment 资源对象其实还与 ReplicaSet 资源对象密切相关, Kubernetes 内部会根据Deployment 对象自动创建相关联的ReplicaSet 对象,通过以下命令,我们可以看到它的命名与 ployment 的名称有对应关系:

kubectl get replicaset

服务发现只要用Sevice的Name 与ClusterIP 地址做 DNS 域名映射即可
ClusterIP 地址是一种虚拟 IP 地址,原因有以下几点:
(1)ClusterIP 地址仅仅作用于 Kubemetes Service 这个对象, 并由 Kubemetes 管理和分配IP 地址(来源于 ClusterIP 地址池),与 Node Master 所在的物理网络完全无关。
(2)因为没有一个“实体网络对象”来响应,所以 ClusterIP 地址无法被 Ping通,Cluster IP 地址只能与 Service Port 组成一个具体的服务访问端点,单独的 Cluster IP 不具备 TC IP 通信的基础。
(3)Cluster 属于 Kubernetes 集群这个封闭的空间,集群外的节点要访问这个通信端口,则需要做一些额外的工作。

kubectl get endpoints
#运行下面的命令即可看到 tomcat service 被分配的 clusterIP 地址及更多的信息
kubectl get svc tomcat-service -o yaml

还有一种特殊的 Service- Headless service ,只要在 Service的定义中设置了 ClusterIP: None 就定义了一个 Headless service, 它与普通 service 的关键区别在于它没有 ClusterIP 地址,如果解析 headless service 的DNS 域名,则返回的是该Service 对应的全部 Pod Endpoint 列表,这意味着客户端是直接与后端的Pod建立 TCP/IP连接进行通信的,没有通过虚拟 clusterIP 地址进行转发,因此通信性能最高,等同千”原生网络通信”。

很多服务都存在多个端口,通常一个端口提供业务服务,另一个端口提供管理服务,比如 Mycat、Codis 等常见中间件。 kubernetes Service 支待多个 Endpoint, 在存在多个 endpoint 的情况下,要求每个 Endpoint 都定义一个名称进行区分。

apiVersion: vl 
kind: Service 
metadata: 
  name : tomcat-service
spec : 
  ports: 
  - port: 8080 
    name: service-port 
  - port: 8005 
    name : shutdown-port
  selector: 
    tier: frontend

NodePort 的确功能强大且通用性强,但也存在一个问题 ,即 每个 Service 都需要在 Node上独占一个端口,而端口又是有限的物理资源,那能不能让多个 Service 共用一个对外端口呢?这就是后来增加的 Ingress 资源对象所要解决的问题。在一定程度上,我们可以把Ingress 的实现机制理解为基于 Nginx 的支持虚拟主机的 HTTP 代理

kind: Ingress 
metadata: 
  name: name-virtual-host-ingress
spec: 
  rules: 
  - host: foo.bar. com 
    http: 
      paths: 
      - backend: 
        serviceName: servicel
        servicePort: 80 
  - host: bar.foo. com 
    http: 
      paths: 
      - backend: 
        serviceName: service2 
        servicePort: 80

YPA ( Vertical Pod Autoscaler) ,即垂直 Pod 自动扩缩容,它根据容器资源
使用率自动推测并设置 Pod 合理的 CPU 和内存的需求指标,从而更加精确地调度 Pod,实现整体上节省集群资源的目标,因为无须人为操作,因此也进一步提升了运维自动化的水平,VPA 目前属于比较新的特性,也不能与 HPA 共同操控同 一组目标 Pod。

存储类

存储类的资源对象主要包括 Volume 、Persistent Volume 、PVC、StorageClass。
-Volume
Volume 是Pod 中能够被多个容器访问的共享目录。
Volume 的使用也 比较简单,在大多数情况下,我们先在 Pod 上声明一个 Volume,然后在容器里引用该 Volume 并将其挂载 (Mount) 到容器里的某个目 录下。
提供三种volume类型:临时目录、宿主机目录、共享存储
(1)emptyDir
一个 emptyDir 是在 分配到 Node 时创建的。它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为这是 Kubernetes 自动分配的一个目录,当Pod Node 移除时,emptyDir 中的数据也被永久移除。
在默认情况下 ernptyDi 使用的是节点的存储介质,例如磁盘或者网络存储。还可以使用 emptyDir.medium 属性,把这个属性设置为 Memory", 就可 以使用更快的基于内存的后端存储了,需要注意的是,这种情况下的 emptyDir 使用的内存会被计入容器的内存消耗,将受到资源限制和配额机制的管理
(2)hostPath
hostPath 为在 Pod 挂载宿主机上的文件或目录

动态存储管理:
Volume 属于静态管理的存储,即我们需要事先定义每个 Volume ,然后将其挂载到 Pod中去用。
Kubernetes 后面就发展了存储动态化的新机制,来实现存储的自动化管理。相关的核心对象(概念)有三个: Persistent Volume (简称 PV) 、StorageClass、PVC。
PV 表示由系统动态创建 (dynamically provisioned) 的一个存储卷,可以被理解成Kubernetes 集群中某个网络存储对应的一块存储,它与 Volume 类似,但 PV 并不是被定义在Pod 上的,而是独立于 Pod 之外定义的。
StorageClass 用来描述和定义某种存储系统的特征。
PVC正如其名,表示应用希望申请的 PV 规格,其中重要的属性包括 accessModes (存储访问模式)、storag la sName (用哪种 Storage ass 来实现动态创建)及 resources (存储的具体规格)

例子

apiVersion: apps/vl  # API 版本
kind: Deployment  #副本控制器 RC
metadata: 
  labels: #标签
   app: mysql 
  name: mysql #对象名称,全局唯一
spec: 
  replicas: 1 #预期的副本数量
  selector: 
    matchLabels: 
     app: mysql
  template: #Pod 模板
    metadata: 
     label:
       app: mysql 
    spec: 
      containers:  #定义容器
       - image: rnysql:5.7 
         name: mysql 
         ports: 
           - containerPort: 3306 
         env: 
           - name: MYSQL_ROOT_PASSWORD 
             value: "123456 "

创建好 mysql-deploy.yaml 文件后,为了将它发布到 Kubernetes 集群中,我们在 Master上运行如下命令:

kubectl apply -f mysql-deploy.yarnl
#运行 kubectl 命令查看刚刚创建的 Deployment:
kubectl get deploy
#查看 Pod 的创建情况
kubectl get pods

在 Kubernetes 节点的服务器上通过 docker ps 指令查看正在运行的容器,发现提供 MySQL 服务的 Po 容器巳创建且正常运行,并且 MySQL Pod 对应的容器多创建了一个 Pause 容器,该容器就是 Pod 的根容器。

docker ps | grep mysql
apiVersion: vl 
kind: Service   #表明是 Kubernetes Service 
meadata:
  name: mysql  # Service 的全局唯一名称
spec: 
  ports: 
    - port: 3306  # Service 提供服务的端口号
  selector: # Service 对应的 Pod 拥有这里定义的标签
    app: mysql

我们通过 kubectl create 命令创建 Service 对象:
MySQL 服务被分配了一个值为 10.245.161.22 ClusterIP 地址,在 Kubemetes 集群中新创建的其他 Pod 就可以通过Service ClusterIP +端口号 3306 来连接和访问它了

kubectl create -f mysql-svc.yaml
kubectl get SVC mysql

Kubernetes 会自动将已存在的 Service 对象以环境变量的形式展现在新生成的 Pod 。

apiVersion: apps/vl 
kind: Deployment 
metadata: 
  labels: 
    app: myweb 
  name: myweb 
spec: 
  replicas: 2 
  selector: 
    matchLabels: 
      app: myweb 
  template: 
    metadata: 
      labels: 
        app: myweb 
    spec: 
     containers: 
     - image: kubeguide/tomcat-app:vl
       name: myweb 
       ports: 
      - containerPort: 8080 
      env: 
      - name: MYSQL_SERVICE_HOST 
        value: 10.245.161.22

"type: NodePort" “nodePort: 30001" 表明此 Service 开启了 NodePort 格式的外网访间模式。

apiVersion: vl 
kind: Service 
metadata: 
  name: nyweb 
spec: 
  type: NodePort
  ports: 
    - port: 8080 
      nodePort: 30001 
  selector: 
    app: myweb
上一篇 下一篇

猜你喜欢

热点阅读