Kubernetes Ingress

一、简介

Service的表现形式为IP:Port,即工作在TCP/IP层。而对于基于HTTP的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟机,这些应用层的转发机制仅仅通过Kubernetes的Service机制是无法实现的。Kubernetes使用了一个Ingress策略定义和一个具体的Ingress Controller,两者结合并实现了一个完整的Ingress负载均衡器。

在定义Ingress策略之前,需要先部署Ingress Controller,以实现为所有的后端Service都提供一个统一的入口。Ingress Controller需要实现基于不同HTTP URL向后转发的负载分发规则,并可以灵活设置7层分发策略。

Ingress Controller 将以Pod的形式运行,监控API Server 的 ingress接口后端的backend services,如果service发生变化,则Ingress Controller应自动更新其转发规则。

二、创建Ingress Controller 和默认的backend服务

下面使用Nginx来实现一个Ingress Controller,需要实现的基本逻辑如下:

  • 监听API Server,获取全部Ingress定义

  • 基于Ingress定义,生成Nginx所需的配置文件/etc/nginx/nginx.conf

  • 执行nginx -s reload命令,重新加载nginx.conf配置文件的内容

 

(1)新建一个namespace,并为默认的ServiceAccount/default 绑定一个ClusterRole

# kubectl create namespace nginx-ingress

serviceaccount-role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-lb
subjects:
- kind: ServiceAccount
  name: default
  namespace: nginx-ingress
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
# kubectl create -f  serviceaccount-role.yaml

(2)创建backend

为了让Ingress Controller正常启动,还需要配置一个默认的backend,用于客户端访问不存在的URL时返回404应答

default-backend.yaml

​
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
  namespace: nginx-ingress
  labels:
    k8s-app: default-http-backend
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    k8s-app: default-http-backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: default-http-backend
  labels:
    k8s-app: default-http-backend
  namespace: nginx-ingress
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: default-http-backend
  template:
    metadata:
      labels:
        k8s-app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: default-http-backend
        image: chenliujin/defaultbackend
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi
# kubectl create -f default-backend.yaml

(3)创建Ingress Controller

nginx-ingress-controller-daemonset.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-ingress-lb
  labels:
    name: nginx-ingress-lb
  namespace: nginx-ingress
spec:
  selector:
    matchLabels:
      name: nginx-ingress-lb
  template:
    metadata:
      labels:
        name: nginx-ingress-lb
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: nginx-ingress-lb
        image: siriuszg/nginx-ingress-controller
        readinessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 10
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 10
        ports:
        - containerPort: 80
          hostPort: 80
        - containerPort: 443
          hostPort: 443
        env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
        args:
        - /nginx-ingress-controller
        - --default-backend-service=$(POD_NAMESPACE)/default-http-backend 
# kubectl create -f nginx-ingress-controller-daemonset.yaml

(4)查看

# kubectl get pods -n nginx-ingress
NAME                                    READY   STATUS    RESTARTS   AGE
default-http-backend-5bd785fcbc-jmg5f   1/1     Running   0          35m
nginx-ingress-lb-svfw2                  1/1     Running   0          36m
nginx-ingress-lb-xkvc6                  1/1     Running   0          36m
nginx-ingress-lb-zs6bk                  1/1     Running   0          36m

(5)验证

用curl访问任意node的80端口,验证nginx-ingress-controller和default-http-backend服务正常工作

# curl node1 
default backend - 404

三、定义Ingress策略

部署一个应用,通过ingress策略转发获取web信息

(1)mysql-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: nginx-ingress
spec:
  selector:
    app: mysql
  ports:
  - port: 3306
    targetPort: 3306---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  labels:
    app: mysql
  namespace: nginx-ingress
spec:
  selector:
    matchLabels:
      app: mysql
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.6
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"

(2)webapp-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace:  nginx-ingress
spec:
  selector:
    app: webapp
  ports:
  - port: 8080
    targetPort: 8080 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  namespace: nginx-ingress
  labels:
    app: webapp
spec:
  selector:
    matchLabels:
      app: webapp
  replicas: 2
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: tomcat-webapp
        image: kubeguide/tomcat-app:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        env:
        - name: MYSQL_SERVICE_HOST
          value: "mysql"
        - name: MYSQL_SERVICE_PORT
          value: "3306"

(3)webapp-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: mywebsite-ingress
  namespace: nginx-ingress
spec:
  rules:
  - host: mywebsite.com
    http:
      paths:
      - path: /demo
        backend: 
          serviceName: webapp
          servicePort: 8080

(4)查看ingress

# kubectl get ingress -n nginx-ingress -o wide
NAME                CLASS    HOSTS           ADDRESS                                        PORTS   AGE
mywebsite-ingress   <none>   mywebsite.com   192.168.10.106,192.168.10.107,192.168.10.108   80      28m

登入任意一个nginx-ingress-controller,查看nginx.conf

server {
        server_name mywebsite.com ;
        
        listen 80  ;
        listen 443  ssl http2 ;
        
        set $proxy_upstream_name "-";
        
        ssl_certificate_by_lua_block {
            certificate.call()
        }
        
        location /demo {
            
            set $namespace      "nginx-ingress";
            set $ingress_name   "mywebsite-ingress";
            set $service_name   "webapp";
            set $service_port   "8080";
            set $location_path  "/demo";
            .....
            
 

(5)访问客户端

# curl -H 'Host:mywebsite.com' http://192.168.10.106/demo/
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>HPE University Docker&Kubernetes Learning</title>
</head>
<body  align="center"><h2>Congratulations!!</h2>
     <br></br>
     <input type="button" value="Add..." onclick="location.href='input.html'" >
         <br></br>
      <TABLE align="center"  border="1" width="600px">
...

(6)外部浏览器访问

修改本机hosts文件

192.168.10.108 mywebsite.com

http://mywebsite.com/demo/

 

原文地址:https://www.cnblogs.com/bigberg/p/13563079.html