相关术语 为清楚起见,本指南定义了以下术语:
Node(节点): kubernetes集群中的一台虚拟机或物理机。
Cluster(集群): 一组与因特网通过隔离的节点,他们是是Kubernetes管理的主要计算资源。
Edge router(边界路由器): 为您的集群强制执行防火墙策略的路由器。这可以是由云提供商管理的网关,也可以是物理硬件。
Cluster network(集群网络): 根据Kubernetes网络模型,促进集群内通信的一组逻辑上的或物理上的链路。
Service(服务): 一种Kubernetes服务,它使用标签选择器标识一组pod。除非另有说明,否则假定服务只有在集群网络中可路由的虚拟ip。
什么是ingress ingress(在kubernetes v1.1时添加)暴露从集群外到集群内服务的HTTP
或HTTPS
路由。定义在ingress
资源上的规则控制流量的路由。
管理对集群中的服务(通常是HTTP)的外部访问的API对象。Ingress可以提供负载平衡、SSL终端和基于名称的虚拟主机。
1 2 3 4 5 internet | [ Ingress ] --|-----|-- [ Services ]
一个ingress
可以配置用于提供外部可访问的服务url、负载均衡流量、SSL终端和提供虚拟主机名配置。ingress controller
负责实现(通常使用负载均衡器(loadbalancer))入口(ingress)。但是它也可以配置你的边缘路由器或额外的前端来帮助处理流量。 ingress
不暴露任何端口或协议。将HTTP和HTTPS之外的服务公开到因特网通常使用类型是NodePort或loadbalance的service。
ingress 资源 一个最小的ingress示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: test-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - http: paths: - path: /testpath backend: serviceName: test servicePort: 80
和其他的kubernetes资源一样,ingress需要apiVersion
、kind
和metadata
字段。 Ingress spec包含配置负载均衡器或代理服务器所需的所有信息。最重要的是,它包含一个针对所有传入请求匹配的规则列表。ingress资源只支持用于指导HTTP通信的规则
ingress 规则 每一个HTTP规则包含以下信息:
一个可选的host
。在本例中没有host
,因此,该规则适用于通过指定的IP地址进行的所有入站HTTP通信。如果提供一个host
(例如,foo.bar.com),这个规则是适用于这一个host
一个paths
(例如 /testpath)的列表。每一个path
都有与之关联的serviceName
和servicePort
,在负载均衡器将流量导向所引用的服务之前,主机和路径必须匹配传入请求的内容
后端是服务和端口名称的组合。对与规则的主机和路径匹配的入口的HTTP(和HTTPS)请求将发送到列出的后端。
默认后端通常配置在一个Ingress控制器中,该控制器将服务于任何与规范中的路径不匹配的请求。(404页面)
默认后端 没有规则的ingress把所有的流量都转发到一个默认后端。默认后端通常是Ingress控制器的一个配置选项,并没有在Ingress资源中指定。 如果没有任何主机或路径匹配Ingress对象中的HTTP请求,则流量将路由到默认后端。
ingress的类型 单service的ingress 现有的Kubernetes概念允许您公开单个服务。您还可以通过指定一个没有规则的默认后端来对一个入口执行此操作。
1 2 3 4 5 6 7 8 apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: test-ingress spec: backend: serviceName: testsvc servicePort: 80
通过kubectl apply -f <文件名>
创建后,你可以看到:
1 2 3 kubectl get ingress test-ingress NAME HOSTS ADDRESS PORTS AGE test-ingress * 107.178.254.228 80 59s
其中107.178.254.228是入口控制器为满足该入口而分配的IP。
根据请求URI匹配 根据所请求的HTTP URI,扇出配置将流量从单个IP地址路由到多个服务。一个入口允许您将负载平衡器的数量保持到最小。例如,设置如下:
1 2 foo.bar.com -> 178.91.123.132 -> / foo service1:4200 / bar service2:8080
定义的ingress如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: simple-fanout-example annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: foo.bar.com http: paths: - path: /foo backend: serviceName: service1 servicePort: 4200 - path: /bar backend: serviceName: service2 servicePort: 8080
通过kubectl apply -f <文件名>
创建后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl describe ingress simple-fanout-example Name: simple-fanout-example Namespace: default Address: 178.91.123.132 Default backend: default-http-backend:80 (10.8.2.3:8080) Rules: Host Path Backends ---- ---- -------- foo.bar.com /foo service1:4200 (10.8.0.90:4200) /bar service2:8080 (10.8.0.91:8080) Annotations: nginx.ingress.kubernetes.io/rewrite-target: / Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 22s loadbalancer-controller default/test
只要服务(s1, s2)存在,Ingress控制器提供一个满足Ingress的特定于实现的负载均衡器。当它这样做时,您可以在address字段中看到负载均衡器的地址。
基于不同域名的虚拟主机 基于名称的虚拟主机支持将HTTP流量路由到同一IP地址的多个主机名。
1 2 3 foo.bar.com --| |-> foo.bar.com s1:80 | 178.91.123.132 | bar.foo.com --| |-> bar.foo.com s2:80
下面的ingress告诉后台负载均衡器根据主机头路由请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: name-virtual-host-ingress spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: service1 servicePort: 80 - host: bar.foo.com http: paths: - backend: serviceName: service2 servicePort: 80
如果您创建一个没有在规则中定义任何主机的Ingress资源,那么可以匹配到Ingress控制器IP地址的任何web流量,而不需要基于名称的虚拟主机。例如,下面的Ingress资源将把first.bar.com请求的流量路由到service1, second.foo.com路由到service2,将任何没有在request中定义主机名(即没有显示请求头)的流量路由到service3。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: name-virtual-host-ingress spec: rules: - host: first.bar.com http: paths: - backend: serviceName: service1 servicePort: 80 - host: second.foo.com http: paths: - backend: serviceName: service2 servicePort: 80 - http: paths: - backend: serviceName: service3 servicePort: 80
TLS 您可以通过指定包含TLS私钥和证书的秘密来保护ingress。目前,入口只支持一个TLS端口443,并假设TLS终端。如果一个入口中的TLS配置部分指定了不同的主机,那么它们将根据通过SNI TLS扩展指定的主机名在同一个端口上进行多路复用(前提是入口控制器支持SNI)。TLS密钥必须包含名为TLS的密钥。crt和tls。包含用于TLS的证书和私钥的密钥,例如:
1 2 3 4 5 6 7 8 9 apiVersion: v1 kind: Secret metadata: name: testsecret-tls namespace: default data: tls.crt: base64 encoded cert tls.key: base64 encoded key type: kubernetes.io/tls
在一个Ingress中引用这个secret
将告诉Ingress控制器使用TLS保护从客户机到负载均衡器的通道。您需要确保您创建的TLS secret来自一个包含sslexample.foo.com CN的证书。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: tls-example-ingress spec: tls: - hosts: - sslexample.foo.com secretName: testsecret-tls rules: - host: sslexample.foo.com http: paths: - path: / backend: serviceName: service1 servicePort: 80
Loadbalancing 一个ingress controller 通过一些应用于所有入口的负载平衡策略设置来引导,例如负载平衡算法、后端权重方案等。更高级的负载平衡概念(例如持久会话、动态权重)还没有通过ingress公开。同样值得注意的是,尽管健康检查不是直接通过入口暴露的,但是在Kubernetes中也存在类似的概念,比如就绪探测,它允许您实现相同的最终结果。
部署Ingress-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 [root@k8s-master ~]$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/deploy.yaml [root@k8s-master ~]$ cat deploy.yaml | grep image image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.33.0 image: docker.io/jettech/kube-webhook-certgen:v1.2.0 [root@k8s-master ~]$ docker pull docker.io/jettech/kube-webhook-certgen:v1.2.0 [root@k8s-master ~]$ docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.33.0 [root@k8s-master opt]$ docker save -o nginx-ingress-controller.tar.gz quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.33.0 [root@k8s-master opt]$ docker save -o kube-webhook-certgen.tar.gz jettech/kube-webhook-certgen:v1.2.0 [root@k8s-master opt]$ scp kube-webhook-certgen.tar.gz nginx-ingress-controller.tar.gz k8s-node01.nnv5.cn:/opt/ [root@k8s-master opt]$ scp kube-webhook-certgen.tar.gz nginx-ingress-controller.tar.gz k8s-node02.nnv5.cn:/opt/ [root@k8s-node02 opt]$ docker load -i kube-webhook-certgen.tar.gz [root@k8s-node02 opt]$ docker load -i nginx-ingress-controller.tar.gz [root@k8s-master ~]$ kubectl apply -f deploy.yaml namespace/ingress-nginx created serviceaccount/ingress-nginx created configmap/ingress-nginx-controller created clusterrole.rbac.authorization.k8s.io/ingress-nginx created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created role.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx created service/ingress-nginx-controller-admission created service/ingress-nginx-controller created deployment.apps/ingress-nginx-controller created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created job.batch/ingress-nginx-admission-create created job.batch/ingress-nginx-admission-patch created role.rbac.authorization.k8s.io/ingress-nginx-admission created rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created serviceaccount/ingress-nginx-admission created ~]$ kubectl get pods -o wide -n ingress-nginx NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES ingress-nginx-controller-58f68f5ccc-5v2qc 1/1 Running 0 10m 10.244.1.18 k8s-node01.nnv5.cn <none> <none> ~]$ kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.96.249.151 <none> 80:31101 /TCP,443:31123/TCP 84m ingress-nginx-controller-admission ClusterIP 10.107.8.188 <none> 443/TCP 84m
hostnetwork方式部署Ingress-nginx 1.下载ingress部署文件
2.给需要运行ingress的节点打标签
1 2 3 4 [root@k8s-master simple-microservice-dev3] node/k8s-node01.nnv5.cn labeled [root@k8s-master simple-microservice-dev3] node/k8s-node02.nnv5.cn labeled
3.修改deployment为daemonset,添加hostnetwork模式
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 apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: terminationGracePeriodSeconds: 300 serviceAccountName: nginx-ingress-serviceaccount nodeSelector: ingress-controller-ready: OK hostNetwork: true [root@k8s-node01 ~] namespace/ingress-nginx unchanged configmap/nginx-configuration unchanged configmap/tcp-services unchanged configmap/udp-services unchanged serviceaccount/nginx-ingress-serviceaccount unchanged clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole unchanged role.rbac.authorization.k8s.io/nginx-ingress-role unchanged rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding unchanged clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding unchanged daemonset.apps/nginx-ingress-controller created
4.查看ingress运行的节点,查看节点监听端口号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@k8s-node01 ~] NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-ingress-controller-9kckx 1/1 Running 0 6m59s 192.168.1.43 k8s-node02.nnv5.cn <none> <none> nginx-ingress-controller-qhf9b 1/1 Running 0 6m59s 192.168.1.42 k8s-node01.nnv5.cn <none> <none> [root@k8s-node01 ~] LISTEN 0 128 *:80 *:* LISTEN 0 128 *:80 *:* LISTEN 0 128 *:80 *:* LISTEN 0 128 *:80 *:* LISTEN 0 128 *:443 *:* LISTEN 0 128 *:443 *:* LISTEN 0 128 *:443 *:* LISTEN 0 128 *:443 *:*
5.创建一个访问示例进行测试
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 78 79 80 [root@k8s-node02 ~] apiVersion: apps/v1 kind: Deployment metadata: labels: app: web name: web spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - image: putianhui/myapp:v2 name: myapp --- apiVersion: v1 kind: Service metadata: labels: app: web name: web spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: web --- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: name-virtual-host-ingress spec: rules: - host: web.nnv5.cn http: paths: - backend: serviceName: web servicePort: 80 [root@k8s-node02 ~] deployment.apps/web created service/web created ingress.networking.k8s.io/name-virtual-host-ingress created [root@k8s-node02 ~] NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/web 3/3 3 3 21s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 41d service/web ClusterIP 10.108.235.31 <none> 80/TCP 21s NAME CLASS HOSTS ADDRESS PORTS AGE ingress.extensions/name-virtual-host-ingress <none> web.nnv5.cn 80 21s [root@k8s-node02 ~] 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.1.42 web.nnv5.cn [root@k8s-node02 ~] web-6dc57ffff9-67fp8 [root@k8s-node02 ~] web-6dc57ffff9-vbczr [root@k8s-node02 ~] web-6dc57ffff9-94vph