kubernetes service的工作模式包括:ClusterIP模式、NodePort模式、LoadBalancer模式、ExternalName模式。
NodePort模式的作用:主要是把集群内部的服务暴露出集群以外。
如果是集群内部的互相沟通,可以通过ClusterIP模式去使用。
原因:NodePort是一种升级版的ClusterIP,不仅可以做到ClusterIP拥有的功能,还支持在当前的物理网卡上绑定一个物理接口,以此实现外部访问。但是功能越多,相当于它消耗的代价就会越高。但是如果不需要集群外部访问,又消耗了更多的一些额外的资源,那肯定不是最理想的,所以一定要有它的功能或者需要使用它的功能,我们再开启或者升级,而不是一次给它上到最高,那可能会带来一定的资源浪费。
NodePort的架构:
①:底层通过deployment控制器创建几个pod。
②:给这些底层pod创建一个ipvs的clusterip类型的服务svc。
③:再次,创建一个deployment类型的控制器,运行一些nginx的pod。这些nginx被nodeport类型的服务所匹配和关联,再绑定到当前物理节点对应物理网卡的物理端口之上。端口范围一般是大于3万,端口范围是30000到32767号端口。
④:NodePort类型服务在物理节点对应物理网卡的物理接口范围是大于3万的,可以在kube-apiserver启动的时候去定义这个端口范围。可以启动kube-apiserver时指定--service-node-port-range=30000-32767去设置。
定义nodeport类型服务的资源清单文件service-nodeport.yaml:
apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
namespace: default
spec:
type:NodePort
selector:
app: myapp
release: stabel
svc: nodeport
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30010
这是当前nodeport类型service的资源清单。这个服务service标签选择器中的标签应该是被匹配pod标签的子集。ports定义当前集群的端口,前面是横杠-表示是对象列表,端口是可以写多个的。NodePort模式可以理解成是ClusterIP模式的升级版本,targetPort代表后端真实服务器的端口号,nodePort代表当前物理网卡上绑定的物理端口号,默认是大于三万的,而且官方强烈不建议通过nodeport手动指定这个端口号,官方会自动去分配nodePort这个端口号。这是一种更理想的状态,防止端口号冲突。
K8s进入容器:
kubectl exec -it $pod_name -c $container_name -n $namespace_name -- /bin/sh
touch deployment-nodeport.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-nodeport-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: stabel
svc: nodeport
template:
metadata:
labels:
app: myapp
release: stabel
env: test
svc: nodeport
spec:
containers:
- name: myapp-container
image: nginx
imagePullPolicy: Always
ports:
- name: http
containerPort: 80
控制器期望spec里面选择器匹配3个标签组成的集合,template就是创建pod的模板。pod模板里面的标签,定义了4个,是满足标签选择器标签的集合的。
创建deployment类型的pod:
kubectl apply -f deployment-nodeport.yaml
查看创建出来的pod:
kubectl get pod --all-namespaces | grep myapp-nodeport-deploy
会查看到运行了3个副本的pod。
创建nodeport类型的service:
kubectl apply -f service-nodeport.yaml
查看创建出来的服务:
kubectl get svc --all-namespaces| grep myapp-nodeport
可以看到,访问集群的30010端口,相当于是访问物理网卡的物理端口。
80号端口就是在集群内部需要访问这个service时可以使用的一个端口,配合着CLUSTER-IP私有IP和这个集群内部端口,我们就可以使用负载均衡的方案访问到它们。80号端口表示通过后端访问集群负载调度器,负载调度器的端口号是80。
NodePort类型的服务service,可以看作是一种升级版的ClusterIP类型。
访问路径是:nodeIP:NodePort-->CLUSTER-IP:Port-->Pod_IP:targetPort
nodeport端口号表示当前物理网卡上绑定的物理的端口号。
使用vim编辑文件的时候,出现格式错乱的情况,可以输入set paste设置粘贴模式之后再粘贴。
Nodeport端口号30010代表物理网卡访问的端口。
80端口是集群内部访问服务的端口,CLUSTER-IP配合着80端口,就可以在集群内部以负载均衡的方式访问到服务。
nodePort类型服务可以理解成一种升级版的clusterip类型服务。
查看当前ipvs负载均衡的规则:
ipvsadm -Ln
可以看到负载均衡规则中的算法、后端真实服务器的IP地址。
查看后端真实服务器的地址:
kubectl get pod -o wide -n $namespace_name
NodePort类型的服务,可以通过CLUSTER-IP:Port的方式在集群内部访问到。
查看pod信息:
kubectl get pod --all-namespaces
进入容器:
kubectl exec -it $pod_name -c $container_name -n $namespace_name -- /bin/bash
wget $svc_name.$namespace_name.svc.cluster.local./hostname.html && cat hostname.html && rm -rf hostname.html
可以知道,在集群内部的容器内部通过域名解析也可以实现nodeport 类型服务的访问。
nodeport类型的服务支持clusterip类型的所有功能。额外的功能就来自于物理网卡nodeport 定义的对外端口以外的访问。
如果一个worker node节点有多块网卡的话,那么它会把当前机器的每一块可用网卡的地址都创建一个ipvs 集群。它会根据当前网卡的实际信息去编写当前的负载均衡集群。可以通过浏览器访问NodeIP:NodePort的方式去访问nodeport 类型服务的对外提供服务的端口。
从集群以外的网络通过当前机器的物理网卡可以访问到kubernetes集群内部。
Nodeport是将集群内部的服务暴露到集群以外的用户的一个非常有效的手段。
当前的每一个物理节点物理网卡的nodeport端口都可以访问,并且是负载均衡的。我们可从每一个节点上去访问到我们当前的后端pod,是没有任何问题的。只要是当前kubernetes 节点,只要创建了nodeport类型的服务,那当前的nodeport 端口每一个节点的每一个物理网卡的每一个物理有效的网卡IP都可以进行外部访问。
在真正的生产环境中,我们可能需要在外部再加一个调度器去负载到当前的每一个节点。以此保证当前的任何一个节点宕机,不会造成我们用户的访问中断。这就是nodeport类型服务的特性。
景色
鼓励的话语:海到尽头天作岸,山登绝顶我为峰。不屈的意志,会带我们杀出重围。具有坚定的信念,坚强的毅力,顽强的斗志,我们的人生终将辉煌!