据我当下所学,对于 Kubernetes 如何对外暴露服务,一个字—**service**,只要是集群内部要访问 pod,通过创建 service,可以做到使用ip访问,那如果想要对互联网提供服务,应该怎么去做,也不能一直使用 IP 访问,而且对于集群来说也是不安全的。本文提到的 Ingress 就是为了弥补 NodePort 存在的不足而生。

Ingress

公开集群外部到集群内服务的 http 和 https 路由。流量路由由 Ingress 资源上定义的规则控制。

Ingress 主要实现集群内所有服务的入口,通过一系列的规则集合来允许外部的访问。可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。 而 ingress 的具体实现是由 ingress Controller 实现。

可以将 Ingress 理解为一个 nginx 应用,它的规则理解为nginx.conf中的server模块,可以指定访问哪些ip哪些域名的哪些端口,可以被转发到哪个service所关联的pod。

Ingress Controller

上述Ingress的功能都依赖与 Ingress Controller,Ingress Controller 才是负责具体转发的组件,外部对集群请求的流量会先到达 Ingress Controller,而 Ingress 就是为了给 Ingress Controller 添加规则,告诉它应该怎么转发,为集群提供全局的负载均衡的能力。

Ingress Controller 并不是Kubernetes自带的组件,用户可以选择不同的Ingress Controller来实现目的,在这里可以参考供使用的 Ingress Controller

部署Ingress Controller

这里以 Kubernetes 官方维护的 Ingress Controller —基于 nginx 的 Ingress Controller 为例

此方法为NodePort方式暴露Ingress的方法:无法访问 raw.githubsercontent 的同学,请点击这里

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.46.0/deploy/static/provider/baremetal/deploy.yaml

国内用户需要修改镜像地址

      containers:
        - name: controller
          image: acicn/ingress-nginx-controller:v0.46.0
          imagePullPolicy: IfNotPresent

还需要添加使用宿主机网络的参数:ingress-controller 将会使用宿主机网络的 80 和 443 端口。

      hostNetwork: true
      containers:
        - name: controller

部署安装

kubectl apply -f deploy.yaml 

查看安装

$ kubectl get pods -n ingress-nginx 
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-ptkwd        0/1     Completed   0          2m59s
ingress-nginx-admission-patch-zdqzp         0/1     Completed   0          2m59s
ingress-nginx-controller-76fc46c57b-t897c   0/1     Running     0          2m59s

验证使用 Ingress

如果集群中存在多台节点,要查看 ingress-controller 被调度到了哪个节点,就要将那个节点的 ip 做之后域名的解析

wget https://www.feiyiblog.com/files/practise/nginx.yaml

将我的示例部署后,可以访问 http://nodeip:30000

<html>
  <body>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <h1 style="text-align:center;color:#1E90FF">Welcome to FeiYi's&copy; Blog</h1>
  </body>
</html>

创建 Ingress

$ vim ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: nginx   # 我的示例所在namespace
spec:
  rules:
  - host: feiyi.yanjiang.chai
    http:
      paths:
      - path: /healhtz  # 我自己写的页面
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80

运行该规则

kubectl apply -f ingress.yaml

查看规则

$ kubectl get ingress -n nginx 
NAME           CLASS    HOSTS                 ADDRESS          PORTS   AGE
test-ingress   <none>   feiyi.yanjiang.chai   x.x.x.x   80      18s

一定要添加本地解析,任何访问验证

$ curl feiyi.yanjiang.chai/healthz/
<html>
  <body>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <h1 style="text-align:center;color:#1E90FF">Healthz Check</h1>
  </body>
</html>

TLS

再来测试一下使用 https 来访问

证书创建

# 生产私钥
openssl genrsa -out tls.key 2048
# 根据私钥生成tls证书,注意CN是域名的形式
openssl req -new -x509 -key tls.key -out tls.cert -days 360 -subj /CN=feiyi.yanjiang.chai
# 根据生成的key和cert创建secret
kubectl create secret tls -n nginx  nginx-tls --cert=tls.cert --key=tls.key

修改 Ingress 规则

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: nginx
spec:
# 添加以下4行即可
  tls:
    - hosts:
      - feiyi.yanjiang.chai
      secretName: nginx-tls
...

重新应用配置并访问验证

$ kubectl apply -f ingress.yaml
$ curl https://feiyi.yanjiang.chai/healthz/ --cacert ./tls/tls.cert  
<!-- --cacert ./tls/tls.cert 是刚才生成的https文件 -->
<html>
  <body>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <h1 style="text-align:center;color:#1E90FF">Healthz Check</h1>
  </body>
</html>

关于ingress规则的说明

如上例子中,我创建的规则中 path 字段只有 /healthz,该路径也必须是服务 pod 中真实存在的,所以使用域名访问时必须加 healthz 路径,否则会报错404,这是因为没有匹配其它路径的规则。如果 path 的值为 / ,则服务中网页根目录的所有子目录都可以访问。这是我摸索了一下午才搞明白的。

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0