自上次文章更新后已经过去 1752 天,文章内容可能已过时了。
六、Service与Igress 6.1 Service 6.1.1 service简介 通过以前的学习,我们已经能够通过ReplicaSet来创建一组Pod来提供具有高可用性的服务。虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题:
Pod IP仅仅是集群内可见的虚拟IP,外部无法访问。
Pod IP会随着Pod的销毁而消失,当ReplicaSet对Pod进行动态伸缩时,Pod IP可能随时随地都会变化,这样对于我们访问这个服务带来了难度。
因此,Kubernetes中的Service对象就是解决以上问题的实现服务发现
核心关键
Service可以看作是一组提供相同服务的Pod对外的访问接口,借助Service,应用可以方便地实现服务发现和负载均衡但是在使用上有以下限制:
只能提供四层负载均衡能力,而没有7层的功能,但有时我们可以能需要更多的匹配规则来转发请求,这点上4层负载均衡是不支持的。
Service同其他Kubernetes对象一样,也是通过yaml或json文件进行定义。此外,它和其他Controller对象一样,通过Label Selector来确定一个Service将要使用哪些Pod。
一个简单的Service定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 apiVersion: v1 kind: Service metadata: labels: run: nginx name: nginx-service spec: ports: - port: 80 protocol: TCP targetPort: 81 selector: app: nginx type: ClusterIP
下面简单分析一下上面的Service描述文件:
通过spec.selector
字段确定这个Service将要使用哪些Label。在本例中,这个名为nginx的Service,将会管理所有具有app: nginx
Label的Pod。
spec.ports.port: 80
表明此Service将会监听80端口,并将所有监听到的请求转发给其管理的Pod。spec.ports.targetPort: 81
表明此Service监听到的80端口的请求都会被转发给其管理的Pod的81端口,此字段可以省略,省略后其值会被设置为spec.ports.port
的值。
type: ClusterIP
表面此Service的type(ExternalName | ClusterIP | NodePort | LoadBalancer)具体下面说。
6.1.2 Service的类型 在Serive定义时我们需要指定spec.type
字段,这个字段拥有四个选项:
ClusterIP 。默认值。给这个Service分配一个Cluster IP,它是Kubernetes系统自动分配的虚拟IP,因此只能在集群内部访问。
NodePort 。将Service通过指定的Node上的端口暴露给外部。通过此方法,访问任意一个NodeIP:nodePort
都将路由到ClusterIP,从而成功获得该服务。访问流程如下:
Client—–>NodeIP:NodePort—–>ClusterIP:ServicePort—–>PodIP:ContainerPort
LoadBalancer 。在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 :NodePort。此模式只能在云服务器(AWS等)上使用。
ExternalName 。把集群外部的服务引入到集群内部来,在集群内部直接访问到。将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。需要 kube-dns 版本在 1.7 以上。
ClusterIP类型
clusterIP
主要在每个node节点使用iptables
或者ipvs
,将请求到clusterIP对应端口的数据,转发到kube-proxy中。然后kube-proxy自己内部实现有负载均衡的方法,并可以查询到这个service下对应pod的地址和端口,进而把数据转发给对应的 pod 地址和端口。
实现上图功能主要由以下几个组件协同:
apiserver :用户通过kubectl命令向apiserver发送创建service的命令,apiserver接收到请求后将数据存储到etcd中
kube-proxy :kubenetes的每个节点中都有一个叫做kube-proxy的进程,这个进程负责感知service,pod的变化,并将
变化的信息写入到本地的iptables或者ipvs规则中去
ipvs或iptables :使用nat等技术将vip的流量转发至endpoint中
一个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apiVersion: v1 kind: Service metadata: name: mynginx-svc labels: name: mynginx-svc spec: selector: app: mynginx-pro type: ClusterIP ports: - name: http port: 80 targetPort: 80 protocol: TCP
NodePort类型
nodeport原理是在每一个集群节点的node上面开放一个端口号,将向该端口号的流量导入到kube-proxy,然后由kube-proxy通过iptables规则或者ipvs将流量转发到对应pod上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 apiVersion: v1 kind: Service metadata: name: mynginx namespace: default spec: selector: app: mynginx-pro app: nginx type: NodePort ports: - port: 80 targetPort: 80 nodePort: 32715
LoadBalancer类型
用于当K8s运行在一个云环境内时,若该云环境支持LBaaS,则此类型可自动触发创建一个软件负载均衡器用于对Service做负载均衡调度。
因为外部所有Client都访问一个NodeIP,该节点的压力将会很大, 而LoadBalancer则可解决这个问题。而且它还直接动态监测后端Node是否被移除或新增了,然后动态更新调度的节点数
ExternalName类型
这种类型的Service通过返回CNAME和它的值,可以将服务映射到externalName字段的内容(例如:hub.nnv5.cn)ExternalName Service是Service的特例,它没有selector,也没有定义任何端口和endpoint,相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。
以域名的方法将集群外部服务导入集群中访问 1 2 3 4 5 6 7 8 apiVersion: v1 kind: Service metadata: name: my-service-1 namespace: default spec: type: ExternalName externalName: hub.nnv5.cn
当查询主机my-service-1.default.svc.cluster.local(svc_name.namespace.svc.cluster.local)时,集群的dns服务器返回一个值my.database.example.com的cname记录。访问这个服务的工作方式和其他的相同,唯一不同的是重定向发生在dns层,而且不会进行代理或转发。
以ip的方式将集群外部服务导入到集群内部访问 示例:将192.168.1.21这台集群外的mysql服务导入到集群内,使其集群内的集群可以访问到
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 ~]$ vim mysql-svc.yaml ------------------------------------------------------ apiVersion: v1 kind: Service metadata: name: mysql-svc labels: name: mysql-svc spec: ports: - name: mysql port: 3306 targetPort: 3306 protocol: TCP clusterIP: "None" ~]$ kubectl apply -f mysql-svc.yaml ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql-svc ClusterIP None <none> 3306 /TCP 10m ~]# vim endpoints.svc.yaml ------------------------------------------------------ apiVersion: v1 kind: Endpoints metadata: name: mysql-svc subsets: - addresses: - ip: 192.168 .1 .21 ports: - port: 3306 集群内任意Pod访问mysql-svc:3306 即可访问到192.168.1.21的数据库,当mysql主机ip更改后,只需修改Endpoints的ip地址即可。
6.1.3 代理模式的分类
注: 以上不论哪种,kube-proxy都通过watch的方式监控着kube-APIServer写入etcd中关于Pod的最新状态信息, 它一旦检查到一个Pod资源被删除了 或 新建,它将立即将这些变化,反应再iptables 或 ipvs规则中,以便 iptables和ipvs在调度Clinet Pod请求到Server Pod时,不会出现Server Pod不存在的情况。
自k8s1.1以后,service默认使用ipvs规则,若ipvs没有被激活,则降级使用iptables规则. 但在1.1以前,service使用的模式默认为userspace.
6.2 Ingress和ingress controller 6.2.1 什么是ingress 从前面的学习,我们可以了解到Kubernetes
暴露服务的方式目前只有三种:LoadBlancer Service、ExternalName、NodePort Service、Ingress
;而我们需要将集群内服务提供外界访问就会产生以下几个问题:
Pod漂移问题 Kubernetes 具有强大的副本控制能力,能保证在任意副本(Pod)挂掉时自动从其他机器启动一个新的,还可以动态扩容等,通俗地说,这个 Pod 可能在任何时刻出现在任何节点上,也可能在任何时刻死在任何节点上;那么自然随着 Pod 的创建和销毁,Pod IP 肯定会动态变化;那么如何把这个动态的 Pod IP 暴露出去?这里借助于 Kubernetes 的 Service 机制,Service 可以以标签的形式选定一组带有指定标签的 Pod,并监控和自动负载他们的 Pod IP,那么我们向外暴露只暴露 Service IP 就行了;这就是 NodePort 模式:即在每个节点上开起一个端口,然后转发到内部 Pod IP 上,如下图所示: 此时的访问方式:http://nodeip :nodeport/
端口管理问题 采用 NodePort 方式暴露服务面临问题是,服务一旦多起来,NodePort 在每个节点上开启的端口会及其庞大,而且难以维护;这时,我们可以能否使用一个Nginx直接对内进行转发呢?众所周知的是,Pod与Pod之间是可以互相通信的,而Pod是可以共享宿主机的网络名称空间的,也就是说当在共享网络名称空间时,Pod上所监听的就是Node上的端口。那么这又该如何实现呢?简单的实现就是使用 DaemonSet 在每个 Node 上监听 80,然后写好规则,因为 Nginx 外面绑定了宿主机 80 端口(就像 NodePort),本身又在集群内,那么向后直接转发到相应 Service IP 就行了,如下图所示:
域名分配及动态更新问题 从上面的方法,采用 Nginx-Pod 似乎已经解决了问题,但是其实这里面有一个很大缺陷:当每次有新服务加入又该如何修改 Nginx 配置呢??我们知道使用Nginx可以通过虚拟主机域名进行区分不同的服务,而每个服务通过upstream进行定义不同的负载均衡池,再加上location进行负载均衡的反向代理,在日常使用中只需要修改nginx.conf即可实现,那在K8S中又该如何实现这种方式的调度呢???
假设后端的服务初始服务只有ecshop,后面增加了bbs和member服务,那么又该如何将这2个服务加入到Nginx-Pod进行调度呢?总不能每次手动改或者Rolling Update 前端 Nginx Pod 吧!!此时 Ingress 出现了,如果不算上面的Nginx,Ingress 包含两大组件:Ingress Controller 和 Ingress。
Ingress 简单的理解就是你原来需要改 Nginx 配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yaml 创建,每次不要去改 Nginx 了,直接改 yaml 然后创建/更新就行了;那么问题来了:”Nginx 该怎么处理?”
Ingress Controller 这东西就是解决 “Nginx 的处理方式” 的;Ingress Controoler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取他,按照他自己模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最后 reload 一下,工作流程如下图:
实际上Ingress也是Kubernetes API的标准资源类型之一,它其实就是一组基于DNS名称(host)或URL路径把请求转发到指定的Service资源的规则。用于将集群外部的请求流量转发到集群内部完成的服务发布。我们需要明白的是,Ingress资源自身不能进行“流量穿透”,仅仅是一组规则的集合,这些集合规则还需要其他功能的辅助,比如监听某套接字,然后根据这些规则的匹配进行路由转发,这些能够为Ingress资源监听套接字并将流量转发的组件就是Ingress Controller。
PS:Ingress 控制器不同于Deployment 控制器的是,Ingress控制器不直接运行为kube-controller-manager的一部分,它仅仅是Kubernetes集群的一个附件,类似于CoreDNS,需要在集群上单独部署。
6.2.3 ingress资源类型 Ingress的资源类型有以下4种:
1、单Service资源型Ingress
2、基于URL路径进行流量转发
3、基于主机名称的虚拟主机
4、TLS类型的Ingress资源
单Service资源型ingress
1 2 3 4 5 6 7 8 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: my-ingress spec: backend: serviceName: my-svc servicePort: 80
Ingress控制器会为其分配一个IP地址接入请求流量,并将其转发至后端my-svc
6.2.3 部署ingress-nginx服务 Deployment的NodePort方式部署
nodePort的部署思路就是通过在每个节点上开辟nodePort的端口,将流量引入进来,而后通过iptables首先转发到ingress-controller容器中,而后由nginx根据ingress的规则进行判断,将其转发到对应的应用web容器中,这种方式部署的nginx域名后面需要加上随机的nodeport端口才能访问
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
DaemonSet的hostNetwork方式 1.直接将ingress-nginx部署的yaml下载下来
1 $ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/deploy.yaml
这个yaml中包含了很多资源的创建,包括namespece、configmap、role、serviceaccount等ingress-nginx需要的资源对象,配置太多就不粘帖出来了,我们重点看下deployment部分
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 apiVersion: apps/v1 kind: Deployment metadata: labels: helm.sh/chart: ingress-nginx-2.11.1 app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/version: 0.34.1 app.kubernetes.io/managed-by: Helm app.kubernetes.io/component: controller name: ingress-nginx-controller namespace: ingress-nginx spec: selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/component: controller revisionHistoryLimit: 10 minReadySeconds: 0 template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/component: controller spec: dnsPolicy: ClusterFirst containers: - name: controller image: us.gcr.io/k8s-artifacts-prod/ingress-nginx/controller:v0.34.1@sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 imagePullPolicy: IfNotPresent lifecycle: preStop: exec : command : - /wait-shutdown args: - /nginx-ingress-controller - --election-id=ingress-controller-leader - --ingress-class=nginx - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller - --validating-webhook=:8443 - --validating-webhook-certificate=/usr/local/certificates/cert - --validating-webhook-key=/usr/local/certificates/key securityContext: capabilities: drop: - ALL add: - NET_BIND_SERVICE runAsUser: 101 allowPrivilegeEscalation: true env : - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace livenessProbe: httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 1 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 1 successThreshold: 1 failureThreshold: 3 ports: - name: http containerPort: 80 protocol: TCP - name: https containerPort: 443 protocol: TCP - name: webhook containerPort: 8443 protocol: TCP volumeMounts: - name: webhook-cert mountPath: /usr/local/certificates/ readOnly: true resources: requests: cpu: 100m memory: 90Mi serviceAccountName: ingress-nginx terminationGracePeriodSeconds: 300 volumes: - name: webhook-cert secret: secretName: ingress-nginx-admission
我们需要使用daemonset部署到特定node,需要修改部分配置:先给要部署nginx-ingress的node打上特定标签,这里测试部署再node01和node02上面
1 2 kubectl label node k8s-node01.nnv5.cn isIngress="true" kubectl label node k8s-node02.nnv5.cn isIngress="true"
然后修改上面deployment部署配置为:
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 apiVersion: apps/v1 kind: DaemonSet metadata: labels: helm.sh/chart: ingress-nginx-2.11.1 app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/version: 0.34.1 app.kubernetes.io/managed-by: Helm app.kubernetes.io/component: controller name: ingress-nginx-controller namespace: ingress-nginx spec: selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/component: controller revisionHistoryLimit: 10 minReadySeconds: 0 template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/component: controller spec: dnsPolicy: ClusterFirst nodeSelector: isIngress: "true" hostNetwork: true containers: - name: controller image: us.gcr.io/k8s-artifacts-prod/ingress-nginx/controller:v0.34.1@sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 imagePullPolicy: IfNotPresent lifecycle: preStop: exec : command : - /wait-shutdown args: - /nginx-ingress-controller - --election-id=ingress-controller-leader - --election-id=ingress-controller-leader - --ingress-class=nginx - --configmap=ingress-nginx/ingress-nginx-controller - --validating-webhook=:8443 - --validating-webhook-certificate=/usr/local/certificates/cert - --validating-webhook-key=/usr/local/certificates/key securityContext: capabilities: drop: - ALL add: - NET_BIND_SERVICE runAsUser: 101 allowPrivilegeEscalation: true env : - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace livenessProbe: httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 1 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 1 successThreshold: 1 failureThreshold: 3 ports: - name: http containerPort: 80 protocol: TCP - name: https containerPort: 443 protocol: TCP - name: webhook containerPort: 8443 protocol: TCP volumeMounts: - name: webhook-cert mountPath: /usr/local/certificates/ readOnly: true resources: requests: cpu: 1m memory: 90Mi serviceAccountName: ingress-nginx terminationGracePeriodSeconds: 300 volumes: - name: webhook-cert secret: secretName: ingress-nginx-admission
然后应用并检查服务,由于配置的hostnetwork,nginx会在特定node本地主机上监听80/443/8181端口。其中8181是nginx-controller默认配置的一个default backend。这样,只要访问node主机有公网IP,就可以直接映射域名来对外暴露服务,如果要实现高可用的话,可以在多个node上部署,前面加一个负载均衡器。
例如你创建一个 www.nnv5.cn 这样域名的ingress
deployment方式部署的你需要获取ingress的svc的80端口映射的nodeport这样访问:http://www.nnv5.cn:32134
daemonset方式部署的你只需要将域名解析到特定节点上,直接访问域名就能到:http://www.nnv5.cn
6.2.4 如何创建ingress资源
Ingress资源时基于HTTP虚拟主机或URL的转发规则,需要强调的是,这是一条转发规则 。它在资源配置清单中的spec字段中嵌套了rules、backend和tls等字段进行定义。如下示例中定义了一个Ingress资源,其包含了一个转发规则:将发往myapp.magedu.com的请求,代理给一个名字为myapp的Service资源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-myapp namespace: default annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: myapp.magedu.com http: paths: - path: / backend: serviceName: myapp servicePort: 80
Ingress 中的spec字段是Ingress资源的核心组成部分,主要包含以下3个字段:
rules:用于定义当前Ingress资源的转发规则列表;由rules定义规则,或没有匹配到规则时,所有的流量会转发到由backend定义的默认后端。
backend:默认的后端用于服务那些没有匹配到任何规则的请求;定义Ingress资源时,必须要定义backend或rules两者之一,该字段用于让负载均衡器指定一个全局默认的后端。
tls:TLS配置,目前仅支持通过默认端口443提供服务,如果要配置指定的列表成员指向不同的主机,则需要通过SNI TLS扩展机制来支持该功能。 backend对象的定义由2个必要的字段组成:serviceName和servicePort,分别用于指定流量转发的后端目标Service资源名称和端口。 rules对象由一系列的配置的Ingress资源的host规则组成,这些host规则用于将一个主机上的某个URL映射到相关后端Service对象,其定义格式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-myapp namespace: default spec: rules: - hosts: <string> http: paths: - path: <string> backend: serviceName: <string> servicePort: <string>
需要注意的是,.spec.rules.host属性值,目前暂不支持使用IP地址定义,也不支持IP:Port的格式,该字段留空,代表着通配所有主机名。 tls对象由2个内嵌的字段组成,仅在定义TLS主机的转发规则上使用。
hosts: 包含 于 使用 的 TLS 证书 之内 的 主机 名称 字符串 列表, 因此, 此处 使用 的 主机 名 必须 匹配 tlsSecret 中的 名称。
secretName: 用于 引用 SSL 会话 的 secret 对象 名称, 在 基于 SNI 实现 多 主机 路 由 的 场景 中, 此 字段 为 可选
6.2.5 创建http类型ingress 创建一个deployment
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: Deployment metadata: name: nginx-v1 labels: deployment: nginx-v1 spec: replicas: 3 selector: matchLabels: app: nginxv1 template: metadata: name: nginxv1 labels: app: nginxv1 spec: restartPolicy: Always containers: - name: nginx-01 image: hub.nnv5.cn/test/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 protocol: TCP workingDir: /opt --- apiVersion: v1 kind: Service metadata: name: nginxv1-svc labels: svc: nginxv1-svc spec: selector: app: nginxv1 ports: - name: web-80 port: 80 targetPort: 80 protocol: TCP
创建ingress关联svc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginxv1-ingress labels: ingress: nginxv1-ingress spec: rules: - host: nginxv1.nnv5.cn http: paths: - backend: serviceName: nginxv1-svc servicePort: 80 path: /
验证访问 1 2 3 4 5 6 7 8 ]$ kubectl get svc -A NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default nginxv1-svc ClusterIP 10.101.16.230 <none> 80/TCP 74m ingress-nginx ingress-nginx-controller NodePort 10.96.249.151 <none> 80:31101/TCP,443:31123/TCP 105m
6.2.6 创建https类型ingress 准备证书 1 2 3 4 5 6 [root@k8s-master ingress] Generating RSA private key, 2048 bit long modulus ................................................................................................+++ .............................................................................................+++ e is 65537 (0x10001) [root@k8s-master ingress]
生成secret
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@k8s-master ingress] secret/nginxv3-ingress-secret created [root@k8s-master ingress] NAME TYPE DATA AGE default-token-zl497 kubernetes.io/service-account-token 3 25h nginxv3-ingress-secret kubernetes.io/tls 2 3s [root@k8s-master ingress] Name: nginxv3-ingress-secret Namespace: default Labels: <none> Annotations: <none> Type: kubernetes.io/tls Data ==== tls.crt: 1289 bytes tls.key: 1675 bytes
创建一个deployment
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: Deployment metadata: name: nginx-v3 labels: deployment: nginx-v3 spec: replicas: 3 selector: matchLabels: app: nginxv3 template: metadata: name: nginxv3 labels: app: nginxv3 spec: restartPolicy: Always containers: - name: nginx-01 image: hub.nnv5.cn/test/myapp:v3 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 protocol: TCP workingDir: /opt --- apiVersion: v1 kind: Service metadata: name: nginxv3-svc labels: svc: nginxv3-svc spec: selector: app: nginxv3 ports: - name: web-80 port: 80 targetPort: 80 protocol: TCP
创建一个ingress
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginxv3-ingress labels: ingress: nginxv3-ingress spec: tls: - hosts: - nginxv3.nnv5.cn secretName: nginxv3-ingress-secret rules: - host: nginxv3.nnv5.cn http: paths: - backend: serviceName: nginxv3-svc servicePort: 80 path: /
验证访问 1 2 3 4 5 6 7 8 ]$ kubectl get svc -A NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default nginxv1-svc ClusterIP 10.101.16.230 <none> 80/TCP 74m ingress-nginx ingress-nginx-controller NodePort 10.96.249.151 <none> 80:31101/TCP,443:31123/TCP 105m