clusterip定义
ClusterIP类型的service创建时,k8s会通过etcd从可分配的ip池中分配一个全局唯一、不可修改的虚拟ip地址,只能在集群内部访问。所有访问该ip的请求,都会被iptables转发到后端的endpoints中。
clusterip举例
1、先创建一个Deployment(Python实现的HTTP服务)请求这个Web Server的时候,会发回这个server的hostname(如果是container,那就是container的hostname);
2、通过kubectl expose给刚才这个deployment创建一个service,端口绑定为8081;
这样,service就有了一个Cluster IP,其实是vip。
apiVersion: apps/v1
kind: Deployment
metadata:
name: pythonHttp-deployment
labels:
app: pythonHttp
namespace: ycloans-repayment-namespace
spec:
replicas: 3
selector:
matchLabels:
app: pythonHttp
template:
metadata:
labels:
app: pythonHttp
spec:
containers:
- name: pythonHttp
image: python:2.7
imagePullPolicy: IfNotPresent
command: ["/bin/bash"]
args: ["-c", "echo \"<p>Hello from $(hostname)</p>\" > index.html; python -m PythonHttpServer 8081"]
ports:
- name: http
containerPort: 8081
---
apiVersion: v1
kind: Service
metadata:
name: pythonHttp-service
namespace: ycloans-repayment-namespace
spec:
selector:
app: pythonHttp
ports:
- protocol: TCP
port: 8081
targetPort: 8081
#进入名为pythonhttp-deployment-xxxx-xxx 的pod控制台,输入:
curl http://localhost:8081
<p>Hello from pythonhttp-deployment-xxxx-xxx</p>
每次访问都会返回该容器的容器名,其他pod也是如此。
#每次返回的hostname不同,vip实现了负载均衡
for i in `seq 4`; do curl 10.105.12.238:8081; done
<p>Hello from pythonhttp-deployment-7dcd755558-5g5h6</p>
<p>Hello from pythonhttp-deployment-7dcd755558-kxh4z</p>
<p>Hello from pythonhttp-deployment-7dcd755558-5g5h6</p>
<p>Hello from pythonhttp-deployment-7dcd755558-kxh4z</p>
实现负载均衡
以下组件参与负载均衡工作:
1、apiserver:kubectl命令向apiserver发送创建service的命令,apiserver接收到请求以后将数据存储到etcd中。
2、kube-proxy:k8s的每个节点中都有一个叫做kube-proxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的iptables中
3、iptables:使用NAT等将vip的流量转至endpoint中
任意一台k8s节点运行iptables -L -v -n -t nat,找到pythonhttp-service的vip,这个chain表示:访问10.105.12.238:8081的流量按照随机的概率,分别以0.33333333349,0.50000000000的概率,转发到另外两个Chain,其实就是pod。
Chain KUBE-SVC-R6MFBEUAZVGLP6NB (1 references) pkts bytes target prot opt in out source destination 5 300 KUBE-MARK-MASQ tcp -- * * !10.244.0.0 10.105.12.238 /* ycloans-repayment-namespace/pythonhttp-service cluster IP */ tcp dpt: 8081 2 120 KUBE-SEP-MT5IQ7BD3QSJZOGM all -- * * 0.0.0.0/0 0.0.0.0/0 /* ycloans-repayment-namespace/pythonhttp-service */ statisti c mode random probability 0.33333333349 1 60 KUBE-SEP-G2ESXO446AEIT5N4 all -- * * 0.0.0.0/0 0.0.0.0/0 /* ycloans-repayment-namespace/pythonhttp-service */ statisti c mode random probability 0.50000000000 2 120 KUBE-SEP-A5AZ7AZCR63OZ7BM all -- * * 0.0.0.0/0 0.0.0.0/0 /* ycloans-repayment-namespace/pythonhttp-service */
Chain KUBE-SEP-G2ESXO446AEIT5N4 (1 references)
集群外部访问
可以使用k8s proxy API来访问。kube-apiserver只是代理http请求,然后将请求转发到某个节点上的 kubelet 进程监听的端口上。最后实际是由该端口上的REST API响应请求。在master节点上创建k8s proxy API:
kubectl --proxy --port=8080
Starting to serve on 127.0.0.1:8080
访问服务的格式:/api/v1/namespaces//services//proxy/
kubectl --get svc -n ycloans-repayment-namespace
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
#省略
pythonhttp-service ClusterIP 10.97.212.105 <none> 8081/TCP 36m
curl http://localhost:8080/api/v1/namespaces/ycloans-repayment-namespace/services/pythonhttp-service:http/proxy/
<p>Hello from pythonhttp-deployment-7dcd755558-fpw75</p>
curl http://localhost:8080/api/v1/namespaces/ycloans-repayment-namespace/services/pythonhttp-service:http/proxy/
<p>Hello from pythonhttp-deployment-7dcd755558-m6qwz</p>
curl http://localhost:8080/api/v1/namespaces/ycloans-repayment-namespace/services/pythonhttp-service:http/proxy/
<p>Hello from pythonhttp-deployment-7dcd755558-fpw75</p>