Kubernetes之Ingress

概述

向外网暴露集群内服务,以使客户端能够访问,有以下几种方法,本文重点描述Ingress。

LoadBalancer

LoadBalancer一般由云服务供应商提供或者用户自定义,运行在集群之外。在创建service时为其配置LoadBalancer相关参数,当从外网访问集群内servcie时,用户直接连接到LoadBalancer服务器,LoadBalancer服务器再将流量转发到集群内service。Loadbalancer配置及使用方法与各云服务供应商有关,本文不详细描述。

NodePort

这种方式要求集群中部分节点有被外网访问的能力。Kubernetes为每个NodePort类型的服务在集群中的每个节点上分配至少一个主机网络端口号。客户通过能被外网访问的节点IP加上节点端口的方式访问服务。大多数情况下不会通过这种方式向集群外暴露服务,原因有四。

  • 其一:大多情况下,为了安全起见,集群中的节点位于完全内网环境中,不应该有被外网直接访问的能力。一般外网访问集群中的节点都是通过边界服务器如网关、跳板等,而这种边界服务器需要通过各种方式进行安全加固。
  • 其二:如果集群内节点可以从外网直接访问的话,则会将集群内节点地址、服务名称、端口号等信息直接暴露在外,非常不安全。
  • 其三:服务端口号一般由系统自动分配,并非固定,而服务名称也可能发生变更,此时外部客户端需要跟踪变更并修改,属于重试耦合。
  • 其四:这种方式,每个服务至少向外网暴露一个端口号,当服务很多时不易于管理。

Ingress

Ingress不是某种产品、组件的名称,它应该是kubernetes向集群外暴露服务的一种思路、技术,用户完全可以根据这种思路提供自己的Ingress实现,当然kubernetes提供了默认Ingress实现还有其它第三方实现,一般无需自己开发。它的思路是这样的,首先在集群内运行一个服务或者pod也可以是容器,不管是什么它至少应该有一个外网可以访问的IP,至少向外网开放一个端口号,让它充当反向代理服务器。当外网想要访问集群内service时,只需访问这个反向代理服务器并指定相关参数,代理服务器根据请求参数并结合内部规则,将请求转发到service。这种思路与LoadBalancer的不同之处是它就位于集群内,而LoadBalancer位于集群外。与NodePort的不同之处是集群只向外暴露一个服务或者pod等,而NodePort是暴露全部service。

Kubernetes用nginx实现反向代理服务器,称为Ingress Controller,是pod类型资源。同时提供了Ingress类型对象,通过创建Ingress对象配置nginx反向代理服务器的转发规则。Nginx反向代理服务器收到来自外网的请求后,用请求的URL地址、请求头字段区别不同service,然后转发请求。

部署Ingress Controller

在Kubernetes中,Ingress Controller典型是pod类型资源,其部署方式与普通pod相同,通过Deployment、DaemonSet等副本控制器部署,其中更值推荐的是DaemonSet方式。Ingress Controller需要部署在具备连通外网能力的节点上,首先在目标节点打上Ingress Controller专用标签,然后在DaemonSet的配置文件中配置节点选择器选中此类标签,控制pod实例可以部署的节点,通过为节点增减相关标签控制Ingress Controller的pod实例个数。Ingress Controller一般占用两个节点主机端口,http用80,https用443。详细参考:https://git.k8s.io/ingress-nginx/README.md。外网通过http://节点外网ip:80/...或者https://节点外网ip:80/...就可以访问内部服务了,当前首先需要创建Ingress对象配置访问策略。

创建Ingress对象

本节通过创建各种Ingress对象,展示Ingress的各种典型用法。

Single Service Ingress

配置文件:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  backend:
    serviceName: testsvc
    servicePort: 80

创建对象:

$ kubectl get ing
NAME                RULE          BACKEND        ADDRESS
test-ingress        -             testsvc:80     107.178.254.228

以上配置中没有具体的rule,所以诸如http(s)://107.178.254.228/xxx之类的请求都转发到testsvc的80端口。

其于URL转发

假如打算实现如下目标:

foo.bar.com -> 178.91.123.132 -> / foo    s1:80
                                 / bar    s2:80

其中foo.bar.com是http请求体头部中的host字段,178.91.123.132是Ingress Controller外网地址,当请求路径与/foo匹配时转发到s1服务的80端口,当与/bar匹配时转发到s2服务的80端口,其最核心逻辑是用URL区分不同服务。

配置如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: s1
          servicePort: 80
      - path: /bar
        backend:
          serviceName: s2
          servicePort: 80

创建对象:

$ kubectl get ing
NAME      RULE          BACKEND   ADDRESS
test      -
          foo.bar.com
          /foo          s1:80
          /bar          s2:80

 基于名称的虚拟主机

实现如下目标:

foo.bar.com --|                 |-> foo.bar.com s1:80
              | 178.91.123.132  |
bar.foo.com --|                 |-> bar.foo.com s2:8

这种方式的核心逻辑是用http请求中的host字段区分不同服务,而不是URL。如host: foo.bar.com的请求被转发到s1服务80端口,如host: bar.foo.com的请求被转发到s2服务80端口。

配置:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: s1
          servicePort: 80
  - host: bar.foo.com
    http:
      paths:
      - backend:
          serviceName: s2
          servicePort: 80

TLS 

利用Secret类型对象为Ingress Controller提供私钥及证书,对通信链路加密。

Secret配置:

apiVersion: v1
data:
  tls.crt: base64 encoded cert
  tls.key: base64 encoded key
kind: Secret
metadata:
  name: testsecret
  namespace: default
type: Secret

在Ingress对象中引用:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: no-rules-map
spec:
  tls:
  - secretName: testsecret
  backend:
    serviceName: s1
    servicePort: 80

 更新Ingress对象

使用kubectl edit命令编辑Ingress实时对象:

$ kubectl get ing
NAME      RULE          BACKEND   ADDRESS
test      -                       178.91.123.132
          foo.bar.com
          /foo          s1:80
$ kubectl edit ing test

 在弹出的编辑器中修改:

spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: s1
          servicePort: 80
        path: /foo
  - host: bar.baz.com
    http:
      paths:
      - backend:
          serviceName: s2
          servicePort: 80
        path: /foo
..

保存关稍后确认更新:

$ kubectl get ing
NAME      RULE          BACKEND   ADDRESS
test      -                       178.91.123.132
          foo.bar.com
          /foo          s1:80
          bar.baz.com
          /foo          s2:80

 参考:

$ kubectl get ing
NAME      RULE          BACKEND   ADDRESS
test      -                       178.91.123.132
          foo.bar.com
          /foo          s1:80
          bar.baz.com
          /foo          s2:80
### 部署 IngressKubernetes 中 #### 准备工作 为了使 Nginx Ingress Controller 正常运行,在集群中安装该控制器是必要的。这可以通过应用官方提供的配置文件来完成: ```bash kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.2/deploy/static/provider/cloud/deploy.yaml ``` 上述命令会部署最新的稳定版本的 Nginx Ingress Controller[^1]。 #### 创建 TLS Secret 对于 HTTPS 支持来说,创建一个包含 SSL 证书和私钥的秘密资源 (Secret) 是必需的操作。通过 `kubectl create` 命令可以轻松实现这一点: ```bash kubectl create secret tls kube-dasboard-ssl --cert=path/to/tls.crt --key=path/to/tls.key -n ingress-nginx ``` 这条指令将会在一个命名空间内创建名为 `kube-dasboard-ssl` 的秘密资源,用于存储指定路径下的证书文件和密钥文件[^4]。 #### 定义 Ingress 资源 定义并应用 Ingress YAML 文件能够设置访问服务的具体规则。下面是一个针对 kubernetes-dashboard 设置 Ingress 的例子: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-kube-dashboard namespace: default annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" spec: tls: - hosts: - dashboard.kube.com secretName: kube-dasboard-ssl rules: - host: dashboard.kube.com http: paths: - pathType: Prefix path: "/" backend: service: name: kubernetes-dashboard port: number: 443 ``` 此配置指定了域名 `dashboard.kube.com` 将被映射到名称为 `kubernetes-dashboard` 的 Service 上,并启用了TLS终止功能以提供安全连接[^2]。 #### 查看日志 如果遇到任何问题或想要验证配置是否生效,可以查看 Ingress 控制器 Pod 的实时日志来进行调试: ```bash kubectl logs -f $(kubectl get pods -l app.kubernetes.io/name=ingress-nginx -o jsonpath='{.items[0].metadata.name}') -n ingress-nginx ``` 这段脚本将获取正在运行的第一个匹配标签的选择器所对应的Pod的名字,并打印其最新日志输出[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值