【云原生 • Kubernetes】kubernetes 核心技术 - Ingress
本文导读
- 一、前言
- 二、Ingress 和 pod 有什么关系
- 三、使用 Ingress 对外暴露应用
一、前言
在以往的操作过程中,我们都是将某端口号对外暴露,然后再使用 IP+端口号
进行访问服务,这是通过 Service 中的 NodePort 实现的。
但是 NodePort 有着明显的缺陷:NodePort 会在每一个 node 节点都启用一个端口,也就是说在集群中的任何一个 node 节点中,使用节点 IP + 端口号都能访问到该服务;每个端口只能使用一次,每个端口也只对应一个应用。而在实际的项目当中,其实都是使用 域名
访问的,根据不同的域名跳转到不同的端口服务中。
Ingress 的应用正是专门用于弥补 NodePort 的这些缺陷。
二、Ingress 和 pod 有什么关系
首先,Ingress 和 pod 是通过 Service 进行关联的,将 Ingress 作为一个统一的访问入口,访问由 Service 关联的一组 pod,如下示意图:
三、使用 Ingress 对外暴露应用
1. 创建应用并使用 NodePort 暴露端口
第一步:创建 nginx 应用,使用 NodePort 对外暴露端口;
[root@master ~]# kubectl create deployment web --image=nginxdeployment.apps/web created[root@master ~]#
查看 pod 可以看到我们创建的 web;
第二步:对外暴露一个端口,如下 32153 即为暴露端口;
[root@master ~]# kubectl expose deployment web --port=80 --target-port=80 --type=NodePortservice/web exposed#查看[root@master ~]# kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetesClusterIP 10.96.0.1<none> 443/TCP 44dmyweb1 NodePort 10.104.70.36 <none> 80:30619/TCP 14dui-weave-scope NodePort 10.110.235.39 <none> 80:31772/TCP 15dwebNodePort 10.96.191.100 <none> 80:32153/TCP 23s[root@master ~]#
此时,在任一 node 节点通过 节点IP+32153
就可以访问到 web 容器中的应用服务,为了避免这个问题,所以 接下来我们开始添加 Ingress
。
2. 应用 Ingress
(1) 部署 Ingress Controller
Ingress Controller 是一个反向代理程序,负责解析 Ingress 的反向代理规则,以 Pod 的形式运行,监控 api-server 的 ingress 端口后的 backend services,如果 Ingress 有增删改的变动,所有的 Ingress Controller 都会及时更新自己相应的转发规则,当 Ingress Controller 收到请求后就会根据这些规则将请求转发到对应的 Service。
Ingress Controller 并不是 k8s 集群内置的,所以需要我们手动下载部署。
第一步:vi 创建 yaml 文件 ingress-controller.yaml
,添加以下内容;
apiVersion: v1kind: Namespacemetadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx---kind: ConfigMapapiVersion: v1metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx---kind: ConfigMapapiVersion: v1metadata: name: tcp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx---kind: ConfigMapapiVersion: v1metadata: name: udp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx---apiVersion: v1kind: ServiceAccountmetadata: name: nginx-ingress-serviceaccount namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx---apiVersion: rbac.authorization.k8s.io/v1beta1kind: ClusterRolemetadata: name: nginx-ingress-clusterrole labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxrules: - apiGroups: - "" resources: - configmaps - endpoints - nodes - pods - secrets verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses verbs: - get - list - watch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses/status verbs: - update---apiVersion: rbac.authorization.k8s.io/v1beta1kind: Rolemetadata: name: nginx-ingress-role namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxrules: - apiGroups: - "" resources: - configmaps - pods - secrets - namespaces verbs: - get - apiGroups: - "" resources: - configmaps resourceNames: # Defaults to "-" # Here: "-" # This has to be adapted if you change either parameter # when launching the nginx-ingress-controller. - "ingress-controller-leader-nginx" verbs: - get - update - apiGroups: - "" resources: - configmaps verbs: - create - apiGroups: - "" resources: - endpoints verbs: - get---apiVersion: rbac.authorization.k8s.io/v1beta1kind: RoleBindingmetadata: name: nginx-ingress-role-nisa-binding namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: nginx-ingress-rolesubjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx---apiVersion: rbac.authorization.k8s.io/v1beta1kind: ClusterRoleBindingmetadata: name: nginx-ingress-clusterrole-nisa-binding labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nginx-ingress-clusterrolesubjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx---apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxspec: replicas: 1 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: hostNetwork: true # wait up to five minutes for the drain of connections terminationGracePeriodSeconds: 300 serviceAccountName: nginx-ingress-serviceaccount nodeSelector: kubernetes.io/os: linux containers: - name: nginx-ingress-controller image: lizhenliang/nginx-ingress-controller:0.30.0 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/ingress-nginx - --annotations-prefix=nginx.ingress.kubernetes.io securityContext: allowPrivilegeEscalation: true capabilities:drop: - ALLadd: - NET_BIND_SERVICE # www-data -> 101 runAsUser: 101 env: - name: POD_NAMEvalueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACEvalueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: httpcontainerPort: 80protocol: TCP - name: httpscontainerPort: 443protocol: TCP livenessProbe: failureThreshold: 3 httpGet:path: /healthzport: 10254scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 httpGet:path: /healthzport: 10254scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 lifecycle: preStop:exec: command: - /wait-shutdown---apiVersion: v1kind: LimitRangemetadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxspec: limits: - min: memory: 90Mi cpu: 100m type: Container
第二步:执行该文件;
[root@master ~]# kubectl apply -f ingress-controller.yaml
(2) 创建 Ingress 规则
创建 Ingress 规则的目的就是要找到访问的内容。
第一步:vi 创建 yaml 文件 ingress.yaml
,添加以下内容;
apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata: name: example-ingressspec: rules: #通过以下域名访问 - host: example.ingredemo.com http: paths: - path: / backend: #服务名称,我们之前创建的web serviceName: web servicePort: 80
第二步:执行该文件;
[root@master ~]# kubectl apply -f ingress.yaml ingress.networking.k8s.io/example-ingress created[root@master ~]#
Ingress 规则创建完成。
(3) 在 Windows 系统的 hosts 文件添加域名访问规则
系统中的 hosts 文件默认在 C:\Windows\System32\drivers\etc
目录下;
编辑该文件;
设置完成后,就可以使用域名来访问我们集群中的服务了。