Kubernetes(五) - Service
Kubernetes解決的另外一個痛點就是服務發現,服務發現機制和容器開放訪問都是通過Service來實現的,把Deployment和Service關聯起來只需要Label標簽相同就可以關聯起來形成負載均衡,基于kuberneres的DNS服務我們只需要訪問Service的名字就能以負載的方式訪問到各個容器
Kubernetes官方文檔:https://kubernetes.io/docs/reference/
Kubernetes官方Git地址:https://github.com/kubernetes/kubernetes
PS:本系列中使用 KubernetesV1.8 RancherV1.6.14
1. Service的三種類型
Service有三種類型:
-
ClusterIP:默認類型,自動分配一個僅cluster內部可以訪問的虛擬IP 常用于內部程序互相的訪問,比如Gitlab需要訪問Redis的postgresql,但是是內部使用的不需要外部訪問,這個時候用ClusterIP就比較合適
-
NodePort:在ClusterIP基礎上為Service在每臺機器上綁定一個端口,這樣就可以通過<NodeIP>:NodePort來訪問改服務 當我們的Gitlab需要提供訪問,可以使用NodePort指定一個端口釋放服務,然后外層負載均衡映射就可以在外部訪問,或者直接訪問對應的端口
PS:NodePort方式暴露服務的端口的默認范圍(30000-32767)如果需要修改則在apiserver的啟動命令里面添加如下參數 –service-node-port-range=1-65535
- LoadBalancer:在NodePort的基礎上,借助cloud provider創建一個外部的負載均衡器,并將請求轉發到<NodeIP>:NodePort LoadBalancer是NodePort的升級版本,相當于和cloud provider結合不需要手動指定
我們經常使用的還是上面前兩種方式,我們先創建一個nginx-deployment鏡像2個Pod以便于接下來的使用
> vim nginx-deployment.yamlapiVersion: extensions/v1beta1 # K8S對應的API版本 kind: Deployment # 對應的類型 metadata:name: nginx-deploymentlabels:name: nginx-deployment spec:replicas: 2 # 鏡像副本數量template:metadata:labels: # 容器的標簽 可和service關聯app: nginxspec:containers:- name: nginx # 容器名和鏡像image: nginximagePullPolicy: Always> kubectl create -f nginx-deployment.yaml我們分別修改一下對應的輸出
> echo nginx1 > /usr/share/nginx/html/index.html > echo nginx2 > /usr/share/nginx/html/index.html安裝好ping 和 curl
> apt-get update > apt-get install curl iputils-ping2. ClusterIP
> vim test-clusterip-service.yaml apiVersion: v1 kind: Service metadata:name: test-clusterip-service # 名稱labels:name: test-clusterip-service spec:type: ClusterIP # 開發端口的類型selector: # service負載的容器需要有同樣的labelsapp: nginxports:- port: 80 # 通過service來訪問的端口targetPort: 80 # 對應容器的端口 > kubectl create -f test-clusterip-service.yaml service "test-clusterip-service" created > kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 12d test-clusterip-service ClusterIP 10.43.202.97 <none> 80/TCP 18s應為selector關聯上了Deployment的Label所以直接訪問是可以訪問到的具體nginx鏡像內,而且應為是兩個Pod所以是負載均衡之前我們修改了輸出多次訪問可以看到不一樣的結果,基于Kube-DNS也可以使用Service名稱進行訪問
root@nginx-deployment-68fcbc9696-wbgxr:/usr/share/nginx/html# curl 10.43.202.97 nginx2 root@nginx-deployment-68fcbc9696-wbgxr:/usr/share/nginx/html# curl test-clusterip-service nginx13. NodePort
NodePort設計出來的主要目的就是對外部放出服務,也就是被外部能夠訪問到,
> vim test-nodeport-service.yaml apiVersion: v1 kind: Service metadata:name: test-nodeport-service # 名稱labels:name: test-nodeport-service spec:type: NodePort # 開發端口的類型selector: # service負載的容器需要有同樣的labelsapp: nginxports:- port: 80 # 通過service來訪問的端口targetPort: 80 # 對應容器的端口nodePort: 30080 # 對應需要放到宿主機IP上的端口> kubectl create -f test-nodeport-service.yaml service "test-nodeport-service" created > kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 12d test-clusterip-service ClusterIP 10.43.202.97 <none> 80/TCP 14m test-nodeport-service NodePort 10.43.101.60 <none> 80:30080/TCP 5s此時在宿主機上的30080端口就可以訪問到我們的兩個Nginx容器了,如果機器綁定的有IP的話就可以直接訪問或者在使用負載均衡對外放出服務
只有在KUbernetes中才會受到Kube-DNS的影響,在宿主機上無法使用test-nodeport-service訪問Service只能通過NodePort進行訪問
[root@k8s-m ~]# curl 127.0.0.1:30080 nginx2 [root@k8s-m ~]# curl 127.0.0.1:30080 nginx14. Ingress
Service主要是處理4層TCP負載,但是往往對外需要放出HTTP七層協議的服務,一般我們在一套集群下如果有多個HTTP服務會使用Nginx來統一接受80端口的數據然后通過域名或者是訪問路徑來選擇不同的服務,Ingress就是解決這個問題誕生的,Ingress可以和Service結合對80端口的訪問更具域名的過濾和訪問路徑的過濾路由到對應的service,我們一起看幾個例子:
foo.bar.com -> 172.168.0.128 -> / foo nginx:80/ bar nginx:80 > vim ing.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata:name: testannotations:nginx.ingress.kubernetes.io/rewrite-target: / spec:rules:- host: foo.bar.comhttp:paths:- path: /foobackend:serviceName: nginxservicePort: 80- path: /barbackend:serviceName: nginxservicePort: 80 > kubectl create -f ing.yaml > kubectl get ing NAME RULE BACKEND ADDRESS test -foo.bar.com/foo nginx:80/bar nginx:80 foo.bar.com --| |-> foo.bar.com nginx:80 | 172.168.0.128 | bar.foo.com --| |-> bar.foo.com nginx:80 apiVersion: extensions/v1beta1 kind: Ingress metadata:name: test spec:rules:- host: foo.bar.comhttp:paths:- backend:serviceName: nginxservicePort: 80- host: bar.foo.comhttp:paths:- backend:serviceName: nginxservicePort: 80支持TLS需要使用Secret預先配置好對應的證書
apiVersion: v1 data:tls.crt: base64 encoded certtls.key: base64 encoded key kind: Secret metadata:name: testsecretnamespace: default type: Opaque apiVersion: extensions/v1beta1 kind: Ingress metadata:name: no-rules-map spec:tls:- secretName: testsecretbackend:serviceName: nginxservicePort: 80使用Ingress能實現部分功能,但是筆者推薦使用網關服務(比如kong)來進行處理會更具靈活功能更下強大可控
小技巧
- 跨namespace訪問Service 到這里我們還沒有展開說NameSpace,NameSpace隔離了資源,比如你在A中不能創建兩個名字一樣的Service(Kubernetes其他資源同理),但是創建出一個NameSpace的是可以創建名字為Nginx的Service的 這個時候你在A空間中訪問nginx-service的是A空間的容器,在B空間訪問是B空間的nginx-service 但是如果需要在B空間訪問A空間的Nginx-service要怎么辦呢?
Kube提供在訪問Service的時候末尾增加NameSpace名字進行訪問,在B空間訪問A的nginx-service可以使用nginx-service.A 進行訪問
本文轉自開源中國-Kubernetes(五) - Service
總結
以上是生活随笔為你收集整理的Kubernetes(五) - Service的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软推出VS Code新特性,为Type
- 下一篇: 《汇编语言》实验五课程