k8s网络-ingress

发布时间 2023-10-22 18:41:17作者: 村尚chun叔

Ingress资源

https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。

Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。

1.为什么会出现Ingress

将应用部署在k8s中,也就是pod后,如何在集群内访问、以及如何在集群外访问,才是核心目的,毕竟还是以web项目为主。

1.在没有ingress(入口)之前,pod对集群外提供访问,只能通过NodePort方式,也就是端口映射方式,但是这个缺点很明显,一个Node上的port有限,并且不能重复使用。

podA占用了80端口,其他服务就无法使用了。

2.我们上一节使用的Service且NodePort类型,是基于四层的代理转发,基于TCP、UDP协议转发。
缺点已经说过了,就像早期于超老师带着大家学nginx一样,Nginx也是支持基于四层、七层的代理转发的。
很明显,基于七层的http转发,粒度更细,能直接基于域名区分请求。
基于七层的http、https协议转发,以及通过域名、路径的转发,能实现更细粒度的请求划分,并且解决端口问题。

【思考下多端口虚拟主机、多域名虚拟主机,是不是区别很大?】

3.为了解决这个问题,Ingress控制器资源出现了,作用就是实现七层的协议转发,通过域名、路径的匹配转发,提供k8s集群的访问入口。

4.有同学想,既然nginx可以实现传统的七层代理转发,为什么还要有ingress?
毕竟你要注意你的应用,以pod形式在k8s环境内运行,外部的nginx无法动态发现k8s创建的资源。

5.k8s下的ingress控制器,具体实现的产品,有ingress-nginx、traefik。

2.图解Ingress工作原理

image

3.Ingress工作机制

想要使用Ingress功能,得先在k8s集群上安装ingress controller。

目前也有很多种软件实现了Ingress控制器,官网维护的就是
https://github.com/kubernetes/ingress-nginx

外部请求先到达Ingress控制器,控制器根据路由规则,找到对应的Service,然后通过Endpoint记录的pod地址列表,将请求最终转发给pod。

4.创建基于域名的Ingress

https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/#path-types

先安装ingress-nginx,使用k8s权威指南第五版的ingress.yaml即可。
https://github.com/kubeguide/K8sDefinitiveGuide-V5-Sourcecode/blob/main/Chapter04/4.6.1%20ingress.yaml

创建Ingress-nginx控制器

[root@k8s-master-10 ~/ingress]#kubectl apply -f ingress.yml 
namespace/nginx-ingress created
serviceaccount/nginx-ingress created
clusterrole.rbac.authorization.k8s.io/nginx-ingress created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress created
secret/default-server-secret created
configmap/nginx-config created
deployment.apps/nginx-ingress created


# [root@k8s-master-10 ~/ingress]#kubectl -n nginx-ingress describe po nginx-ingress-75c88594dc-klfqc 

# 发现需要有node-Selector
# 给节点打上标签
[root@k8s-master-10 ~/ingress]#kubectl label nodes k8s-master-10 role=ingress-nginx-controller

# 又发现,k8s-master默认有污点,pod不能容忍,因此没法部署。

设置master也参与pod调度

[root@k8s-master-10 ~/ingress]#kubectl describe nodes k8s-master-10  |grep Taint
Taints:             node-role.kubernetes.io/master:NoSchedule

# 去掉污点
kubectl taint node k8s-master-10 node-role.kubernetes.io/master:NoSchedule-

验证ingress-nginx控制正常

[root@k8s-master-10 ~/ingress]#kubectl -n nginx-ingress get po -owide
NAME                             READY   STATUS    RESTARTS   AGE     IP         NODE            NOMINATED NODE   READINESS GATES
nginx-ingress-75c88594dc-klfqc   1/1     Running   0          7m47s   10.2.0.6   k8s-master-10   <none>           <none>

[root@k8s-master-10 ~/ingress]#kubectl -n nginx-ingress get all -owide
NAME                                 READY   STATUS    RESTARTS   AGE     IP         NODE            NOMINATED NODE   READINESS GATES
pod/nginx-ingress-75c88594dc-klfqc   1/1     Running   0          8m33s   10.2.0.6   k8s-master-10   <none>           <none>

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS      IMAGES                      SELECTOR
deployment.apps/nginx-ingress   1/1     1            1           8m33s   nginx-ingress   nginx/nginx-ingress:1.7.2   app=nginx-ingress

NAME                                       DESIRED   CURRENT   READY   AGE     CONTAINERS      IMAGES                      SELECTOR
replicaset.apps/nginx-ingress-75c88594dc   1         1         1       8m33s   nginx-ingress   nginx/nginx-ingress:1.7.2   app=nginx-ingress,pod-template-hash=75c88594dc


# 其实就是运行了一个nginx在pod里

创建ingree规则

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: yuchaoit
spec:
  rules:                                 # 转发规则
  - host: "www.yuchaoit.cn"            # 填入你们的业务域名
    http:                                # 基于http协议解析
      paths:                            # 基于url路径匹配
      - pathType: Prefix                 #要设置路径类型,否则不合法,
        path: "/"                     # 以 / 分割的URL路径前缀匹配,区分大小写,这里表默认所有路径。
        backend:                      # 后端Service信息的组合
          service:                    
            name: service1    # 代理到名字是service1的ClusterIP
            port:                    # 代理到的Service的端口号。
              number: 80

创建,查看ingress

[root@k8s-master-10 ~/ingress]#kubectl create -f my-ingress.yml 
ingress.networking.k8s.io/test-ingress created


[root@k8s-master-10 ~/ingress]#kubectl -n yuchaoit get ingress -o wide
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME           CLASS    HOSTS             ADDRESS   PORTS   AGE
test-ingress   <none>   www.yuchaoit.cn             80      10s

# 查看ingress是否正确
[root@k8s-master-10 ~/ingress]#kubectl -n yuchaoit describe ingress test-ingress

创建ingress后端的service、pod

apiVersion: apps/v1      # 注意这里与Pod的区别,Deployment是apps/v1而不是v1
kind: Deployment         # 资源类型为Deployment
metadata:
  name: nginx-deployment            # Deployment的名称
  namespace: yuchaoit
spec:
  replicas: 2            # Pod的数量,Deployment会确保一直有2个Pod运行         
  selector:              # Label Selector
    matchLabels:
      app: nginx
  template:              # Pod的定义,用于创建Pod,也称为Pod template
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.14.0
        name: nginx-containers
        imagePullPolicy: IfNotPresent
        ports:
          - name: http
            containerPort: 80 # 指明容器内要暴露的端口
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi

创建svc

apiVersion: v1
kind: Service
metadata:
  name: service1        # Service的名称
  namespace: yuchaoit
spec:
  selector:          # Label Selector,选择包含app=nginx标签的Pod
    app: nginx
  ports:
  - name: service0
    targetPort: 80   # Pod的端口
    port: 80         # Service对外暴露的端口,也就是ClusterIP的port
    protocol: TCP    # 转发协议类型,支持TCP和UDP
  type: ClusterIP    # Service的类型

创建结果

[root@k8s-master-10 ~/ingress]#kubectl -n yuchaoit get svc service1 -owide
NAME       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service1   ClusterIP   10.1.56.133   <none>        80/TCP    15s   app=nginx

检验ingress状态

image

访问七层负载均衡的k8s集群

修改pod首页,查看效果。

kubectl -n yuchaoit exec -it nginx-deployment-6f7886b6db-xsj8n -- bash -c 'echo "<meta charset=utf8>老司机带你学k8s,222" > /usr/share/nginx/html/index.html'

kubectl -n yuchaoit exec -it nginx-deployment-6f7886b6db-pvjd5 -- bash -c 'echo "<meta charset=utf8>老司机带你学k8s,111" > /usr/share/nginx/html/index.html'

image

ingress七层代理原理(面试背)

在生产下,ingress的七层域名,就直接绑定到SLB的地址即可。

1. ingress controller 通过和 api-server交互,动态感知集群中ingress规则的变化

2. ingress controller 读取ingress规则,也就是你们的业务域名,对应哪个Service、自动生成nginx配置,再写入到ingress控制器所处的pod,里面的nginx.conf

3. 自动reload nginx,实现域名,配置动态更新。

grep -E '[a-z]' /etc/nginx/conf.d/yuchaoit-test-ingress.conf