k8s nodeport无法访问_k8s学习之service详解
1.概述
通過Deployment來創建一組Pod來提供具有高可用性的服務。每個Pod都會分配一個單獨的Pod IP,卻存在如下兩問題:
1.pod ip僅僅集群內部可見的虛擬IP,外部無法訪問
2.pod ip會隨著pod的銷毀而消失,ip可能會隨時變化,導致訪問服務不方便
k8s中的service就是解決以上問題的實現服務發現的核心關鍵。service能夠提供負載均衡能力,但是在使用上有以下限制:
只提供4層負載均衡能力,沒有7層功能。
2.service類型詳解
2.1 service的類型
ClusterIp:默認類型,自動分配一個僅 Cluster 內部可以訪問的虛擬 IP
NodePort:在 ClusterIP 基礎上為 Service 在每臺機器上綁定一個端口,這樣就可以通過 :NodePort 來訪問該服務
LoadBalancer:在 NodePort 的基礎上,借助 cloud provider 創建一個外部負載均衡器,并將請求轉發到NodePort。(是付費服務,而且價格不菲)
ExternalName:把集群外部的服務引入到集群內部來,在集群內部直接使用。沒有任何類型代理被創建,這只有 kubernetes 1.7 或更高版本的 kube-dns 才支持
2.2 ClusterIP
類型為ClusterIP的service,這個service有一個Cluster-IP,其實就一個VIP。具體實現原理依靠kubeproxy組件,通過iptables或是ipvs實現.這種類型的service 只能在集群內訪問。
演示案例
使用tomcat鏡像演示
docker pull tomcat:9.0.20-jre8-alpine資源文件
apiVersion: apps/v1kind: Deploymentmetadata: name: clusterip-demo labels: ? app: clusterip-demospec: replicas: 1 template: ? metadata: ? ? name: clusterip-demo ? ? labels: ? ? ? app: clusterip-demo ? spec: ? ? containers: ? ? ? - name: clusterip-demo ? ? ? ? image: tomcat:9.0.20-jre8-alpine ? ? ? ? imagePullPolicy: IfNotPresent ? ? ? ? ports: ? ? ? ? ? - containerPort: 8080 ? ? restartPolicy: Always selector: ? matchLabels: ? ? app: clusterip-demo---apiVersion: v1kind: Servicemetadata: name: clusterip-sevcice-demospec: ?#service管理pod是通過標簽來管理的,所以這里選擇必須和pod的標簽一樣 selector: ? app: clusterip-demo ports: ? - port: 8080 ? ? targetPort: 8080 type: ClusterIP部署service:
#部署service[root@k8s-master01 service]# kubectl apply -f clusterip-demo.yml deployment.apps/clusterip-demo createdservice/clusterip-sevcice-demo created#查看service 注意虛擬ip 10.1.92.52[root@k8s-master01 service]# kubectl get svcNAME ? ? ? ? ? ? ? ? ? ? TYPE ? ? ? CLUSTER-IP ? EXTERNAL-IP ? PORT(S) ? AGEclusterip-sevcice-demo ? ClusterIP ? 10.1.92.52 ? ? ? ? ?8080/TCP ? 23skubernetes ? ? ? ? ? ? ? ClusterIP ? 10.1.0.1 ? ? ? ? ? ?443/TCP ? 4d#在集群內部同過curl 訪問能訪問tomcat[root@k8s-master01 service]# curl 10.1.92.52:8080 ? ? ? ? ? ? ? Apache Tomcat/9.0.20 ? ? ? ? ? ? ? ? ? ........#service 刪除,deployment、pod一并刪除[root@k8s-master01 service]# kubectl delete -f clusterip-demo.yml deployment.apps "clusterip-demo" deletedservice "clusterip-sevcice-demo" deleted[root@k8s-master01 service]# kubectl get podNo resources found in default namespace.2.3 NodePort
實際應用中我們不可能全部都是集群內部訪問,肯定也需要集群外部訪問,ClusterIP無法滿足需求,而NodePort 可以通過實現方案。其原理是在node上開一個端口,將向該端口的流量導入到kube-proxy,然后由 kube-proxy 進一步到給對應的 pod.
案例演示:
資源文件:
apiVersion: apps/v1kind: Deploymentmetadata: name: nodeport-demo labels: ? app: nodeport-demospec: replicas: 1 template: ? metadata: ? ? name: nodeport-demo ? ? labels: ? ? ? app: nodeport-demo ? spec: ? ? containers: ? ? ? - name: nodeport-demo ? ? ? ? image: tomcat:9.0.20-jre8-alpine ? ? ? ? imagePullPolicy: IfNotPresent ? ? ? ? ports: ? ? ? ? ? - containerPort: 8080 ? ? restartPolicy: Always selector: ? matchLabels: ? ? app: nodeport-demo---apiVersion: v1kind: Servicemetadata: name: nodeport-service-demospec: selector: ? app: nodeport-demo #注意與pod的標簽保持一致(編寫時忘了,坑了15分鐘) ports: ? - port: 9090 #集群內部訪問ip ? ? targetPort: 8080 #映射pod內容器端口 ? ? nodePort: 30088 #集群外部訪問端口 type: NodePort部署service
#部署[root@k8s-master01 service]# kubectl apply -f nodeport-demo.yml deployment.apps/nodeport-demo createdservice/nodeport-service-demo created#查看service 注意虛擬ip 10.1.253.107[root@k8s-master01 service]# kubectl get serviceNAME ? ? ? ? ? ? ? ? ? TYPE ? ? ? CLUSTER-IP ? ? EXTERNAL-IP ? PORT(S) ? ? ? ? AGEkubernetes ? ? ? ? ? ? ClusterIP ? 10.1.0.1 ? ? ? ? ? ? ?443/TCP ? ? ? ? 4d1hnodeport-service-demo ? NodePort ? ?10.1.253.107 ? ? ? ? ?9090:30088/TCP ? 8s#集群內部通過curl訪問,能訪問到tomcat首頁[root@k8s-master01 service]# curl 10.1.253.107:9090 ? ? ? ? ? ? ? Apache Tomcat/9.0.20 ? ? ? ? ? ? .....集群外部通過瀏覽器訪問 http://192.168.223.131:30088(master)和http://192.168.223.132:30088/(work)
2.3 LoadBalancer(收費的沒法玩了)
LoadBalancer類型的service 是可以實現集群外部訪問服務的另外一種解決方案。不過并不是所有的k8s集群都會支持,大多是在公有云托管集群中會支持該類型。負載均衡器是異步創建的,關于被提供的負載均衡器的信息將會通過Service的status.loadBalancer字段被發布出去。
apiVersion: v1kind: Servicemetadata: name: service-davidspec: ports: - port: 3000 ? protocol: TCP ? targetPort: 443 ? nodePort: 30080 selector: ? run: pod-david type: LoadBalancer2.4 ExternalName(很少用)
類型為 ExternalName 的service將服務映射到 DNS 名稱,而不是典型的選擇器,例如my-service或者cassandra。可以使用spec.externalName參數指定這些服務。
kind: ServiceapiVersion: v1metadata: name: service-davidspec: ports: - port: 3000 ? protocol: TCP ? targetPort: 443 ? type: ExternalName ? externalName: www.david.com
總結
以上是生活随笔為你收集整理的k8s nodeport无法访问_k8s学习之service详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 卑字开头的成语有哪些啊?
- 下一篇: 电视剧《功夫足球》的内容是?