K8S调度管理

1.1 调度框架

1.1.1 调度体系

学习目标

这一节,我们从 流程调度、调度细节、小结 三个方面来学习。

流程调度

集群层面-节点调度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i4h0fiwz-1688395349489)(image/image-20220722223752806.png)]

	kube-scheduler负责将接收到的资源调度到指定的节点中

资源层面 - k8s集群资源的管控

在这里插入图片描述

网络层面 - k8s集群资源的访问

在这里插入图片描述

认证层面 - k8s集群资源的认证

在这里插入图片描述

调度细节

pod周期 - pod创建的完整流程

在这里插入图片描述

pod组成 - pod创建到成功,经历了什么

在这里插入图片描述

存储层面 - pod数据是如何整合的

在这里插入图片描述

创建层面 - 资源使用的数据同步

在这里插入图片描述

资源层面

角度解析
资源配置项Kubernetes技术已经对Pod做了相应的资源配额设置,目前主要包括两方面:CPU和内存
配额限制Kubernetes中,对于每种资源的配额限定都需要两个参数:申请配额(Requests)和最大配额(Limits)
存活状态pod层面主要是根据探针来实现的服务质量的检测:livenessProbe和readinessProbe。
对象分组在kubernetes内部,尤其是pod层面,通过 标签和标签选择器 或者 nodeName 等机制实现资源的分组管理。
服务质量在Kubernetes内部靠实时的监控各种资源对象的状态值,对比相应的"期望状态值",然后由内部的组件做出自动的资源调整。

小结


1.1.2 资源调度

学习目标

这一节,我们从 调度框架、原理解析、小结 三个方面来学习。

调度框架

基本框架

	kubernetes在进行资源调度的时候,是遵循一个基本原则的:
		预选原则 - 把不合适的剔除,剩余满足条件的。
		优选原则 - 满足条件的评优,选择一个最好的。

调度框架

在这里插入图片描述

	新型的调度框架是在传统调度逻辑的基础上,进行了整合再拆分。基本流程还是一样:队列-预选-评分-绑定,将这个基本流程划分为了三个部分:
	任务队列 - 接收所有待分配的任务,任务本身会根据优先级合理调整队列的顺序。
	调度循环 - 通过扩展接口的方式整合大量的预选机制和评分机制,同时为了方便扩展,预留了备用接口
	绑定循环 - 先后通过预绑定队列(防止突发的高优先级任务出现),然后进行正常的节点任务绑定。

常见的 预选参数和优选参数

在这里插入图片描述

	无论是传统的调度功能还是新型的调度功能,对于各种功能函数来说,本质上的逻辑变化不大,只不过在实现细节上稍微有些不同。而且为了让调度的能力符合通用的使用,默认情况下,开启了一部分通用的策略,没有开启的策略可以通过配置参数的方式来进行扩展加载。

原理解析

调度梳理

	根据上面对调度功能函数的了解,上面的大部分功能函数都是静态的函数,只管调用即可,只有个别的一些函数支持用户自定义的场景。
	对于节点预选功能,主要是基于资源的各种限制来进行管控,我们可以通过不同的调度器配置来进行定制。而对于优选策略的配置,是我们比较关注的高阶调度。根据我们的梳理,这些高阶的调度主要包括如下几个方面
调度策略解析
节点调度为即将执行的任务,选择合理的节点
Pod调度为即将执行的任务,分配合理的逻辑关联搭配
污点调度在任务调度的时候,设定一些避免措施
拓扑调度在任务已确定调度的前提下,合理的分配任务,实现资源的高效利用

在这里插入图片描述

调度思路

名称解析
亲和 与 反亲和满足条件后,就分配 或者 远离 指定的节点。
硬亲和 与 软亲和不会遵循绝对的条件阈值,而是根据实际情况,做出倾向性策略硬亲和会考量预选和优选策略,而软亲和仅考虑优选策略

小结


1.2 资源调度

1.2.1 节点调度

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

简介

关于资源对于节点的调度来说,主要有两种场景:
	指定节点 - 根据节点的标签,直接将应用部署到指定的节点
	节点亲和 - 根据任务的配置倾向,选择合适的节点来进行资源的配置

指定节点

指定节点
	将pod调度到特定的节点上,我们可以根据名称或者标签的方式来实现
	指定名称
		kubectl explain pod.spec.nodeName
	指定标签
		kubectl explain pod.spec.nodeSelector

节点亲和

对于节点的调度主要有以下两种场景:
节点亲和
	kubectl explain pod.spec.affinity.nodeAffinity
    节点软亲和
        - preferredDuringSchedulingIgnoredDuringExecution
    节点硬亲和
        - requiredDuringSchedulingIgnoredDuringExecution
	
注意:
	这些调度策略,仅在调度时候有用,一旦调度成功后,节点状态无法满足调度要求,也不会影响正常运行的pod

简单实践

准备工作

创建工作节点
[root@kubernetes-master1 ~]# mkdir /data/kubernetes/schduler; cd /data/kubernetes/schduler

名称节点调度

定制资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 01_kubernetes_scheduler_nodename.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-nodename
spec:
  nodeName: kubernetes-node2
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
   
应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl apply -f 01_kubernetes_scheduler_nodename.yaml
pod/superopsmsb-nodename created

查看资源对象效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-nodename -o wide
NAME                   READY   STATUS    RESTARTS   AGE   IP           NODE               NOMINATED NODE   READINESS GATES
superopsmsb-nodename   1/1     Running   0          9s    10.244.2.8   kubernetes-node2   <none>           <none>
[

移除资源对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl delete -f 01_kubernetes_scheduler_nodename.yaml

标签节点调度

定制资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 02_kubernetes_scheduler_selector.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-nodeselector
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  nodeSelector:
    node: ssd
  配置解析:
  	将应用调度到包含node标签,并且值为ssd的节点主机上
  	
应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 02_kubernetes_scheduler_selector.yaml
pod/superopsmsb-nodeselector created
查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-nodeselector -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
superopsmsb-nodeselector   0/1     Pending   0          7s    <none>   <none>   <none>           <none>

查看节点
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get node --show-labels  | grep ssd
[root@kubernetes-master1 /data/kubernetes/schduler]#

查看pod

[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe pod superopsmsb-nodeselector
...
Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  22s (x2 over 89s)  default-scheduler  0/6 nodes are available: 3 node(s) didn't match Pod's node affinity/selector, 3 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.

后续操作

为节点添加标签
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label nodes  kubernetes-node2 node=ssd
node/kubernetes-node2 labeled
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get node --show-labels  | grep ssd
kubernetes-node2     Ready    <none>                 18h   v1.23.8   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=kubernetes-node2,kubernetes.io/os=linux,node=ssd

查看pod效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-nodeselector -o wide
NAME                       READY   STATUS    RESTARTS   AGE     IP           NODE               NOMINATED NODE   READINESS GATES
superopsmsb-nodeselector   1/1     Running   0          2m39s   10.244.2.9   kubernetes-node2   <none>           <none>
结果显示
	一旦有节点满足需求,pod自然就被调度到指定的node节点上了
收尾动作
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl delete -f 02_kubernetes_scheduler_selector.yaml
pod "superopsmsb-nodeselector" deleted
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node2 node-
node/kubernetes-node2 unlabeled

小结


1.2.2 节点亲和

学习目标

这一节,我们从 软亲和、硬亲和、小结 三个方面来学习。

软亲和

属性解析

查看pod关于节点亲和相关的属性
kubectl explain pod.spec.affinity.nodeAffinity 
	- preferredDuringSchedulingIgnoredDuringExecution 软亲和性 能满足最好,不满足也没关系。
        preference 优先级
            matchExpressions
        	matchFields
        weight 权重值,1-100
			对于满足所有调度要求的每个节点,调度程序将通过迭代此字段的元素计算总和
			并在节点与对应的节点匹配时将“权重”添加到总和。
注意:
	与硬亲和属性不同,这里需要注意的是软亲和属性是一个列表对象,而preference不是一个列表项了。

实践-将pod最好部署到包含env标签值是dev 或者 test的结点上,都没有的话也就随便找一个了

定制资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 03_kubernetes_scheduler_preferred_affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-node-preferred-affinity
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 50
        preference:
          matchExpressions:
          - key: env
            operator: In
            values:
            - test
      - weight: 20
        preference:
          matchExpressions:
          - key: env
            operator: In
            values:
            - dev
   注意:
		软亲和的权重配置是与硬亲和的区别所在。
		
应用资源定义文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl apply -f 03_kubernetes_scheduler_preferred_affinity.yaml
pod/superopsmsb-node-preferred-affinity created

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  get pod superopsmsb-node-preferred-affinity -o wide
NAME                                  READY   STATUS    RESTARTS   AGE   IP           NODE               NOMINATED NODE   READINESS GATES
superopsmsb-node-preferred-affinity   1/1     Running   0          18s   10.244.3.6   kubernetes-node3   <none>           <none>

删除资源
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl delete -f 03_kubernetes_scheduler_preferred_affinity.yaml

后续操作

准备节点标签
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node1 env=dev
node/kubernetes-node1 labeled
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node2 env=test
node/kubernetes-node2 labeled 

再次运行资源对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl apply -f 03_kubernetes_scheduler_preferred_affinity.yaml
pod/superopsmsb-node-preferred-affinity created

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  get pod superopsmsb-node-preferred-affinity -o wide
NAME                                  READY   STATUS    RESTARTS   AGE   IP            NODE               NOMINATED NODE   READINESS GATES
superopsmsb-node-preferred-affinity   1/1     Running   0          19s   10.244.2.10   kubernetes-node2   <none>           <none>

收尾动作

删除资源
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl delete -f 03_kubernetes_scheduler_preferred_affinity.yaml

移除标签
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node1 env-
node/kubernetes-node1 unlabeled
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node2 env-
node/kubernetes-node2 unlabeled

硬亲和

属性解析

查看pod关于节点亲和相关的属性
kubectl explain pod.spec.affinity.nodeAffinity
	- requiredDuringSchedulingIgnoredDuringExecution 硬亲和性  必须满足亲和性。
    	nodeSelectorTerms: 节点选择主题
            matchExpressions  匹配表达式,可用大量运算符:
                In					label 的值在某个列表中
                NotIn				label 的值不在某个列表中
                Gt					label 的值大于某个值
                Lt					label 的值小于某个值
                Exists				某个 label 存在
                DoesNotExist		某个 label 不存在
            matchFields  匹配字段,可以不定义标签值

实践-将pod只部署到包含env标签值是dev 或者 test的节点上

定制资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 04_kubernetes_scheduler_required_affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-node-required-affinity
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: env
            operator: In
            values:
            - dev
            - test
应用资源定义文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl apply -f 04_kubernetes_scheduler_required_affinity.yaml
pod/superopsmsb-node-required-affinity created

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-node-required-affinity
NAME                                 READY   STATUS    RESTARTS   AGE
superopsmsb-node-required-affinity   0/1     Pending   0          20s
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe pod superopsmsb-node-required-affinity
...
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  48s   default-scheduler  0/6 nodes are available: 3 node(s) didn't match Pod's node affinity/selector, 3 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.
任一结点添加标签
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node2 env=dev
node/kubernetes-node2 labeled

确认效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-node-required-affinity -o wide
NAME                                 READY   STATUS    RESTARTS   AGE   IP            NODE               NOMINATED NODE   READINESS GATES
superopsmsb-node-required-affinity   1/1     Running   0          95s   10.244.2.11   kubernetes-node2   <none>           <none>
结果显示:
	只有节点上存在符合标签后,该资源才会被创建到指定结点

收尾动作

删除资源对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl delete -f 04_kubernetes_scheduler_required_affinity.yaml
pod "superopsmsb-node-required-affinity" deleted
清理标签
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node2 env-
node/kubernetes-node2 unlabeled

小结


1.2.3 Pod亲和

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

场景需求

所谓的pod调度,主要说的是pod彼此之间的亲和性,也就是说,哪些pod应该在一起。
	比如:我们的k8s集群的节点分布在不同的区域或者不同的机房
		当服务A和服务B需要高效的交流数据的话,要求部署在同一个区域或者同一机房的时候。
		当服务A需要做冗余操作,那么多个服务A必须在不同的位置

属性解析

查看pod级别的亲和性属性
kubectl explain pod.spec.affinity.podAffinity
    requiredDuringSchedulingIgnoredDuringExecution -- 硬亲和性:
        labelSelector  	选择跟那组Pod亲和,前提得知道如何判断
        namespaces 		选择哪个命名空间进行条件匹配
        topologyKey 		指定节点上的哪个键,这是一个必选项
        注意:这三个条件是一个逻辑与的关系
    preferredDuringSchedulingIgnoredDuringExecution -- 软亲和性:
        podAffinityTerm	与权重关联的亲和选项,这是一个必选项
            labelSelector 
        	namespaces 		表示仅在指定的命名空间中查找
        	topologyKey 	在指定节点上的标签关键字
        weight				权重,这是一个必选项

在这里插入图片描述

简单实践

准备工作

准备主机节点标签
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node1 env=dev
node/kubernetes-node1 labeled
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node2 env=test
node/kubernetes-node2 labeled
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node3 env=release
node/kubernetes-node3 labeled

创建基础资源配置
[root@kubernetes-master1 /data/kubernetes/schduler]# for env in {dev,test,release}
do
cat >> 05_kubernetes_scheduler_pod_base.yaml <<-EOF
---
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-pod-$env
  labels:
    env: $env
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  nodeSelector:
    env: $env
EOF
done

应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 05_kubernetes_scheduler_pod_base.yaml
pod/superopsmsb-pod-dev created
pod/superopsmsb-pod-test created
pod/superopsmsb-pod-release created

确认效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod -o wide | grep pod
superopsmsb-pod-dev       1/1 Running ... 10.244.1.5    kubernetes-node1 ...
superopsmsb-pod-release   1/1 Running ... 10.244.3.7    kubernetes-node3 ...
superopsmsb-pod-test      1/1 Running ... 10.244.2.12   kubernetes-node2 ...
结果显示:
	每个节点上都有1个pod而且标签不一样

硬亲和实践1- pod和只和携带标签env=release的pod部署在一起

创建资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 06_kubernetes_scheduler_pod_require-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-pod-affinity
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: env, operator: In, values: ["release"]}
        topologyKey: kubernetes.io/hostname
属性解析:
	属性详解:
        topologyKey的来源:
        ]# kubectl get nodes -o yaml | grep kubernetes.io/hostname
          kubernetes.io/hostname: kubernetes-master1
          kubernetes.io/hostname: kubernetes-master2
          kubernetes.io/hostname: kubernetes-master3
          kubernetes.io/hostname: kubernetes-node1
          kubernetes.io/hostname: kubernetes-node2
          kubernetes.io/hostname: kubernetes-node3
        其实指定 kubernetes.io/hostname 和 主机名 效果是一样的,只不过一个是自动获取,一个是手工指定

应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl apply -f 06_kubernetes_scheduler_pod_require-affinity.yaml
pod/superopsmsb-pod-affinity created

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-pod-affinity -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE               NOMINATED NODE   READINESS GATES
superopsmsb-pod-affinity   1/1     Running   0          21s   10.244.2.13   kubernetes-node3   <none>           <none>

删除资源对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  delete -f 06_kubernetes_scheduler_pod_require-affinity.yaml
pod "superopsmsb-pod-affinity" deleted
清理pod对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  delete pod superopsmsb-pod-release
pod "superopsmsb-pod-release" deleted

再次创建资源对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl apply -f 06_kubernetes_scheduler_pod_require-affinity.yaml
pod/superopsmsb-pod-affinity created

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-pod-affinity -o wide              NAME                       READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
superopsmsb-pod-affinity   0/1     Pending   0          7s    <none>   <none>   <none>           <none>
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe pod superopsmsb-pod-affinity
...
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  30s   default-scheduler  0/6 nodes are available: 3 node(s) didn't match pod affinity rules, 3 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.
  
删除资源对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  delete -f 06_kubernetes_scheduler_pod_require-affinity.yaml
pod "superopsmsb-pod-affinity" deleted

软亲和实践2- pod最好和携带标签env=dev的pod部署在一起

创建资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 07_kubernetes_scheduler_pod_prefer_affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-pod-preferred
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 60
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - {key: env, operator: In, values: ["dev"]}
          topologyKey: kubernetes.io/hostname
      - weight: 30
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - {key: env, operator: In, values: ["test"]}
          topologyKey: kubernetes.io/hostname

应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 07_kubernetes_scheduler_pod_prefer_affinity.yaml
pod/superopsmsb-pod-preferred created

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-pod-preferred -o wide             NAME                        READY   STATUS    RESTARTS   AGE   IP           NODE               NOMINATED NODE   READINESS GATES
superopsmsb-pod-preferred   1/1     Running   0          14s   10.244.1.6   kubernetes-node1   <none>           <none>
结果显示:
	pod直接去找最好的地方了
	
清理资源对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl delete -f 07_kubernetes_scheduler_pod_prefer_affinity.yaml

小结


1.2.4 Pod反亲和

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

简介

所谓的反亲和,其实就是满足条件的话,就离这个pod远远的,从此不见面。与亲和正好相反

属性解析

查看pod反亲和实践
kubectl explain pod.spec.affinity.podAntiAffinity
    requiredDuringSchedulingIgnoredDuringExecution -- 硬亲和性:
        labelSelector  		选择跟那组Pod亲和,前提得知道如何判断
        namespaces 			选择哪个命名空间进行条件匹配
        topologyKey 		指定节点上的哪个键,这是一个必选项
        注意:这三个条件是一个逻辑与的关系
    preferredDuringSchedulingIgnoredDuringExecution -- 软亲和性:
        podAffinityTerm	与权重关联的亲和选项,这是一个必选项
            labelSelector 
            namespaces 	
            topologyKey 	
        weight				权重,这是一个必选项

注意:Pod反亲和性场景,当应用服务A和数据库服务B要求尽量不要在同一台节点上的时候。

在这里插入图片描述

简单实践

准备工作

应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 05_kubernetes_scheduler_pod_base.yaml
pod/superopsmsb-pod-dev created
pod/superopsmsb-pod-test created
pod/superopsmsb-pod-release created

硬性反亲和实践- pod不和携带标签env=dev的pod部署在一起

创建资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 08_kubernetes_scheduler_pod_required_antiaffinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-pod-required
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: env, operator: In, values: ["dev"]}
        topologyKey: kubernetes.io/hostname

应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 08_kubernetes_scheduler_pod_required_antiaffinity.yaml
pod/superopsmsb-pod-required created

[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  get pod superopsmsb-pod-required -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP           NODE               NOMINATED NODE   READINESS GATES
superopsmsb-pod-required   1/1     Running   0          20s   10.244.3.8   kubernetes-node3   <none>           <none>
结果显示:
	随便找了一个不携带env=dev的pod在一起了
	
清理环境
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl delete -f 08_kubernetes_scheduler_pod_required_antiaffinity.yaml

软性反亲和实践-pod最好不和携带标签env=dev的pod部署在一起

创建资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 09_kubernetes_scheduler_pod_preferred_antiaffinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-pod-preferred
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchExpressions:
              - {key: env, operator: In, values: ["dev"]}
            topologyKey: kubernetes.io/hostname
        - weight: 50
          podAffinityTerm:
            labelSelector:
              matchExpressions:
              - {key: env, operator: In, values: ["test"]}
            topologyKey: kubernetes.io/hostname

应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 09_kubernetes_scheduler_pod_preferred_antiaffinity.yaml
pod/superopsmsb-pod-preferred created

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  get pod superopsmsb-pod-preferred -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP           NODE               NOMINATED NODE   READINESS GATES
superopsmsb-pod-preferred   1/1     Running   0          15s   10.244.3.9   kubernetes-node3   <none>           <none>
结果显示:
	pod去找了一个清净的地方来玩了

收尾实践

清理所有的资源对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  delete -f 09_kubernetes_scheduler_pod_preferred_antiaffinity.yaml -f 05_kubernetes_scheduler_pod_base.yaml

小结


1.2.5 污点&容忍度

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

需求

	我们之前所学的所有调度策略,都是基于pod的属性来选择我们新的pod资源应该如何创建,而实际的生产角度上,往往会出现基于node节点的属性来选择是否让新的pod资源进行创建,但是对于节点来说,没有所谓的节点反亲和性,但是有一种类似的策略:污点和容忍度。

术语解析

术语解析
污点(taints)是定义在node节点上的键值属性数据。主要作用是让节点拒绝pod,尤其是不符合node规则的pod。
容忍度(tolerations)是定义在Pod上的键值属性数据,用于配置可容忍的污点,调度器将其调度至容忍污点的节点上或无污点的节点

应用

	Taint(污点)和 Toleration(容忍)是相互配合的,可以用来避免 pod 被分配到不合适的节点上,每个节点上都可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taint 的 pod,是不会被该节点接受的。
	比如:A节点是集群中很重要的节点,不要将无关的pod来我这里运行,那么我们就可以在A上面添加一些污点标识。

在这里插入图片描述

污点功能

	Kubernetes自1.6起支持使用污点自动标识问题节点,它通过节点控制器在特定条件下自动为节点添加污点信息实现。它们都使用NoExecute效用标识,因此非能容忍此类污点的现在Pod对象也会遭到驱逐。目前,内建使用的此类污点有如下几个。
	node.kubernetes.io/not-ready:节点进入NotReady状态时被自动添加的污点。
	node.alpha.kubernetes.io/unreachable:节点进入NotReachable状态时被自动添加的污点。
	node.kubernetes.io/out-of-disk:节点进入OutOfDisk状态时被自动添加的污点。
	node.kubernetes.io/memory-pressure:节点内存资源面临压力。
	node.kubernetes.io/disk-pressure:节点磁盘资源面临压力。
	node.kubernetes.io/network-unavailable:节点网络不可用。
	node.cloudprovider.kubernetes.io/uninitialized:kubelet由外部的云环境程序启动时,它自动为节点添加此污点,待到云控制器管理器中的控制器初始化此节点时再将其删除。

不过,Kubernetes的核心组件通常都要容忍此类的污点,以确保其相应的DaemonSet控制器能够无视此类污点于节点上部署相应的关键Pod对象,例如kube-proxy或kube-flannel等。

属性示例

查看污点和污点容忍度
]# kubectl describe pod kube-apiserver-master -n kube-system
...
Tolerations:       :NoExecute

]# kubectl describe pod kube-proxy -n kube-system
... 	 
Node-Selectors:              kubernetes.io/os=linux
Tolerations:                 op=Exists				污点容忍度 
                             node.kubernetes.io/disk-pressure:NoSchedule op=Exists
                             node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                             node.kubernetes.io/network-unavailable:NoSchedule op=Exists
                             node.kubernetes.io/not-ready:NoExecute op=Exists
                             node.kubernetes.io/pid-pressure:NoSchedule op=Exists
                             node.kubernetes.io/unreachable:NoExecute op=Exists
                             node.kubernetes.io/unschedulable:NoSchedule op=Exists

]# kubectl get node master -o yaml
...
  taints:	污点
  - effect: NoSchedule		效用标识,
    key: node-role.kubernetes.io/master
...

简单实践

Taints污点-属性解析

Taint是节点上属性,我们看一下Taints如何定义

kubectl explain node.spec.taints(对象列表)
    effect	pod不能容忍这个污点时,他的行为是什么,
    	他有三个值:NoSchedule、PreferNoSchedule、NoExecute
    key  	定义一个key=value:effect
    value 	定义一个值,这是一个必选项
	timeAdded

effect的属性值

属性解析
NoSchedule不能容忍此污点的Pod对象不可调度至当前节点,属于强制型约束关系,但添加污点对节点上现存的Pod对象不产生影响
PreferNoScheduleNoSchedule的柔性约束版本,即调度器尽量确保不会将那些不能容忍此污点的Pod对象调度至当前节点,除非不存在其他任何能够容忍此污点的节点可用;添加该类效用的污点同样对节点上现存的Pod对象不产生影响。
NoExecute不能容忍此污点的新Pod对象不可调度至当前节点,属于强制型约束关系,而且节点上现存的Pod对象因节点污点变动或Pod容忍度变动而不再满足匹配条件时,Pod对象将会被驱逐。

Tolerations 容忍度- 属性解析

Tolerations 是Pod上属性,我们看一下Tolerations如何定义

kubectl explain pod.spec.tolerations
    effect  			节点调度后的操作
    key 				被容忍的key
    operator  			Exists只要key在就可以调度,Equal(等值比较)必须是值要相同
    tolerationSeconds  	资源被驱逐的宽限时间,默认是0 就是立即被驱逐
    value  				被容忍key的值

容忍度的判断方式

在Pod对象上定义容忍度时,它支持两种操作符,
	一种是等值比较,表示容忍度与污点必须在key、value和effect三者之上完全匹配,
	一种是存在性判断(Exists),表示二者的key和effect必须完全匹配,而容忍度中的value字段要用空值。
当不指定key值和effect值时,且operator为Exists,表示容忍所有的污点
tolerations:
  - operator: "Exists"
  
当不指定effect值时,则能匹配污点key对应的所有effects情况
tolerations:
  - key: "key"
    operator: "Exists"

容忍度的匹配原则

	一个节点可以配置使用多个污点,而一个Pod对象也可以有多个容忍度,将一个Pod对象的容忍度套用到特定节点的污点之上进行匹配度检测时,时将遵循如下逻辑:
	1)首先处理每个有着与之匹配的容忍度的污点;
    2)对于不能匹配到容忍度的所有污点,若存在一个污点使用了NoSchedule效用标识,则拒绝调度当前Pod至该节点;
    3)对于不能匹配到容忍度的所有污点,若都不具有NoSchedule效用标识,但至少有一个污点使用了PreferNoScheduler效用标准,则调度器会尽量避免将当前Pod对象调度至该节点。
    4)如果至少有一个不能匹配容忍度的污点使用了NoExecute效用标识,节点将立即驱逐当前Pod对象,或者不允许该Pod调度至给定的节点;而且,即便容忍度可以匹配到使用了NoExecute效用标识的污点,若在Pod上定义容忍度时同时使用tolerationSeconds属性定义了容忍时限,则在超出时限后当前脚Pod也将会被节点所驱逐。

小结


1.2.6 污点实践

学习目标

这一节,我们从 污点实践、容忍度实践、小结 三个方面来学习。

污点实践

命令格式

查看污点:
	kubectl describe nodes | grep -i taint

添加污点:
	kubectl taint node <node-name> <key>=<value>:<effect> ...

删除污点:
	kubectl taint node <node-name> <key>[:<effect>]-

简单实践

查看污点
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe nodes | egrep  'Hostname|Taints'
Taints:             node-role.kubernetes.io/master:NoSchedule
  Hostname:    kubernetes-master1
Taints:             node-role.kubernetes.io/master:NoSchedule
  Hostname:    kubernetes-master2
Taints:             node-role.kubernetes.io/master:NoSchedule
  Hostname:    kubernetes-master3
Taints:             <none>
  Hostname:    kubernetes-node1
Taints:             <none>
  Hostname:    kubernetes-node2
Taints:             <none>
  Hostname:    kubernetes-node3
添加污点
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl taint node kubernetes-node1 node-type=production:NoSchedule
node/kubernetes-node1 tainted
确认效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe nodes kubernetes-node1 | egrep  'Hostname|Taints'
Taints:             node-type=production:NoSchedule
  Hostname:    kubernetes-node1
给node1增加标签
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl label node kubernetes-node1 env=dev --overwrite
node/kubernetes-node1 not labeled

创建资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 10_kubernetes_scheduler_pod_taint_test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-pod-taint
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  nodeSelector:
    env: dev


应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 10_kubernetes_scheduler_pod_taint_test.yaml pod/superopsmsb-pod-taint created
查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-pod-taint
NAME                    READY   STATUS    RESTARTS   AGE
superopsmsb-pod-taint   0/1     Pending   0          6s

[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  describe pod superopsmsb-pod-taint
...
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  52s   default-scheduler  0/6 nodes are available: 1 node(s) had taint {node-type: production}, that the pod didn't tolerate, 2 node(s) didn't match Pod's node affinity/selector, 3 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.
  结果显示:
	由于污点原因,无法将pod创建到指定结点上
	
删除key为node-type,effect为NoSchedule的污点
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl taint node kubernetes-node1 node-type-
node/kubernetes-node1 untainted
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe nodes kubernetes-node1 | egrep  'Hostname|Taints'
Taints:             <none>
  Hostname:    kubernetes-node1

再次查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-pod-taint
NAME                    READY   STATUS    RESTARTS   AGE
superopsmsb-pod-taint   1/1     Running   0          2m9s
结果显示:
	因为node1上的污点消除后,立刻就有pod正常运行了

简单实践

容忍度实践

为node1定制特殊污点
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl taint node kubernetes-node1 node-type=production:NoSchedule
node/kubernetes-node1 tainted

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe nodes kubernetes-node1 | egrep  'Hostname|Taints'
Taints:             node-type=production:NoSchedule
  Hostname:    kubernetes-node1
创建资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 11_kubernetes_scheduler_pod_tolerations_test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-pod-tolerations
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
  nodeSelector:
    env: dev
  tolerations:
  - key: "node-type"
    operator: "Equal"
    value: "production"
    effect: "NoSchedule"
    
应用资源定义文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 11_kubernetes_scheduler_pod_tolerations_test.yaml
pod/superopsmsb-pod-tolerations created

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod superopsmsb-pod-tolerations
NAME                          READY   STATUS    RESTARTS   AGE
superopsmsb-pod-tolerations   1/1     Running   0          4s
结果显示:
	pod的容忍度配置成功了

容忍度驱离方法

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod -o wide | grep node1
superopsmsb-pod-tolerations   1/1     Running   0          95s   10.244.1.10   kubernetes-node1   <none>           <none>

强制节点驱离pod
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl taint node kubernetes-node1 diskfull=true:NoExecute
node/kubernetes-node1 tainted
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod -o wide | grep node1
superopsmsb-pod-tolerations   1/1     Terminating   0          108s   10.244.1.10   kubernetes-node1   <none>           <none>
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod -o wide | grep node1
No resources found in default namespace.
结果显示:
	node1一旦被打上标签,其上的pod就被删除了
注意:
	一旦节点被打上diskfull=true:NoExecute,除了集群运行所需要的pod之外,其他都被清理,包括flannel的pod都会被驱离

清理措施

清理污点
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl taint node kubernetes-node1 node-type-
node/kubernetes-node1 untainted
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl taint node kubernetes-node1 diskfull-
node/kubernetes-node1 untainted
查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod -n kube-flannel -o wide
NAME                    ... RESTARTS      AGE   IP          NODE               ...
kube-flannel-ds-2z4bb   ... 0             18s   10.0.0.15   kubernetes-node1   ...
kube-flannel-ds-8f2tz   ... 2 (10h ago)   23h   10.0.0.17   kubernetes-node3   ...
kube-flannel-ds-dg9bb   ... 2 (10h ago)   23h   10.0.0.14   kubernetes-master3 ...
kube-flannel-ds-h4mkp   ... 2 (10h ago)   23h   10.0.0.13   kubernetes-master2 ...
kube-flannel-ds-mctqk   ... 2 (10h ago)   23h   10.0.0.16   kubernetes-node2   ...
kube-flannel-ds-pjkl5   ... 1 (10h ago)   23h   10.0.0.12   kubernetes-master1 ...
结果显示:
	一旦污点被驱离,flannel的pod立刻就回来了

小结


1.3 流量调度

1.3.1 Ingress基础

学习目标

这一节,我们从 场景需求、方案解读、小结 三个方面来学习。

场景需求

简介

	在实际的应用中,kubenetes接受的不仅仅有内部的流量,还有外部流量,我们可以通过两种方式实现将集群外部的流量引入到集群的内部中来,从而实现外部客户的正常访问。
service方式:
    nodePort、externalIP 等service对象方式,借助于 namespace、iptables、ipvs 等代理模式实现流量的转发。
Host方式:
    通过node节点的 hostNetwork 与 hostPort 及配套的port映射,以间接的方式实现service的效果

k8s网络

在这里插入图片描述

在业内有一个不成文的说法,就是:
	将集群内部 pod之类对象 之间的网络通信称为 东西向流量;
	将集群外部应用 和 集群内部之间对象 之间的网络通信 称为 南北向流量。
		南入↓  -- ingress
		北出↑  -- egress

问题

	1 在实际的应用中,虽然我们可以基于service或host等多种方式实现集群内外的网络通信,但是这些内容都是基于四层协议来进行调度的,而且服务级别的健康检查功能很难实现。
	2 而对于外部流量的接入,一般都是http(s)协议的数据,四层协议是无法实现的。尤其是涉及到各种ssl会话的管理,由于其位于osi七层模型的会话层,要高于传输层的四层,service和host是无法正常实现的。
	3 虽然service能够实现将外部流量引入到集群内部,但是其本质上,是通过网络规则方式来进行转发的,形象的说法就是在墙上打洞,将集群内部的服务暴露到外部。甚至这些洞和洞之间根本没有关联关系。	

方案

在这里插入图片描述

	为了解决上述的问题,就引入了一种新的解决方法ingress,简单来说,它可以解决上面提出的三个问题:
		1 可以基于https的方式,将集群外部的流量统一的引入到集群内部
		2 通过一个统一的流量入口,避免将集群内部大量的"洞"暴露给外部。
	
	ingress这种利用应用层协议来进行流量的负载均衡效果,它可以实现让用户通过域名来访问相应的service就可以了,无需关心Node IP及Port是什么,避免了信息的泄露。
	ingress 是k8s上的一种标准化资源格式,它为了剥离与特定负载均衡功能实现软件的相关性,而抽象出来的一种公共的统一的声明式配置格式。然后借助于特定的ingress controller功能负责将其加载并转换成k8s集群内部的配置信息。
	ingress的特点符合我们之前对于CRD的学习 - ingress + controller,所以,其具备了动态更新并加载新配置的特性。而且ingress本身是不具备实现集群内外流量通信的功能的,这个功能是通过 controller来实现的。

方案解读

实现

	Ingress由任何具有反向代理功能的程序实现,如Nginx、Traefik、Envoy、HAProxy、Vulcand等,Ingress本身是运行于集群中的Pod资源对象。
	ingress 主要包含两个组件Ingress Controller和Ingress。
组件解析
Ingress将Nginx的配置抽象成一个Ingress对象,每个服务对应一个ingress的yaml配置文件
Ingress Controller将新加入的Ingress转化成Nginx的配置文件并使之生效

问题梳理

如果我们将ingress 以pod的方式部署到k8s集群内部,那么就会遇到多个问题:
	1 ingress的pod如何引入外部流量
		- 通过一个专用的service就可以实现了
	2 ingress的pod如何把流量负载均衡到其他pod
		- 关于pod负载均衡的流量,直接通过controller转发给后端pod即可。
	3 后端应用的pod很多,如何知道谁是我们要转发的目标?
		- 通过k8s的server对所有的pod进行分组管理,借助于controller内部的负载均衡配置,找到对应的目标。

原理解析

Ingress是授权入站连接到达集群服务的规则集合。
    从外部流量调度到nodeport上的service
    从service调度到ingress-controller
    ingress-controller根据ingress[Pod]中的定义(虚拟主机或者后端的url)
    根据虚拟主机名直接调度到后端的一组应用pod中

在这里插入图片描述

注意:
	整个流程中涉及到了两处service内容
	service ingress-nginx 是帮ingress controller接入外部流量的
	虚线表示service对后端的应用进行分组,实现是ingress实际的访问流程

常见的解决方案

对于ingress controller的软件实现,其实没有特殊的要求,只要能够实现七层的负载均衡功能效果即可,各种组织对于ingress的controller虽然实现方式不同,但是功能基本上一样,常见的实现方式有:
Ingress-Nginx: Kong
HAProxy
	性能相对于nginx来说,较稳定
Envoy: 
	基于C++语言开发,本身就为动态环境设计的,支持配置动态加载的XDS API
	不能像ingress-nginx一样,直接加载配置文件并动态加载转换成对应的应用配置,所以需要借助于其他控制平面工具来实现。
	常见解决方案:Contour, Gloo
Traefik
注意:ingress 自从 1.6版本引入后,在1.19 正式进入了一个稳定版本状态。

小结


1.3.2 Ingress实践

学习目标

这一节,我们从 环境部署、简单实践、小结 三个方面来学习。

环境部署

参考资料:https://github.com/kubernetes/ingress-nginx
安装文档:https://kubernetes.github.io/ingress-nginx/deploy/

配置文件解析

apiVersion: networking.k8s.io/v1   			# 资源所属的API群组和版本
kind: Ingress   							# 资源类型标识符
metadata:  									# 元数据
  name <string>  							# 资源名称
  annotations:   							# 资源注解,v1beta1使用下面的注解来指定要解析该资源的控制器类型
    kubernetes.io/ingress.class: <string>   # 适配的Ingress控制器类别,便于多ingress组件场景下,挑选针对的类型
  namespace <string>  						# 名称空间
spec:
  rules <[]Object>   						# Ingress规则列表,也就是http转发时候用到的 url关键字
  - host <string>   						# 虚拟主机的FQDN,支持“*”前缀通配,不支持IP,不支持指定端口
    http <Object>
      paths <[]Object>   					# 虚拟主机PATH定义的列表,由path和backend组成
      - path <string>   					# 流量匹配的HTTP PATH,必须以/开头
        pathType <string>  					# 支持Exact、Prefix和ImplementationSpecific,必选
        backend <Object>   					# 匹配到的流量转发到的目标后端
          resource <Object>   				# 引用的同一名称空间下的资源,与下面两个字段互斥
          service <object>  				# 关联的后端Service对象
            name <string>  					# 后端Service的名称
            port <object>  					# 后端Service上的端口对象
              name <string>  	 			# 端口名称
              number <integer>   			# 端口号
  tls <[]Object>   							# TLS配置,用于指定上rules中定义的哪些host需要工作HTTPS模式
  - hosts <[]string>   						# 使用同一组证书的主机名称列表
    secretName <string>   					# 保存于数字证书和私钥信息的secret资源名称,用于主机认证
  backend <Object>   						# 默认backend的定义,可嵌套字段及使用格式跟rules字段中的相同
  ingressClassName  <string>   				# ingress类名称,用于指定适配的控制器,类似于注解的功能

环境部署

获取配置文件
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# mkdir ingress ; cd ingress
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# wget  https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/1.24/deploy.yaml
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# mv deploy.yaml ingress-deploy.yaml
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# cp ingress-deploy.yaml{,.bak}
获取镜像
for i in nginx-ingress-controller:v1.3.0 kube-webhook-certgen:v1.1.1
do
  docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$i
  docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$i kubernetes-register.superopsmsb.com/google_containers/$i
  docker push kubernetes-register.superopsmsb.com/google_containers/$i
  docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$i
done
修改基础镜像
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# grep image: ingress-deploy.yaml
          image: kubernetes-register.superopsmsb.com/google_containers/nginx-ingress-controller:v1.3.0
          image: kubernetes-register.superopsmsb.com/google_containers/kube-webhook-certgen:v1.1.1
          image: kubernetes-register.superopsmsb.com/google_containers/kube-webhook-certgen:v1.1.1
          
开放访问入口地址  
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# vim ingress-deploy.yaml
...
334 apiVersion: v1
335 kind: Service
...
344   namespace: ingress-nginx
345 spec:
      ...
348   ipFamilyPolicy: SingleStack
349   externalIPs: ['10.0.0.12']			# 增加一个外网访问的入口ip
350   ports:
351   - appProtocol: http
352     name: http
353     port: 80
...
628   failurePolicy: Ignore				    # 为了避免默认的准入控制限制,改为Ignore
...
应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# kubectl apply -f ingress-deploy.yaml

确认效果
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# kubectl get all -n ingress-nginx
NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-s5p7h        0/1     Completed   0          105s
pod/ingress-nginx-admission-patch-qnjmv         0/1     Completed   0          105s
pod/ingress-nginx-controller-6cc467dfd9-c2dfg   1/1     Running     0          105s

NAME                                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.109.163.145   10.0.0.12     80:31547/TCP,443:31185/TCP   105s
service/ingress-nginx-controller-admission   ClusterIP   10.96.223.121    <none>        443/TCP                      105s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   1/1     1            1           105s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-6cc467dfd9   1         1         1       105s

NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           8s         105s
job.batch/ingress-nginx-admission-patch    1/1           7s         105s
测试访问页面
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# curl 10.0.0.12:31547
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

直接获取状态码
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# curl -I -o /dev/null -s -w %{http_code}"\n" 10.0.0.12:31547
404

简单实践

创建deployment

定义资源文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 12_kubernetes_scheduler_ingress_deployment_nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: superopsmsb-nginx-deployment
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx-web
  template:
    metadata:
      labels:
        app: nginx-web
    spec:
      containers:
      - name: nginx-web
        image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
---
apiVersion: v1
kind: Service
metadata:
  name: superopsmsb-nginx-service
spec:
  selector:
    app: nginx-web
  ports:
    - name: nginx
      port: 80
      
应用资源文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 12_kubernetes_scheduler_ingress_deployment_nginx.yaml
deployment.apps/superopsmsb-nginx-deployment created
service/superopsmsb-nginx-service created


查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get deployments
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
superopsmsb-nginx-deployment   4/4     4            4           25s
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get svc
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes                  ClusterIP   10.96.0.1       <none>        443/TCP   2d14h
superopsmsb-nginx-service   ClusterIP   10.97.149.207   <none>        80/TCP    25s
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod -o wide
NAME                                            READY   STATUS    RESTARTS   AGE   IP            NODE               NOMINATED NODE   READINESS GATES
superopsmsb-cm-nginx                            1/1     Running   0          18h   10.244.1.19   kubernetes-node1   <none>           <none>
superopsmsb-nginx-deployment-64fc5c5f6c-c2vmm   1/1     Running   0          25s   10.244.1.21   kubernetes-node1   <none>           <none>
superopsmsb-nginx-deployment-64fc5c5f6c-dt4hx   1/1     Running   0          25s   10.244.1.22   kubernetes-node1   <none>           <none>
superopsmsb-nginx-deployment-64fc5c5f6c-mxxbh   1/1     Running   0          25s   10.244.3.19   kubernetes-node3   <none>           <none>
superopsmsb-nginx-deployment-64fc5c5f6c-zn57z   1/1     Running   0          25s   10.244.2.16   kubernetes-node2   <none>           <none>
superopsmsb-secret-nginx                        1/1     Running   0          16h   10.244.1.20   kubernetes-node1   <none>           <none>

创建ingress

定义资源文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat  13_kubernetes_scheduler_ingress_test.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: superopsmsb-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: nginx.superopsmsb.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: superopsmsb-nginx-service
            port: 
              number: 80
属性解析:
	注释信息,对于不同的ingress的内容是不一样的
	对于ingress来说,最终要的就是rules了,这里的hosts是一个自定义的域名
    
应用资源文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 13_kubernetes_scheduler_ingress_test.yaml
ingress.networking.k8s.io/superopsmsb-ingress created
查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get ingress
NAME                  CLASS    HOSTS                   ADDRESS   PORTS   AGE
superopsmsb-ingress   <none>   nginx.superopsmsb.com             80      17s

查看详细信息
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe ingress superopsmsb-ingress
Name:             superopsmsb-ingress
Labels:           <none>
Namespace:        default
Address:
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  nginx.superopsmsb.com
                         /   superopsmsb-nginx-service:80 (10.244.1.21:80,10.244.1.22:80,10.244.2.16:80 + 1 more...)
Annotations:             kubernetes.io/ingress.class: nginx
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  Sync    23s   nginx-ingress-controller  Scheduled for sync
结果显式:
	ingress 将 后端的superopsmsb-nginx-service:80 的样式自动与 ingress 的 url(/) 关联在一起了
访问效果
[root@kubernetes-master1 /data/kubernetes/schduler]# curl 10.0.0.12
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
为了更好的演示域名的效果,我们为externalIPs的ip地址做一个域名绑定
[root@kubernetes-master1 /data/kubernetes/schduler]# echo '10.0.0.12 nginx.superopsmsb.com' >> /etc/hosts

确认效果
[root@kubernetes-master1 /data/kubernetes/schduler]# curl nginx.superopsmsb.com
Hello Nginx, superopsmsb-nginx-deployment-64fc5c5f6c-dt4hx-1.23.0
结果显式:
	通过域名可以正常的访问后端的服务,而非域名访问方式受到了限制
非域名方式进行访问
[root@kubernetes-master1 /data/kubernetes/schduler]# curl http://10.0.0.12
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
[root@kubernetes-master1 /data/kubernetes/schduler]# curl http://10.0.0.12 -H "Host:nginx.superopsmsb.com"
Hello Nginx, superopsmsb-nginx-deployment-64fc5c5f6c-zn57z-1.23.0

结果显示:
	通过自定义携带域名的方式可以正常访问。

小结


1.3.3 Ingress进阶

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

需求

nginx controller的功能远不止我们所说的主机域名的管理,在实际的工作需求中,肯定会遇到,不同的功能服务以子路径的方式来进行访问,以及与https相关的访问。

准备工作

单独再来一个flask的服务
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 14_kubernetes_scheduler_ingress_deployment_flask.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: superopsmsb-flask-deployment
spec:
  replicas: 4
  selector:
    matchLabels:
      app: flask-web
  template:
    metadata:
      labels:
        app: flask-web
    spec:
      containers:
      - name: flask-web
        image: kubernetes-register.superopsmsb.com/superopsmsb/flask_web:v0.1

---
apiVersion: v1
kind: Service
metadata:
  name: superopsmsb-flask-service
spec:
  selector:
    app: flask-web
  ports:
    - name: flask
      port: 80
配置解析
	为了避免多个service使用同一个后端端口,我们这里一定要为service的端口命名
应用资源文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl apply -f 14_kubernetes_scheduler_ingress_deployment_flask.yaml
deployment.apps/superopsmsb-flask-deployment created
service/superopsmsb-flask-service created

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get deployment
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
superopsmsb-flask-deployment   3/4     4            3           17s
superopsmsb-nginx-deployment   4/4     4            4           55m

简单实践

  • 多主机访问实践

需求

访问 flask.superopsmsb.com/的时候,返回flask的结果
访问 nginx.superopsmsb.com/的时候,返回nginx的结果

资源配置文件

编辑资源定义文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 15_kubernetes_scheduler_ingress_mulhost.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: superopsmsb-ingress-mulhost
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: nginx.superopsmsb.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: superopsmsb-nginx-service
            port:
              name: nginx
  - host: flask.superopsmsb.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: superopsmsb-flask-service
            port:
              name: flask
 配置解析:
 	这里面有两个主机访问的地址是同一个后端端口,如果还用number的话,就无法正常的识别导致同一个地址访问不同的后端效果
              
应用资源文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 15_kubernetes_scheduler_ingress_mulhost.yaml
ingress.networking.k8s.io/superopsmsb-ingress-mulhost created
查看ingress效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get ingress
NAME                          CLASS    HOSTS                                         ADDRESS     PORTS   AGE
superopsmsb-ingress-mulhost   <none>   nginx.superopsmsb.com,flask.superopsmsb.com   10.0.0.17   80      30s

查看ingress详情
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe ingress superopsmsb-ingress-mulhost
Name:             superopsmsb-ingress-mulhost
Labels:           <none>
Namespace:        default
Address:          10.0.0.17
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  nginx.superopsmsb.com
                         /   superopsmsb-nginx-service:nginx (10.244.1.21:80,10.244.1.22:80,10.244.2.16:80 + 1 more...)
  flask.superopsmsb.com
                         /   superopsmsb-flask-service:flask (10.244.1.23:80,10.244.2.20:80,10.244.3.25:80 + 1 more...)
Annotations:             kubernetes.io/ingress.class: nginx
Events:
  Type    Reason  Age               From                      Message
  ----    ------  ----              ----                      -------
  Normal  Sync    2s (x2 over 31s)  nginx-ingress-controller  Scheduled for sync

实践

提前准备多个后端主机的域名
echo '10.0.0.12 flask.superopsmsb.com nginx.superopsmsb.com' >> /etc/hosts
访问效果
  • 单域名多url访问

需求

访问 shuji.superopsmsb.com/flask的时候,返回flask的结果
访问 shuji.superopsmsb.com/nginx的时候,返回nginx的结果

注意事项:
	由于这里涉及到了域名的url转发,而后端服务有可能不存在,随意我们需要在后端url转发的时候,取消转发关键字。
	方法就是,在annotation中添加一个重写的规则
		nginx.ingress.kubernetes.io/rewrite-target: /
		即,所有的请求,把ingress匹配到的url关键字清除掉

测试效果

编辑资源定义文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 16_kubernetes_scheduler_ingress_mulurl.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: superopsmsb-ingress-mulurl
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: shuji.superopsmsb.com
    http:
      paths:
      - path: /nginx
        pathType: Prefix
        backend:
          service:
            name: superopsmsb-nginx-service
            port:
              name: nginx
      - path: /flask
        pathType: Prefix
        backend:
          service:
            name: superopsmsb-flask-service
            port:
              name: flask
              
应用资源文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 16_kubernetes_scheduler_ingress_mulurl.yaml ingress.networking.k8s.io/superopsmsb-ingress-mulurl created


查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get ingress
NAME                         CLASS    HOSTS                   ADDRESS   PORTS   AGE
superopsmsb-ingress-mulurl   <none>   shuji.superopsmsb.com             80      33s

查看ingress资源详情
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe ingress superopsmsb-ingress-mulurl
Name:             superopsmsb-ingress-mulurl
Labels:           <none>
Namespace:        default
Address:
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  shuji.superopsmsb.com
                         /nginx   superopsmsb-nginx-service:nginx (10.244.1.21:80,10.244.1.22:80,10.244.2.16:80 + 1 more...)
                         /flask   superopsmsb-flask-service:flask (10.244.1.24:80,10.244.2.21:80,10.244.2.22:80 + 1 more...)
Annotations:             kubernetes.io/ingress.class: nginx
                         nginx.ingress.kubernetes.io/rewrite-target: /
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  Sync    33s   nginx-ingress-controller  Scheduled for sync
准备域名解析
[root@kubernetes-master1 /data/kubernetes/schduler]# echo '10.0.0.12 shuji.superopsmsb.com' >> /etc/hosts
浏览器访问效果
[root@kubernetes-master1 /data/kubernetes/schduler]# curl shuji.superopsmsb.com/flask
Hello Flask-V0.1, 来访者ip: 10.244.3.24, 主机名: superopsmsb-flask-deployment-766544c668-qgm92, Pod地址: 10.244.1.24!
[root@kubernetes-master1 /data/kubernetes/schduler]# curl shuji.superopsmsb.com/nginx
Hello Nginx, superopsmsb-nginx-deployment-64fc5c5f6c-mxxbh-1.23.0

小结


1.3.4 Ingress认证

学习目标

这一节,我们从 web认证、集群认证、小结 三个方面来学习。

web认证

需求

我们准备对基础的flask应用进行https方式来进行访问

方法:
	ingress的tls规则就可以帮助我们实现对http应用进行https升级

简单实践

定制secret文件
[root@kubernetes-master1 /data/kubernetes/schduler]# mkdir ingress-tls && cd ingress-tls
[root@kubernetes-master1 /data/kubernetes/schduler/ingress-tls]# (umask 077; openssl genrsa -out tls.key 2048)
Generating RSA private key, 2048 bit long modulus
......................................................................................+++
...............................+++
e is 65537 (0x10001)
[root@kubernetes-master1 /data/kubernetes/schduler/ingress-tls]# openssl req -new -x509 -key tls.key -out tls.crt -subj "/CN=shuji.superopsmsb.com" -days 365
[root@kubernetes-master1 /data/kubernetes/schduler/ingress-tls]# kubectl create secret tls superopsmsb-ingress-tls --cert=./tls.crt --key=./tls.key
secret/ingress-tls created

确认效果
[root@kubernetes-master1 /data/kubernetes/schduler/ingress-tls]# ls
tls.crt  tls.key
编辑资源定义文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 17_kubernetes_scheduler_ingress_tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: superopsmsb-ingress-tls
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: shuji.superopsmsb.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: superopsmsb-nginx-service
            port:
              number: 80
  tls:
  - hosts:
    - shuji.superopsmsb.com
    secretName: superopsmsb-ingress-tls
              
应用资源文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl apply -f 17_kubernetes_scheduler_ingress_tls.yaml
ingress.networking.k8s.io/superopsmsb-ingress-tls created
查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get ingress
NAME                         CLASS    HOSTS                   ADDRESS     PORTS     AGE
superopsmsb-ingress-mulurl   <none>   shuji.superopsmsb.com   10.0.0.17   80        16m
superopsmsb-ingress-tls      <none>   shuji.superopsmsb.com               80, 443   19s

查看ingress详情
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe ingress superopsmsb-ingress-tls
Name:             superopsmsb-ingress-tls
Labels:           <none>
Namespace:        default
Address:
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  superopsmsb-ingress-tls terminates shuji.superopsmsb.com
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  shuji.superopsmsb.com
                         /   superopsmsb-nginx-service:80 (10.244.1.21:80,10.244.1.22:80,10.244.2.16:80 + 1 more...)
Annotations:             kubernetes.io/ingress.class: nginx
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  Sync    19s   nginx-ingress-controller  Scheduled for sync
结果显示:
	所有访问 shuji.superopsmsb.com的请求都需要进行tls的处理,否则失效。
访问测试效果
[root@kubernetes-master1 /data/kubernetes/schduler]# curl shuji.superopsmsb.com
<html>
<head><title>308 Permanent Redirect</title></head>
<body>
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>nginx</center>
</body>
</html>
[root@kubernetes-master1 /data/kubernetes/schduler]# curl https://shuji.superopsmsb.com.com

curl: (35) Peer reports it experienced an internal error.
[root@kubernetes-master1 /data/kubernetes/schduler]# curl -k https://shuji.superopsmsb.com
Hello Nginx, superopsmsb-nginx-deployment-64fc5c5f6c-c2vmm-1.23.0

集群认证

需求

	我们知道,对于k8s的dashboard来说,它所实现的功能还是比较多的,而且原则上要求必须是https方式来进行访问。我们之前是通过service的方式实现正常的请求访问。有了ingress,我们也可以自由的访问dashboard了。比如我们访问k8s的dashboard的首页地址是
	https://10.0.0.12:nodeport/#/login

思路

	除了我们之前所说的动态url的方式之外,就需要tls认证了。关于对集群内部的ingress的tls访问方式,可以借助于ingress controller的annotation的方式向nginx中传递一些属性,从而上nginx支持相应的功能。这与我们上一节的方式有所不同
		1 通过两个annotation中的规则
			ingress.kubernetes.io/ssl-passthrough: "true"
				- 以为后面的dashboard本身就做了tls功能,所以这里进行tls代理即可
    		nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    			- 对后端直接启动https协议访问即可。
    			
参考资料:
	https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
定制ingress资源配置文件
[root@kubernetes-master1 /data/kubernetes/schduler]# cat 18_kubernetes_scheduler_ingress_tls_dashboard.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: superopsmsb-ingress-dashboard
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/ingress.class: "nginx"
    ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/rewrite-target: /$2	
spec:
  rules:
  - host: shuji.superopsmsb.com
    http:
      paths:
      - path: /dashboard(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port: 
              number: 443

应用资源文件
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 18_kubernetes_scheduler_ingress_tls_dashboard.yaml
ingress.networking.k8s.io/superopsmsb-ingress-dashboard created
查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get ingress -n kubernetes-dashboard
NAME                            CLASS    HOSTS                   ADDRESS   PORTS   AGE
superopsmsb-ingress-dashboard   <none>   shuji.superopsmsb.com             80      17s

查看ingress详情
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe ingress -n kubernetes-dashboard
Name:             superopsmsb-ingress-dashboard
Labels:           <none>
Namespace:        kubernetes-dashboard
Address:
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  shuji.superopsmsb.com
                         /dashboard(/|$)(.*)   kubernetes-dashboard:443 (10.244.3.28:8443)
Annotations:             ingress.kubernetes.io/ssl-passthrough: true
                         kubernetes.io/ingress.class: nginx
                         nginx.ingress.kubernetes.io/backend-protocol: HTTPS
                         nginx.ingress.kubernetes.io/rewrite-target: /$2
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  Sync    17s   nginx-ingress-controller  Scheduled for sync
浏览器访问 https://shuji.superopsmsb.com/dashboard/ 查看效果

在这里插入图片描述

结果显示:
	借助于nginx-controller的tls功能可以正常的实现相关的https的效果。

小结


1.3.5 Ingress扩展

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

简介

	默认情况下,Ingress是通过 Deployment + nodePort的方式将集群内部的服务暴露出去的,而且默认情况下,整个kubernetes集群中只有一个ingress-nginx实例。

[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl get pod -n ingress-nginx  | grep controll
ingress-nginx-controller-6cc467dfd9-c2dfg   1/1     Running     0          52m

思路:

	如果集群中唯一的ingress-nginx出现了故障,将导致整个kubernetes集群不可用。所以我们需要将这个集群业务的唯一入口进行高可用处理,根据我们之前的kubernetes资源对象知识,我们可以按照以下思路来进行:
	1 借助于Daemonset的方式实现ingress的多节点部署
	2 为了限制ingress-controller仅仅部署到master节点上,我们这里采用nodeSeler的方式来筛选master节点
	3 为了避免NodePort的劣势凸显,可以直接使用宿主机的80和443端口,我们可以采用HostNetwork的方式实现Cluster和node的网络互通,让Cluster直接监听node的端口。前提是宿主机的这两个端口不被占用
	所以最终我们可以确定 DaemonSet + HostNetwork + nodeSelector方式来部署ingress-nginx高可用集群。

准备工作

文件备份
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# cp ingress-deploy.yaml ingress-daemonset.yaml

检查主机环境

[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# for i in {12..14}; do  ssh root@10.0.0.$i "netstat -tnulp | egrep '443|80'"; done
tcp        0      0 10.0.0.12:2380          0.0.0.0:*               LISTEN      2146/etcd
tcp6       0      0 :::6443                 :::*                    LISTEN      31072/kube-apiserve
tcp        0      0 10.0.0.13:2380          0.0.0.0:*               LISTEN      2234/etcd
tcp6       0      0 :::6443                 :::*                    LISTEN      28944/kube-apiserve
tcp        0      0 10.0.0.14:2380          0.0.0.0:*               LISTEN      2186/etcd
tcp6       0      0 :::6443                 :::*                    LISTEN      29045/kube-apiserve

简单实践

修改文件

修改资源清单文件
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# vim ingress-daemonset.yaml
...
390 apiVersion: apps/v1
391 kind: DaemonSet			# 将Deployment修改为 DaemonSet
...
491       dnsPolicy: ClusterFirst
492       hostNetwork: true   # 增加cluster和node网络的互通
493       tolerations:
494         - operator: Exists
495       nodeSelector:
496         ingressSelect: "true"  # 专属的节点部署标签,而且必须加上双引号
497         kubernetes.io/os: linux
所有master节点添加标识
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# for i in 1 2 3
do 
  kubectl label node kubernetes-master$i ingressSelect=true
done
应用资源清单文件
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# kubectl apply -f ingress-daemonset.yaml

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# kubectl get pod -n ingress-nginx  -o wide
NAME                                   READY   STATUS      RESTARTS   AGE    IP            NODE                 NOMINATED NODE   READINESS GATES
ingress-nginx-admission-create-mn4tl   0/1     Completed   0          116s   10.244.2.25   kubernetes-node2     <none>           <none>
ingress-nginx-admission-patch-rbtl5    0/1     Completed   0          116s   10.244.3.31   kubernetes-node3     <none>           <none>
ingress-nginx-controller-85c26         1/1     Running     0          116s   10.0.0.14     kubernetes-master3   <none>           <none>
ingress-nginx-controller-88w6j         1/1     Running     0          116s   10.0.0.12     kubernetes-master1   <none>           <none>
ingress-nginx-controller-v2k7z         1/1     Running     0          116s   10.0.0.13     kubernetes-master2   <none>           <none>
[root@kubernetes-mas
端口检查效果
[root@kubernetes-master1 /data/kubernetes/schduler/ingress]# for i in {12..14}; do  ssh root@10.0.0.$i "netstat -tnulp | egrep ':(443|80)'"; done
tcp        0      0 0.0.0.0:443     ...78308/nginx: master
tcp        0      0 0.0.0.0:80      ...78308/nginx: master
tcp6       0      0 :::443          ...78308/nginx: master
tcp6       0      0 :::80           ...78308/nginx: master
tcp        0      0 0.0.0.0:80      ...72502/nginx: master
tcp        0      0 0.0.0.0:443     ...72502/nginx: master
tcp6       0      0 :::80           ...72502/nginx: master
tcp6       0      0 :::443          ...72502/nginx: master
tcp        0      0 0.0.0.0:80      ...72415/nginx: master
tcp        0      0 0.0.0.0:443     ...72415/nginx: master
tcp6       0      0 :::80           ...72415/nginx: master
tcp6       0      0 :::443          ...72415/nginx: master

确认效果

创建资源对象
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl  apply -f 17_kubernetes_scheduler_ingress_tls.yaml

查看效果
[root@kubernetes-master1 /data/kubernetes/schduler]# kubectl describe ingress superopsmsb-ingress-tls
Name:             superopsmsb-ingress-tls
Labels:           <none>
Namespace:        default
Address:          10.0.0.12,10.0.0.13,10.0.0.14
...
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    17s (x2 over 40s)  nginx-ingress-controller  Scheduled for sync
  Normal  Sync    17s (x2 over 40s)  nginx-ingress-controller  Scheduled for sync
  Normal  Sync    17s (x2 over 40s)  nginx-ingress-controller  Scheduled for sync
查看访问效果
[root@kubernetes-master1 /data/kubernetes/schduler]# curl https://shuji.superopsmsb.com -k
Hello Nginx, superopsmsb-nginx-deployment-64fc5c5f6c-mhgcs-1.23.0

小结

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KubernetesK8s)是一种用于容器编排和管理的开源平台,它提供了多维资源调度算法来实现高效的资源管理和利用。 K8s使用多维资源调度算法来平衡集群中所有节点的资源负载,确保每个节点能够充分利用其可用的计算和存储资源。这些资源包括CPU、内存、存储和网络带宽等。K8s通过采集集群中每个节点的资源使用情况,并将其报告给调度策略,从而实现资源的智能分配。 在K8s中,多维资源调度算法主要涉及以下几个方面: 1. 资源分配:K8s通过分配节点上的资源来满足容器的需求。调度器会考虑所有容器资源需求,并将其分配到合适的节点上。该算法会根据容器资源请求和节点的可用资源进行匹配,从而避免资源的浪费和不平衡。 2. 负载均衡:K8s通过负载均衡算法将容器分散到不同的节点上,以避免资源瓶颈和单点故障。该算法会根据节点的负载情况和容器资源需求,将容器分配到最佳节点上,从而实现负载的均衡。 3. 弹性调度K8s具有弹性调度的能力,可以根据节点的可用资源容器的优先级,自动对容器进行调度。当集群容量不足或节点发生故障时,该算法可以自动将容器从一个节点迁移到另一个节点上,以确保容器的正常运行。 总之,K8s的多维资源调度算法是为了实现高效、均衡和可靠的资源管理。通过合理分配和调度容器资源需求,K8s可以最大化地利用集群的资源,并提供高可用性和可伸缩性的应用环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值