K8s Ingress笔记

  一 要理解一个概念,首先要明白它是干什么用的,然后再去理解它是怎么实现的。Ingress的作用就是提供一个集群外部访问集群内部的入口。那么它是怎么实现的呢,我们知道,集群内部的Cluster IP外部是无法直接访问到的,而在 K8s集群中,集群外部访问内部pod中的应用大概有以下几种形式:

 1.  通过开启proxy模式访问Cluster IP。这种方式要求我们运行 kubectl 作为一个未认证的用户,因此我们不能用  
 这种方式把服务暴露到 internet 或者在生产环境使用。
 2.  直接访问pod,pod中定义hostPort,并设置pod级别的hostwork=true,直接将pod中的端口映射到pod所在的物  
 理主机或者虚拟机上。通过访问主机ip:hostPort即可访问集群内部pod;这种方式只能非常少量使用,否则和直接  
 使用docker没多大区别。
 3.  先访问Service,Service可以直接通过集群内部负载均衡至pod中的应用,而外部访问集群中的Service可以通  
 过在Service中定义NodePort实现;这种方式在集群中的每台主机上开放一个随机的或指定的端口,且每个端口  
 只能提供一个服务,它是通过端口不同来区分不同应用,而不是通过域名,管理不便,不适合在大规模集群中部  
 署。
 4.   通过LoadBlancer Service访问Service,这个需要接入云服务,每个服务都会由云服务提供一个IP作为入口,  
 转发相应的流量,但每个LoadBlancer Service都会产生费用,成本比较高。
 5.   Ingress,K8s中的API对象,定义了一组规则。Ingress本身只是定义了一组规则,需要配合Ingress controllor  
 才有意义,不理解Ingress controllor没关系,继续往下。

  二 如果不通过Ingress,我们也可以手动在Service前部署一个反向代理,比如nginx或者haproxy。

  1. nginx运行在集群中,所以可以访问到集群内部的Service,只需在nginx配置中proxy_pass指向相应的Service   
  Cluster IP或者dns即可,多一个服务也就是多配置一个nginx中的虚拟机主机。
  2. 通过设置hostPort即可从外部访问nginx,再通过nginx反向代理至后端应用的Service;或者不通过hostPort,  
  再在nginx前端再加一个Service,通过设置Service的NodePort来访问nginx。

  三 通过自己部署nginx反向代理这种方式好像就OK了啊,那一直说的Ingress又是什么?

            Ingress是K8s中的API对象,定义了一组规则,对应于nginx(或者haproxy,traefik等)的一段配置,可以  
    近似成一段虚拟主机的配置,其实Ingress和自己部署反向代理思路都是一样的,只不过自己部署反向代理时,  
    如果新增加一个服务,你自己需要去增加nginx中的配置并重新加载配置,而在Ingress中你增加一个服务,你需  
    要增加一个Ingress的配置并运行,Ingress会自己去请求K8s的api以获得新增应用的nds或者Cluster Ip,然后将  
    你写的Ingress规则转换成nginx配置,并修改到ngixn中,然后自动reload nginx。
            简单来说,两者的区别就是:当新增后端应用时,一种需要增加nginx配置,另外一种需要增加Ingress规  
    则。你可以简单的把Ingress理解为一段类似nginx虚拟主机的配置,因为它会自动为你转换。

四 说道这里,部署Ingress就很简单了,不过在Ingress中有它自己的一些术语。一个完整的Ingress有以下几个组件:

    1.  反向代理,可以是nginx、traefik、Haproxy等。
    2.  Ingress controllor,即Ingress控制器,监听apiserver,获取服务新增,删除等变化,并结合ingress规则动  
    态更新到反向代理负载均衡器上,并重载配置使其生效。
    3.  Ingress,K8s的一个资源对象,定义了一组规则,你可以简单理解为一段对应nginx虚拟机主机的配置。而  
    实际上,Ingress controllor和反向代理,也就是上面的1,2两个组件,都是结合在一起的。比如traefik,它同时  
    具备反向代理和Ingress controllor的功能;如果使用nginx,那么你需要部署专用的nginx,它也集成了Ingress   
    controllor。
    本文采用traefik来部署反向代理和Ingress controllor,有关traefik的详细介绍可以参考官网。

五 实际部署。

       本文从开始到现在,已经覆盖了很多的背景和知识。你可能担心现在会是最难的部分,但实际上它最简单,    
Ingress之所以比较复杂,唯一原因是因为“其他的一切”,而我们已经很好地学完了这些东西。

1. 如果K8s使用了rbac,而Ingress controllor需要访问apiserver,所以需要先为traefik配置一个Service Account。
cat > traefik-ingress-rbac.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress
  namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress
subjects:
  - kind: ServiceAccount
    name: traefik-ingress
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
EOF
kubectl apply -f traefik-ingress-rbac.yaml
        第一段配置定义了一个Service Account,第二段配置将定义的Service Account绑定到cluster-admin这个已经  
存在的ClusterRole上,cluster-admin是具有访问apiserver的权限的。 

2. 然后需要部署一个traefik,并且将它暴露到集群外,它既是反向代理也是Ingress controllor。
cat > traefik-ingress-controller.yaml << EOF
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      terminationGracePeriodSeconds: 60
      serviceAccountName: traefik-ingress
      containers:
      - image: traefik
        name: traefik-ingress-lb
        resources:
          limits:
            cpu: 200m
            memory: 30Mi
          requests:
            cpu: 100m
            memory: 20Mi
        ports:
        - containerPort: 80
          hostPort: 80
        - containerPort: 8080
        args:
        - --web
        - --kubernetes
EOF
kubectl apply -f traefik-ingress-controller.yaml
         这是traefik官方文档的部署文件,我只是在它里面加了个Service Account,可以看到,它采用设置pod的  
hostPort方式来将80端口暴露到集群外,80端口可以看做是反向代理http的端口,接收并转发所有的定义到Ingress  
的流量。而它在pod中还对集群内部有一个8080端口,8080端口一个后端应用,提供了traefik-web-ui。8080端口  
是traefik默认的webUI端口,8080端口定义为Pod的端口,集群外部是无法直接访问到的,所以我们还需要部署一  
个Service+Ingress。  

3. 部署Service+Ingress
cat > traefik-web-ui.yaml << EOF
apiVersion: v1
kind: Service
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  rules:
  - host: traefik-ui.com
    http:
      paths:
      - backend:
          serviceName: traefik-web-ui
          servicePort: 80
EOF
kubectl apply -f  traefik-web-ui.yaml
       当你真正要访问该traefik-ui.com时,你还需要将这个域名绑定到它对应的IP地址,也就是hostPort所在的主  
  机的IP。配置好hosts文件后,访问traefik-ui.com。OK

       1. 可以看到Ingress中,当访问traefik-ui.com这个域名时,对应会访问到名为traefik-web-ui的Service的80  
端口中。而Service的80端口对应后端的traefik web UI的8080端口。到此为止,一个完整的Ingress就部署完成  
了,它的访问流程是这样的:
       集群外部访问traefik-ui.com-->请求会到达traefik所在的主机的IP:hostPort上,也就是IP:80-->由于Ingress规  
则此时被转换成traefik中的反向代理配置,根据Ingress规则会被转发往traefik-web-ui这个Service:80上-->  
Service转发到后端标签为 traefik-ingress-lb的pod的8080端口中,实际上又回到了traefik,不过是8080端口。
       简单来说:请求域名---->traefik:80---->Ingress(只是Ingerss规则,实际还是由traefik完成)---->  
后端Service:80---->traefik:8080

       2. 部署其他后端服务时也是一样,把上面的后端Service和应用换成相应的就行了。比如部署一个tomcat,那  
么 需要再部署3个K8s资源,分别是tomcat-deployment.yaml、tomcat-service.yaml、tomcat-Ingress.yaml,  
你请求的域名为Ingress中的host配置的域名,你请求流程为:
       请求域名---->traefik:80---->Ingress(只是Ingerss规则,实际还是由traefik完成)---->tomcat-Service  
---->tomcat-deployment中的Pod。

      3. 上面是通过hostPort暴露traefik,可以直接访问80端口,如果需要在多台node上部署,可以通过给相应  
的node 设置lable,然后部署时指定nodeSelector。
      我们同样可以通过Service的NodePort暴露traefik,需要在traefik前再加一个Service,默认NodePort端口  
范围 为30000-32767,如果想直接暴露80端口,需要修改apiserver的配置,tomcat采用该方式的请求流程为:
      请求---->traefik-service的Nodeport---->traefik---->Ingress(只是Ingerss规则,实际还是由traefik完成)  
---->tomcat-Service---->tomcat-deployment中的Pod。

猜你喜欢

转载自blog.51cto.com/13645243/2118455