zzzzy09

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

术语

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

  • 节点: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 {
        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>
[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 的支持情况。

 

posted on 2019-08-21 17:27  zzzzy09  阅读(346)  评论(0编辑  收藏  举报