zoukankan      html  css  js  c++  java
  • Kubernetes 第十章 Ingress

    术语

    在本篇文章中你将会看到一些在其他地方被交叉使用的术语,为了防止产生歧义,我们首先来澄清下。

    • 节点:Kubernetes集群中的一台物理机或者虚拟机。
    • 集群:位于Internet防火墙后的节点,这是kubernetes管理的主要计算资源。
    • 边界路由器:为集群强制执行防火墙策略的路由器。 这可能是由云提供商或物理硬件管理的网关。
    • 集群网络:一组逻辑或物理链接,可根据Kubernetes网络模型实现群集内的通信。 集群网络的实现包括Overlay模型的 flannel 和基于SDN的OVS
    • 服务:使用标签选择器标识一组pod成为的Kubernetes服务。 除非另有说明,否则服务假定在集群网络内仅可通过虚拟IP访问。

    什么是 Ingress?

    通常情况下,service 和 pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 通过边缘路由器 (edge router) 将其转发给相关的 Pod 或者丢弃。如下图所示

     internet
            |
      ------------
      [Services]

    而 Ingress 就是为进入集群的请求提供路由规则的集合,如下图所示

    //这张图说明了ingress 的数据处理流程,客户端通过 service 暴露的端口进去集群,然后数据转发到ingress , ingress 调度到 pods 。这时ingress 通过 kuberneters API 监听pods 对应service 变化,动态修改ingress nginx  配置

    Ingress 可以给 service 提供集群外部访问的 URL、负载均衡、SSL 终止、HTTP 路由等。为了配置这些 Ingress 规则,集群管理员需要部署一个 Ingress controller,它监听 Ingress 和 service 的变化,并根据规则配置负载均衡并提供访问入口。

    Ingress的组成部分

    Nginx:实现负载均衡到pod的集合

    Ingress Controller:从集群api获取services对应pod的ip到nginx配置文件中

    Ingress:为nginx创建虚拟主机

    1.创建ingress-nginx   controller  引擎

     标准安装 ingress controller 配置文件:  https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml   

    //需要先创建 ingress-controller ,选择引擎为 nginx 的nginx-ingress-controller 

    //这一步安装了 ingeess-controller  pod 

    [root@kube ~]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
    namespace/ingress-nginx created
    configmap/nginx-configuration created
    configmap/tcp-services created
    configmap/udp-services created
    serviceaccount/nginx-ingress-serviceaccount created
    clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
    role.rbac.authorization.k8s.io/nginx-ingress-role created
    rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
    clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
    deployment.apps/nginx-ingress-controller created
    [root@kube ~]# 
    [root@kube ~]# 
    [root@kube ~]# 
    [root@kube ~]# kubectl get namespace
    NAME              STATUS   AGE
    default           Active   41d
    ingress-nginx     Active   8s
    kube-node-lease   Active   41d
    kube-public       Active   41d
    kube-system       Active   41d
    new-namespace     Active   6d19h
    [root@kube ~]# 
    [root@kube test]# kubectl get pods -n ingress-nginx     //检查nginx-ingress-controller  是否创建成功   -n 为指定 namesapce 为 inrgess-nginx 
    NAME                                        READY   STATUS    RESTARTS   AGE
    nginx-ingress-controller-7995bd9c47-5qkr4   1/1     Running   0          6h4m
    [root@kube test]# 
    [root@kube test]# kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx --watch   //检查是否创建成功
    NAMESPACE       NAME                                        READY   STATUS    RESTARTS   AGE
    ingress-nginx   nginx-ingress-controller-7995bd9c47-5qkr4   1/1     Running   0          6h53m

    2. 创建 ingress-nginx   service 

      本次测试使用的ingress-nginx 是在NodePort 方式发布,因此需要先定义nodeport 类型的service 作为流量入口

    [root@kube test]# cat ingress-service.yaml 
    apiVersion: v1
    kind: Service
    metadata:
      name: ingress-nginx
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    spec:
      type: NodePort
      ports:
        - name: http
          port: 80
          targetPort: 80
          protocol: TCP
          nodePort: 30080    //在所有被允许的  node 上都暴露了相关的端口
    
        - name: https
          port: 443
          targetPort: 443
          protocol: TCP
          nodePort: 30443
      selector:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    
    [root@kube test]# kubectl apply -f ingress-service.yaml
    service/ingress-nginx created
    [root@kube test]# kubectl get service -n ingress-nginx
    NAME            TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
    ingress-nginx   NodePort   10.107.89.78   <none>        80:30080/TCP,443:30443/TCP   2m27s
    [root@kube test]# 

    3.创建被调度的 service 资源

    [root@kube test]# cat ingress-demo.yaml 
    apiVersion: v1
    kind: Service            //service 部分
    metadata:
      name: myapp-ingress
      namespace: default
    spec:
      selector:
        app: myapp-ingress
      ports:
      - name: http
        port: 80
        targetPort: 80    
    
    ---
    
    apiVersion: apps/v1
    kind: Deployment     //deployment 部分
    metadata:
      name: my-ingress
      namespace: default
    spec:
      replicas: 2
      selector: 
        matchLabels:
          app: myapp-ingress
          release: canary-ingress
      template:       //pods 部分
        metadata:
          labels:
            app: myapp-ingress
            release: canary-ingress
        spec:
          containers:
          - name: myapp-pod
            image: nginx:1.7.9 
            ports:
            - name: http
              containerPort: 80
    [root@kube test]# 

    4.发布 ingress 资源

    [root@kube test]# cat ingress-my-ingress.yaml 
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: testname-ingress
    spec:
      rules:
      - host: zy.ingress.com
        http:
          paths:
          - path: 
            backend:
              serviceName: myapp-ingress
              servicePort: 80
    [root@kube test]# 
    [root@kube test]# 
    [root@kube test]# kubectl apply -f ingress-my-ingress.yaml
    ingress.extensions/test-ingress created
    [root@kube test]# kubectl  get ingress
    NAME           HOSTS   ADDRESS   PORTS   AGE
    test-ingress   *                 80      20s
    
    [root@kube test]# kubectl describe ingress test-ingress
    Name:             test-ingress
    Namespace:        default
    Address:          
    Default backend:  myapp-ingress:80 (10.244.1.17:80,10.244.2.39:80)
    Rules:
      Host  Path  Backends
      ----  ----  --------
      *     *     myapp-ingress:80 (10.244.1.17:80,10.244.2.39:80)
    Annotations:
      kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{},"name":"test-ingress","namespace":"default"},"spec":{"backend":{"serviceName":"myapp-ingress","servicePort":80}}}
    
    Events:
      Type    Reason  Age   From                      Message
      ----    ------  ----  ----                      -------
      Normal  CREATE  69s   nginx-ingress-controller  Ingress default/test-ingress
    [root@kube test]# 
    [root@kube test]# kubectl describe  test-ingress        //修改了yaml 文件 ,添加了host
    error: the server doesn't have a resource type "test-ingress"
    [root@kube test]# kubectl describe  ingress test-ingress
    Name:             test-ingress
    Namespace:        default
    Address:          
    Default backend:  default-http-backend:80 (<none>)
    Rules:
      Host            Path  Backends
      ----            ----  --------
      zy.ingress.com  
                         myapp-ingress:80 (10.244.1.17:80,10.244.2.39:80)
    Annotations:
      kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{},"name":"test-ingress","namespace":"default"},"spec":{"rules":[{"host":"zy.ingress.com","http":{"paths":[{"backend":{"serviceName":"myapp-ingress","servicePort":80},"path":null}]}}]}}
    
    Events:
      Type    Reason  Age   From                      Message
      ----    ------  ----  ----                      -------
      Normal  CREATE  37m   nginx-ingress-controller  Ingress default/test-ingress
      Normal  UPDATE  12m   nginx-ingress-controller  Ingress default/test-ingress
    [root@kube test]# 

    检查:

    [root@kube test]# kubectl exec -n ingress-nginx -it nginx-ingress-controller-7995bd9c47-5qkr4 -- /bin/bash
    www-data@nginx-ingress-controller-7995bd9c47-5qkr4:/etc/nginx$ cat nginx.conf 
    .....................................
    
        ## start server zy.ingress.com
        server {
            server_name zy.ingress.com ;
            
            listen 80;
            
            set $proxy_upstream_name "-";
            set $pass_access_scheme $scheme;
            set $pass_server_port $server_port;
            set $best_http_host $http_host;
            set $pass_port $pass_server_port;
    ....................................
    [root@kube test]# curl http://10.2.61.22:30080/     //在后续添加了  Host 字段因此用ip  访问失败
    <html>
    <head><title>404 Not Found</title></head>
    <body>
    <center><h1>404 Not Found</h1></center>
    <hr><center>openresty/1.15.8.1</center>
    </body>
    </html>
    [root@kube test]# curl http://zy.ingress.com:30080/     //换成域名成功
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
             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>
    [root@kube test]# 

    5.Ingress 类型

    单服务 Ingress
    多服务的 Ingress
    虚拟主机 Ingress
    TLS Ingress

    单服务 Ingress

    单服务 Ingress 即该 Ingress 仅指定一个没有任何规则的后端服务。

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: test-ingress
    spec:
      backend:
        serviceName: testsvc
        servicePort: 80

    注:单个服务还可以通过设置 Service.Type=NodePort 或者 Service.Type=LoadBalancer 来对外暴露。

    多服务的 Ingress

    路由到多服务的 Ingress 即根据请求路径的不同转发到不同的后端服务上,比如

    foo.bar.com -> 178.91.123.132 -> / foo    s1:80
                                     / bar    s2:80
    

    可以通过下面的 Ingress 来定义:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: test
    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - path: /foo
            backend:
              serviceName: s1
              servicePort: 80
          - path: /bar
            backend:
              serviceName: s2
              servicePort: 80

    使用 kubectl create -f 创建完 ingress 后:

    $ kubectl get ing
    NAME      RULE          BACKEND   ADDRESS
    test      -
              foo.bar.com
              /foo          s1:80
              /bar          s2:80

    虚拟主机 Ingress

    虚拟主机 Ingress 即根据名字的不同转发到不同的后端服务上,而他们共用同一个的 IP 地址,如下所示

    foo.bar.com --|                 |-> foo.bar.com s1:80
                  | 178.91.123.132  |
    bar.foo.com --|                 |-> bar.foo.com s2:80
    

    下面是一个基于 Host header 路由请求的 Ingress:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: test
    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - backend:
              serviceName: s1
              servicePort: 80
      - host: bar.foo.com
        http:
          paths:
          - backend:
              serviceName: s2
              servicePort: 80

    注:没有定义规则的后端服务称为默认后端服务,可以用来方便的处理 404 页面。

    TLS Ingress

    TLS Ingress 通过 Secret 获取 TLS 私钥和证书 (名为 tls.crt 和 tls.key),来执行 TLS 终止。如果 Ingress 中的 TLS 配置部分指定了不同的主机,则它们将根据通过 SNI TLS 扩展指定的主机名(假如 Ingress controller 支持 SNI)在多个相同端口上进行复用。

    定义一个包含 tls.crt 和 tls.key 的 secret:

    apiVersion: v1
    data:
      tls.crt: base64 encoded cert
      tls.key: base64 encoded key
    kind: Secret
    metadata:
      name: testsecret
      namespace: default
    type: Opaque
    Ingress 中引用 secret:
    
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: no-rules-map
    spec:
      tls:
        - secretName: testsecret
      backend:
        serviceName: s1
        servicePort: 80

    注意,不同 Ingress controller 支持的 TLS 功能不尽相同。 请参阅有关 nginxGCE 或任何其他 Ingress controller 的文档,以了解 TLS 的支持情况。

  • 相关阅读:
    20189221 2018-2019-2 《密码与安全新技术专题》第五周作业
    2018-2019-2 20189221 《网络攻防技术》第九周作业
    2018-2019-2 20189221 《网络攻防技术》第八周作业
    20189221 2018-2019-2 《密码与安全新技术专题》第四周作业
    2018-2019-2 20189221 《网络攻防技术》第七周作业
    2018-2019-2 20189221 《网络攻防技术》第六周作业
    20189221 2018-2019-2 《密码与安全新技术专题》第三周作业
    2018-2019-1 20189203《Linux内核原理与分析》第五周作业
    2018-2019-1 20189203《Linux内核原理与分析》第四周作业
    2018-2019-1 20189203《Linux内核原理与分析》第三周作业
  • 原文地址:https://www.cnblogs.com/zy09/p/11390021.html
Copyright © 2011-2022 走看看