6-1 ingress及ingress controller

Kubernetes v1.19 [stable]
管理对集群中服务的外部访问的API对象,通常是HTTP。
Ingress可以提供负载平衡、SSL终止和基于名称的虚拟主机
Ingress 是什么?
Ingress将来自集群外部的HTTP和HTTPS路由暴露给集群内的服务。流量路由由Ingress资源上定义的规则控制。
可以将Ingress配置为提供服务外部可访问的 URL、负载均衡流量、SSL/TLS,以及提供基于名称的虚拟主机。Ingress 控制器 通常负责通过负载均衡器来实现 ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress不会公开任意端口或协议。若将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或者 Service.Type=LoadBalancer 类型的服务。
ingress是k8s集群里工作在osi网络参考模型下,第7层的应用,对外暴露的接口;
service只能进行L4流量调度器,表现形式是ip+port;
ingress则可以调度不同业务域、不同URL访问路径的业务流量;

文档:https://kubernetes.io/docs/concepts/services-networking/ingress/

Ingress-Nginx官网地址:https://kubernetes.github.io/ingress-nginx/

GitHub地址:https://github.com/kubernetes/ingress-nginx/

ingress所需的yaml文件:
namespace.yaml  rabc.yaml  configmap.yaml  tcp-services-configmap.yaml  udp-services-cnfigmap.yaml with-rabc.yaml
# kubectl apply -f  namespace.yaml
# kubectl apply -f  rabc.yaml
....
# kubectl get pod -n ingress-nginx
这是一个简单的示例,其中Ingress将其所有流量发送到一个Service:

Ingress可以配置为向服务提供外部可访问的 URL、负载平衡流量、终止SSL/TLS并提供基于名称的虚拟主机。一个入口控制器负责履行入口,通常有一个负载均衡器,虽然它也可以配置您的边缘路由器或额外的前端,以帮助处理流量。

Ingress不会公开任意端口或协议。向Internet公开HTTP和HTTPS以外的服务通常使用Service.Type=NodePort或Service.Type=LoadBalancer类型的服务
示例1:
https://cloud.tencent.com/developer/article/1718482
https://www.cnblogs.com/zhanglianghhh/p/13721288.html

镜像下载与重命名:因quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0无法拉取下来镜像,所以:


docker pull registry.cn-beijing.aliyuncs.com/google_registry/nginx-ingress-controller:0.30.0

docker tag 89ccad40ce8e quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0

docker rmi  registry.cn-beijing.aliyuncs.com/google_registry/nginx-ingress-controller:0.30.0

使用nginx:0.30
ingress-nginx的yaml文件修改后并启动:
下载包:
wget https://github.com/kubernetes/ingress-nginx/archive/nginx-0.30.0.tar.gz
tar -xf nginx-0.30.0.tar.gz
解压后:yaml文件在下载包中的位置:ingress-nginx-nginx-0.30.0/deploy/static/mandatory.yaml
cp -a ingress-nginx-nginx-0.30.0/deploy/static/mandatory.yaml ./
yaml文件配置修改:

# vim mandatory.yaml

………………

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   # 注释掉

………………

      nodeSelector:

        kubernetes.io/hostname: vm1   # 修改处,需注意打的master的标签label值

      # 如下几行为新加行  作用【允许在master节点运行】

      tolerations:

      - key: node-role.kubernetes.io/master  

        effect: NoSchedule

………………

          ports:

            - name: http

              containerPort: 80

              hostPort: 80    # 添加处【可在宿主机通过该端口访问Pod】

              protocol: TCP

            - name: https

              containerPort: 443

              hostPort: 443   # 添加处【可在宿主机通过该端口访问Pod】

              protocol: TCP

………………
# kubectl apply -f mandatory.yaml 

namespace/ingress-nginx created

configmap/nginx-configuration created

configmap/tcp-services created

configmap/udp-services created

serviceaccount/nginx-ingress-serviceaccount created

clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created

role.rbac.authorization.k8s.io/nginx-ingress-role created

rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created

clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created

daemonset.apps/nginx-ingress-controller created

limitrange/ingress-nginx created


# kubectl get ds -n ingress-nginx -owide

NAME                       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                AGE   CONTAINERS                 IMAGES                                                                             SELECTOR

nginx-ingress-controller   1         1         1       1            1           kubernetes.io/hostname=vm1   62s   nginx-ingress-controller   registry.cn-beijing.aliyuncs.com/google_registry/nginx-ingress-controller:0.30.0   app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx




# kubectl get pod -n ingress-nginx -owide

NAME                             READY   STATUS    RESTARTS   AGE   IP           NODE   NOMINATED NODE   READINESS GATES

nginx-ingress-controller-9hs4s   1/1     Running   0          66s   10.244.0.7   vm1    <none>           <none>


创建deployment和service:
deployment_service1的yaml:
# cat deploy_service1.yaml
apiVersion: apps/v1

kind: Deployment

metadata:

  name: myapp-deploy1

  namespace: default

spec:

  relicas: 3

  selector:

    matchLabels:

      app: myapp

      release: v1

  template:

    metadata:

      labels:

        app: myapp

        release: v1

    spec:

          containers:

          - name: myapp

            image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1

            imagePullPolicy: IfNotPresent

            ports:

            - name: http

              containerPort: 80

---

apiVersion: v1

kind: Service

metadata:

  name: myapp-clusterip1

  namespace: default

spec:

  type: ClusterIP #默认类型

  selector:

    app: myapp

    release: v1

  ports:

  - name: http

    port: 80

    targetPort: 80













































启动Deployment和Service
# kubectl apply -f deploy_service1.yaml
# kubectl get deployment -owide

NAME            READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES                                                      SELECTOR

myapp-deploy1   3/3     3            3           5m19s   myapp        registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1   app=myapp,release=v1






# kubectl get rs -owide

NAME                       DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                                                      SELECTOR

myapp-deploy1-7dc65c445c   3         3         3       5m55s   myapp        registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1   app=myapp,pod-template-hash=7dc65c445c,release=v1






# kubectl get pod -owide

NAME                             READY   STATUS    RESTARTS   AGE    IP            NODE   NOMINATED NODE   READINESS GATES

myapp-deploy1-7dc65c445c-7sckz   1/1     Running   0          67s     10.244.1.34   vm2    <none>           <none>

myapp-deploy1-7dc65c445c-mqnst   1/1     Running   0          6m15s   10.244.1.33   vm2    <none>           <none>

myapp-deploy1-7dc65c445c-wn5vb   1/1     Running   0          67s     10.244.1.35   vm2    <none>           <none>






# kubectl get svc -owide

NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE     SELECTOR

kubernetes         ClusterIP   10.1.0.1       <none>        443/TCP   44d     <none>

myapp-clusterip1   ClusterIP   10.1.165.199   <none>        80/TCP    3m19s   app=myapp,release=v1




curl访问pod:
# curl 10.244.1.34
# curl 10.244.1.34/hostname.html
# curl 10.244.1.33/hostname.html
# curl 10.244.1.35/hostname.html
curl访问svc:
# curl 10.1.165.199
# curl 10.1.165.199/hostname.html #多次curl

deployment_service2的yaml:
# cat deploy_service2.yaml 

apiVersion: apps/v1

kind: Deployment

metadata:

  name: myapp-deploy2

  namespace: default

spec:

  replicas: 3

  selector:

    matchLabels:

      app: myapp

      release: v2

  template:

    metadata:

      labels:

        app: myapp

        release: v2

    spec:

          containers:

          - name: myapp

            image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v2

            imagePullPolicy: IfNotPresent

            ports:

            - name: http

              containerPort: 80

---

apiVersion: v1

kind: Service

metadata:

  name: myapp-clusterip2

  namespace: default

spec:

  type: ClusterIP #默认类型

  selector:

    app: myapp

    release: v2

  ports:

  - name: http

    port: 80

    targetPort: 80

启动Deployment和Service
# kubectl apply -f deploy_service2.yaml
# kubectl get deployment -owide

NAME            READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES                                                      SELECTOR

myapp-deploy1   3/3     3            3           14m    myapp        registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1   app=myapp,release=v1

myapp-deploy2   3/3     3            3           110s   myapp        registry.cn-beijing.aliyuncs.com/google_registry/myapp:v2   app=myapp,release=v2



# kubectl get rs -owide

NAME                       DESIRED   CURRENT   READY   AGE    CONTAINERS   IMAGES                                                      SELECTOR

myapp-deploy1-7dc65c445c   3         3         3       14m    myapp        registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1   app=myapp,pod-template-hash=7dc65c445c,release=v1

myapp-deploy2-744ff669dc   3         3         3       118s   myapp        registry.cn-beijing.aliyuncs.com/google_registry/myapp:v2   app=myapp,pod-template-hash=744ff669dc,release=v2

# kubectl get pod -owide

NAME                             READY   STATUS    RESTARTS   AGE     IP            NODE   NOMINATED NODE   READINESS GATES

myapp-deploy1-7dc65c445c-7sckz   1/1     Running   0          9m51s   10.244.1.34   vm2    <none>           <none>

myapp-deploy1-7dc65c445c-mqnst   1/1     Running   0          14m     10.244.1.33   vm2    <none>           <none>

myapp-deploy1-7dc65c445c-wn5vb   1/1     Running   0          9m51s   10.244.1.35   vm2    <none>           <none>

myapp-deploy2-744ff669dc-5rzrm   1/1     Running   0          2m3s    10.244.1.36   vm2    <none>           <none>

myapp-deploy2-744ff669dc-mbkxv   1/1     Running   0          2m3s    10.244.1.37   vm2    <none>           <none>

myapp-deploy2-744ff669dc-zwkkz   1/1     Running   0          2m3s    10.244.1.38   vm2    <none>           <none>

# kubectl get svc -owide

NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE    SELECTOR

kubernetes         ClusterIP   10.1.0.1       <none>        443/TCP   44d    <none>

myapp-clusterip1   ClusterIP   10.1.165.199   <none>        80/TCP    16m    app=myapp,release=v1

myapp-clusterip2   ClusterIP   10.1.125.102   <none>        80/TCP    2m9s   app=myapp,release=v2

curl访问svc:
# curl 10.1.125.102
# curl 10.1.125.102/hostname.html #多次curl


Ingress HTTP代理访问
yaml文件(由于自建的service在默认default名称空间,因此这里也是default名称空间)
# cat ingress-http.yaml 

apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

  name: nginx-http

  namespace: default

spec:

  rules:

    - host: www.zytest01.com

      http: 

        paths:

        - path: /

          backend:

            serviceName: myapp-clusterip1

            servicePort: 80

    - host : www.zytest02.com

      http:

        paths:

        - path: /

          backend: 

            serviceName: myapp-clusterip2

            servicePort: 80

启动ingress并查看状态:
# kubectl apply -f ingress-http.yaml 

ingress.networking.k8s.io/nginx-http created

# kubectl get ingress

NAME         CLASS    HOSTS                               ADDRESS   PORTS   AGE

nginx-http   <none>   www.zytest01.com,www.zytest02.com             80      5s


查看Nginx的配置:
# kubectl get pod -n ingress-nginx

NAME                             READY   STATUS    RESTARTS   AGE

nginx-ingress-controller-9hs4s   1/1     Running   0          47m




# kubectl exec -it nginx-ingress-controller-9hs4s -n ingress-nginx bash

$ cat /etc/nginx/nginx.conf
......
    ## start server www.zytest01.com

    server {

        server_name www.zytest01.com ;
    

        listen 80  ;

        listen 443  ssl http2 ;
    

        set $proxy_upstream_name "-";
    

        ssl_certificate_by_lua_block {

            certificate.call()

        }
        

        location / {
            set $namespace      "default";

            set $ingress_name   "nginx-http";

            set $service_name   "myapp-clusterip1";

            set $service_port   "80";

            set $location_path  "/";



......
    ## start server www.zytest02.com

    server {

        server_name www.zytest02.com ;



        listen 80  ;

        listen 443  ssl http2 ;



        set $proxy_upstream_name "-";



        ssl_certificate_by_lua_block {

            certificate.call()

        }



        location / {
            set $namespace      "default";

            set $ingress_name   "nginx-http";

            set $service_name   "myapp-clusterip2";

            set $service_port   "80";

            set $location_path  "/";

......

浏览器访问:

hosts文件修改,添加如下信息(192.168.1.84为master/ingress机器的ip)

文件位置:C:\WINDOWS\System32\drivers\etc\hosts



192.168.1.84  www.zytest01.com  www.zytest02.com
浏览器里输入:http://www.zytest01.com  http://www.zytest02.com

Ingress HTTPS代理访问
SSL证书创建:
# mkdir cert
# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BeiJing/O=BTC/OU=MOST/CN=zhang/emailAddress=ca@test.com"
cert]# ls -l

total 8

-rw-r--r-- 1 root root 1359 Oct  6 01:06 tls.crt

-rw-r--r-- 1 root root 1708 Oct  6 01:06 tls.key

# kubectl create secret tls tls-secret --key tls.key --cert tls.crt

secret/tls-secret created

创建ingress https
yaml文件(由于自建的service在默认default名称空间,因此这里也是default名称空间)
# cat ingress-https.yaml 

apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

  name: nginx-https

  namespace: default

spec:

  tls:

    - hosts: 

      - www.zytest01.com

      - www.zytest02.com

      secretName: tls-secret

  rules:

    - host: www.zytest01.com

      http:

        paths:

        - path: /

          backend:

            serviceName: myapp-clusterip1

            servicePort: 80

    - host: www.zytest02.com

      http:

        paths:

        - path: /

          backend:

            serviceName: myapp-clusterip2

            servicePort: 80

启动ingress https并查看状态
# kubectl apply -f ingress-https.yaml 
# kubectl get ingress -owide

NAME          CLASS    HOSTS                               ADDRESS   PORTS     AGE

nginx-http    <none>   www.zytest01.com,www.zytest02.com             80        26m

nginx-https   <none>   www.zytest01.com,www.zytest02.com             80, 443   79s

浏览器访问
hosts文件修改后再在浏览器访问:
浏览器里输入:https://www.zytest01.com  https://www.zytest02.com

Ingress-Nginx实现BasicAuth认证
官网地址:



https://kubernetes.github.io/ingress-nginx/examples/auth/basic/
准备工作:
# htpasswd -c auth foo

New password: 

Re-type new password: 

Adding password for user foo

# ls -l

-rw-r--r-- 1 root root  42 Oct  6 11:03 auth

# cat auth 

foo:$apr1$Z3CNOfQA$kgNyXwHUz9gwGLmqnFJ.p1

# kubectl create secret generic basic-auth --from-file=auth

secret/basic-auth created



# kubectl get secret 

NAME                  TYPE                                  DATA   AGE

basic-auth            Opaque                                1      8s

default-token-4fzfg   kubernetes.io/service-account-token   3      44d

tls-secret            kubernetes.io/tls                     2      9h

 

# kubectl get secret  basic-auth -oyaml

apiVersion: v1

data:

  auth: Zm9vOiRhcHIxJFozQ05PZlFBJGtnTnlYd0hVejlnd0dMbXFuRkoucDEK

kind: Secret

metadata:

  creationTimestamp: "2021-10-06T03:03:28Z"

  name: basic-auth

  namespace: default

  resourceVersion: "785781"

  selfLink: /api/v1/namespaces/default/secrets/basic-auth

  uid: f2144306-cafe-41ac-a2d0-15ab8f438602

type: Opaque

ingress yaml文件:
cat ingress-basicauth.yaml 

apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

  name: ingress-with-auth

  annotations:

    # type of authentication

    nginx.ingress.kubernetes.io/auth-type: basic

    # name of the secret that contains the user/password definitions

    nginx.ingress.kubernetes.io/auth-secret: basic-auth

    # message to display with an appropriate context why the authentication is required

    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'

spec:

  rules:

  - host: www.auth.zytest01.com

    http:

      paths:

      - path: /

        backend:

          serviceName: myapp-clusterip1

          servicePort: 80

启动ingress并且查看状态:
# kubectl apply -f ingress-basicauth.yaml 

ingress.networking.k8s.io/ingress-with-auth created

# kubectl get ingress -owide

NAME                CLASS    HOSTS                               ADDRESS   PORTS     AGE

ingress-with-auth   <none>   www.auth.zytest01.com                              80        68s



浏览器访问:写hosts后访问,需要输入用户名和密码
http://www.auth.zytest01.com

Ingress-Nginx实现Rewrite重写

官网地址:



https://kubernetes.github.io/ingress-nginx/examples/rewrite/
名称描述值nginx.ingress.kubernetes.io/rewrite-target必须重定向的目标URLStringnginx.ingress.kubernetes.io/ssl-redirect指示位置部分是否只能由SSL访问(当Ingress包含证书时,默认为True)Boolnginx.ingress.kubernetes.io/force-ssl-redirect即使Ingress没有启用TLS,也强制重定向到HTTPSBoolnginx.ingress.kubernetes.io/app-root定义应用程序根目录,Controller在“/”上下文中必须重定向该根目录Stringnginx.ingress.kubernetes.io/use-regex指示Ingress上定义的路径是否使用正则表达式Bool

ingress yaml文件:
# cat ingress-rewrite.yaml 

apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

  annotations:

    nginx.ingress.kubernetes.io/rewrite-target: https://www.baidu.com

  name: rewrite

  namespace: default

spec:

  rules:

  - host: www.rewrite.zytest01.com

    http:

      paths:

      - backend:

          serviceName: myapp-clusterip1

          servicePort: 80

启动ingress并且查看状态:
# kubectl apply -f ingress-rewrite.yaml 

ingress.networking.k8s.io/rewrite created

# kubectl get ingress -owide

NAME                CLASS    HOSTS                               ADDRESS   PORTS     AGE



rewrite             <none>   www.rewrite.zytest.com                        80        66s



浏览器访问:写hosts后访问,需要输入用户名和密码
http://www.rewrite.zytest01.com
之后,可见重定向到了https://www.baidu.com 百度页面



----------------------------------
其它示例:
service.yaml
apiVersion:v1
kind: Service
metadata:
    name: myapp
    namespace: default
spec:
    selector:
        app: myapp
        release: canary
        ports:
        - name: http
        targetPort: 80
        port: 80
---
apiVersion:apps/v1
kind: Deployment
metadata:
    name: myapp-deploy
    namespace: default
spec:
    replicas: 3
    selector: 
        mathLables:
            app: myapp
            release: canary
    template:
        metadata:
            labels: 
                app: myapp
                release: canary
        spec:
            containers:
            - name: myapp
              image: ikubernets/app: v2
              ports:
              - http:
                 containerPort: 80

services-nodeport.yaml
apiVersion: v1

kind: Service

metadata:

  name: ingress-nginx

  namespace: ingress-nginx

spec:

  type: Nodeport

  ports:

  - name: http

    port: 80

    targetPort: 80

    protocol: TCP

    nodePort: 30080

  - name: https

    port: 443

    targetPort: 443

    protocol: TCP

    nodePort: 300443    

  selector:

    app: ingress-nginx

  

基于ingress的后端app应用:
myapp-ingress.yaml
apiVsersion:extensions/v1beta1
kind:Ingress
metadata:
    name: myapp-ingress
    namespace: default
    annotations:
        kubernetes.io/ingress.class: "nginx"
spec:
    rules: 
    - host:  rancher.domain.com
      http:
         path: 
         - path:
            backend: 
                  serviceName:myapp
                  servicePort: 80
# kubectl apply -f myapp-ingress.yaml
# kubectl get ingress
在浏览器访问:rancher.domain.com:30080

tomcat应用:
tomcat-deploy.yaml
apiVersion: v1

kind: Service

metadata:

  name: tomcat

  namespace: default

spec:

  selector:

    app: tomcat

    release: canary

  ports:

  - name: http

    port: 8080

    targetPort: 8080

  - name: ajp

    port: 8009

    targetPort: 8009    

---

apiVersion: v1

kind: Deployment

metadata:

  name: tomcat-deploy

  namespace: default

spec:

  replicas: 3

  selector:

    matchLabels:

      app: tomcat

      release: canary

  template:

    metadata:

      labels:

        app: tomcat

        release: canary        

    spec:

      containers:

      - name: tomcat

        image: tomcat:8.5.32-jre8-alpine

        ports:

        - name: http

          containerPort: 8080

        - name: ajp

          containerPort: 8009











  

ingress-tomcat.yaml
apiVsersion:extensions/v1beta1
kind:Ingress
metadata:
    name: ingress-tomcat
    namespace: default
    annotations:
        kubernetes.io/ingress.class: "nginx"
spec:
    rules: 
    - host:  tomcat.domain.com
      http:
         path: 
         - path:
            backend: 
                  serviceName:tomcat
                  servicePort: 8080

# kubectl apply -f tomcat-deploy.yaml 
# kubectl apply -f ingress-tomcat.yaml
# kuebctl get pod 
# kubectl get svc
# kubectl get ingress
NAME        HOSTS    ADDRESS    PORTS    AGE
ingtess-tomcat        tomcat.domain.com        80    10m
浏览器访问:tomcat.domain.com:30080

基于https:

# kubectl secret

ingress-tomcat-tls.yaml
apiVsersion:extensions/v1beta1
kind:Ingress
metadata:
    name: ingress-tomcat-tls
    namespace: default
    annotations:
        kubernetes.io/ingress.class: "nginx"
spec:
    tls:
    - hosts: 
      - tomcat.domain.com
   secretName: tomcat-ingress.secret
    rules: 
    - host:  tomcat.domain.com
      http:
         path: 
         - path:
            backend: 
                  serviceName:tomcat
                  servicePort: 8080
# kubectl apply -f ingress-tomcat-tls.yaml
# kuebctl get ingress
NAME        HOSTS    ADDRESS    PORTS    AGE
ingtess-tomcat        tomcat.domain.com        80,443    10m
ingtess-tomcat-tls    tomcat.domain.com        80,443    1m
浏览器访问:  https:tomcat.domain.com:30443

# kubectl get pods -n ingress
nginx-ingress-controller--d658896cd-t55dm    
# kubectl exec -it  nginx-ingress-controller--d658896cd-t55dm -n ingress
cat nginx.conf

 

posted @ 2022-11-14 23:49  Sky-wings  阅读(79)  评论(0编辑  收藏  举报