6-1 Service对象&实现


  • 为什么需要Service

每个 Pod 都有自己的 IP 地址,但是在 Deployment 中,在同一时刻运行的 Pod 集合可能与稍后运行该应用程序的 Pod 集合不同。
这导致了一个问题:如果一组 Pod(称为“后端”)为群集内的其他 Pod(称为“前端”)提供功能,那么前端如何找出并跟踪要连接的IP地址,以便前端可以使用后端部分?

  • Service 定义

将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
使用Kubernetes 服务无需修改应用程序即可使用通用的服务发现机制。Kubernetes 为 Pods提供自己的 IP 地址,并为一组Pod提供相同的DNS名,并且可以在它们之间进行负载均衡。

  • 定义 Service

Service 在Kubernetes中是一个REST对象,和Pod类似。像所有的REST对象一样,Service 定义可以基于 POST 方式,请求 API server 创建新的实例。
例如,假定有一组 Pod,它们对外暴露了 9376 端口,同时还被打上 app=MyApp 标签。

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: my-service
  5. spec:
  6. selector:
  7. app: MyApp
  8. ports:
  9. - protocol: TCP
  10. port: 80
  11. targetPort: 9376

上述配置创建一个名称为“my-service”的Service 对象,它会将请求代理到使用 TCP 端口 9376,并且具有标签“app=MyApp”的 Pod 上。Kubernetes 为该服务分配一个 IP 地址(有时称为“集群IP”),该IP 地址由服务代理使用。

说明:需要注意的是,Service 能够将一个接收 port 映射到任意的 targetPort。 默认情况下,targetPort 将被设置为与 port 字段相同的值。

6-2 集群内部访问 Pod


在集群中暴露 Pod

创建一个 Nginx Pod,声明它具有一个容器端口80:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: my-nginx
  5. spec:
  6. selector:
  7. matchLabels:
  8. run: my-nginx
  9. replicas: 2
  10. template:
  11. metadata:
  12. labels:
  13. run: my-nginx
  14. spec:
  15. containers:
  16. - name: my-nginx
  17. image: nginx
  18. ports:
  19. - containerPort: 80

这使得可以从集群中任何一个节点来访问它。检查节点,该 Pod 正在运行:

  1. kubectl apply -f ./run-my-nginx.yaml
  2. kubectl get pods -l run=my-nginx -o wide
  1. NAME READY STATUS RESTARTS AGE IP NODE
  2. my-nginx-3800858182-jr4a2 1/1 Running 0 13s 10.244.3.4 kubernetes-minion-905m
  3. my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 kubernetes-minion-ljyd

检查 Pod 的 IP 地址:

  1. kubectl get pods -l run=my-nginx -o yaml | grep podIP
  2. podIP: 10.244.3.4
  3. podIP: 10.244.2.5

-l是指label。

此时能够通过 ssh 登录到集群中的任何一个节点上,使用 curl 也能调通所有 IP 地址。 需要注意的是,容器不会使用该节点上的 80 端口,也不会使用任何特定的 NAT 规则去路由流量到 Pod 上。 这意味着可以在同一个节点上运行多个 Pod,使用相同的容器端口,并且可以从集群中任何其他的 Pod 或节点上使用 IP 的方式访问到它们。

创建 Service

Kubernetes Service 从逻辑上定义了运行在集群中的一组 Pod,这些 Pod 提供了相同的功能。 当每个 Service 创建时,会被分配一个唯一的 IP 地址(也称为 clusterIP)。 这个 IP 地址与一个 Service 的生命周期绑定在一起,当 Service 存在的时候它也不会改变。 可以配置 Pod 使它与 Service 进行通信,Pod 知道与 Service 通信将被自动地负载均衡到该 Service 中的某些 Pod 上。

可以使用 kubectl expose 命令为 2个 Nginx 副本创建一个 Service:

  1. kubectl expose deployment/my-nginx
  2. service/my-nginx exposed

这等价于使用 kubectl create -f 命令创建,对应如下的 yaml 文件:
nginx-svc.yaml

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: my-nginx
  5. labels:
  6. run: my-nginx
  7. spec:
  8. ports:
  9. - port: 80
  10. protocol: TCP
  11. selector:
  12. run: my-nginx

上述规约将创建一个 Service,对应具有标签 run: my-nginx 的 Pod,目标 TCP 端口 80, 并且在一个抽象的 Service 端口(targetPort:容器接收流量的端口;port:抽象的 Service 端口,可以使任何其它 Pod 访问该 Service 的端口)上暴露。 查看你的 Service 资源:

  1. kubectl get svc my-nginx
  1. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  2. my-nginx ClusterIP 10.0.162.149 <none> 80/TCP 21s

正如前面所提到的,一个 Service 由一组 backend Pod 组成。这些 Pod 通过 endpoints 暴露出来。 Service Selector 将持续观察,结果被 POST 到一个名称为 my-nginx 的 Endpoint 对象上。 当 Pod 终止后,它会自动从 Endpoint 中移除,新的能够匹配上 Service Selector 的 Pod 将自动地被添加到 Endpoint 中。 检查该 Endpoint,注意到 IP 地址与在第一步创建的 Pod 是相同的。

  1. kubectl describe svc my-nginx
  1. Name: my-nginx
  2. Namespace: default
  3. Labels: run=my-nginx
  4. Annotations: <none>
  5. Selector: run=my-nginx
  6. Type: ClusterIP
  7. IP: 10.0.162.149
  8. Port: <unset> 80/TCP
  9. Endpoints: 10.244.2.5:80,10.244.3.4:80
  10. Session Affinity: None
  11. Events: <none>
  1. kubectl get ep my-nginx
  1. NAME ENDPOINTS AGE
  2. my-nginx 10.244.2.5:80,10.244.3.4:80 1m

现在,能够从集群中任意节点上使用 curl 命令请求 Nginx Service <CLUSTER-IP>:<PORT> 。 注意 Service IP 完全是虚拟的,它从来没有走过网络。

访问 Service

Kubernetes支持两种查找服务的主要模式: 环境变量和DNS。 前者开箱即用,而后者则需要CoreDNS

环境变量

当 Pod 在 Node 上运行时,kubelet 会为每个活跃的 Service 添加一组环境变量。 这会有一个顺序的问题。想了解为何,检查正在运行的 Nginx Pod 的环境变量(Pod 名称将不会相同):

  1. kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
  1. KUBERNETES_SERVICE_HOST=10.0.0.1
  2. KUBERNETES_SERVICE_PORT=443
  3. KUBERNETES_SERVICE_PORT_HTTPS=443

6-3 集群内Pod 通信机制


Kubernetes 支持两种基本的服务发现模式 — 环境变量和DNS。

  • 环境变量

当Pod 运行在Node 上,kubelet 会为每个活跃的Service添加一组环境变量。 它同时支持Docker links 、 简单的 {SVCNAME}_SERVICE_HOST{SVCNAME}_SERVICE_PORT 变量。这里Service的名称需大写,横线被转换成下划线。
举个例子,一个名称为“my-nginx”的Service 暴露了 TCP 端口 80,同时给它分配了 Cluster IP 地址 10.1.180.155,这个 Service 生成了如下环境变量:

  1. MY_NGINX_PORT_80_TCP_PORT=80
  2. MY_NGINX_PORT_80_TCP_PROTO=tcp
  3. MY_NGINX_PORT_80_TCP_ADDR=10.1.180.155

说明:当您具有需要访问服务的Pod时,并且您正在使用环境变量方法将端口和群集 IP 发布到客户端Pod 时,必须在客户端 Pod 出现之前创建服务。 否则,这些客户端 Pod 将不会设定其环境变量。

  • DNS

可以使用附加组件 为 Kubernetes 集群设置 DNS 服务。
支持群集的 DNS 服务器(例如CoreDNS)监视 Kubernetes API 中的新服务,并为每个服务创建一组DNS 记录。 如果在整个群集中都启用了DNS,则所有 Pod 都应该能够通过其 DNS 名称自动解析服务。
例如,如果在Kubernetes 命名空间“my-ns”中有一个名为“my-service”的服务,则控制节点和DNS服务共同为“my-service.my-ns”创建 DNS 记录。“my-ns”命名空间中的 Pod 应该能够通过简单地对 my-service 进行名称查找来找到它(“my-serwice.my-ns”也可以)。
其他命名空间中的Pod必须将名称限定为 my-service.my-ns。这些名称将解析为为服务分配的群集 IP。

6-4 实践Service创建DNS记录

Kubernetes DNS 在群集上调度 DNS Pod 和服务,并配置 kubelet 以告知各个容器使用 DNS 服务的 IP来解析 DNS 名称。


服务

  • A/AAAA 记录

“普通”服务会以 my-svc.my-namespace.svc.cluster-domain.example 这种名字的形式被分配一个
DNS A 或AAAA记录,取决于服务的 IP 协议族。 该名称会解析成对应服务的集群 IP。

  • Pods A/AAAA 记录

经由 Deployment或者DaemonSet 所创建的所有 Pods 都会有如下 DNS 解析项与之对应:

  1. pod-ip-address.deployment-name.my-namespace.svc.cluster-domain.example.
  • Pod 的 hostname 和 subdomain 字段

当前,创建 Pod 时其主机名取自 Pod 的 metadata.name值。

Pod 规约中包含一个可选的 hostname 字段,可以用来指定 Pod 的主机名。当这个字段被设置时,它将优先于 Pod的名字成为该 Pod的主机名。举个例子,给定一个hostname设置为“my-host”的Pod,该 Pod 的主机名将被设置为“my-host”。

Pod 规约还有一个可选的 subdomain 字段,可以用来指定 Pod 的子域名。 举个例子,某 Pod 的hostname 设置为“foo”,subdomain 设置为“bar”,在名字空间“my-namespace”中对应的完全限定域名为“foo.bar.my-namespace.svc.cluster-domain.example”。

示例:

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: default-subdomain
  5. spec:
  6. selector:
  7. name: busybox
  8. clusterIP: None
  9. ports:
  10. - name: foo # 实际上不需要指定端口号
  11. port: 80
  12. targetPort: 80
  13. ---
  14. apiVersion: v1
  15. kind: Pod
  16. metadata:
  17. name: busybox1
  18. labels:
  19. app: busybox
  20. spec:
  21. hostname: busybox1
  22. subdomain: default-subdomain
  23. containers:
  24. - name: busyb ox
  25. image: busybox:1.28
  26. command: ["sh","-c","sleep 1h"]
  27. resources:
  28. limits:
  29. memory: "128Mi"
  30. ports:
  31. - containerPort: 80
  32. ---
  33. apiVersion: v1
  34. kind: Pod
  35. metadata:
  36. name: busybox2
  37. labels:
  38. app: busybox
  39. spec:
  40. hostname: busybox2
  41. subdomain: default-subdomain
  42. containers:
  43. - name: myapp
  44. image: busybox:1.28
  45. command: ["sh","-c","sleep 1h"]
  46. resources:
  47. limits:
  48. memory: "128Mi"
  49. cpu: "500m"
  50. ports:
  51. - containerPort: 80

Pod 将 看 到 自 己 的 域 名 为 “busybox-1.default-subdomain.my-namespace.svc.cluster-domain.example“。DNS 会为此名字提供一个A 记录或 AAAA 记录,指向该 Pod 的 IP。“busybox1”和“busybox2”这两个 Pod 分别具有它们自己的 A 或 AAAA 记录。

6-5从集群外部访问Service


从集群外部访问Service的方法

1. ClusterIP:

仅仅使用一个集群内部的IP地址-这是默认值。选择这个值意味着你只想这个服务集群内部才可以被访问到

2. NodePort:

在集群内部IP的基础上,在集群的每一个节点的端口上开放这个服务。你可以在任意:NodePort地址上访问到这个服务。

3. LoadBalancer:

在使用一个集群内部IP地址和在NodePort上开放一个服务之外,向云提供商申请一个负载均衡器,会让流量转发到这个在每个节点上以:NodePort的形式开放的服务上。
在使用一个集群内部IP地址和在NodePort上开放一个Service的基础上,还可以向云提供者申请一个负载均衡器,将流量转发到已经以NodePort形式开发的Service上。

实战从集群外部访问Service

  • 创建 Nginx pod

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. name: nginx
    5. spec:
    6. selector:
    7. matchLabels:
    8. app: nginx
    9. template:
    10. metadata:
    11. labels:
    12. app: nginx
    13. spec:
    14. containers:
    15. - name: nginx
    16. image: registry.cn-beijing.aliyuncs.com/qingfeng666/nginx
    17. resources:
    18. limits:
    19. memory: "128Mi"
    20. cpu: "500m"
    21. ports:
    22. - containerPort: 80
  • 创建NodePort类型的Service

    1. apiVersion: v1
    2. kind: Service
    3. metadata:
    4. labels:
    5. app: nginx
    6. name: nginx-deployment
    7. spec:
    8. selector:
    9. app: nginx
    10. ports:
    11. - port: 80
    12. name: nginx-service80
    13. protocol: TCP
    14. targetPort: 80
    15. nodePort: 30001
    16. selector:
    17. app: nginx
    18. type: NodePort

6-6 Ingress介绍


Ingress

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是HTTP。
Ingress 公开了从集群外部到集群内服务的HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
下面是一个将所有流量都发送到同一Service的简单Ingress示例:
image.png

可以将Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。 Ingress控制器通常负责通过负载均衡器来实现 Ingress。


环境准备

必须具有Ingress 控制器才能满足 Ingress 的要求。 仅创建 Ingress 资源本身没有任何效果。需要部署Ingress控制器,例如 ingress-nginx。


Ingress资源

一个最小的Ingress 资源示例:minimal-ingress.yaml

  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress
  3. metadata:
  4. name: minimal-ingress
  5. annotations:
  6. nginx.ingress.kubernetes.io/rewrite-target: /
  7. spec:
  8. rules:
  9. - http:
  10. paths:
  11. - path: /testpath
  12. pathType: Prefix
  13. backend:
  14. service:
  15. name: test
  16. port:
  17. number: 8080

Ingress资源仅支持用于转发HTTP 流量的规则。

Ingress 规则

每个HTTP 规则都包含以下信息:

  1. 可选的host。在此示例中,未指定 host,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 通信。如果提供了 host(例如 foo.bar.com),则rules 适用于该 host。
  2. 路径列表 paths(例如,/testpath),每个路径都有一个由serviceName和servicePort定义的关联后端。在负载均衡器将流量定向到引用的服务之前,主机和路径都必须匹配传入请求的内容。
  3. backend(后端)是Service文档中所述的服务和端口名称的组合。 与规则的 host 和 path 匹配的对Ingress的HTTP(和HTTPS)请求将发送到列出的 backend。

安装 Nginx Ingress 控制器


Ingress控制器

为了让Ingress 资源工作,集群必须有一个正在运行的Ingress控制器。
与其他类型的控制器不同,Ingress 控制器不是随集群自动启动的。

进行安装

  • 使用NodePort安装
    1. kubectl create -f ingress-nginx-controller.yaml
    ingress-nginx-controller.yaml文件 ```yaml apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx

kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx


kind: ConfigMap apiVersion: v1 metadata: name: tcp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx


kind: ConfigMap apiVersion: v1 metadata: name: udp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx


apiVersion: v1 kind: ServiceAccount metadata: 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/v1 kind: ClusterRole metadata: name: nginx-ingress-clusterrole labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules:

  • 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/v1 kind: Role metadata: name: nginx-ingress-role namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules:

  • 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/v1 kind: RoleBinding metadata: name: nginx-ingress-role-nisa-binding namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: nginx-ingress-role subjects:

  • kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: nginx-ingress-clusterrole-nisa-binding labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nginx-ingress-clusterrole subjects:

  • kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx

kind: Service apiVersion: v1 metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: clusterIP: 10.1.211.240 externalTrafficPolicy: Cluster ports:

  • name: http nodePort: 31686 port: 80 protocol: TCP targetPort: http
  • name: https nodePort: 30036 port: 443 protocol: TCP targetPort: https selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx sessionAffinity: None type: NodePort

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: 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:

  1. # wait up to five minutes for the drain of connections
  2. terminationGracePeriodSeconds: 300
  3. serviceAccountName: nginx-ingress-serviceaccount
  4. containers:
  5. - name: nginx-ingress-controller
  6. image: registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.26.1
  7. args:
  8. - /nginx-ingress-controller
  9. - --configmap=$(POD_NAMESPACE)/nginx-configuration
  10. - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
  11. - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
  12. - --publish-service=$(POD_NAMESPACE)/ingress-nginx
  13. - --annotations-prefix=nginx.ingress.kubernetes.io
  14. securityContext:
  15. allowPrivilegeEscalation: true
  16. capabilities:
  17. drop:
  18. - ALL
  19. add:
  20. - NET_BIND_SERVICE
  21. # www-data -> 33
  22. runAsUser: 33
  23. env:
  24. - name: POD_NAME
  25. valueFrom:
  26. fieldRef:
  27. fieldPath: metadata.name
  28. - name: POD_NAMESPACE
  29. valueFrom:
  30. fieldRef:
  31. fieldPath: metadata.namespace
  32. ports:
  33. - name: http
  34. containerPort: 80
  35. - name: https
  36. containerPort: 443
  37. livenessProbe:
  38. failureThreshold: 3
  39. httpGet:
  40. path: /healthz
  41. port: 10254
  42. scheme: HTTP
  43. initialDelaySeconds: 10
  44. periodSeconds: 10
  45. successThreshold: 1
  46. timeoutSeconds: 10
  47. readinessProbe:
  48. failureThreshold: 3
  49. httpGet:
  50. path: /healthz
  51. port: 10254
  52. scheme: HTTP
  53. periodSeconds: 10
  54. successThreshold: 1
  55. timeoutSeconds: 10
  56. lifecycle:
  57. preStop:
  58. exec:
  59. command:
  60. - /wait-shutdown

  1. - 查看部署状态
  2. ```bash
  3. kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --watch
  • 检查部署版本 ```bash POD_NAMESPACE=ingress-nginx POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app.kubernetes.io/name=ingress-nginx)

kubectl exec -it $POD_NAME -n $POD_NAMESPACE — /nginx-ingress-controller —verison

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2791505/1645251834471-dab84321-c346-4859-aa00-58b0bd8b7263.png#clientId=ue4945f8e-96bf-4&from=paste&height=208&id=u28275725&margin=%5Bobject%20Object%5D&name=image.png&originHeight=416&originWidth=2052&originalType=binary&ratio=1&size=427539&status=done&style=none&taskId=ue079cd2a-99ee-41a3-aaa2-e200a5e40f2&width=1026)
  2. - 现在执行
  3. ```bash
  4. kubectl get all -n ingress-nginx

image.png

6-7 Nginx Ingress 控制器实战


部署一个Hello World应用

  1. 使用下面的命令创建一个Deployment:

    1. kubectl create deployment web --image=registry.cn-beijing.aliyuncs.com/qingfeng666/hello-app:1.0

    输出:

    1. deployment.apps/web created

    查看运行pod所在节点地址:

    1. [root@node1 ~]# kubectl get po -owide
    2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
    3. web-5978f64c6-v4fl5 1/1 Running 0 95s 10.244.1.16 node1 <none> <none>
  2. 将 Deployment 暴露出来:

    1. kubectl expose deployment web --type=NodePort --port=8080

    输出:

    1. service/web exposed
  3. 验证 Service 已经创建,并且可能从节点端口访问:

    1. kubectl get service web

    输出:

    1. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    2. web NodePort 10.1.83.203 <none> 8080:30704/TCP 60s
  4. 使用节点端口信息访问服务:

    1. curl node1:30704

    输出:

    1. Hello, world!
    2. Version: 1.0.0
    3. Hostname: web-5978f64c6-v4fl5

创建一个 Ingress 资源

创建之前需要先创建 Ingress Nginx Controller!

下面是一个Ingress 资源的配置文件,负责通过 hello-world.info 将服务请求 转发到你的服务。

  1. 根据下面的 YAML 创建文件 example-ingress.yaml :

    1. apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4. name: example-ingress
    5. annotations:
    6. nginx.ingress.kubernetes.io/rewrite-target: /
    7. spec:
    8. rules:
    9. - host: hello-world.info
    10. http:
    11. paths:
    12. - path: /
    13. pathType: Prefix
    14. backend:
    15. service:
    16. name: web
    17. port:
    18. number: 8080
  2. 通过运行下面的命令创建 Ingress 资源:

    1. kubectl apply -f example-ingress.yaml

    输出:

    1. ingress.networking.k8s.io/example-ingress created
  3. 验证IP地址已经被设置:

    1. kubectl get ingress

    说明:此操作可能需要几分钟。

    输出:

    1. NAME CLASS HOSTS ADDRESS PORTS AGE
    2. example-ingress <none> hello-world.info 10.1.211.240 80 31s
  4. /etc/hosts文件末尾添加以下内容(IP为Ingress的IP):

    1. 10.1.211.240 hello-world.info
  5. 验证 Ingress 控制器能够转发请求流量:

    1. curl hello-world.info

    输出:

    1. Hello, world!
    2. Version: 1.0.0
    3. Hostname: web-5978f64c6-v4fl5