赞
踩
Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。
service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)
1、Cluster IP(虚拟IP):默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。想在外部访问需要结合node port。
2、Node Port(节点端口):将Service通过指定的Node上的端口暴露给外部,访问任意一个Node IP:nodePort都将路由到ClusterIP。
3、Load Balancer(负载均衡器):在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 NodeIP:NodePort,此模式只能在云服务器上使用。
4、 External Name(服务对外的名称):将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。
Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。
kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源。
server1:172.25.38.1 harbor仓库端
server2:172.25.38.2 k8s master端
server3:172.25.38.3 k8s node端
server4:172.25.38.4 k8s node端
IPVS模式的service,可以使K8s集群支持更多量级的Pod。
在server2上下载ipvsadm,并修改模式为ipvs
yum install -y ipvsadm
kubectl edit cm kube-proxy -n kube-system #修改为ipvs模式
以删掉的方式更新kube-proxy,会自动重建
kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
IPVS模式下,kube-proxy会在service创建后,在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配service IP。
kube-proxy通过linux的IPVS模块,以rr轮询方式调度service中的Pod
此模式下,service会被分配一个ClusterIP,此IP默认会通过RR策略轮询后端pod。但因为没有对应的网络实体,所以外部无法访问,只能内部访问。
service定义文件内容如下:
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
ports:
- name: http
port: 80
targetPort: 80
selector:
app: myapp
type: ClusterIP
应用创建service,可以看到clusterIP
此方式会将node节点主机的端口绑定至Service,通过节点主机的指定端口可以访问pod,提供负载均衡策略。
service定义文件内容如下:
apiVersion: v1
kind: Service
metadata:
name: mysvc
spec:
ports:
- name: http
port: 80
targetPort: 80
selector:
app: nginx
type: NodePort
应用创建service,可以看到开放端口,查看策略为rr,端口也正常开放
访问节点指定端口时可以负载均衡
构建LoadBalance需要metallb组件。首先导入metallb镜像,在私有仓库创建metallb。
docker load -i metallb-v0.10.2.tar
docker push reg.westos.org/metallb/controller:v0.10.2
docker push reg.westos.org/metallb/speaker:v0.10.2
修改proxy策略,strictARP改为 true,编写定义文件,文件内容过长就不放了,应用文件.
编辑IP池配置文件configmap.yaml,内容如下
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 172.25.38.100-172.25.38.200
应用文件
编辑service定义文件,内容如下
apiVersion: v1
kind: Service
metadata:
name: lb-svc
spec:
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
selector:
app: myapp
type: LoadBalancer
应用文件
已经分配到了一个负载均衡器的IP,外部可以通过这个IP访问服务
ExternalName:可以为svc设定地址名称,并且可以在svc上变动。检验时无需为svc分配pod资源。
编写定义文件,内容如下:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ExternalName
externalName: www.westos.org
应用文件
通过如下命令可以得到dns服务器的ip,我们下面解析要用
使用如下命令可以获得解析,没有问题
service允许为其分配一个公有IP(如下文件),注意 k8s的externalIPs只是提供了给了一个外部访问的ip,但如果没有pod开放对应接口是无法获取到内容的,因此需要与实际pod相对应。
$ vim ex-service.yaml
apiVersion: v1
kind: Service
metadata:
name: ex-service
spec:
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
externalIPs:
- 172.25.38.100
此IP不纳入Kubectl管理,无法通过外部节点访问,若需访问则要将其设置在节点的真实网卡上。
k8s内内置dns解析服务,用于实现域名访问
创建并进入交互式pod,使用nslookup 命令查询dns记录,例如可以查看到lb-svc的分配ip
查看kube-dns,可以看到dns端口为9153,以及dns服务节点10.244.0.18:9153,10.244.0.19:9153
Headless Service不需要分配一个VIP(虚拟IP),而是直接以DNS记录的方式解析出被代理Pod的IP地址。
域名格式:$(servicename).$(namespace).svc.cluster.local
Pod滚动更新后,依然可以解析。
编写定义文件,内容如下
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- name: http
port: 80
targetPort: 80
selector:
app: nginx
clusterIP: None
应用文件,进入交互式pod,查看解析,并进行域名访问,访问失败
是因为需要一个标签匹配的pod来提供访问,而我没有,更改一个pod的标签,得到后端节点
再进入解析就没有问题了,得到后端解析
访问也没有问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。