> 文档中心 > 【云原生 • Kubernetes】kubernetes 核心技术 - Ingress

【云原生 • Kubernetes】kubernetes 核心技术 - Ingress

在这里插入图片描述

本文导读

  • 一、前言
  • 二、Ingress 和 pod 有什么关系
  • 三、使用 Ingress 对外暴露应用
    • 1. 创建应用并使用 NodePort 暴露端口
    • 2. 应用 Ingress
      • (1) 部署 Ingress Controller
      • (2) 创建 Ingress 规则
      • (3) 在 Windows 系统的 hosts 文件添加域名访问规则

一、前言

在以往的操作过程中,我们都是将某端口号对外暴露,然后再使用 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 目录下;

在这里插入图片描述
编辑该文件;

在这里插入图片描述

设置完成后,就可以使用域名来访问我们集群中的服务了。