kubernetes ingress 及 Ingress Controller

server 有一个问题就是无论哪种类型都只能实现 4 层转发和代理,如果要建立一个 http 的服务,那么每一个 app 都要建立成一个 http 主机,因为 4 层调度本身是无法卸载 http 会话的,事实上 k8s 集群还有一种引入集群外部流量的方式:ingress,ingress 资源是一种七层调度器,但他也脱离不了 server资源 和 web 服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-joOEKfYz-1624628357507)(https://raw.githubusercontent.com/ma823956028/image/master/picgo/20200829002221.png)]

图中 ingress-nginx service 可以被 DaemonSet 配合 ingress 共享网络名称空间的方式代替

Ingress

负责k8s中的7层负载均衡。其在物理机中有多种部署方式,而主要则有nodePort和hostNetwork两种部署方式。

  • nodePort:

    kubernetes 在内部集群中进行调度时,后端被代理的 pod 资源不会配置 https 的他们就是明文的 http,k8s 使用一个特殊的 pod (ingress) 对于这个 pod 来说她是运行在用户空间的正常的运行程序,如 nginx、haproxy 等,当用户试图访问某个后端服务时,不会直接访问该服务的 svc,而是先到 ingress,而 pod 与 pod 之间是在同一个网段的,这样就可以让 ingress 直接与后端 pod 通信并完成反代,而 ingress 需要接入外部流量则需要 svc,NodePort 的 svc。为了让 svc 拥有负载功能,即外部访问任意一个 Node 都能访问到这个 svc,则又需要在 node 之上再增加一个 LoadBalancer,这样架构会导致 4 次反代性能会大打折扣

  • hostnetwork:

    于是新的解决方案是让 ingress 共享节点的网络名称空间,相当于监听了宿主机的地址,所以边界流量直接经由 loadbalancer 或负载均衡器被打到了 ingress,并有它继续反代给真正的 pod,其中 loadbalancer 做四层代理给 ingress,ingress 做七层卸载给对应的 pod,但这样就会失去 ingress 的 svc,这样则只能在一个节点运行 ingress 也就造成了单点故障,所以这个 ingress 需要 DaemonSet 来控制 ingress,这样就恢复了高可用和负载能力,而大规模部署 k8s 集群时,我们会按比例挑出部分 node,并给 node 增加污点,让其他 pod 不可以运行在这些 node 上,但让 ingress 容忍这些污点加上 DaemonSet 来管理并让前端的 loadbalancer 调度

Ingress Controller

它与控制器不同,控制器作为 controllermanager 的子组件存在,而 Ingress 则单独特指一组 pod,而 ingress 的实现方式通常有三种

  1. Haproxy:并不被推荐
  2. nginx:主流
  3. Envoy:服务网格中多用此类服务
  4. Traefik:为微服务而生,与 nginx 竞争

Ingress 资源

我们知道 ingress 本身就是一个 web 服务了,但比如当我们使用 url 映射功能,让一个 url 通过 upstream server 配置映射到后端服务,在传统架构中非常容易实现,但容器内 pod 是有生命周期的,为了解决这个问题则需要引入 svc,通过这个 svc 关联至后端的 pod,但这个 svc 仅仅帮忙分类,不做转发节点使用,这个 svc 关联了多少 pod 就会写入 upstream 配置(此时写入配置的 ip 是 podip),所以这个 svc 可以是 headless 类型,这个 svc 是通过 ingress 资源写入 upstream 的,ingress 资源可以通过边界注入到 ingress controller 中并保存配置文件还可以通过 headless svc 动态的发现 pod 改变并写入配置文件和重载 nginx,此时就凸显出 nginx 作为传统建构中 web 服务的不足之处,Envoy 和 Traefik 都可以发现配置文件写入并自动重载自身服务实现动态机制,更加配合 ingress controller 的这种机制

部署 Ingress nginx

  1. 拖拽 github 仓库上的代码,并构建 ingress-nginx Controller

    [root@master-0 ~]# yum install git
    [root@master-0 ~]# git clone https://github.com/kubernetes/ingress-nginx.git
    [root@master-0 ~]# cd /root/ingress-nginx/deploy/static/provider/cloud
    [root@master-0 cloud]# kubectl apply -f deploy.yaml
    
  2. 构建后端 pod 与 service

    [root@master-0 ingress]# cat deploy-demo.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: myapp
      namespace: default
    spec:
      selector:
        app: myapp
        release: canary
      type: ClusterIP
      clusterIP: 10.208.208.208
      ports:
      - name: http
        targetPort: 80
        port: 80
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp-deploy
      namespace: default
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: myapp
          release: canary
      template:
        metadata:
          labels:
            app: myapp
            release: canary
        spec:
          containers:
          - name: myapp
            image: nginx:1.7
            ports:
            - name: http
              containerPort: 80
    [root@master-0 ingress]# kubectl apply -f deploy-demo.yaml
    service/myapp created
    deployment.apps/myapp-deploy unchanged
    
  3. 此时,为了让 ingress controller 接入集群外部流量,我们可以修改 with-rbac.yaml 文件来实现共享 node 的网络名称空间,当然还可以给 ingress controller 增加一个 nodeport 的 service 的方式来实现,这里使用第二种方法

    [root@master-0 ingress]# cat service-nodeport.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: ingress-nginx
      namespace: ingress-nginx
    spec:
      type: NodePort
      ports:
      - name: http
        port: 80
        targetPort: 80
        protocol: TCP
        nodePort: 30080
      - name: https
        port: 443
        targetPort: 443
        protocol: TCP
        nodePort: 30443
      selector:
        app: ingress-nginx
    [root@master-0 ingress]# kubectl apply -f .
    service/myapp unchanged
    deployment.apps/myapp-deploy unchanged
    service/ingress-nginx created
    [root@master-0 ingress]# kubectl get svc -n ingress-nginx
    NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
    ingress-nginx                        NodePort       10.220.176.76    <none>        80:30080/TCP,443:30443/TCP   31s
    ... ...
    
  4. 使用 ingress 资源增加 nginx 规则

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ingress-myapp
      namespace: default                        # 与发布的后端 pod 处在同一个名称空间
      annotations:
        kubernetes.io/ingress.class: "nginx"    # 标识使用 nginx
    spec:
      rules:
      - host: myapp.magedu.com                  # 虚拟机主机型,这个域名必须能被公网访问
        http:
          paths:                                # 请求路径以及映射到后端的集合,可以有多个
          - path:                               # 空即根值
            backend:
              serviceName: myapp                # 后端 pod 的信息
              servicePort: 80
    

HTTPS 的证书处理

  1. 生成证书

    [root@master-0 ingress]# openssl genrsa -out tls.key 2048
    [root@master-0 ingress]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=magedu.com
    [root@master-0 ingress]# ls
    deploy-demo.yaml  ingress-myapp.yaml  service-nodeport.yaml  tls.crt  tls.key
    
  2. 将证书创建为 secret 资源

    [root@master-0 ingress]# kubectl create secret tls ingress-secret --cert=tls.crt --key=tls.key
    secret/ingress-secret created
    [root@master-0 ingress]# kubectl describe secrets ingress-secret    #base64编码
    Name:         ingress-secret
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Type:  kubernetes.io/tls
    
    Data
    ====
    tls.key:  1675 bytes
    tls.crt:  1277 bytes
    
  3. 创建 https 的 yaml 文件

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ingress-myapp-tls
      namespace: default
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      tls:            #证书配置集合
      - hosts:
        - myapp.magedu.com      #列表形式
        secretName: ingress-secret
      rules:
      - host: myapp.magedu.com
        http:
          paths:
          - path:
            backend:
              serviceName: myapp
              servicePort: 80
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值