Kubernetes服务访问Ingress

264 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

Kubernetes服务访问之Ingress

对于Kubernetes的Service,无论是Cluster-Ip和NodePort均是四层的负载,集群内的服务如何实现七层的负载均衡,这就需要借助于Ingress,Ingress控制器的实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,我们以nginx的实现为例做演示。

Ingress-nginx是7层的负载均衡器 ,负责统一管理外部对k8s cluster中service的请求。主要包含:

  • ingress-nginx-controller:根据用户编写的ingress规则(创建的ingress的yaml文件),动态的去更改nginx服务的配置文件,并且reload重载使其生效(是自动化的,通过lua脚本来实现);
  • ingress资源对象:将Nginx的配置抽象成一个Ingress对象,每添加一个新的Service资源对象只需写一个新的Ingress规则的yaml文件即可(或修改已存在的ingress规则的yaml文件)
示意图:

image.png

实现逻辑

1)ingress controller通过和kubernetes api交互,动态的去感知集群中ingress规则变化

2)然后读取ingress规则(规则就是写明了哪个域名对应哪个service),按照自定义的规则,生成一段nginx配置

3)再写到nginx-ingress-controller的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器把生成的nginx配置写入/etc/nginx.conf文件中

4)然后reload一下使配置生效。以此达到域名分别配置和动态更新的问题。

安装

官方文档

$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
## 或者使用myblog/deployment/ingress/mandatory.yaml
## 修改部署节点
$ grep -n5 nodeSelector mandatory.yaml
    spec:
      hostNetwork: true #添加为host模式
      # wait up to five minutes for the drain of connections
      terminationGracePeriodSeconds: 300
      serviceAccountName: nginx-ingress-serviceaccount
      nodeSelector:
        ingress: "true"     #替换此处,来决定将ingress部署在哪些机器
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
          args:

使用示例:myblog/deployment/ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myblog
  namespace: demo
spec:
  rules:
  - host: myblog.devops.cn
    http:
      paths:
      - path: /
        backend:
          serviceName: myblog
          servicePort: 80

ingress-nginx动态生成upstream配置:

                server_name myblog.devops.cn ;
​
                listen 80  ;
                listen [::]:80  ;
                listen 443  ssl http2 ;
                listen [::]:443  ssl http2 ;
​
                set $proxy_upstream_name "-";
​
                ssl_certificate_by_lua_block {
                        certificate.call()
                }
​
                location / {
​
                        set $namespace      "demo";
                        set $ingress_name   "myblog";
访问

域名解析服务,将 myblog.devops.cn解析到ingress的地址上。ingress是支持多副本的,高可用的情况下,生产的配置是使用lb服务(内网F5设备,公网elb、slb、clb,解析到各ingress的机器,如何域名指向lb地址)

本机,添加如下hosts记录来演示效果。

192.168.136.128 myblog.devops.cn

HTTPS访问:

#自签名证书
$ openssl req -x509 -nodes -days 2920 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=*.devops.cn/O=ingress-nginx"# 证书信息保存到secret对象中,ingress-nginx会读取secret对象解析出证书加载到nginx配置中
$ kubectl -n demo create secret tls https-secret --key tls.key --cert tls.crt
secret/https-secret created

修改yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myblog-tls
  namespace: demo
spec:
  rules:
  - host: myblog.devops.cn
    http:
      paths:
      - path: /
        backend:
          serviceName: myblog
          servicePort: 80
  tls:
  - hosts:
    - myblog.devops.cn
    secretName: https-secret

然后,访问 myblog.devops.cn/blog/index/