Cloud Native应用交付

  • 首页
  • 关于本站
  • 个人介绍
  • Downloads
  • Repo
    • Github
    • Container
  • F5
    • F5 Python SDK
    • F5-container
    • F5-LBaaS
  • 社交
    • 联系我
    • 微信/微博
    • 公众号
    • 打赏赞助
行至水穷处 坐看云起时
Cloud Native Application Services: cnadn.net
  1. 首页
  2. F5技术
  3. 正文

K8s nginx ingress controller 原理及测试

2017年09月24日 27716点热度 3人点赞 0条评论

k8s version: 1.6.7 无CNI

[title]1. 创建Service Account[/title]

YAML
1
2
3
4
5
6
[root@docker1 complete-example]# more nginx-ingress-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress
  namespace: default

kubectl create -f nginx-ingress-sa.yaml

[title]2. 绑定sa到role[/title]

YAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@docker1 complete-example]# cat nginx-ingress-sa-role-binding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: nginx-ingress
  namespace: default
subjects:
  - kind: ServiceAccount
    namespace: default
    name: nginx-ingress
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

注意这里随意给了一个较高的角色

kubectl create -f nginx-ingress-sa-role-binding.yaml

上述工作是为了保证nginx controller pod获得权限与api server通信:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Kubernetes                                                  Workstation
+---------------------------------------------------+     +------------------+
|                                                   |     |                  |
|  +-----------+   apiserver        +------------+  |     |  +------------+  |
|  |           |   proxy            |            |  |     |  |            |  |
|  | apiserver |                    |  ingress   |  |     |  |  ingress   |  |
|  |           |                    | controller |  |     |  | controller |  |
|  |           |                    |            |  |     |  |            |  |
|  |           |                    |            |  |     |  |            |  |
|  |           |  service account/  |            |  |     |  |            |  |
|  |           |  kubeconfig        |            |  |     |  |            |  |
|  |           +<-------------------+            |  |     |  |            |  |
|  |           |                    |            |  |     |  |            |  |
|  +------+----+      kubeconfig    +------+-----+  |     |  +------+-----+  |
|         |<--------------------------------------------------------|        |
|                                                   |     |                  |
+---------------------------------------------------+     +------------------+

[title]3. 创建nginx controller pod需要使用的缺省tls 证书及key[/title]

kubectl create -f default-server-secret.yaml
相关yaml文件从https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/complete-example 获取

[title]4. 部署nginx ingress controller[/title]

YAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[root@docker1 complete-example]# cat nginx-ingress-rc.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: nginx-ingress-ds
  labels:
    app: nginx-ingress-ctrl
spec:
  template:
    metadata:
      labels:
        app: nginx-ingress-ctrl
    spec:
      serviceAccountName: nginx-ingress
      containers:
      - image: nginxdemos/nginx-ingress:1.0.0
        name: nginx-ingress-lb
        ports:
        - containerPort: 80
          hostPort: 80
        - containerPort: 443
          hostPort: 443
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        # Uncomment the lines below to enable extensive logging and/or customization of
        # NGINX configuration with configmaps
        args:
         #- -v=3
         #- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
          - -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret

注意这里使用的是daemonset方式部署,为了保证每个node上都存在一个nginx pod

[title]5. 创建相关测试用APP pod及其相关service[/title]

1
2
3
4
$ kubectl create -f tea-rc.yaml
$ kubectl create -f tea-svc.yaml
$ kubectl create -f coffee-rc.yaml
$ kubectl create -f coffee-svc.yaml

[title]6. 创建nginx 提供应用ssl访问时候所需的证书及key[/title]

1
$ kubectl create -f cafe-secret.yaml

[title]7. 创建k8s中的ingress 资源[/title]

1
kubectl create -f cafe-ingress.yaml

[title]8. 验证测试[/title]

1
2
3
[root@docker1 complete-example]# kubectl get ing
NAME           HOSTS              ADDRESS   PORTS     AGE
cafe-ingress   cafe.example.com             80, 443   11d

注意系统本没有显示 ingress 的 address,这可能是由于我的环境没有使用CNI缘故?但从node节点的主机IP上是可以访问到相关nginx发布的应用的.

1
2
3
4
5
6
[root@docker1 complete-example]# kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
coffee-rc-94c0j              1/1       Running   1          11d
nginx-ingress-ds-hwhl3       1/1       Running   0          1h
nginx-ingress-ds-j845z       1/1       Running   0          1h
tea-rc-4501t                 1/1       Running   1          11d

测试环境为了节省资源,只设置coffee,tea应用分别只其一个pod.

docker inspect 某个具体ingress controller pod:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "849a063de3679beb132885677e95de4e953e5d9731940d614fc04982aa5a7f1f",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "443/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "443"
                    }
                ],
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "80"
                    }
                ]
            },

访问某个具体的ingress controller所在node的宿主IP:访问coffee目录获得如下应用显示请求被分往coffee pod

访问/tea目录,请求被分往tea pod:

当创建ingress resource时, ingress controller上日志显示:

1
I0924 13:05:24.593156       1 event.go:218] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"cafe-ingress", UID:"efc09df3-9884-11e7-911f-000c29420d98", APIVersion:"extensions", ResourceVersion:"168360", FieldPath:""}): type: 'Normal' reason: 'AddedOrUpdated' Configuration for default/cafe-ingress was added or updated

说明nginx controller获得相关ingress指定的配置更新.

[title]Ingress原理[/title]

Ingress (resource)是k8s中配置controller的具体规则实现,可以理解为k8s具备L7 LB实现(比如基于host,基于uri)。

Ingress controller监控ingress resource配置,并对LB进行配置。一般来说controller会和具体的software LB作为一个pod被部署,不同的SW LB需要不同的controller实现。真正执行这些规则来分发请求的是 SW LB,所以controller里可以是nginx也可以其它比如traefik。下图描述了ingress的原理(注意图中错误: nginx实际直接将请求发送给pod,不经过service):

nginx controller通过监视api server获取相关ingress、service、endpoint、secret、node、configmap对象,并在程序内部不断循环监视相关service是否有新的endpoints变化,一旦发生变化则自动更新nginx.tmpl 模板配置并产生新的配置文件进行reload

ingress resource里配置的是service名称,但nginx controller是直接将请求发送到相关pods.

nginx自动产生的一个配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
[root@docker1 complete-example]# kubectl exec nginx-ingress-ds-hwhl3 -- cat /etc/nginx/conf.d/default-cafe-ingress.conf
 
upstream default-cafe-ingress-cafe.example.com-tea-svc {
 
 
server 10.2.13.5:80; <<<<<<< pod地址
}
upstream default-cafe-ingress-cafe.example.com-coffee-svc {
 
 
server 10.2.13.4:80; <<<<<<< pod地址
}
 
 
server {
 
listen 80;
 
listen 443 ssl;
ssl_certificate /etc/nginx/secrets/default-cafe-secret;
ssl_certificate_key /etc/nginx/secrets/default-cafe-secret;
 
 
 
 
 
server_tokens on;
 
server_name cafe.example.com;
 
 
 
 
if ($scheme = http) {
  return 301 https://$host:443$request_uri;
}
 
 
location /tea {
  proxy_http_version 1.1;
 
 
  proxy_connect_timeout 60s;
  proxy_read_timeout 60s;
  client_max_body_size 1m;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Port $server_port;
  proxy_set_header X-Forwarded-Proto $scheme;
 
  proxy_buffering on;
 
  proxy_pass http://default-cafe-ingress-cafe.example.com-tea-svc;
 
}
location /coffee {
  proxy_http_version 1.1;
 
 
  proxy_connect_timeout 60s;
  proxy_read_timeout 60s;
  client_max_body_size 1m;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Port $server_port;
  proxy_set_header X-Forwarded-Proto $scheme;
 
  proxy_buffering on;
 
  proxy_pass http://default-cafe-ingress-cafe.example.com-coffee-svc;
 
}
}

[title]ingress的一些问题[/title]

还不能支持较为复杂的LB特性,例如会话保持,nginx controller扩展了ingress可以做会话保持但必须使用nginx plus。

业务规则发生变化,会导致频繁修改ingress配置,且所变化都会引起nginx reload配置,这在大并发,复杂系统环境下可能会产生较大问题

外部访问的入口依赖使用controller所在node的宿主IP,且端口暴露在node IP上,对于多个应用需要同时使用相同端口时候会导致端口冲突

外部访问入口分散在多个node IP上,使得外部统一访问变得困难,且存在潜在的单点故障,一个node 失败,客户端只有重新发起到新的node节点的访问(虽然可以使用dns来轮询这些IP),因此有必要为这些入口访问点构建统一的虚拟IP(漂移IP),这可以通过在k8s环境外部使用其它高级LB来实现,比如F5。或者将多个提供访问的node节点构建为一个集群(比如使用keepalived),可参考 https://jimmysong.io/kubernetes-handbook/practice/edge-node-configuration.html

所以基本上ingress的方案还得需要一个外部LB来做统一的高容量请求入口,ingress只能作为k8s内部的二级LB(且功能有限)。与其这样,不如直接通过将pod暴露给外部LB来直接做负载均衡,可参考:https://www.myf5.net/post/2334.htm

其它缺点:

nginx无图形界面统一管理,nginx plus有 但是是商业版本。

ingress没有业务监控检查功能

只支持http L7

不能混合支持L4/L7 LB

不支持TLS的SNI,以及SSL re-encrypt

(2020.6修改,L4/L7.SNI,ssl passthrough 都能支持了)

相关文章

  • How to build Nginx Plus as k8s Ingress controller and run with F5 CIS together
  • K8s ingress中nginx可实现功能案例
  • 项目:k8s Gateway API 的BIG-IP实现
  • F5 CES 用融合的思想保护k8s出向流量安全
  • Container Egress Services 容器出向流量策略管控
本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: ingress ingress controller k8s nginx
最后更新:2020年06月18日

纳米

linjing.io

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理。

页面AI聊天助手

纳米

linjing.io

☁️迈向Cloud Native ADC ☁️

认证获得:
TOGAF: ID 152743
Kubernetes: CKA #664
Microsoft: MCSE MCDBA
Cisco: CCNP
Juniper: JNCIS
F5:
F5 Certified Solution Expert, Security
F5 Certified Technology Specialist, LTM/GTM/APM/ASM
F5 Certified BIG-IP Administrator
  • 点击查看本博技术要素列表
  • 归档
    分类
    • AI
    • Automation
    • Avi Networks
    • Cisco ACI
    • CISCO资源
    • F5 with ELK
    • F5-Tech tips
    • F5技术
    • Juniper
    • Linux
    • NGINX
    • SDN
    • ServiceMesh
    • WEB编程
    • WINDOWS相关
    • 业界文章
    • 交换机技术
    • 化云为雨/Openstack
    • 协议原理
    • 容器/k8s
    • 我的工作
    • 我的生活
    • 网站技术
    • 路由器技术
    • 项目案例
    标签聚合
    envoy api flannel openstack DNS F5 network docker irule nginx bigip k8s neutron istio gtm
    最近评论
    汤姆 发布于 8 个月前(09月10日) 嗨,楼主,里面的json怎么下载啊,怎么收费啊?
    汤姆 发布于 8 个月前(09月09日) 大佬,kib的页面可以分享下吗?谢谢
    zhangsha 发布于 1 年前(05月12日) 资料发给我下,谢谢纳米同志!!!!lyx895@qq.com
    李成才 发布于 1 年前(01月02日) 麻烦了,谢谢大佬
    纳米 发布于 1 年前(01月02日) 你好。是的,因为以前下载系统插件在一次升级后将所有的下载生成信息全弄丢了。所以不少文件无法下载。DN...
    浏览次数
    • Downloads - 183,756 views
    • 联系我 - 118,966 views
    • 迄今为止最全最深入的BIGIP-DNS/GTM原理及培训资料 - 116,491 views
    • Github - 103,645 views
    • F5常见log日志解释 - 79,768 views
    • 从传统ADC迈向CLOUD NATIVE ADC - 下载 - 74,619 views
    • Sniffer Pro 4 70 530抓包软件 中文版+视频教程 - 74,320 views
    • 迄今为止最全最深入的BIGIP-DNS/GTM原理及培训资料 - 67,770 views
    • 关于本站 - 60,890 views
    • 这篇文档您是否感兴趣 - 55,491 views
    链接表
    • F5SE创新
    • Jimmy Song‘s Blog
    • SDNlab
    • Service Mesh社区
    • 三斗室
    • 个人profile
    • 云原生社区

    COPYRIGHT © 2023 Cloud Native 应用交付. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    京ICP备14048088号-1

    京公网安备 11010502041506号