service详解ingress详解

Posted givenchy_yzl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了service详解ingress详解相关的知识,希望对你有一定的参考价值。

service(智能负载均衡器)

service主要是提供负载均衡和服务自动发现。它是 k8s 中最核心的资源之一, 每一个 Service 就是我们平常所说的一个“微服务”。

如上图所示,Kubernetes 的 Service 定义了一个服务的访问入口,前端的应用(Pod)通过这个入口地址访 问其背后的一组由 Pod 副本组成的集群实例,Service 与其后端的 Pod 副本集群之间是通过 Label 来 实现关联的,而 Deployment 则是保证 Service 的服务能力和服务质量始终处于预期的标准。

通过分析,识别并建模系统中的所有服务为微服务,最终我们的系统是由多个提供不同业务能力而彼此独立 的微服务单元所组成,服务之间通过 TCP/IP 进行通信,从而形成了强大而又灵活的弹性网络,拥有强大的分布 式能力、弹性扩展能力、容错能力。

vim service.yaml
apiVersion: v1
kind: Service
metadata:
  name: service
spec:
  selector:
    release: stable
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: "TCP"
    - name: https
      port: 443
      targetPort: 443
      protocol: "TCP"

怎样让外界的可访问我们的服务?
怎样找到对应的POD?
通过标签找到

关联哪些POD
怎样暴露服务

service的工作方式

在 Kubernetes 迭代过程中,给 Service 设置里三种工作方式,分别是:Userspace 方式、Iptables 以及 Ipvs, 这三种方式到现在为止,官方推荐使用 IPVS, 当集群不支持 IPVS 的时候,集群会降级到 Iptables。

userspace

Client Pod 要访问 Server Pod 时,它先将请求发给本机内核空间中的 service 规则,由它再将请求,转给监听 在指定套接字上的 kube-proxy,kube-proxy 处理完请求,并分发请求到指定 Server Pod 后,再将请求递交给内 核空间中的 service,由 service 将请求转给指定的 Server Pod。由于其需要来回在用户空间和内核空间交互通信, 因此效率很差

Iptables 模型 (类似于软件转发)

直接由内核中的 iptables 规则,接受 Client Pod 的请求,并处理完成后,直接转发给指定 ServerPod。这 种方式不再将请求转发给 kube-proxy,性能提升很多。

Ipvs 模型 (类似于内核转发)

在 ipvs 模式下,kube-proxy 监视 Kubernetes 服务和端点,调用 netlink 接口相应地创建 IPVS 规则, 并 定期将 IPVS 规则与 Kubernetes 服务和端点同步。 该控制循环可确保 IPVS 状态与所需状态匹配。 访问服务 时,IPVS 将流量定向到后端 Pod 之一。 IPVS 代理模式基于类似于 iptables 模式的 netfilter 挂钩函数,但是使用哈希表作为基础数据结构,并且 在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向 通信的延迟要短,并且在同步代理规则时具有更好的性能。与其他代理模式相比,IPVS 模式还支持更高的网络 流量吞吐量。

总结:kube-proxy 都通过 watch 的方式监控着 kube-APIServer 写入 etcd 中关于 Pod 的最新状态 信息,它一旦检查到一个 Pod 资源被删除了 或 新建,它将立即将这些变化,反应在 iptables 或 ipvs 规则中, 以便 iptables 和 ipvs 在调度 Clinet Pod 请求到 Server Pod 时,不会出现 Server Pod 不存在的情况。 自 k8s1.1 以后,service 默认使用 ipvs 规则,若 ipvs 没有被激活,则降级使用 iptables 规则. 但在 1.1 以前, service 使用的模式默认为 userspace。

service的类型

Service 是 Kubernetes 对外访问的窗口,针对不同的场景,kubernetes 为我们设置了四种 Service 的类型。

cluster ip(向集群内部暴露一个ip)

kubernetes 默认就是这种方式,是集群内部访问的方式,外部是无法访问的。其主要用于为集群内 Pod 访 问时,提供的固定访问地址,默认是自动分配地址,可使用 ClusterIP 关键字指定固定 IP

[root@kubernetes-master-01 test]# cat clusterip.yaml 
kind: Service 
apiVersion: v1
metadata: 
  name: my-svc 
spec: 
  type: ClusterIP 
  selector: 
    app: nginx 
  ports: 
    - port: 80 
      targetPort: 80 
[root@kubernetes-master-01 test]# vim clusterip.yaml 
[root@kubernetes-master-01 test]# kubectl apply -f clusterip.yaml 
service/my-svc created 

[root@kubernetes-master-01 test]# kubectl get svc 

NAME          TYPE           CLUSTER-IP        EXTERNAL-IP        PORT(S)       AGE 
kubernetes   ClusterIP       10.96.0.1           <none>           443/TCP       11d 
my-svc       ClusterIP      10.96.222.172        <none>           80/TCP        21s 
nginx         NodePort        10.96.6.147        <none>          80:42550/TCP   11m 

[root@kubernetes-master-01 test]# curl 10.96.6.147 
<!DOCTYPE html> 
<html> 
<head> 
<title>Welcome to nginx!</title> 
<style> 
	body { 
	width: 35em; 
	margin: 0 auto; 
	font-family: Tahoma, Verdana, Arial, sans-serif; 
	} 
</style> 
</head> 
<body> <h1>Welcome to nginx!</h1> 
<p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> 

<p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at 
<a href="http://nginx.com/">nginx.com</a>.</p> 

<p><em>Thank you for using nginx.</em></p> 
</body
</html>

headless service

kubernates 中还有一种 service 类型:headless serivces 功能,字面意思无 service 其实就是改 service 对 外无提供 IP。一般用于对外提供域名服务的时候

headless service的使用场景?
仅仅需要关联Pod的场景中可以使用此类型,即不需要提供负载均衡的情况下使用

2、Service与Pod之间的关系
service -> endpoints -> pod
endpoint与service同步创建同步删除

示例:

#编辑配置文件
[root@m01 ~]# vim headless.yaml
kind: Service
apiVersion: v1
metadata:
  name: nginx-svc
spec:
  clusterIP: None
  selector:
    app: test-svc
  ports:
    - port: 80
      targetPort: 80
      name: http


#部署
[root@m01 ~]# kubectl apply -f headless.yaml 

#查看   
[root@m01 ~]# kubectl get svc
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
baidu        ExternalName   <none>           www.taobao.com   <none>           23h
kubernetes   ClusterIP      10.96.0.1        <none>           443/TCP          22d
nginx-svc    ClusterIP      None             <none>           80/TCP           9s
service      ClusterIP      10.101.126.130   <none>           80/TCP,443/TCP   46h 
       

#查看资源详情
kubectl describe [资源类型] [资源名称]

node port

在宿主主机中开启一个端口与负载均衡IP的端口一一对应,外界可以使用宿主主机的端口访问集群内部服务

LoadBalancer(依赖于公网ip)

是实现暴露服务的另一种解决方案,它依赖于公有云弹性IP实现

ExternalName

ExternalName Service 是 Service 的一个特例,它没有选择器,也没有定义任何端口或 Endpoints
将其他连接设置一个集群内部的别名,实际上就是集群 DNS 服务器将 CNAME 解析到了外部地址上,即用一个别名实现两个项目的无感知迁移

如:我们现在有两个项目,
项目一:a.abc.com 项目二:b.abc.com
用externalname将c.abc.com解析到a.abc.com,如果想将项目迁移到项目二的话,直接将c.abc.com解析到b.abc.com,此时用户就会无感知项目迁移

示例:将百度无感知迁移到淘宝上

vim externalname.yaml

apiVersion: v1
kind: Service
metadata:
  name: baidu
spec:
  externalName: www.baidu.com
  type: ExternalName

kubectl apply -f externalname.yaml
kubectl run test -it --rm --image=busybox:1.28.3
nslookup baidu

[root@m01 ~]# vim externalname.yaml 
apiVersion: v1
kind: Service
metadata:
  name: baidu
spec:
  externalName: www.taobao.com
  type: ExternalName
kubectl apply -f externalname.yaml
kubectl run test -it --rm --image=busybox:1.28.3
nslookup baidu                     

ingress

ingress是基于域名的网络转发资源,ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP和HTTPS。
Ingress 可以提供负载均衡、SSL 和基于名称的虚拟托管。

必须具有 ingress 控制器【例如 ingress-nginx】才能满足 Ingress 的要求。仅创建 Ingress 资源无效。

在生产环境中常用的Ingress有Treafik、Nginx、HAProxy、Istio等
nginx ingress : 性能强
traefik :原生支持k8s
istio : 服务网格,服务流量的治理

Ingress 公开了从集群外部到集群内 services 的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。

可以将 Ingress 配置为提供服务外部可访问的 URL、负载均衡流量、 SSL / TLS,以及提供基于名称的虚拟主机。Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。

Ingress 不会公开任意端口或协议。若将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或者 Service.Type=LoadBalancer 类型的服务。详情如下图

ingress架构图



部署ingress nginx

1、下载部署文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/baremetal/deploy.yaml

2、修改镜像
sed -i 's#k8s.gcr.io/ingress-nginx/controller:v0.44.0@sha256:3dd0fac48073beaca2d67a78c746c7593f9c575168a17139a9955a82c63c4b9a#registry.cn-hangzhou.aliyuncs.com/k8sos/ingress-controller:v0.44.0#g'  deploy.yaml

3、部署
[root@k8s-m-01 ~]# kubectl apply -f deploy.yaml 

4、开始编辑ingress配置清单并部署
vim ingress.yaml

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress-ingress
  namespace: default 
  annotations:  
    kubernetes.io/ingress.class: "nginx"
spec:  
  rules:    
    - host: www.test.com      
      http:        
        paths:          
          - path: /            
            backend:              
              serviceName: service              
              servicePort: 80

[root@m01 ~]# kubectl apply -f ingress.yaml 

#查看是否配置成功
[root@m01 ~]# kubectl get ingress
NAME              CLASS    HOSTS          ADDRESS        PORTS   AGE
ingress-ingress   <none>   www.test.com   192.168.1.56   80      50s

#资源类型
kind: Ingress
#版本号
apiVersion: extensions/v1beta1
#元数据
metadata:
#名称
  name: ingress-ingress
#命名空间
  namespace: default 
#注解
  annotations:  
    kubernetes.io/ingress.class: "nginx"

spec:  
rules:  
#指定域名  
- host: www.test.com      
  http:        
    paths:          
      - path: /            
        backend:              
          serviceName: service              
          servicePort: 80


5、修改hosts解析
192.168.1.56 www.test.com 

6、测试使用域名访问
[root@m01 ~]#  kubectl get svc -n ingress-nginx 
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.106.156.132   <none>        80:30156/TCP,443:32452/TCP   28m
ingress-nginx-controller-admission   ClusterIP   10.105.74.237    <none>        443/TCP                      28m

网页访问
www.test.com:30156,出现页面即为成功

查看ingress是否安装成功
[root@m01 ~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-ddljh 0/1 Completed 0 49m
ingress-nginx-admission-patch-ttp8c 0/1 Completed 0 49m
ingress-nginx-controller-796fb56fb5-gsngx 1/1 Running 0 49m

apiVersion: v1
kind: Namespace
metadata:
  name: wordpress
---
apiVersion: v1
kind: Service
metadata:
  name: wordpress
  namespace: wordpress
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
    app: wordpress
  clusterIP: None
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: wordpress
  namespace: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
        - name: php
          image: alvinos/php:wordpress-v2
        - name: nginx
          image: alvinos/nginx:wordpress-v2
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: wordpress
  namespace: wordpress
   

以上是关于service详解ingress详解的主要内容,如果未能解决你的问题,请参考以下文章

k8s3 Service详解 Ingress服务 数据存储 安全认证

k8s Ingress使用详解

[云原生专题-41]:K8S - 核心概念 - Service业务的统一网关接口Ingress详解安装常见操作命令

Ingress详解

K8S系列第十三讲:Ingress详解

Traefk配置https域名详解