kubernetes暴露服務
k8s的dns實作了服務在叢集“内”被自動發現,那麼在生産環境下,服務在k8s叢集”外“被使用和通路呢?
我們來看一下kubernetes暴露服務的方式
一:kube-proxy轉發的兩種模式
一個簡單的網絡代理和負載均衡器,負責service的實作,Service都會在所有的Kube-proxy節點上展現。具體來說,就是實作了内部從pod到service和外部的從node port向service的通路。kube-proxy在轉發時主要有兩種模式Userspace和Iptables。
1.userspace
userspace是在使用者空間,通過kuber-proxy實作LB的代理服務。在K8S1.2版本之前,是kube-proxy預設方式,所有的轉發都是通過kube-proxy實作的。這個是kube-proxy的最初的版本,較為穩定,但是效率也自然不太高。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5iYlVWMkJDOygTMmdDOjFDN4ATZ4MTZwUTNihjYyUWZw8CX0AzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL1M3Lc9CX6MHc0RHaiojIsJye.png)
2.iptables
另外一種方式是iptables方式(如下圖)。是純采用iptables來實作LB。在K8S1.2版本之後,kube-proxy預設方式。所有轉發都是通過Iptables核心子產品實作,而kube-proxy隻負責生成相應的Iptables規則。
注意:
使用Userspace模式(k8s版本為1.2之前預設模式),外部網絡可以直接通路cluster IP。
使用Iptables模式(k8s版本為1.2之後預設模式),外部網絡不能直接通路cluster IP。
二:轉發K8S後端服務的四種方式
方式1:ClusterIP
此類型會提供一個叢集内部的虛拟IP(與Pod不在同一網段),以供叢集内部的pod之間通信使用。ClusterIP也是Kubernetes service的預設類型。
為了實作圖上的功能主要需要以下幾個元件的協同工作:
apiserver:在建立service時,apiserver接收到請求以後将資料存儲到etcd中。
kube-proxy:k8s的每個節點中都有該程序,負責實作service功能,這個程序負責感覺service,pod的變化,并将變化的資訊寫入本地的iptables中。
iptables:使用NAT等技術将virtualIP的流量轉至endpoint中。
具體實作方法:
-
使用userspace模式,修改master的/etc/kubernetes/proxy
把KUBE_PROXY_ARGS="“改為KUBE_PROXY_ARGS=”–proxy-mode=userspace"
2.重新開機kube-proxy服務
3.在核心路由裝置或者源主機上添加一條路由,通路cluster IP段的路由指向到master上。
在客戶端上添加如下路由條目:
[root@vm20 ~]# route add -net 10.254.244.0/24 gw 192.168.245.250
注:10.254.244.0/24是建立service之後的cluster ip所在網段
方式2:NodePort
NodePort模式除了使用cluster ip外,也将service的port映射到每個node的一個指定内部port上,映射的每個node的内部port都一樣。
為每個節點暴露一個端口,通過nodeip + nodeport可以通路這個服務,同時服務依然會有cluster類型的ip+port。内部通過clusterip方式通路,外部通過nodeport方式通路。
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
ports:
- port: 88
targetPort: 80
selector:
app: nginx
apiVersion: v1
kind: Service
metadata:
name: nginx-services
labels:
app: nginx
spec:
type: NodePort
ports:
- port: 88
targetPort: 80
nodePort: 30010
selector:
app: nginx
方式3:loadbalance
[root@master nginx]# cat nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
[root@master nginx]# kubectl create -f nginx-deploy.yaml
[root@master nginx]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-585449566-9459t1/1 Running 0 3m49s
nginx-deployment-585449566-pn8w5 1/1Running 0 3m49s
[root@master nginx]# kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer