k8s学习笔记-Server资源
工作模式:
在 Kubernetes v1.0 版本,代理完全在 userspace。在 Kubernetes v1.1 版本,新增了 iptables 代理,但并不是默认的运行模式。 从 Kubernetes v1.2 起,默认就是 iptables 代理。
在 Kubernetes v1.0 版本,Service 是 “4层”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了 Ingress API(beta 版),用来表示 “7层”(HTTP)服务。
userspace: 1.1 -
这种模式,kube-proxy 会监视 Kubernetes master 对 Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会在本地 Node 上打开一个端口(随机选择)。 任何连接到“代理端口”的请求,都会被代理到 Service 的backend Pods 中的某个上面(如 Endpoints 所报告的一样)。 使用哪个 backend Pod,是基于 Service 的 SessionAffinity 来确定的。 最后,它安装 iptables 规则,捕获到达该 Service 的 clusterIP(是虚拟 IP)和 Port 的请求,并重定向到代理端口,代理端口再代理请求到 backend Pod。
网络返回的结果是,任何到达 Service 的 IP:Port 的请求,都会被代理到一个合适的 backend,不需要客户端知道关于 Kubernetes、Service、或 Pod 的任何信息。


iptables: 1.10 -
这种模式,kube-proxy 会监视 Kubernetes master 对 Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会安装 iptables 规则,从而捕获到达该 Service 的 clusterIP(虚拟 IP)和端口的请求,
进而将请求重定向到 Service 的一组 backend 中的某个上面。 对于每个 Endpoints 对象,它也会安装 iptables 规则,这个规则会选择一个 backend Pod。
和 userspace 代理类似,网络返回的结果是,任何到达 Service 的 IP:Port 的请求,都会被代理到一个合适的 backend,不需要客户端知道关于 Kubernetes、Service、
或 Pod 的任何信息。 这应该比 userspace 代理更快、更可靠。然而,不像 userspace 代理,如果初始选择的 Pod 没有响应,iptables 代理能够自动地重试另一个 Pod,所以它需要依赖 readiness probes。


ipvs: 1.11+

kubectl explain service
kubectl explain service.spec
kubectl explain service.spec.type
Type:
ExternalName, ClusterIP, NodePort,LoadBalancer
kubectl explain service.spec.ports
[root@k8s-master k8s]# vim service-demo.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: default
spec:
selector:
app: redis
role: logstor
type: ClusterIP
ports:
- port: 6379
targetPort: 6379
[root@k8s-master k8s]# kubectl apply -f service-demo.yaml
service/redis created
[root@k8s-master k8s]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 41d
redis ClusterIP 10.97.218.31 <none> 6379/TCP 8s
资源记录:
SVC_NAME.NS_NAME.DOMAIN.LTD
svc.cluster.local.
redis.default.svc.cluster.local.
[root@k8s-master k8s]# kubectl describe svc redis
Name: redis
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis","namespace":"default"},"spec":{"ports":[{"port":6379,"targ...
Selector: app=redis,role=logstor
Type: ClusterIP
IP: 10.97.218.31
Port: <unset> 6379/TCP
TargetPort: 6379/TCP
Endpoints: 10.244.1.190:6379
Session Affinity: None
Events: <none>
其实是 Service ----- Endpoints------pod
设置NodePort
vim myapp-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
release: canary
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080
[root@k8s-master k8s]# kubectl get svc myapp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp NodePort 10.108.102.12 <none> 80:30080/TCP 5m59s
[root@k8s-master k8s]# kubectl get pods -l app=myapp
NAME READY STATUS RESTARTS AGE
myapp-deploy-6b56d98b6b-6lkx8 1/1 Running 0 8m40s
myapp-deploy-6b56d98b6b-8nhhn 1/1 Running 0 8m40s
myapp-deploy-6b56d98b6b-t8kdf 1/1 Running 0 8m40s
可以通过node的IP访问服务了
Mac@~ $while true;do curl http://10.211.55.12:30080/hostname.html;sleep 1;done
myapp-deploy-6b56d98b6b-t8kdf
myapp-deploy-6b56d98b6b-t8kdf
myapp-deploy-6b56d98b6b-8nhhn
myapp-deploy-6b56d98b6b-6lkx8
myapp-deploy-6b56d98b6b-t8kdf
myapp-deploy-6b56d98b6b-6lkx8
myapp-deploy-6b56d98b6b-6lkx8
myapp-deploy-6b56d98b6b-8nhhn
默认的策略是,通过 round-robin 算法来选择 backend Pod。
实现基于客户端 IP 的会话亲和性,类似hash,可以通过设置 service.spec.sessionAffinity 的值为 "ClientIP",默认是None
kubectl explain svc.spec.sessionAffinity
[root@k8s-master k8s]# kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"ClientIP"}}'
service/myapp patched
Mac@~ $while true;do curl http://10.211.55.11:30080/hostname.html;sleep 1;done
myapp-deploy-6b56d98b6b-8nhhn
myapp-deploy-6b56d98b6b-8nhhn
myapp-deploy-6b56d98b6b-8nhhn
myapp-deploy-6b56d98b6b-8nhhn
myapp-deploy-6b56d98b6b-8nhhn
Headless Service
有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建 Headless Service。
这个选项允许开发人员自由寻找他们自己的方式,从而降低与 Kubernetes 系统的耦合性。 应用仍然可以使用一种自注册的模式和适配器,对其它需要发现机制的系统能够很容易地基于这个 API 来构建。
对这类 Service 并不会分配 Cluster IP,kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了 select
对定义了 selector 的 Headless Service,Endpoint 控制器在 API 中创建了 Endpoints 记录,并且修改 DNS 配置返回 A 记录(地址),通过这个地址直接到达 Service 的后端 Pod上。
[root@k8s-master k8s]# vim myapp-svc-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
namespace: default
spec:
selector:
app: myapp
release: canary
clusterIP: None
ports:
- port: 80
targetPort: 80
[root@k8s-master k8s]# kubectl apply -f myapp-svc-headless.yaml
service/myapp-svc created
[root@k8s-master k8s]# kubectl get svc myapp-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-svc ClusterIP None <none> 80/TCP 3s
[root@k8s-master k8s]# dig -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
; <<>> DiG 9.9.4-RedHat-9.9.4-73.el7_6 <<>> -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49864
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;myapp-svc.default.svc.cluster.local. IN A
;; ANSWER SECTION:
myapp-svc.default.svc.cluster.local. 5 IN A 10.244.2.59
myapp-svc.default.svc.cluster.local. 5 IN A 10.244.1.191
myapp-svc.default.svc.cluster.local. 5 IN A 10.244.2.60
看一下Pod ip:
[root@k8s-master k8s]# kubectl get pods -o wide -l app=myapp
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-6b56d98b6b-6lkx8 1/1 Running 0 63m 10.244.2.59 k8s-node1 <none> <none>
myapp-deploy-6b56d98b6b-8nhhn 1/1 Running 0 63m 10.244.1.191 k8s-node2 <none> <none>
myapp-deploy-6b56d98b6b-t8kdf 1/1 Running 0 63m 10.244.2.60 k8s-node1 <none> <none>
参考资料:http://docs.kubernetes.org.cn/703.html

浙公网安备 33010602011771号