Kubernetes 中使用 Ingress 实现服务暴露详解

在 Kubernetes 中,我们需要将应用程序暴露给外部。传统上,这可以通过 NodePort 或 LoadBalancer 类型的服务实现。但是,在生产环境中使用 Ingress 类型的服务可以更好地满足需求。这篇文章将介绍 Kubernetes 中使用 Ingress 实现服务暴露的详细过程,并包含示例代码,以帮助读者更好地了解 Ingress 的使用。

Ingress 是什么?

Ingress 是一种 Kubernetes 资源类型,用于将入站的 HTTP(S) 流量路由到后端服务。Ingress 是一种 API 对象,允许您定义如何将流量路由到 Kubernetes 集群中的服务。

如何使用 Ingress?

在 Kubernetes 中使用 Ingress 的步骤如下:

第一步:安装 Ingress Controller

Ingress Controller 是一个实现了 Ingress 标准的反向代理服务。在 Kubernetes 中,有很多 Ingress Controller 的实现,如 Nginx、Traefik 等。在这里,我们以 Nginx Ingress Controller 为例。

首先,我们需要安装 Ingress Controller,可以参考下面代码:

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  use-proxy-protocol: "false"
  use-forwarded-headers: "true"
  http-snippet: |
    # HTTP Headers to increase security
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    # block known suspicious user agents
    if ($http_user_agent ~* (BlackWidow|Bot\ mailto:craftbot@yahoo.com|ChinaClaw|Custo|DISCo|Download\ Demon|eCatch|EasyDL|EirGrabber|EmailSiphon|EmailWolf|Express\ WebPictures|ExtractorPro|EyeNetIE|FlashGet|GetRight|GetWeb!|Go!Zilla|Go-Ahead-Got-It|GrabNet|Grafula|HMView|HTTrack|Image\ Stripper|Image\ Sucker|Indy\ Library|InterGET|Internet\ Ninja|JetCar|JOC\ Web\ Spider|larbin|LeechFTP|Mass\ Downloader|MIDown\ tool|Mister\ PiX|Navroad|NearSite|NetAnts|NetSpider|Net\ Vampire|NetZIP|Octopus|Offline\ Explorer|Offline\ Navigator|PageGrabber|Papa\ Foto|pavuk|pcBrowser|RealDownload|ReGet|SiteSnagger|SmartDownload|SuperBot|SuperHTTP|Surfbot|tAkeOut|Teleport\ Pro|VoidEYE|Web\ Image\ Collector|Web\ Sucker|WebAuto|WebCopier|WebFetch|WebGo\ IS|WebLeacher|WebReaper|WebSauger|Website\ eXtractor|Website\ Quester|WebStripper|WebWhacker|WebZIP|Wget|Widow|WWWOFFLE) ) {
      return 403;
    }
    # block requests with HTTP method specified
    if ($request_method ~* "(PUT|DELETE|PATCH)") {
      return 405;
    }
    # block some HEAD requests that consume service resources
    if ($request_method = HEAD) {
      return 404;
    }
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
data:
  "9000": "example-service/example-port"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: udp-services
  namespace: ingress-nginx
data:
  "53": "example-service/example-port"
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ingress-nginx-role
rules:
  - apiGroups:
      - ''
      - extensions
      - networking.k8s.io
    resources:
      - configmaps
      - endpoints
      - ingress
      - nodes
      - pods
      - secrets
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ''
      - extensions
      - networking.k8s.io
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ''
      - extensions
      - networking.k8s.io
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ''
      - extensions
      - networking.k8s.io
    resources:
      - configmaps
    verbs:
      - create
      - get
  - apiGroups:
      - ''
      - extensions
      - networking.k8s.io
    resources:
      - endpoints
    verbs:
      - create
      - get
  - apiGroups:
      - ''
      - extensions
      - networking.k8s.io
    resources:
      - ingress
    verbs:
      - create
      - get
  - apiGroups:
      - ''
      - extensions
      - networking.k8s.io
    resources:
      - pods
    verbs:
      - get
  - apiGroups:
      - ''
      - extensions
    resources:
      - events
    verbs:
      - create
      - patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ingress-nginx-role-nisa-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ingress-nginx
  template:
    metadata:
      labels:
        app: ingress-nginx
    spec:
      # serviceAccountName: nginx-ingress-serviceaccount
      terminationGracePeriodSeconds: 60
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
          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-controller
            - --annotations-prefix=nginx.ingress.kubernetes.io
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
              hostPort: 80
            - name: https
              containerPort: 443
              hostPort: 443
            - name: es-metadata-gatherer
              containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 80
      targetPort: 80
    - name: https
      port: 443
      targetPort: 443
  selector:
    app: ingress-nginx

第二步:创建服务

创建一个后端服务,以便为访问者提供应用程序的实例。可以参考下面代码:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-app
  labels:
    app: example-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
        - name: example-app
          image: nginx
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: example-app
  ports:
    - port: 8080
      targetPort: 80

第三步:定义 Ingress

定义 Ingress 的规则以将访问路由到服务。在这个例子中,我们将通过域名访问应用程序,该应用程序已映射到 Kubernetes 中的 NodePort 30000。在宿主机器的 /etc/hosts 文件中,将域名指向 NodePort 30000。可以参考下面代码:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /example
            backend:
              serviceName: example-service
              servicePort: 80

第四步:测试

现在可以通过浏览器访问 http://example.com/example,应该可以看到该应用程序的页面。

总结

本文介绍了 Kubernetes 中使用 Ingress 实现服务暴露的详细过程,并提供了示例代码以帮助读者更好地了解 Ingress 的使用。使用 Ingress 可以更好地管理和控制流量,并为应用程序提供更稳定和更安全的服务,值得我们在实践中深入应用。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659f8f5fadd4f0e0ff821eb7


纠错反馈