service配置(ClusterIP、NodePort、LoadBalancer、ExternalName)
service
ipvs负载均衡
Service 的负载均衡是由 kube-proxy 加上 iptables 来共同实现的.
kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源。
IPVS模式的service,可以使K8s集群支持更多量级的Pod。
service的类型:
-
ClusterIP:默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。
-
NodePort:将Service通过指定的Node上的端口暴露给外部,访问任意一个NodeIP:nodePort都将路由到ClusterIP。
-
LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 :NodePort,此模式只能在云服务器上使用。
-
ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过spec.externlName 设定)
-
yum install -y ipvsadm
-
kubectl edit cm kube-proxy -n kube-system #修改为ipvs模式
更新kube-proxy pod
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模式
默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。
[root@server1 mnt]# vim service.yaml
[root@server1 mnt]# cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
ports:
- name: http
port: 80
targetPort: 80
selector:
app: myapp
type: ClusterIP
NodePort
将Service通过指定的Node上的端口暴露给外部,访问任意一个NodeIP:nodePort都将路由到ClusterIP
[root@server1 pod]# vim svc.yaml
[root@server1 pod]# cat svc.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: myapp
访问节点指定端口时可实现负载均衡
LoadBalance方式
在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 :NodePort,此模式只能在云服务器上使用。
外部访问service,适用共有云上的k8s服务
在私有仓库创建metallb,上传镜像
修改proxy策略
- kubectl edit cm kube-proxy -n kube-system
部署应用metallb.yaml
[root@server1 mnt]# kubectl -n metallb-system get all
NAME READY STATUS RESTARTS AGE
pod/controller-674f4b76b8-8h8c2 1/1 Running 2 28h
pod/speaker-86h7k 0/1 CrashLoopBackOff 221 2d3h
pod/speaker-tv454 0/1 CrashLoopBackOff 49 2d3h
pod/speaker-z4jd4 0/1 CrashLoopBackOff 228 2d3h
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/speaker 3 3 0 3 0 kubernetes.io/os=linux 2d3h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/controller 1/1 1 1 2d3h
NAME DESIRED CURRENT READY AGE
replicaset.apps/controller-674f4b76b8 1 1 1 2d3h
[root@server1 mnt]# kubectl -n metallb-system get secrets
NAME TYPE DATA AGE
controller-token-l75gx kubernetes.io/service-account-token 3 2d3h
default-token-j42nb kubernetes.io/service-account-token 3 2d3h
memberlist Opaque 1 2d3h
speaker-token-pzv75 kubernetes.io/service-account-token 3 2d3h
[root@server1 mnt]# kubectl -n metallb-system get pod
NAME READY STATUS RESTARTS AGE
controller-674f4b76b8-8h8c2 1/1 Running 2 28h
speaker-86h7k 0/1 CrashLoopBackOff 221 2d3h
speaker-tv454 0/1 CrashLoopBackOff 49 2d3h
speaker-z4jd4 0/1 CrashLoopBackOff 228 2d3h
编辑IP池配置文件
[root@server1 mnt]# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 172.25.33.10-172.25.33.20
- kubectl apply -f configmap.yaml
[root@server1 mnt]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 5d4h
[root@server1 mnt]# kubectl get cm -n metallb-system
NAME DATA AGE
config 1 2d3h
kube-root-ca.crt 1 2d3h
编辑svc文件选中后端pod标签app: myapp ,应用svc文件
[root@server1 pod]# cat lb-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: lb-svc
spec:
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
selector:
app: myapp
type: LoadBalancer
分配到ip
在其它主机访问
External
将服务通过 DNS CNAME 记录方式转发到指定的域名(通过spec.externlName 设定)(externlName可以为svc设定地址名称,且可以在svc上变动)
[root@server1 mnt]# cat ex-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ExternalName
externalName: www.westos.org
- kubectl apply -f ex-svc.yaml
- kubectl get svc my-service
- yum install -y bind-utils.x86_64
- dig -t A my-service.default.svc.cluster.local. @10.244.116.131 查看解析过程
[root@server1 mnt]# dig -t A my-service.default.svc.cluster.local. @10.244.116.131
; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> -t A my-service.default.svc.cluster.local. @10.244.116.131
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22177
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;my-service.default.svc.cluster.local. IN A
;; ANSWER SECTION:
my-service.default.svc.cluster.local. 30 IN CNAME www.westos.org.
;; Query time: 2811 msec
;; SERVER: 10.244.116.131#53(10.244.116.131)
;; WHEN: Fri Jul 30 15:33:10 CST 2021
;; MSG SIZE rcvd: 129
-
ExternalIP
service允许为其分配一个公有IP,注意 :k8s的externalIP只是提供了给了一个外部访问的ip,但如果没有pod开放对应接口是无法获取到内容的,因此需要与实际pod相对应。此IP不纳入Kubectl管理,无法通过外部节点访问,若需访问则要将其设置在节点的真实网卡上。 -
kubectl apply -f ex-svc1.yaml
[root@server1 mnt]# cat ex-svc1.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: myapp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
externalIPs:
- 172.25.33.15