赞
踩
Kubernetes Service定义了这样一种抽象:逻辑上的一组Pod,一种可以访问它们的策略 —— 通常被称为微服务。这一组Pod能够被Service访问到,通常是通过selector实现的。
Service可以提供负载均衡的能力,但是使用上存在如下限制:
在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName 的形式。
从Kubernetes v1.0开始,已经可以使用 userspace代理模式。Kubernetes v1.1添加了 iptables 代理模式,在 Kubernetes v1.2 中kube-proxy 的 iptables 模式成为默认设置。Kubernetes v1.8添加了 ipvs 代理模式。
为什么不使用 DNS 轮询?
原因如下:
这种模式,kube-proxy 会监视 Kubernetes 控制节点对 Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会配置 iptables 规则,从而捕获到达该 Service 的 clusterIP 和端口的请求,进而将请求重定向到 Service 的一组 backend 中的某个上面。对于每个 Endpoints 对象,它也会配置 iptables 规则,这个规则会选择一个 backend 组合。
默认的策略是,kube-proxy 在 iptables 模式下随机选择一个 backend。
使用 iptables 处理流量具有较低的系统开销,因为流量由 Linux netfilter 处理,而无需在用户空间和内核空间之间切换。 这种方法也可能更可靠。
如果 kube-proxy 在 iptables模式下运行,并且所选的第一个 Pod 没有响应,则连接失败。 这与userspace模式不同:在这种情况下,kube-proxy 将检测到与第一个 Pod 的连接已失败,并会自动使用其他后端 Pod 重试。
我们可以使用 Pod readiness 探测器 验证后端 Pod 是否可以正常工作,以便 iptables 模式下的 kube-proxy 仅看到测试正常的后端。这样做意味着可以避免将流量通过 kube-proxy 发送到已知已失败的Pod。
在 ipvs 模式下,kube-proxy监视Kubernetes服务(Service)和端点(Endpoints),调用 netlink 接口相应地创建 IPVS 规则, 并定期将 IPVS 规则与 Kubernetes服务(Service)和端点(Endpoints)同步。该控制循环可确保 IPVS 状态与所需状态匹配。访问服务(Service)时,IPVS 将流量定向到后端Pod之一。
IPVS代理模式基于类似于 iptables 模式的 netfilter 挂钩函数,但是使用哈希表作为基础数据结构,并且在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。
IPVS提供了更多选项来平衡后端Pod的流量。这些是:
注意:要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 之前使 IPVS Linux 在节点上可用。 当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 如果未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。
Kubernetes 中Service有以下4中类型:
需要注意的是:Service 能够将一个接收 port 映射到任意的 targetPort。默认情况下,targetPort 将被设置为与 port 字段相同的值。
Service域名格式:( s e r v i c e n a m e ) . (service name).(servicename).(namespace).svc.cluster.local,其中 cluster.local 为指定的集群的域名
Deoployment的资源清单
[root@master test]# cat test.yml --- apiVersion: v1 kind: Pod metadata: name: test labels: app: test spec: containers: - image: nginx name: nginx --- apiVersion: v1 kind: Service metadata: name: test spec: ports: - port: 80 targetPort: 80 nodePort: 30001 selector: app: test type: NodePort [root@master test]# kubectl apply -f deploy.yml deployment.apps/deploy created [root@master test]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES deploy-585449566-lkdnn 1/1 Running 0 24s 10.244.2.68 node2.example.com <none> <none> deploy-585449566-ngbwj 1/1 Running 0 24s 10.244.1.75 node1.example.com <none> <none> deploy-585449566-nlnpl 1/1 Running 0 24s 10.244.1.76 node1.example.com <none> <none> [root@master test]# curl 10.244.2.68 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> [root@master test]# curl 10.244.1.75 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> [root@master test]# curl 10.244.1.76 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>
[root@master test]# cat svc.yml apiVersion: v1 kind: Service metadata: name: svc spec: selector: app: nginx ports: - name: nginx port: 80 targetPort: 80 [root@master test]# kubectl apply -f svc.yml service/svc created [root@master ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d svc ClusterIP 10.96.69.194 <none> 80/TCP 8s [root@master ~]# curl 10.96.69.194 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>
[root@master test]# cat svc-nodeport.yml apiVersion: v1 kind: Service metadata: name: svc-nodeport spec: type: NodePort selector: app: nginx ports: - name: nginx1 port: 80 targetPort: 80 nodePort: 30001 [root@master test]# kubectl apply -f svc-nodeport.yml service/svc-nodeport created [root@master test]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d svc-nodeport NodePort 10.109.130.221 <none> 80:30001/TCP 95s [root@master test]# curl 10.109.130.221:30001 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> [root@master test]# curl 10.109.130.221 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>
在使用支持外部负载均衡器的云提供商的服务时,设置 type 的值为 “LoadBalancer”, 将为 Service 提供负载均衡器。 负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段发布出去。
apiVersion: v1 kind: Service metadata: name: test1 spec: selector: app: test1 ports: - protocol: TCP port: 80 targetPort: 9376 clusterIP: 10.106.217.38 type: LoadBalancer status: loadBalancer: ingress: - ip: 192.15.8.127
来自外部负载均衡器的流量将直接重定向到后端 Pod 上,不过实际它们是如何工作的,这要依赖于云提供商。
某些云提供商允许设置 loadBalancerIP。 在这些情况下,将根据用户设置的 loadBalancerIP 来创建负载均衡器。 如果没有设置 loadBalancerIP 字段,将会给负载均衡器指派一个临时 IP。 如果设置了 loadBalancerIP,但云提供商并不支持这种特性,那么设置的 loadBalancerIP 值将会被忽略掉。
[root@master test]# cat test.yml --- apiVersion: apps/v1 kind: Deployment metadata: name: test labels: app: test spec: replicas: 3 selector: matchLabels: app: test template: metadata: labels: app: test spec: containers: - image: dockerimages123/httpd:v0.1 name: test imagePullPolicy: IfNotPresent [root@master test]# kubectl apply -f test.yml deployment.apps/test created [root@master haproxy]# kubectl get pod NAME READY STATUS RESTARTS AGE test-85cd869cd6-7524t 1/1 Running 0 4m49s test-85cd869cd6-8khgw 1/1 Running 0 4m49s test-85cd869cd6-kc7fw 1/1 Running 0 4m49s // 滚动更新 [root@master haproxy]# kubectl set image deploy/test test=dockerimage123/httpd:v2.0 deployment.apps/test image updated [root@master haproxy]# kubectl get pod NAME READY STATUS RESTARTS AGE test-6cfbd9b7f-5dxjk 1/1 Running 0 13s test-6cfbd9b7f-8kbs8 1/1 Running 0 11s test-6cfbd9b7f-sv9km 1/1 Running 0 14s test-85cd869cd6-7524t 1/1 Terminating 0 9m24s test-85cd869cd6-8khgw 1/1 Terminating 0 9m24s test-85cd869cd6-kc7fw 1/1 Terminating 0 9m24s [root@master haproxy]# kubectl get pod NAME READY STATUS RESTARTS AGE test-6cfbd9b7f-5dxjk 1/1 Running 0 103s test-6cfbd9b7f-8kbs8 1/1 Running 0 101s test-6cfbd9b7f-sv9km 1/1 Running 0 104s [root@master haproxy]# kubectl rollout history deploy test deployment.apps/test REVISION CHANGE-CAUSE 1 <none> 2 <none> 3 <none> [root@master haproxy]# kubectl rollout history deploy test --revision=3 deployment.apps/test with revision #3 //查看上一个版本的信息 Pod Template: Labels: app=test pod-template-hash=6cfbd9b7f Containers: test: Image: dockerimages123/httpd:v2.0 Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> [root@master haproxy]# kubectl rollout undo deploy test //回滚到上一个版本 deployment.apps/test rolled back [root@master haproxy]# kubectl get pod NAME READY STATUS RESTARTS AGE test-6cfbd9b7f-5dxjk 1/1 Running 0 32m test-6cfbd9b7f-8kbs8 1/1 Running 0 32m test-6cfbd9b7f-sv9km 1/1 Running 0 32m
[root@master test]# kubectl create deploy test --image nginx
deployment.apps/test1 created
[root@master test]# kubectl get pod
test1-6d5588f8cc-4hgnt 1/1 Running 0 6m33s
[root@master test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test-5f6778868d-4t9xd 1/1 Running 0 2m23s
test1-6d5588f8cc-4hgnt 1/1 Running 0 8m51s
test1-6d5588f8cc-b9qsw 1/1 Running 0 49s
test1-6d5588f8cc-vkvh5 1/1 Running 0 49s
[root@master test]# cat test.yml --- apiVersion: v1 kind: Pod metadata: name: test labels: app: test spec: containers: - image: nginx name: nginx - image: redis name: redis - image: memcached name: memcached [root@master test]# kubectl apply -f test.yml pod/test created [root@master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test3 3/3 Running 0 18m
[root@master test]# cat test.yml --- apiVersion: v1 kind: Pod metadata: name: test labels: app: test spec: containers: - image: nginx name: nginx --- apiVersion: v1 kind: Service metadata: name: test1 spec: ports: - port: 80 targetPort: 80 nodePort: 30001 selector: app: test1 type: NodePort [root@master test]# kubectl apply -f test.yml pod/test unchanged service/test created [root@master test]# kubectl get pod,svc NAME READY STATUS RESTARTS AGE pod/test 1/1 Running 0 50s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d1h service/test4 NodePort 10.110.1100.198 <none> 80:30001/TCP 50s [root@master test]# curl 10.110.1100.198 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> [root@master test]# curl 192.168.182.150:30001 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>
[root@master test]# kubectl run test2 --image busybox -- sleep 500 pod/test2 created [root@master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test2 1/1 Running 0 22s [root@master test]# kubectl exec -it test2 -- /bin/sh / # nslookup kubernetes Server: 10.96.0.10 Address: 10.96.0.10:53 Name: kubernetes.default.svc.cluster.local Address: 10.96.0.1 *** Can't find kubernetes.svc.cluster.local: No answer *** Can't find kubernetes.cluster.local: No answer *** Can't find kubernetes.example.com: No answer *** Can't find kubernetes.default.svc.cluster.local: No answer *** Can't find kubernetes.svc.cluster.local: No answer *** Can't find kubernetes.cluster.local: No answer *** Can't find kubernetes.example.com: No answer
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。