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。

原文地址:http://blog.51cto.com/13645243/2118455

时间: 2024-08-30 11:46:47

K8s Ingress笔记的相关文章

K8s Ingress 模式简介及示例

注: 默认本文读者具备一定的k8s基础,并对k8s的apiserver.service.controller manager等基本概念有所了解. 模式简介: Ingress在service之前加了一层ingress,结构如下: ingress -> service -> label selector -> pods www.ok1.com -> app1-service -> app1 selector -> app1 1234 Port:80 or other -&g

K8s Ingress Nginx 支持 Socket.io

Ingress 及 Ingress Controller 简介 Ingress:是k8s 资源对象,用于对外暴露服务,该资源对象定义了不同主机名(域名)及 URL 和对应后端 Service(k8s Service)的绑定,根据不同的路径路由 http 和 https 流量. Ingress Contoller:是一个pod服务,封装了一个Web前端负载均衡器,同时在其基础上实现了动态感知Ingress 并根据Ingress的定义动态生成前端web负载均衡器的配置文件,比如Nginx Ingre

前后端分离架构+k8s+ingress

一.概述 在前面几篇文章中,已经讲到了前后端分离架构和ingress,链接如下: https://www.cnblogs.com/xiao987334176/p/12195722.html https://www.cnblogs.com/xiao987334176/p/12195797.html 接下来使用k8s进行发布应用 二.演示3.0 环境说明 k8s集群 系统 docker ip 主机名 配置 centos 7.6 19.03.5 192.168.31.150 k8s-master 2核

【K8S学习笔记】Part1:使用端口转发访问集群内的应用

本文介绍如何使用kubectl port-forward命令连接K8S集群中运行的Redis服务.这种连接方式有助于数据库的调试工作. 注意:本文针对K8S的版本号为v1.9,其他版本可能会有少许不同. 0x00 准备工作 在进行该操作之前,需要满足以下条件: 需要有一个K8S集群,并且配置好了kubectl命令行工具来与集群通信.如果未准备好集群,那么你可以使用Minikube创建一个K8S集群,或者你也可以使用下面K8S环境二者之一: Katacoda Play with Kubernete

【K8S学习笔记】Part2:获取K8S集群中运行的所有容器镜像

本文将介绍如何使用kubectl列举K8S集群中运行的Pod内的容器镜像. 注意:本文针对K8S的版本号为v1.9,其他版本可能会有少许不同. 0x00 准备工作 需要有一个K8S集群,并且配置好了kubectl命令行工具来与集群通信.如果未准备好集群,那么你可以使用Minikube创建一个K8S集群,或者你也可以使用下面K8S环境二者之一: Katacoda Play with Kubernetes 如果需要查看K8S版本信息,可以输入指令kubectl version. 在本练习中,我们将使

【K8S学习笔记】Part3:同一Pod中多个容器间使用共享卷进行通信

本文将展示如何使用共享卷(Volume)来实现相同Pod中的两个容器间通信. 注意:本文针对K8S的版本号为v1.9,其他版本可能会有少许不同. 0x00 准备工作 需要有一个K8S集群,并且配置好了kubectl命令行工具来与集群通信.如果未准备好集群,那么你可以使用Minikube创建一个K8S集群,或者你也可以使用下面K8S环境二者之一: Katacoda Play with Kubernetes 如果需要查看K8S版本信息,可以输入指令kubectl version. 0x01 创建一个

k8s ingress

Ingress 一.     什么是Ingress 通常情况下,service 和 pod 的 IP 仅可在集群内部访问.集群外部的请求需要通过负载均衡转发到 service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 通过边缘路由器 (edge router) 将其转发给相关的 Pod 或者丢弃. 而 Ingress 就是为进入集群的请求提供路由规则的集合  Ingress 可以给 service 提供集群外部访问的 URL.负载均衡.SSL 终止.HTTP

k8s学习笔记

安装 yum install -y etcd firewalld 启动 systemctl start etcd systemctl start docker systemctl start kube-apiserver systemctl start kube-controller-manager systemctl start kube-scheduler systemctl start kubelet systemctl start kube-proxy 启动mysql服务 vi mysq

streamsets k8s 部署试用

使用k8s 进行 streamsets的部署(没有使用持久化存储) k8s deploy yaml 文件 deploy.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: streamsets namespace: big-data labels: app: streamsets spec: replicas: 1 template: metadata: labels: app: streamsets spec