7. kubernetes Service资源
[TOC]
本文基于马哥的docker和k8s视频总结, 在此致谢马哥.
Service
工作模式: userspace, iptables, ipvs -> 四层代理
- userspace: 1.1 -
- iptables: 1.10 -
- ipvs: 1.11 +
四种类型:
-
ClusterIP
: 仅用于集群内部通信 -
NodePort
: 接入集群外的流量 -
LoadBalancer
: 依赖于底层LBAAS的云计算环境 -
ExternalName
: 把集群外的服务引入集群内部, 可在集群内部直接使用
资源记录:
-
SVC_NAME.NS_NAME.DOMAIN.LTD.
(LTD: 资源域名后缀, 默认是svc.cluster.local.
或cluster.local.
)- 例如:
redis.default.svc.cluster.local.
- 例如:
kubectl explain svc
ClusterIP
apiVersion: v1
kind: Service
metadata:
name: redis # svc name
namespace: default
spec:
selector: # Service.spec.selector比较特殊, 只支持等值关系
app: redis
role: logstor
clusterIP: 10.97.97.97 # 固定地址, 但此种方法极易冲突, 建议不指定, 让系统自动分配
type: ClusterIP
# sessionAffinity: 默认是None(随机调度), 定义为ClientIP时会将来自同一个client的IP调度至同一个后端pod
ports:
- name: redis-pod # 指明pod名称
port: 6379 # 对外提供服务的端口, 即service地址上的端口
targetPort: 6379 # 容器的端口, 即pod地址上的端口
# nodePort: 指明节点上的端口, 只有类型是NodePort才使用此项(在集群外被访问时使用)
# protocol: TCP 默认就是TCP
kubectl apply -f svc-demo.yml
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":{"clusterIP":"10.97.97.97","...
Selector: app=redis,role=logstore
Type: ClusterIP
IP: 10.97.97.97
Port: redis-pod 6379/TCP
TargetPort: 6379/TCP
Endpoints: 10.244.1.34:6379 # 被Selector匹配到的后端地址
Session Affinity: None
Events: <none>
NodePort
- Client请求 -> NodeIP:NodePort -> ServiceIP:ServicePort -> PodIP:ContainerPort
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: mynginx
release: canary
type: NodePort
clusterIP: 10.99.99.99
ports:
- port: 80
targetPort: 80
nodePort: 30080 # 可以不指定, 系统动态分配, 默认范围30000 - 32767
# 此时可被集群外访问, 可看到请求会被负载均衡至node上的各pod
while true; do curl http://192.168.200.201:30080/hostname.html; sleep 1; done
ExternalName
- FQDN 被coreDNS解析 (CNAME -> 真正的FQDN)
kubectl explain svc.spec.externalName
headless-Service
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
namespace: default
spec:
selector:
app: mynginx
release: canary
clusterIP: None # 使用无头service时这样定义
ports:
- port: 80
targetPort: 80
dig -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
# 可看到地址直接被10.96.0.10的DNS服务器解析为myapp的pod的IP
dig -t A myapp.default.svc.cluster.local. @10.96.0.10
# 可以对比有头服务