Ingress介绍

在K8S集群中,Service和Pod的IP和端口只能在集群内部网络中路由,而对集群外部是不可见的。为了让外部应用可以直接访问集群内部的服务,则需要暴露服务,K8S目前提供了三种暴露服务的方式:LoadBlancer、NodePort、Ingress。本文主要记录了Ingress的部署和使用。

简单得说,Ingress是允许入站连接到达集群服务的规则集合。它扮演者边缘路由器得角色,可以为外部提供可访问服务的URL、流量负载均衡、可被终止的ssl连接、以及基于配置的虚拟主机。Ingress由Ingress Controller和Ingress Service两部分组成。

  • Ingress Controller

​ 负责将新加入的Ingress转化为Nginx的配置文件并使得其生效。

  • Ingress 服务

​ 将Nginx的配置抽象成一个Ingress对象。

部署Ingress

1、准备部署文件

  • 下载部署文件

截至本文编写时,ingress-nginx项目最新主分支对应版本为0.23.0。

最新版本地址:https://github.com/kubernetes/ingress-nginx/tree/master/deploy

指定版本号下载:https://github.com/kubernetes/ingress-nginx/tree/nginx-0.23.0/deploy

  • 部署文件介绍

① namespace.yaml

​ 创建独立的命名空间 ingress-nginx

② configmap.yaml

③ rbac.yaml

​ 负责Ingress的RBAC授权的控制,其创建了Ingress用到的ServiceAccount、ClusterRole、Role、RoleBinding、ClusterRoleBinding

④ with-rbac.yaml

​ 使用带rbac的方式创建ingress-controller,是整个ingress的核心部署文件。

​​‌‌​​​‌‌​‌​​‌‌‍​‌​‌‌‌​​‌‌‌‌​‌​‍​‌​​‌​​​‌​​​‌‌​‍​‌​‌‌​​​‌‌​​​​​‍​​‌​‌‌‌‌‌‌‌‌​​​‍​‌‌​​‌‌‌​‌‌​​‌‌‌‍​‌‌​​​‌‌‌​​​‌​‌‍​​‌‌‌‌‌‌‌‌​​‌‌‍‌​‌‌​‌​​‍‌‌​​​‌‌‌‍‌​‌​‌‌​​‍​‌​​‌​​​‌‌​​​​‌‍​‌‌‌​​‌​​​​​‌​‌​‍​​​​​​​​‌‌‌​​‌​‌‍‌​‌‌​‌‌​‍‌​​‌​​​‌‍‌​​‌‌​​​‍‌​​​‌‌​‌‍‌​​‌‌​‌​‍‌​​​‌‌​​‍‌​​​‌‌​​‍​​​‌​​‌​‌‌‌‌​‌‌‍​‌‌​‌‌‌‌​​​‌​‌‌‌‍​​​​​​​‌​​​‌‌​‌‍​‌‌​​​​‌​​​​​​​‍​​​‌​‌​‌‌​‌​‌‌‌‍​​‌‌‌‌‌‌‌‌​​‌​‍​​​​​​​​‌‌‌‌​​‌‌‍​​​‌​‌​‌‌​​‌‌‌​‍‌​​‌‌‌‌​‍‌​​‌‌​‌‌‍‌​​‌​​‌​‍‌​​‌​‌‌​‍‌​​‌​​​‌‍​‌‌​​​‌​‌‌‌​​​‌‍‌‌​​‌‌​‌‍‌‌​​‌‌‌‌‍‌‌​​‌‌‌​‍‌‌​​​‌‌​‍‌‌​‌​​‌​‍‌‌​​‌‌‌‌‍‌‌​​‌‌​​‍‌‌​‌​​‌​‍‌‌​​‌‌‌‌‍‌‌​​‌​‌‌‍​‌​‌‌​‌‌‌‌​​‌​​‍​‌‌​​​​‌​‌​​​‌‌‍​​​​​​​​‌‌‌‌​​‌‌‍​‌​‌‌​​​‌‌​​​​​‍​​‌‌​‌​​‌‌‌‌​​​‍​‌​‌​​​‌‌​​‌‌‌‌‍​‌​‌​​​‌​‌‌‌‌‌‌‍​​​​​​​​‌‌‌​​‌​‌‍‌​​‌​‌‌‌‍‌​​​‌​‌‌‍‌​​​‌​‌‌‍‌​​​‌‌‌‌‍‌‌​​​‌​‌‍‌​‌​​​‌‌‍‌​‌​​​‌‌‍‌​​​‌​​​‍‌​​​‌​​​‍‌​​​‌​​​‍‌‌​‌​​​‌‍‌​​‌​‌‌​‍‌​​‌​‌​​‍‌​​‌​‌‌​‍‌​​​‌​​​‍‌​​‌​‌‌​‍‌‌​‌​​​‌‍‌​​‌​​‌​‍‌​​‌‌​‌​‍‌​‌​​​‌‌‍‌​​‌‌‌‌​‍‌​​​‌‌​‌‍‌​​‌‌‌​​‍‌​​‌​‌‌‌‍‌​​‌​‌‌​‍‌​​​‌​​‌‍‌​​‌‌​‌​‍‌​​​‌‌​​‍‌​‌​​​‌‌‍‌‌​​‌​​‌‍‌‌​​‌‌​‌‍‌‌​​‌‌​‌‍‌‌​‌​​​‌‍‌​​‌​‌‌‌‍‌​​​‌​‌‌‍‌​​‌​​‌​‍‌​​‌​​‌‌

⑤ mandatory.yaml

 该文件整合了前面四项文件的内容,是用于实际部署ingress服务的yaml文件。即只需要使用该文件就可以完成ingress-controller的全部部署工作。

2、部署Ingress

  • 下载实际所需的yaml文件
# 部署ingress-controller
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

# 对外部提供服务所需
wget  https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
  • 修改mandatory.yaml,替换镜像地址

部署文件中默认镜像地址为:
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.23.0

修改为:

registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.23.0

修改文件中部署方式的部分,将默认的Deployment修改为Daemonset,去掉replicas字段:

...省略部分...
apiVersion: apps/v1
kind: DaemonSet  # 这里默认为Deployment,修改为Daemonset
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  # 删除这行
...省略部分...
  • 修改service-nodeport.yaml,增加NodePort,固定端口
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 80
      nodePort: 30080  #http
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      nodePort: 30443  #https
      protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
  • 部署nginx-ingress-controller
kubectl apply -f mandatory.yaml 
kubectl apply -f service-nodeport.yaml

3、查看Ingress-nginx组件状态

  • 查看Pod状态
kubectl get pods -n ingress-nginx

  • 查看service状态
kubectl get svc -n ingress-nginx

  • 查看daemonset状态
kubectl get ds -n ingress-nginx

4、验证Ingress-nginx服务

以nodeIP+nodePort的形式访问ingress-nginx服务,可以看到页面状态报404是正常的,因为这时还没有后端服务。

访问健康检查url,可以看到内容为空,但返回值为200。

curl http://172.16.1.101:30080/healthz -I

创建后端服务

1、配置后端服务

  • 首先创建一个nginx的后端服务 nginx-demo.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: default
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
  • 创建相关服务并检查状态
kubectl apply -f nginx-demo.yaml
  • 查看nginx应用状态:

  • 创建Ingress资源,将nginx服务添加到Ingress-nginx中

ingress-nginx.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: ingress.ikiwi.me
    http:
      paths:
        - path: /
          backend:
            serviceName: nginx
            servicePort: 80
kubectl apply -f ingress-nginx.yaml
  • 查看资源状态:
kubectl get ingress

  • 配置域名解析,在测试环境使用hosts解析
172.16.1.101 ingress.ikiwi.me
  • 使用域名访问应用,可以看到成功访问到了nginx服务。

现在已经有一个nginx应用了,再创建一个tomcat应用,为后续实验做准备。

  • 创建tomcat后端服务 tomcat-demo.yaml,文件内容如下:
apiVersion: v1
kind: Service
metadata:
  name: tomcat
  namespace: default
spec:
  selector:
    app: tomcat
  ports:
  - port: 8080
    targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: tomcat
        image: tomcat:alpine
        ports:
        - containerPort: 8080

2、配置Ingress策略

修改ingress-nginx.yaml,将tomcat服务增加到Ingress-nginx中。这里有多种策略配置。

① 不同域名转发到不同的服务

ingress-nginx.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
spec:
  rules:
  - host: ingress.ikiwi.me
    http:
      paths:
        - path: /
          backend:
            serviceName: nginx
            servicePort: 80
  - host: tomcat.ikiwi.me
    http:
      paths:
        - path: /
          backend:
            serviceName: tomcat
            servicePort: 8080

创建好后测试访问,分别访问不同域名:

② 同一域名,使用不同的URL转发到不同的服务上

ingress-nginx.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
spec:
  rules:
  - host: ingress.ikiwi.me
    http:
      paths:
        - path: /nginx
          backend:
            serviceName: nginx
            servicePort: 80
        - path: /tomcat
          backend:
            serviceName: tomcat
            servicePort: 8080

配置服务证书

这里用给tomcat服务添加证书为例。

  • 生成私钥
openssl genrsa -out tls.key 2048
  • 自签发证书
openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Shanghai/L=Shanghai/O=DevOps/CN=tomcat.ikiwi.me
  • 创建K8S使用的证书配置文件Secret
kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key
  • 查看Secret描述
kubectl describe secret tomcat-ingress-secret
  • 创建带tls认证的tomcat后端服务

ingress-tomcat-tls.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tomcat-tls
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "nginx"
  labels:
    app: tomcat
spec:
  tls:
  - hosts:
    - tomcat.ikiwi.me
    secretName: tomcat-ingress-secret
  rules:
  - host: tomcat.ikiwi.me
    http:
      paths:
        - backend:
            serviceName: tomcat
            servicePort: 8080

创建好后,访问服务,结果如下图所示,由于是自签发证书不受信任。HTTPS已可以成功访问。

文章目录