ingress-nginx:
kubernetes暴露服务的方式:ClusterIP、NodePort、LoadBalancer、ingress
我对于这几种模式,简单的理解如下,
ClusterIP,集群内的应用都可以访问,集群外部无法访问。
NodePort,相信初学者接触的第一个对外暴露服务的方式就是NodePort方式,是kubernetes引导外部流量到pod最原始的方式,
Nodeport即在每个node上开放一个特定端口,对应到某个pod的端口,集群外部通过 nodeIP:NodePort的方式进行访问,
它的缺点也比较明显:
每个端口对应一种服务,
每个node上都需要开放NodePort端口,
默认端口范围30000-32767,可以修改,
如果某个node的ip地址发生变化,可能需要人工干预
LoadBalancer,是暴露服务到internet的标准方式,每个服务对应一个单独的IP地址,转发所有流量到对应的服务,可以转发任意类型的流量,
这种方式,最大的缺点就是每个暴露的服务都需要有自己的IP地址
Ingress
ingress事实上不是一种服务类型。它处于多个服务的前端,扮演着“智能路由”或者集群入口的角色。
ingress可能是暴露服务最强大,也是最复杂的方式,它的控制器有各种类型,包括 Google Cloud Load Balancer, Nginx,Contour,Istio,等等。它还有各种插件,比如 cert-manager(https://github.com/jetstack/cert-manager),它可以为你的服务自动提供 SSL 证书。
如果想用一个ip暴露多个服务,这些服务都使用相同的7层协议,比如http,那ingres将是最有用的。
接下来,我们对ingress-nginx进行测试,
一、部署
下载官方yaml文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.20.0/deploy/mandatory.yaml
更新yaml里面两处镜像地址,此处使用的是阿里的镜像仓库
image: registry.cn-hangzhou.aliyuncs.com/google_containers/defaultbackend:1.4 image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.23.0
部署nginx-ingress-controller
[k8s@k8s-m1 ingress]$ kubectl apply -f mandatory.yamlnamespace/ingress-nginx createddeployment.extensions/default-http-backend createdservice/default-http-backend createdconfigmap/nginx-configuration createdconfigmap/tcp-services createdconfigmap/udp-services createdserviceaccount/nginx-ingress-serviceaccount createdclusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole createdrole.rbac.authorization.k8s.io/nginx-ingress-role createdrolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding createdclusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding createddeployment.extensions/nginx-ingress-controller created
查看部署后的状态
#deployment状态[k8s@k8s-m1 ingress]$ kubectl get deployment -n ingress-nginxNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEdefault-http-backend 1 1 1 1 7mnginx-ingress-controller 1 1 1 1 7m#pod状态[k8s@k8s-m1 ingress]$ kubectl get pods -n ingress-nginx -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODEdefault-http-backend-598df75c7d-ngfvs 1/1 Running 0 3m 172.60.75.2 k8s-m1nginx-ingress-controller-67954599b4-hbkfg 1/1 Running 0 3m 172.60.19.3 vm10-10-8-10ksccom #svc状态[k8s@k8s-m1 ingress]$ kubectl get svc -n ingress-nginx -o wideNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORdefault-http-backend ClusterIP 10.240.44.251 80/TCP 4m app.kubernetes.io/name=default-http-backend,app.kubernetes.io/part-of=ingress-nginx
default-http-backend是安装的一个默认后端,ClusterIP类型,可以在集群任意node访问,用于返回404结果
二、测试
[root@k8s-m2 ~]# curl http://10.240.44.251default backend - 404[root@k8s-m2 ~]# curl http://10.240.44.251/healthzok[root@k8s-m2 ~]#
到这里,说明ingress-nginx已经部署成功了。
以上是通过default-http-backend进行访问,并没有对集群外部暴露服务,
接下来继续,看看对外暴露服务的方式
三、通过nodeport的方式将服务暴露出去
下载nodePort模板
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
default backend - 404[k8s@k8s-m1 ingress]$ cat service-nodeport.yamlapiVersion: v1kind: Servicemetadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxspec: type: NodePort ports: - name: http port: 80 targetPort: 80 protocol: TCP - name: https port: 443 targetPort: 443 protocol: TCP selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx---#生效[k8s@k8s-m1 ingress]$ kubectl create -f service-nodeport.yaml
查看svc状态
[k8s@k8s-m1 ingress]$ kubectl get svc -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEdefault-http-backend ClusterIP 10.240.13.11480/TCP 44mingress-nginx NodePort 10.240.82.29 80:8807/TCP,443:8956/TCP 40mnginx-1108 ClusterIP 10.240.31.31 80/TCP,1935/TCP 42m
创建一个应用
[k8s@k8s-m1 ingress]$ cat nginx-1.10.2.yamlapiVersion: v1kind: Servicemetadata: name: nginx-1108 labels: app: nginx-1108 namespace: ingress-nginxspec: selector: app: nginx-1108 ports: - name: http80 port: 80 targetPort: 80 - name: rtmp1935 port: 1935 targetPort: 1935---apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: nginx-1108 labels: addonmanager.kubernetes.io/mode: Reconcile namespace: ingress-nginxspec: template: metadata: labels: app: nginx-1108 spec: containers: - name: my-nginx-1108 image: rtmp-nginx:1.10.8 imagePullPolicy: Never command: ["/usr/local/nginx/sbin/nginx","-g","daemon off;"] ports: - containerPort: 80
创建ingress规则
# 域名方式访问,本次使用域名方式测试nginx-ingress]# cat ingress-host-nginx-1.10.2.yaml apiVersion: extensions/v1beta1kind: Ingressmetadata: name: pand-ingress annotations: ingress.kubernetes.io/ssl-redirect: "false"spec: rules: - host: www.test1.com http: paths: - backend: serviceName: nginx-1108 servicePort: 80 # url路径方式访问nginx-ingress]# cat ingress-path-nginx-1.10.2.yaml apiVersion: extensions/v1beta1kind: Ingressmetadata: name: test-ingress annotations: ingress.kubernetes.io/ssl-redirect: "false" spec: rules: - http: paths: - path: /test1 backend: serviceName: nginx-1108 servicePort: 80
使用ingress域名规则进行测试
[root@k8s-m2 ~]# curl http://10.240.82.29/default backend - 404[[root@k8s-m2 ~]# curl -H "Host: foo.bar.com" http://10.240.82.29/successfully[root@k8s-m2 ~]# curl -H "Host: foo.bar.com" http://nodePort+port/successfully
四、通过hostNetwork的方式,对外暴露服务
修改mandatory.yaml,对nginx-ingress-controller添加hostNetwork: true,
hostNetwork是直接定义pod的网络方式,定义后,物理机ip就是nginx-ingress的ip,通过物理机ip直接访问nginx-ingress端口,将请求转发给后端pod
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxspec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: hostNetwork: true serviceAccountName: nginx-ingress-serviceaccount nodeSelector: zone: test_node containers: - name: nginx-ingress-controller image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.23.0
kubectl apply -f mandatory.yaml
查看pod所在物理机监听的端口,多了一个80端口,即nginx-ingress端口
tcp 0 0 10.10.8.11:2380 0.0.0.0:* LISTENtcp 0 0 0.0.0.0:80 0.0.0.0:* LISTENtcp 0 0 0.0.0.0:8800 0.0.0.0:* LISTENtcp 0 0 0.0.0.0:8801 0.0.0.0:* LISTEN
测试
#通过物理机ip测试[k8s@k8s-m1 ~]$ curl http://10.69.58.68/default backend - 404