ingress的操作流程详解

ingress

一、ingress相关简介

1.ingress概述
Ingress公开了从集群外部到集群内服务的HTTP和HTTPS路由。流量路由由Ingress资源上定义的规则控制。
下面是一个将所有流量都发送到同一Service的简单Ingress示例:
ingress的操作流程详解
可以将Ingress配置为服务提供外部可访问的URL、负载均衡流量、终止SSL/TLS,以及提供基于名称的虚拟主机等能力。Ingress控制器通常负责通过负载均衡器来实现Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress不会公开任意端口或协议。将HTTP和HTTPS以外的服务公开到Internet时,通常使用Service.Type=NodePort或Service.Type=LoadBalancer类型的服务。
ingress的操作流程详解
在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,Kubernetes目前提供了以下几种方案:

NodePort

LoadBalancer(负载均衡)

Ingress(入口)

2.Ingress组成

ingress controller:将新加入的Ingress转化成Nginx的配置文件并使之生效。

3.ingress服务

将Nginx的配置抽象成一个Ingress对象,每添加一个新的服务只需写一个新的Ingress的yaml文件即可。

4.Ingress工作原理

(1)ingress controller通过和kubernetes api交互,动态的去感知集群中ingress规则变化;

(2)然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置;

(3)再写到nginx-ingress-controller的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中;

(4)然后reload一下使配置生效。以此达到域名分配配置和动态更新的问题;

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

创建2个Deployment
        第一个:nginx镜像,replicas:3;
        第二个:httpd镜像,replicas:4;

创建2个SVC资源
        第一个和第一个Deploy绑定;
        第二个和第二个Deploy绑定;

ingress的操作流程详解
(1)创建deploy-svc1.yaml文件和deploy-svc2.yaml 文件

[root@master ingress]# vim deploy-svc1.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: deploy1
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: deploy1
        image: nginx
---
kind: Service
apiVersion: v1
metadata:
  name: svc1
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
[root@master ingress]# vim deploy-svc2.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: deploy2
spec:
  replicas: 4
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: deploy1
        image: httpd
---
kind: Service
apiVersion: v1
metadata:
  name: svc2
spec:
  selector:
    app: httpd
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
[root@master ingress]# kubectl apply -f deploy-svc1.yaml
deployment.extensions/deploy1 created
service/svc1 created
[root@master ingress]# kubectl apply -f deploy-svc2.yaml
deployment.extensions/deploy2 created
service/svc2 created
[root@master ingress]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   39d
svc1         ClusterIP   10.104.24.77   <none>        80/TCP    59s
svc2         ClusterIP   10.99.246.13   <none>        80/TCP    55s
[root@master ingress]# kubectl get pod
NAME                      READY   STATUS    RESTARTS   AGE
deploy1-5f7dd597c-jj5bd   1/1     Running   0          61s
deploy1-5f7dd597c-lhwwc   1/1     Running   0          61s
deploy1-5f7dd597c-rkcg7   1/1     Running   0          61s
deploy2-bf5d8d7b9-4p4ff   1/1     Running   0          57s
deploy2-bf5d8d7b9-74tgj   1/1     Running   0          57s
deploy2-bf5d8d7b9-lt79w   1/1     Running   0          57s
deploy2-bf5d8d7b9-z5rc4   1/1     Running   0          57s

(2)下载部署的Ingress:0.35.0版本,镜像是国外镜像,可以提前准备deploy.yaml
编辑文件启用hostNetwork网络,我们只需在deploy.yaml文件添加hostNetwork: true即可。 如果在Pod中使用hostNetwork:true配置网络,那么Pod中运行的应用程序可以直接使用node节点的端口,这样node节点主机所在网络的其他主机,都可以通过该端口访问到此应用程序。

[root@master ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.35.0/deploy/static/provider/baremetal/deploy.yaml
[root@master ingress]# ls
deploy-svc1.yaml  deploy.yaml
deploy-svc2.yaml
[root@master ingress]# vim deploy.yaml
...
  spec:
    hostNetwork: true  #这里添加字段
    dnsPolicy: ClusterFirst
    containers:
      - name: controller
...
[root@master ingress]# kubectl apply -f deploy.yaml
[root@master ingress]# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-kz6xn        0/1     Completed   0          43s
ingress-nginx-admission-patch-mh2qq         0/1     Completed   1          43s
ingress-nginx-controller-674c958759-89hp8   1/1     Running     0          53s
[root@master ingress]# kubectl get svc -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.98.192.225    <none>        80:30045/TCP,443:32531/TCP   89s
ingress-nginx-controller-admission   ClusterIP   10.110.144.179   <none>        443/TCP                      89s

(3)查看Ingress-nginx-controller容器内部详情。可以看到现在已经有一个模板,用来描述Ingress资源能够收集到的信息了。

[root@master ingress]# kubectl exec -it -n ingress-nginx ingress-nginx-controller-674c958759-89hp8 bash
bash-5.0$ ls
fastcgi.conf            mime.types              scgi_params
fastcgi.conf.default    mime.types.default      scgi_params.default
fastcgi_params          modsecurity             template
fastcgi_params.default  modules                 uwsgi_params
geoip                   nginx.conf              uwsgi_params.default
koi-utf                 nginx.conf.default      win-utf
koi-win                 opentracing.json
lua                     owasp-modsecurity-crs
bash-5.0$ cat nginx.conf
...
		location / {

			set $namespace      "";
			set $ingress_name   "";
			set $service_name   "";
			set $service_port   "";
			set $location_path  "/";
...

(4)创建对应的ingress规则

[root@master ingress]# vim ingress.yaml
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: bdqn-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: ingress.bdqn.com
    http:
      paths:
      - path: /nginx
        backend:
          serviceName: svc1
          servicePort: 80
      - path: /httpd
        backend:
          serviceName: svc2
          servicePort: 80
[root@master ingress]# kubectl apply -f ingress.yaml
[root@master ingress]# kubectl get ingresses.
NAME           HOSTS              ADDRESS   PORTS   AGE
bdqn-ingress   ingress.bdqn.com             80      19s
[root@master ingress]# kubectl get ingresses.
NAME           HOSTS              ADDRESS   PORTS   AGE
bdqn-ingress   ingress.bdqn.com             80      19s
[root@master ingress]# kubectl describe ingresses. bdqn-ingress
Name:             bdqn-ingress
Namespace:        default
Address:          192.168.229.210
Default backend:  default-http-backend:80 (<none>)
Rules:
  Host              Path  Backends
  ----              ----  --------
  ingress.bdqn.com
                    /nginx   svc1:80 (10.244.1.21:80,10.244.1.22:80,10.244.2.22:80)
                    /httpd   svc2:80 (10.244.1.23:80,10.244.1.24:80,10.244.2.23:80 + 1 more...)
...
[root@master ingress]# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-kz6xn        0/1     Completed   0          14m
ingress-nginx-admission-patch-mh2qq         0/1     Completed   1          14m
ingress-nginx-controller-674c958759-89hp8   1/1     Running     0          14m
[root@master ingress]# kubectl exec -it -n ingress-nginx ingress-nginx-controller-674c958759-89hp8 bash
bash-5.0$ cat nginx.conf
...
		location ~* "^/nginx" {

			set $namespace      "default";
			set $ingress_name   "bdqn-ingress";
			set $service_name   "svc1";
			set $service_port   "80";
			set $location_path  "/nginx";
...
		location ~* "^/httpd" {

			set $namespace      "default";
			set $ingress_name   "bdqn-ingress";
			set $service_name   "svc2";
			set $service_port   "80";
			set $location_path  "/httpd";
...

(5)修改本机的域名解析,进行浏览器访问。

[root@master ingress]# kubectl get pod -n ingress-nginx -o wide
NAME                                        READY   STATUS      RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
ingress-nginx-admission-create-kz6xn        0/1     Completed   0          17m   10.244.1.25       node1   <none>           <none>
ingress-nginx-admission-patch-mh2qq         0/1     Completed   1          17m   10.244.2.25       node2   <none>           <none>
ingress-nginx-controller-674c958759-89hp8   1/1     Running     0          17m   192.168.229.210   node2   <none>           <none>
zhangjiedeMacBook-Pro:~ zhangjie$ sudo vim /etc/hosts
192.168.229.210 ingress.bdqn.com
[root@master ingress]# kubectl get svc -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.98.192.225    <none>        80:30045/TCP,443:32531/TCP   26m
ingress-nginx-controller-admission   ClusterIP   10.110.144.179   <none>        443/TCP                      26m

(6)浏览器访问

http://ingress.bdqn.com/nginx:30045
http://ingress.bdqn.com/httpd:30045

ingress的操作流程详解
ingress的操作流程详解
7.基于http实现虚拟主机的访问
ingress的操作流程详解
前提:ingress-nginx-controller服务已经在集群中完成部署

[root@master vhost]# kubectl get pod -n ingress-nginx

编辑ingress1.bdqn.io域名所需的Deployment和svc资源

[root@master vhost]# vim deploy-svc1.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: deploy1
spec:
  replicas: 2
  template:
    metadata:
      labels:
        version: v1
    spec:
      containers:
      - name: httpd1
        image: 192.168.1.10:5000/httpd:v1
---
kind: Service
apiVersion: v1
metadata:
  name: svc1
spec:
  selector:
    version: v1
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
[root@master vhost]# kubectl apply -f deploy-svc1.yaml
[root@master vhost]# vim deploy-svc2.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: deploy2
spec:
  replicas: 2
  template:
    metadata:
      labels:
        version: v2
    spec:
      containers:
      - name: httpd2
        image: 192.168.1.10:5000/httpd:v2
---
kind: Service
apiVersion: v1
metadata:
  name: svc2
spec:
  selector:
    version: v2
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
[root@master vhost]# kubectl apply -f deploy-svc2.yaml

访问各svc资源的ClusterIP验证服务

[root@master vhost]# kubectl get svc
[root@master vhost]# curl 10.244.1.25
[root@master vhost]# curl 10.244.2.25

创建对应的ingress规则

[root@master vhost]# vim ingress.yaml
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress1
spec:
  rules:
    - host: ingress1.bdqn.io
      http:
        paths:
        - path: /
          backend:
            serviceName: svc1
            servicePort: 80
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress2
spec:
  rules:
    - host: ingress2.bdqn.io
      http:
        paths:
        - path: /
          backend:
            serviceName: svc2
            servicePort: 80
[root@master vhost]# kubectl apply -f ingress.yaml
[root@master vhost]# kubectl describe ingresses. ingress1
[root@master vhost]# kubectl describe ingresses. ingress2

在本机上做域名解析之后,用浏览器访问验证。
8.基于https的访问
创建证书

[root@master https]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
[root@master https]# ls
tls.crt  tls.key

创建secret资源,将证书保存到k8s集群中。

[root@master https]# kubectl create secret tls tls-secret --key=tls.key --cert=tls.crt

创建新的deploy5.yaml

[root@master https]# vim deploy5.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: deploy5
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx5
    spec:
      containers:
      - name: nginx5
        image: nginx
---
kind: Service
apiVersion: v1
metadata:
  name: svc5
spec:
  selector:
    app: nginx5
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

创建对应的ingress规则

[root@master https]# vim ingress5.yaml
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: https
spec:
  tls:
    - hosts:
      - ingress5.bdqn.com
      secretName: tls-secret
  rules:
    - host: ingress5.bdqn.com
      http:
        paths:
        - path: /
          backend:
            serviceName: svc5
            servicePort: 80

本机编写域名解析并使用浏览器访问验证。

上一篇:【细小碎的oi小知识点总结贴】不定时更新(显然也没人看qwq)


下一篇:容器编排系统k8s之Ingress资源