K8S之Ingress-Nginx

K8S之Ingress-Nginx

Ingress诞生背景

我们都知道Service的表现形式为IP:Port,工作在TCP/IP层。对于基于HTTP的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟服务器,这些应用层的转发机制仅通过kubernetes的Service机制是无法实现的。

因此就有了Ingress将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制。

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP和HTTPS。可以提供负载均衡、SSL 和基于名称的虚拟托管

Pod和ingress的关系

  • 通过Service关联Pod
  • 基于域名访问
  • 通过Ingress controller实现Pod的负载
  • 支持TCP/UDP四层和HTTP七层

Ingress-Nginx工作原理

  • ingress controller,它是一个nginx控制器,通过和kubernetes api交互,动态的去感知集群中ingress规则变化,
  • 然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置,
  • 再写到nginx-ingress-controller的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,
  • 然后reload一下使配置生效。以此达到域名分别配置和动态更新的问题。
  • 访问的端口是不会发生改变,访问域名+端口的形式进行负载,不识别IP+port的形式访问
  • 默认对外暴露的端口是80和443

ingress-nginx会创建一个NodePort类型的service,暴露端口提供给外部访问。

通过ingress策略的改变(比如:增加一个域名解析,解析不同的集群内部的service),ingress controller会监听APIserver的变化,发生变化以后会在ingress controller(本质是一个在ingress-nginx空间下的pod)动态更新nginx的配置文件,增加nginx的域名解析条数。到达动态更新配置的目的。(一个ingress规则实例化对象就是一个域名)

Ingress-nginx的构成

Ingress-nginx由两部分组成:Ingress Controller 和 **Ingress **

  • Ingress 这个玩意,简单的理解就是 你原来要改 Nginx 配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yml 创建,每次不要去改 Nginx 了,直接改 yml 然后创建/更新就行了;那么问题来了:”Nginx 咋搞?”
  • Ingress Controller 这东西就是解决 “Nginx 咋搞” 的;Ingress Controoler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取他,按照他自己模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最后 reload 一下,工作流程如下图

K8S之Ingress-Nginx_第1张图片

在实际应用中,最新版本 Kubernetes 已经将 Nginx 与 Ingress Controller 合并为一个组件,所以 Nginx 无需单独部署,只需要部署 Ingress Controller 即可

Ingress-nginx作用

  • 动态配置服务
      如果按照传统方式, 当新增加一个服务时, 我们可能需要在流量入口加一个反向代理指向我们新的k8s服务. 而如果用了Ingress-nginx, 只需要配置好这个服务, 当服务启动时, 会自动注册到Ingress的中, 不需要而外的操作。
  • 减少不必要的端口映射
      配置过k8s的都清楚, 第一步是要关闭防火墙的, 主要原因是k8s的很多服务会以NodePort方式映射出去, 这样就相当于给宿主机打了很多孔, 既不安全也不优雅. 而Ingress可以避免这个问题, 除了Ingress自身服务可能需要映射出去, 其他服务都不要用NodePort方式

部署 Ingress-Nginx

1.下载Ingress-nginx

wget  https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.18.0/deploy/mandatory.yaml

2.创建 Ingress - Nginx

kubectl  apply -f mandatory.yaml  # 生成ingress-nginx的pod
kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-7995bd9c47-7vvfd   1/1     Running   0          5h5m

kubectl  apply -f service-nodeport.yaml  # 生成一个nodeport类型的service,提供给外部用户方式
kubectl get service -n ingress-nginx
NAME          TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)                      AGE
ingress-nginx NodePort   10.106.240.167  <none>       80:31839/TCP,443:30704/TCP   5h5m

3.测试

curl http://10.106.240.167 # ip来自上一步
# 如果返回404则表示安装成功

Ingress-nginx的代理方式

Ingress HTTP 代理访问

1.生成yaml文件

deployment、Service、Ingress Yaml 文件

vim ingress.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx-pod
    spec:
      containers:
        - name: nginx
          image: 10.0.0.136:9090/library/nginx:v1
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx-pod
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
    - host: www.js.com  # ingress-nginx解析的域名
      http:
        paths:
        - path: /  
          backend:
            serviceName: nginx-service
            servicePort: 80
2.生成ingress实例
kubectl apply -f ingress.yaml
3.查看
kubectl get ingress
NAME             HOSTS        ADDRESS   PORTS   AGE
nginx-ingress    www.js.com             80      4h44m    # 生成解析的域名
4.查看ingress生成的访问端口
kubectl get service -n ingress-nginx
NAME           TYPE      CLUSTER-IP      EXTERNAL-IP  PORT(S)                      AGE
ingress-nginx  NodePort  10.106.240.167         80:31839/TCP,443:30704/TCP   5h44m
5.在Windows的hosts文件添加解析
10.0.0.111 www.js.com
6.访问
http:www.js.com:31839

Ingress HTTPS 代理访问

1.创建证书,以及 cert 存储方式
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
kubectl create secret tls tls-secret --key tls.key --cert tls.crt
2.生成yaml文件

deployment、Service、Ingress Yaml 文件

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-test
spec:
  tls:
    - hosts:
      - hello.js.com
      secretName: tls-secret
  rules:
    - host: hello.js.com
      http:
        paths:
        - path: /
          backend:
             :serviceName nginx-service2  # 使用了之间创建的service实例
            servicePort: 80
3.生成ingress实例
kubectl apply -f hello.yaml
4.查看是否生成对应的域名
kubectl get ingress
NAME             HOSTS          ADDRESS   PORTS     AGE
nginx-test       hello.js.com             80, 443   9m17s
5.查看访问域名使用的端口
 kubectl get service -n ingress-nginx
NAME            TYPE      CLUSTER-IP     EXTERNAL-IP PORT(S)                      AGE
ingress-nginx   NodePort  10.106.240.167 <none>      80:31839/TCP,443:30704/TCP   5h20m  # 可以发现使用https访问的话使用的端口是30704,使用http访问的话是31839
6.访问测试(浏览器)
https://hello.js.com:30704  # 访问成功

Nginx 进行 BasicAuth

1.安装生成认证的命令
yum install -y httpd-tools
2.访问密码认证
htpasswd -c auth helloworld helloworld
New password:   # 输入密码
3.生成k8s的secret文件
kubectl create secret generic basic-auth --from-file=helloworld
4.生成yaml文件
vim auth.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: json
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'HelloWorld'
spec:
  rules:
  - host: json.js.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service
          servicePort: 80

Ingress-Nginx重定向

参数说明:

名称 描述
nginx.ingress.kubernetes.io/rewrite-target 必须重定向流量的目标URI
nginx.ingress.kubernetes.io/ssl-redirect 指示位置部分是否仅可访问SSL(当Ingress包含证书时默认为True) 布尔
nginx.ingress.kubernetes.io/force-ssl-redirect 即使Ingress未启用TLS,也强制重定向到HTTPS 布尔
nginx.ingress.kubernetes.io/app-root 定义Controller必须重定向的应用程序根,如果它在’/'上下文中
nginx.ingress.kubernetes.io/use-regex 指示Ingress上定义的路径是否使用正则表达式 布尔

重定向应用程序根

访问不一样的url,重定向不同的中断

vim rewrite.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/app-root:: /host/index.html  # 重定向到这个文件
  name: approot
  namespace: default
spec:
  rules:
  - host: www.js.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80
        path: /

流量重定向到目标URI

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-test
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: http://www.jn.com
spec:
  rules:
  - host: www.js.com
    http:
      paths:
      - backend:
          serviceName: service-1
          servicePort: 80
        path: /hello
      - backend:
          serviceName: service-2
          servicePort: 80
        path: /world

你可能感兴趣的:(kubernetes,kubernetes)