菜单
本页目录

5 Kubernetes-service

LBC:负载均衡集群

HAC:高可用集群

HPC:高性能运算集群

一、概念

1)service:负载调度器(svc)

​ K8S中的逻辑分组(名字空间、标签)。svc为逻辑分组的标签分组

Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务。 这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector

![image-20230121101941413](5 Kubernetes-service.assets/image-20230121101941413.png)

2)迭代核心

​ 在 kubernetes 集群中,每个节点运行一个kube-proxy 进程。负责为 service 实现了一种 VIP(虚拟ip) 的形式,而不是 ExternalName 的形式

​ 在 Kubernetes v1.0 版本,代理完全在 userspace ,在 Kubernetes v1.1 版本,新增了 iptables 代理,但并不是默认的运行模式。

​ 从 Kubernetes v1.2 起,默认就是 iptables 代理。

​ 在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理

​ 在 Kubernetes 1.14 版本开始默认使用 ipvs 代理

3)Kube-proxy 底层工作方式

Ⅰ、userspace 代理模式

image-20230121102807103

userspace基本实现了四层代理

​ 1、kube-proxy 监听 apiserver ,将负载网络变化信息通过 netlinks 接口,写入到 iptables

​ 2、kube-proxy 代理访问本地 podclient 请求

Ⅱ、iptables 代理模式

image-20230121102832193

iptables

​ 1、kube-proxy 仅监听 apiserver ,将负载网络变化信息,通过 netlinks 接口,写入至 iptables

​ 2、本地 podclient 请求,直接通过 iptables 负载

​ 优点:Kube-proxy 压力变小

Ⅲ、ipvs 代理模式

​ 注意:ipvs 模式需要在安装集群时启用模块,若未安装,则 kube-proxy 将回退到 iptables 代理模式

image-20230121102854375

ipvs:(将 iptables 替换为更底层的内核技术)

kube-proxy 监听 apiserver 将负载网络变化信息通过 netlinks 接口写入至 ipvs

​ 优点:kube-proxy 压力变小,由 netfilter 替换为 ipvs ,负载能力进一步加强

注意:ipvs 负载的流量

ipvs 仅负载本机节点,客户端 pod 请求的流量。每一个节点都有一个 ipvs 负载。从而压力均摊

限制:

Service能够提供负载均衡的能力,但是在使用上有以下限制:

1、只提供 4 层负载均衡能力

​ **只提供 4 层负载均衡能力,而没有 7 层功能。**但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的

2、不能实现https会话卸载层

https 会话卸载层需要7层的能力,而此处的4层负载不能实现

拓展:https 会话卸载层原理图:

​ 用户--》代理server--》真实server,都采用https。

为了防止反复tcp握手连接,需要持久化链接

image-20230121105822925

https 会话卸载层

​ 用户---》代理server,采用https。代理server--》真实server,采用由七层卸载为4层的http

image-20230121110233973

3、暴露一个接口,从而能实现7层的能力

​ 在 Kubernetes v1.0 版本,Service 是 “4层”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了 Ingress API(beta 版),用来表示 “7层”(HTTP)服务

4)Service 的类型

1、Clusterip 类型

​ 集群内部的调用。默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP**(重点)**

原理:

nginx控制器 指向 svc调度器svc调度器 再去管理 tomcat控制器 。若 tomcat控制器 管理的 pod 出现故障,则直接由 tomcat控制器 重建 pod ,而 svc调度器 也会做出对应的负载调整

image-20230121112239312

拓展:短时间内ipvs仍保留之前调度的ip

​ 之前调度的ip信息会隔一段时间再删除

pod ipvs RS 的信息删除的步骤:

​ 1、将死亡的 pod 地址权重改写为 0 ​ 2、删除此 pod 地址

2、Nodeport 类型

	**将内部服务暴露出去**,使用3万以上的端口。在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 `<NodeIP>: NodePort` 来访问该服务

原理:

​ 当客户端访问节点的 <NodeIP>: NodePort ,由 ipvs 负载到集群内部的 nginx-pod ,再转发至 clusterip 调度器的负载均衡中,再转发到真实的服务器

image-20230121113457704

3、LoadBalancer 类型

​ 在 NodePort 的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到: NodePort

​ 前提:cloud provider (云供应商)

拓展:K8S 高可用拓扑图

​ 1、在 Kubernetes 外部也需要结合 ipvs 实现

image-20230121113909866

​ 2、在 Kubernetes 外部,结合 LAAS (负载均衡即服务) 实现**(即LoadBalancer 类型)**

image-20230121114136201

4、ExternalName 类型

​ 将外部不稳定的地址或域名,通过DNS做别名的方式,实现解析

​ service域名:创建完成svc以后默认产生

serviceName.nameSpaceName.svc.domainName.
		eg:
			myapp.default.svc.cluster.local.

原理:

![image-20230121114838676](5 Kubernetes-service.assets/image-20230121114838676.png)

二、实验

1)Clusterip 类型

1、创建控制器

[root@k8s-master01 ~]# mkdir 5 ; cd 5
[root@k8s-master01 5]# vim 1.deployment.yaml
[root@k8s-master01 5]# cat 1.deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      release: stabel
  template:
    metadata:
      labels:
        app: myapp
        release: stabel
        env: test
    spec:
      containers:
      - name: myapp
        image: wangyanglinux/myapp:v1
        ports:
        - name: http
          containerPort: 80
[root@k8s-master01 5]# kubectl apply -f 1.deployment.yaml 
deployment.apps/myapp-deploy created
[root@k8s-master01 5]# kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
myapp-deploy-684d6487b6-cm2bq   1/1     Running   0          3s
myapp-deploy-684d6487b6-dzt7d   1/1     Running   0          3s
myapp-deploy-684d6487b6-vd27z   1/1     Running   0          3s

2、创建svc

[root@k8s-master01 5]# vim 2.service.yaml
[root@k8s-master01 5]# kubectl apply -f 2.service.yaml 
service/myapp created
[root@k8s-master01 5]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   10d
myapp        ClusterIP   10.110.66.4   <none>        80/TCP    2s
[root@k8s-master01 5]# cat 2.service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  type: ClusterIP
  selector:
    app: myapp
    release: stabel
  ports:
  - name: http
    port: 80
    targetPort: 80

3、测试负载均衡

[root@k8s-master01 5]# while true;do curl 10.110.66.4/hostname.html;sleep 1;done

image-20230121120047894

底层原理:ipvs

注意:当前本地的ipvs,只负载当前节点的客户端

image-20230121120438218

4、模拟测试pod挂掉

​ 若控制器管理的pod挂掉,控制器会重建pod,svc会重新调度新的pod,实现负载均衡

[root@k8s-master01 5]# kubectl delete pod myapp-deploy-684d6487b6-cm2bq

[root@k8s-master01 5]# kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
myapp-deploy-684d6487b6-6vrvv   1/1     Running   0          18s
myapp-deploy-684d6487b6-dzt7d   1/1     Running   0          13m
myapp-deploy-684d6487b6-vd27z   1/1     Running   0          13m

​ 重新调度成功,之前的调度ip负载权重为0:(规则同步与控制器创建pod实时)

image-20230121121125621

拓展:短时间内ipvs仍保留之前调度的ip

​ 之前调度的ip信息会隔一段时间再删除

pod ipvs RS 的信息删除的步骤:

​ 1、将死亡的 pod 地址权重改写为 0 ​ 2、删除此 pod 地址

5、pod内部也有负载均衡

​ 创建一个客户端pod,进入测试负载均衡

[root@k8s-master01 5]# vim 3.pod.yaml 

[root@k8s-master01 5]# cat 3.pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-1
    image: wangyanglinux/myapp:v1
  - name: busybox-1
    image: busybox:1.36.0
    command:
    - "/bin/sh"
    - "-c"
    - "sleep 3600"
    
[root@k8s-master01 5]# kubectl apply -f 3.pod.yaml 

[root@k8s-master01 5]# kubectl exec -it pod-demo -c busybox-1 -- /bin/sh
/ # wget http://10.110.66.4/hostname.html && cat hostname.html && rm -rf hostname.html

​ 验证负载均衡

image-20230121122513513

6、svc域名解析

​ service域名:创建完成svc以后默认产生

serviceName.nameSpaceName.svc.domainName.
		eg:
			myapp.default.svc.cluster.local.

用途:此特性可以实现通过域名指向svc。即使创建的svc地址变化,也能精准定位

​ 即使 service 还未创建,根据规则编写,就能知道创建完成的 service 如何通过域名访问

​ 比如:在编写配置文件 deployment-tomcat.yaml ,会提前编写 service-taomcat.yamldeployment-nginx.yaml

​ 在编写deployment-nginx.yaml 时,直接指向 svc-tomcat的域名,就能实现 nginx控制器 指向 svc-tomcat调度器

Ⅰ 查询集群的域名
[root@k8s-master01 5]# cat /usr/local/kubernetes/install/kubeadm-config.yaml |grep dnsDomain
  dnsDomain: cluster.local

Ⅱ 查询集群内部的dns地址

​ 存在两个dns地址:实现高可用

[root@k8s-master01 5]# kubectl get pod -n kube-system -o wide |grep coredns
coredns-5c98db65d4-fb8z2               1/1     Running   11         10d   172.100.1.185    k8s-node01     <none>           <none>
coredns-5c98db65d4-gqtpz               1/1     Running   11         10d   172.100.1.186    k8s-node01     <none>           <none>
[root@k8s-master01 5]# ipvsadm -Ln |grep :53
TCP  10.96.0.10:53 rr
  -> 172.100.1.185:53             Masq    1      0          0         
  -> 172.100.1.186:53             Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 172.100.1.185:53             Masq    1      0          0         
  -> 172.100.1.186:53             Masq    1      0          0
Ⅲ svc域名解析
[root@k8s-master01 5]# yum -y install bind-utils
[root@k8s-master01 5]# dig -t A myapp.default.svc.cluster.local. @10.96.0.10

image-20230121124155786

Ⅳ 验证
[root@k8s-master01 5]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   10d
myapp        ClusterIP   10.110.66.4   <none>        80/TCP    45m

7、会话保持

​ 在固定的时间内,将 同一请求 分配至同一台机器(类似 ipvs 中的持久化连接)

$ ipvsadm -A -t 192.168.20.201 -s rr -p 192.168.20.202

​ K8S 集群中:

service.spec.sessionAffinity.ClientIP
service.spec.sessionAffinityConfig.clientIP

image-20230121125920605

Ⅰ 查看默认未设置会话保持
[root@k8s-master01 5]# kubectl get svc myapp -o yaml |grep session
  sessionAffinity: None
Ⅱ 设置会话保持(也可设置不同的yaml文件实现)
[root@k8s-master01 5]# kubectl edit svc myapp


  sessionAffinity: ClientIP
  sessionAffinityConfig: 
    clientIP:
      timeoutSeconds: 3000

image-20230121143518999

Ⅲ 测试

​ 设定了 service 会话亲和性以后,先访问一次得到 pod hostname,然后等待 3小时 以后,在去访问应该会发现跳转至一个新的 pod,如果一直不间断访问下去, pod 不会改变

​ 一直访问,则会一直保持会话

[root@k8s-master01 5]# while true;do curl 10.110.66.4/hostname.html;sleep 1;do
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
^C

​ 停留一段时间再访问

[root@k8s-master01 5]# curl 10.110.66.4/hostname.html;date
myapp-deploy-684d6487b6-vd27z
2023年 01月 21日 星期六 16:17:07 CST


# 停留一段时间再访问


[root@k8s-master01 5]# curl 10.110.66.4/hostname.html;date
myapp-deploy-684d6487b6-dzt7d
2023年 01月 21日 星期六 16:21:09 CST

[root@k8s-master01 5]# kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
myapp-deploy-684d6487b6-6vrvv   1/1     Running   0          4h12m
myapp-deploy-684d6487b6-dzt7d   1/1     Running   0          4h25m
myapp-deploy-684d6487b6-vd27z   1/1     Running   0          4h25m
pod-demo                        2/2     Running   4          4h2m

8、Headless Service (statefulSet 控制器专用,后续介绍)

​ 有时不需要或不想要负载均衡,以及单独的 Service IP 。遇到这种情况,可以通过指定 Cluster IP ( spec.clusterIP ) 的值为 “ None ” 来创建 Headless Service 。这类 Service 并不会分配 Cluster IP, kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由

# yum -y install bind-utils
[root@k8s-master mainfests]# vim myapp-svc-headless.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-headless
  namespace: default
spec:
  selector:
    app: myapp
  clusterIP: "None"
  ports: 
  - port: 80
    targetPort: 80

[root@k8s-master mainfests]# dig -t A myapp-headless.default.svc.cluster.local. @10.96.0.10

2)Nodeport 类型

​ 采用的是 ipvs集群 中的 nat转换,作为工作方式(端口映射)

不仅仅是负载均衡。若只有一个pod,也可用过 Nodeport 给外部提供访问

[root@k8s-master01 5]# vim 4.nodeport.yaml 
[root@k8s-master01 5]# cat 4.nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-nodeport
  namespace: default
spec:
  type: NodePort
  selector:
    app: myapp
    release: stabel
  ports:
  - name: http
    port: 80
    targetPort: 80
#    nodePort: 30005
#    设置指定端口,不建议自定义,避免冲突
[root@k8s-master01 5]# kubectl apply -f 4.nodeport.yaml

​ 浏览器访问测试:

image-20230121145739939

3)LoadBalancer

loadBalancer 和 nodePort 其实是同一种方式。区别在于 loadBalancer 比 nodePort 多了一步,就是可以调用 cloud provider 去创建 LB 来向节点导流

TWtF3j

4)ExternalName

​ 利用本集群的 dns插件 ,将一个固定的域名 my-service-1.default.svc.cluster.local.解析到一个不固定的域名 hub.xinxianghf.com1 上,实现每一个pod的配置文件不用单独修改,仅需改 service对象的别名 即可

kind: Service
apiVersion: v1
metadata:
  name: my-service-1
  namespace: default
spec:
  type: ExternalName
  externalName: hub.xinxianghf.com

  
# my-service-1.default.svc.cluster.local.  

当查询主机 my-service.defalut.svc.cluster.local ( SVC_NAME.NAMESPACE.svc.cluster.local )时,集群的 DNS 服务将返回一个值 my.database.example.com 的 CNAME 记录。访问这个服务的工作方式和其他的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发

三、Endpoints

1、介绍

Endpoints是一个资源对象。一组 pod 的服务端点集合

image-20230201202236264

Endpoint 分类:

​ 自动生成:若创建 service 控制器,存在标签选择器,则会自动生成 Endpoints

​ 手动配置:若创建的 service 控制器,不存在标签选择器(无 selector),则需要手动创建(有灵活性)

![image-20230201202526856](5 Kubernetes-service.assets/image-20230201202526856.png)

![image-20230201202548982](5 Kubernetes-service.assets/image-20230201202548982.png)

2、实验

1)Endpoints 自动创建

​ 1.创建deployment控制器管理pod

​ 2.创建svc负载deployemnt控制器(会自动创建和 service 同名的 Endpoints

[root@k8s-master01 6]# mkdir 6 ;cd 6
[root@k8s-master01 6]# kubectl create deployment myapp --image=wangyanglinux/myapp:v1 --dry-run -o yaml > 1.deployment.yaml
[root@k8s-master01 6]# vim 1.deployment.yaml 
[root@k8s-master01 6]# cat 1.deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp
  name: myapp
spec:
  replicas: 5
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - image: wangyanglinux/myapp:v1
        name: myapp
[root@k8s-master01 6]# kubectl apply -f 1.deployment.yaml 
deployment.apps/myapp created



[root@k8s-master01 6]# kubectl create svc clusterip myapp --tcp=80:80 --dry-run -o yaml > 2.svc.yaml
[root@k8s-master01 6]# cat 2.svc.yaml 
apiVersion: v1
kind: Service
metadata:
  labels:
    app: myapp
  name: myapp
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: myapp
[root@k8s-master01 6]# kubectl apply -f 2.svc.yaml 
service/myapp created
[root@k8s-master01 6]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   22d
myapp        ClusterIP   10.104.33.100   <none>        80/TCP    3s
[root@k8s-master01 6]# kubectl get endpoints
NAME         ENDPOINTS                                                     AGE
kubernetes   192.168.20.201:6443                                           22d
myapp        172.100.1.50:80,172.100.1.51:80,172.100.2.86:80 + 2 more...   39s

2)手动创建 Endpoints

创建的 service 不指定标签选择器。需要手动创建 Endpoints

1.根据 3.svc.yaml 文件创建 serviceEndpoints
# 3.svc.yaml 文件详解
apiVersion: v1				#指定核心组为 v1版
kind: Service				#指定创建的资源对象为 service
metadata:					#指定元数据信息
  name: nginx					#指定service对象的名称
spec:							#定义service对象的期望
  ports:							#定义端口信息
    - protocol: TCP					#tcp连接
      port: 6666					#外部访问svc的端口
      targetPort: 80				#svc负载后台访问的端口
# 创建没有标签选择器的service
[root@k8s-master01 6]# vim 3.svc.yaml
[root@k8s-master01 6]# cat 3.svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - protocol: TCP
      port: 6666
      targetPort: 80
[root@k8s-master01 6]# kubectl apply -f 3.svc.yaml 
service/nginx created


# 验证:没有自动创建Endpoints
[root@k8s-master01 6]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    22d
myapp        ClusterIP   10.96.9.32      <none>        80/TCP     66m
nginx        ClusterIP   10.109.102.43   <none>        6666/TCP   18s
[root@k8s-master01 6]# kubectl get Endpoints
NAME         ENDPOINTS                                                     AGE
kubernetes   192.168.20.201:6443                                           22d
myapp        172.100.1.52:80,172.100.1.53:80,172.100.2.89:80 + 2 more...   67m
2.在node01节点中部署服务
docker run -itd -p 80:80 --net host wangyanglinux/myapp:v1

浏览器测试访问:![image-20230201222641732](5 Kubernetes-service.assets/image-20230201222641732.png)

3.手动创建Endpoints

将刚才在node01中部署的服务,添加到自动创建的 service 中(手动创建 Endpoints 实现)

# cat 4.Endpoints.yaml 详解
apiVersion: v1
kind: Endpoints				#指定创建的资源对象为 Endpoints
metadata:					#定义资源对象中的元数据信息
  name: nginx
subsets:					#定义管理的ip地址和端口
  - addresses:
      - ip: 192.168.20.202
    ports:
      - port: 80
[root@k8s-master01 6]# vim 4.Endpoints.yaml
[root@k8s-master01 6]# cat 4.Endpoints.yaml
apiVersion: v1
kind: Endpoints
metadata:
  name: nginx
subsets:
  - addresses:
      - ip: 192.168.20.202
    ports:
      - port: 80
      
[root@k8s-master01 6]# kubectl apply -f 4.Endpoints.yaml 
endpoints/nginx created
[root@k8s-master01 6]# kubectl get Endpoints
NAME         ENDPOINTS                                                     AGE
kubernetes   192.168.20.201:6443                                           22d
myapp        172.100.1.52:80,172.100.1.53:80,172.100.2.89:80 + 2 more...   90m
nginx        192.168.20.202:80                                             105s
[root@k8s-master01 6]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    22d
myapp        ClusterIP   10.96.9.32      <none>        80/TCP     89m
nginx        ClusterIP   10.109.102.43   <none>        6666/TCP   22m
4.测试访问
[root@k8s-master01 6]# curl 10.109.102.43:6666/hostname.html
k8s-node01

注意:Endpoints可跟踪多个ip

  - addresses:
      - ip: 172.17.0.2
      - ip: 172.17.0.3
      - ip: 172.17.0.4
      ... ...

四、ingress

**Ingress-Nginx github 地址:**https://github.com/kubernetes/ingress-nginx

**Ingress-Nginx 官方网站:**https://kubernetes.github.io/ingress-nginx/

由于 service 的负载是4层负载,可以借助nginx、ingress-nginx实现七层负载

1、可手动创建nginx,实现七层负载

实现会话卸载层:客户端与nginx之间采用https,nginx与内部采用http

原理图:![image-20230201225316412](5 Kubernetes-service.assets/image-20230201225316412.png)

2、通过ingress自动实现七层负载

ingress-nginx是ingress实现的其中一种方式

![image-20230201230152321](5 Kubernetes-service.assets/image-20230201230152321.png)

原理:尽可能减少nginx的重启

​ 对配置文件的修改:store协程 监听apiserver是否存在reload,syncqueue协程 再次判断是否reload

​ 重要的:两个协程进行判断为重要的之后,直接进行重启

​ 不重要的:store协程 为不重要的判断后,放入一级缓冲,经过主城后,放入二级缓冲,经过syncqueue协程 再次判断是否reload

![image-20230201230218541](5 Kubernetes-service.assets/image-20230201230218541.png)

3、ingress实验

拓展:Rancher Desktop 的 K3S (相当于精简版K8S,省去了一些的无用的接口)

​ K3S目标:边缘计算(每个独立的位置都能进行运算)

1)ingress-nginx搭建

Ⅰ 清理
[root@k8s-master01 6]# kubectl delete deployment --all
deployment.extensions "myapp" deleted
[root@k8s-master01 6]# kubectl delete svc nginx myapp
service "nginx" deleted
service "myapp" deleted
[root@k8s-master01 6]# kubectl get pod 
No resources found.
Ⅱ 准备环境
[root@k8s-master01 ~]# mkdir /usr/local/kubernetes/ingress
[root@k8s-master01 ~]# cd !$
cd /usr/local/kubernetes/ingress

上传压缩包(本次采用基础本地安装)

![image-20230202000935212](5 Kubernetes-service.assets/image-20230202000935212.png)

# master01节点中
$ yum -y install unzip ;unzip Ingress-nginx.zip
[root@k8s-master01 ingress]# cd Ingress-nginx
[root@k8s-master01 Ingress-nginx]# tar -xf ingress-nginx.tar.gz 
[root@k8s-master01 Ingress-nginx]# cd ingress-nginx 
[root@k8s-master01 ingress-nginx]# docker load -i ingress.tar 

[root@k8s-master01 ingress-nginx]# scp ingress.tar root@n1:/root/

[root@k8s-master01 ingress-nginx]# scp ingress.tar root@n2:/root/


# node01节点中
[root@k8s-node01 ~]# docker load -i ingress.tar

# node02节点中
[root@k8s-node02 ~]# docker load -i ingress.tar
Ⅲ 根据 yaml 文件创建ingress-nginx

​ mandatory.yaml #运行deployment控制器

​ service-nodeport #运行service的ingress-nginx

[root@k8s-master01 ingress-nginx]# kubectl apply -f mandatory.yaml 
[root@k8s-master01 ingress-nginx]# kubectl apply -f service-nodeport.yaml

[root@k8s-master01 ingress-nginx]# kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.96.131.122   <none>        80:30914/TCP,443:30050/TCP   4m6s

Ⅳ 测试访问

![image-20230202003631956](5 Kubernetes-service.assets/image-20230202003631956.png)

![image-20230202003650479](5 Kubernetes-service.assets/image-20230202003650479.png)

![image-20230202003702197](5 Kubernetes-service.assets/image-20230202003702197.png)

2)ingress http代理访问---实现虚拟主机

实现:同一个ip,能用不同的域名访问,且不同域名下的资源不同

Ⅰ、创建5.http.yaml、6.http.yaml,并进行部署
[root@k8s-master01 6]# pwd
/root/6
[root@k8s-master01 6]# ls
1.deployment.yaml  2.svc.yaml  3.svc.yaml  4.Endpoints.yaml
[root@k8s-master01 6]# vim 5.http.yaml
[root@k8s-master01 6]# cat 5.http.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: www1
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: www1
    spec:
      containers:
        - name: nginx
          image: wangyanglinux/myapp:v1
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: www1
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: www1
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: www1
spec:
  rules:
    - host: www1.hongfu.com
      http:
        paths:
        - path: /
          backend:
            serviceName: www1
            servicePort: 80



[root@k8s-master01 6]# kubectl apply -f 5.http.yaml 
[root@k8s-master01 6]# cp -a 5.http.yaml 6.http.yaml
[root@k8s-master01 6]# vim 6.http.yaml 
[root@k8s-master01 6]# cat 6.http.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: www2
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: www2
    spec:
      containers:
        - name: nginx
          image: wangyanglinux/myapp:v2
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: www2
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: www2
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: www2
spec:
  rules:
    - host: www2.hongfu.com
      http:
        paths:
        - path: /
          backend:
            serviceName: www2
            servicePort: 80
[root@k8s-master01 6]# kubectl apply -f 6.http.yaml 


Ⅱ、查看运行状态,并获取http端口号
[root@k8s-master01 6]# kubectl get pod,deployment,ingress,svc
NAME                        READY   STATUS    RESTARTS   AGE
pod/www1-7cfb5dd7bf-2bs26   1/1     Running   0          6m57s
pod/www1-7cfb5dd7bf-2l8qg   1/1     Running   0          6m57s
pod/www2-68dd4464cf-9cz85   1/1     Running   0          113s
pod/www2-68dd4464cf-nhpx8   1/1     Running   0          113s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/www1   2/2     2            2           6m57s
deployment.extensions/www2   2/2     2            2           113s

NAME                      HOSTS             ADDRESS   PORTS   AGE
ingress.extensions/www1   www1.hongfu.com             80      6m57s
ingress.extensions/www2   www2.hongfu.com             80      113s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   22d
service/www1         ClusterIP   10.110.217.28   <none>        80/TCP    6m57s
service/www2         ClusterIP   10.103.47.29    <none>        80/TCP    113s



[root@k8s-master01 6]# kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.96.131.122   <none>        80:30914/TCP,443:30050/TCP   21m


Ⅲ Windows写入hosts文件
192.168.20.201		www1.hongfu.com
192.168.20.201		www2.hongfu.com
192.168.20.201		ssl.hongfu.com
192.168.20.201		auth.hongfu.com
192.168.20.201		rew.hongfu.com
Ⅳ 浏览器测试访问:

![image-20230202005006727](5 Kubernetes-service.assets/image-20230202005006727.png)

![image-20230202005019697](5 Kubernetes-service.assets/image-20230202005019697.png)

3)ingress https代理访问---会话卸载层

注意:会话卸载层的客户端访问,需要有路由实现地址转换

​ 客户端访问路由地址,路由将来自80的访问转换端口为31891,经过svc-nodeport到ingress-nginx,由80跳转到443

​ 客户端再次访问,由记录直接访问443,这个时候需要路由将来自443的访问转换为31732。若没有,则不会访问成功。

![image-20230202011338917](5 Kubernetes-service.assets/image-20230202011338917.png)

拓展:label与annotation区别

​ label:集群内部使用的约定

​ annotation:第三方开发与使用者之间的约定

Ⅰ、创建证书
[root@k8s-master01 6]# mkdir 7
[root@k8s-master01 6]# cd 7/
[root@k8s-master01 7]# openssl genrsa -des3 -out tls.key 2048

[root@k8s-master01 7]# openssl req -new -key tls.key -out tls.csr

[root@k8s-master01 7]# cp tls.key tls.key.org
[root@k8s-master01 7]# openssl rsa -in tls.key.org -out tls.key

[root@k8s-master01 7]# openssl x509 -req -days 365 -in tls.csr -signkey tls.key -out 
[root@k8s-master01 7]# ls
tls.crt  tls.csr  tls.key  tls.key.org

Ⅱ、cert存储
kubectl create secret tls tls-secret --key tls.key --cert tls.crt
Ⅲ、创建deployment控制器
[root@k8s-master01 7]# vim 1.deployment.yaml
[root@k8s-master01 7]# cat 1.deployment.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: ssl
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: ssl
    spec:
      containers:
        - name: nginx
          image: wangyanglinux/myapp:v3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: ssl
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: ssl

[root@k8s-master01 7]# kubectl apply -f 1.deployment.yaml 
Ⅳ、创建ingress对象

**annotation中定义:**与ingress-nginx官方规定好的需要开启的功能key,和对应value

[root@k8s-master01 7]# vim 2.ingress.yaml 
[root@k8s-master01 7]# cat 2.ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ssl.hongfu.com
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - ssl.hongfu.com
    secretName: tls-secret
  rules:
  - host: ssl.hongfu.com
    http:
      paths:
      - path: /
        backend:
          serviceName: ssl
          servicePort: 80
[root@k8s-master01 7]# kubectl apply -f 2.ingress.yaml 
Ⅴ 测试访问

此处因为没有路由,所以80跳转到443失败:

image-20230202011615493

访问443端口成功: image-20230202012015522

4)nginx进行BasicAuth---目录保护

Ⅰ、创建登录用户、创建cert存储
[root@k8s-master01 6]# mkdir 8
[root@k8s-master01 6]# cd 8/
[root@k8s-master01 8]# pwd
/root/6/8
[root@k8s-master01 6]# yum -y install httpd-tools
[root@k8s-master01 6]# htpasswd -c auth foo

[root@k8s-master01 6]# kubectl create secret generic basic-auth --from-file=auth

Ⅱ、创建deployment、ingress
[root@k8s-master01 8]# vim 1.deployment.yaml 
[root@k8s-master01 8]# cat 1.deployment.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: auth
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: auth
    spec:
      containers:
        - name: nginx
          image: wangyanglinux/myapp:v4
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: auth
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: auth
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: auth
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - wangyang'
spec:
  rules:
  - host: auth.hongfu.com
    http:
      paths:
      - path: /
        backend:
          serviceName: auth
          servicePort: 80
           
[root@k8s-master01 8]# kubectl apply -f 1.deployment.yaml 

Ⅲ、查看svc端口
[root@k8s-master01 8]# kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.96.131.122   <none>        80:30914/TCP,443:30050/TCP   63m

Ⅳ、测试访问

(前提:Windows的hosts文件有定义)

出现认证: ![image-20230202013043722](5 Kubernetes-service.assets/image-20230202013043722.png)

​ ![image-20230202090904690](5 Kubernetes-service.assets/image-20230202090904690.png)

登录成功: ![image-20230202013449976](5 Kubernetes-service.assets/image-20230202013449976.png)

​ ![image-20230202090956813](5 Kubernetes-service.assets/image-20230202090956813.png)

5)nginx进行重写---地址跳转

Ⅰ、根据yaml文件创建ingress

注意:此处的Ingress资源对象的期望中,规则中,http的定义可以不写

[root@k8s-master01 6]# vim 9.rew.yaml 
[root@k8s-master01 6]# cat 9.rew.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: rew
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9404712539650433019%22%7D&n_type=-1&p_from=-1
spec:
  rules:
  - host: rew.hongfu.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80
[root@k8s-master01 6]# kubectl apply -f 9.rew.yaml 
Ⅱ、测试访问

(前提:hosts文件存在定义)

地址跳转