负载均衡器:
- ip不能变
- ip要在外部能够访问到
- 负载均衡器能够实时感知后端代理的pod的ip变化,并做相应在负载均衡更新
Service 服务
- RC(
replicationcontrollers)、RS(replicasets)和Deployment只是保证了支撑服务的微服务Pod的数量,但是没有解决如何访问这些服务的问题。 - 一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。要稳定地提供服务需要服务发现和负载均衡能力。服务发现完成的工作,是针对客户端访问的服务,找到对应的的后端服务实例。
- 在K8s集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。在K8s集群中微服务的负载均衡是由Kube-proxy实现的。
- Kube-proxy是K8s集群内部的负载均衡器。它是一个分布式代理服务器,在K8s的每个节点上都有一个;这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的Kube-proxy就越多,高可用节点也随之增多。与之相比,我们平时在服务器端使用反向代理作负载均衡,还要进一步解决反向代理的高可用问题。
- 客户端访问节点时通过 iptables实现的
- iptables规则是通过 kube-proxy写入的
- apiserver通过监控 kube-proxy去进行对服务和端点的监控
- kube-proxy通过 pod的标签( lables)去判断这个断点信息是否写入到 Endpoints里
- Kubernetes Service定义了这样一种抽象: Service是一种可以访问 Pod逻辑分组的策略, Service通常是通过 Label Selector访问 Pod组。
- Service能够提供负载均衡的能力,但是在使用上有以下限制:
- 只提供 4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的
service类型
- Service在 K8s中有以下四种类型
- clusterIp:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP
# gvk
apiVersion: v1
kind: Service
# metadata
metadata:
labels:
app: webserver-sts
name: webserver-sts
spec:
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: webserver
res: sts
type: ClusterIP
- nodePort在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过: NodePort来访问该服务
- 它也会为service生成一个clusterip
- 它会在所有的宿主机上随机映射一个端口 30000 - 32767
apiVersion: v1
kind: Service
# metadata
metadata:
labels:
app: webserver-deploy-nodeport
name: webserver-deply-nodeport
namespace: cka
spec:
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: webserver
type: example
type: NodePort
- loadBalancerNodePort的基础上,借助Cloud Provider创建一个外部负载均衡器,并将请求转发到NodePort
- 这是当kubernetes 部署到公有云上时才会使用到的选项,是向云提供商申请一个负载均衡器,将流量转发到已经以NodePort形式开放的service上
apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
ports:
- port: 80
targetPort: 80
selector:
name: hello-deployment
- externalName把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 Kubernetes 1.7或更高版本的kube-dns才支持
ingress
- k8s的Pod和Service需要通过NodePort把服务暴露到外部, 但是随着微服务的增多。 端口会变得不好管理。 所以通常情况下 我们会设计一个Ingress来做路由的转发,方便统一管理。效果如图:
- 增加了7层的识别能力,可以根据 http header, path 等进行路由转发。
- Ingress 主要分为两部分
- Ingress Controller: 是流量的入口,是一个实体软件,实时实现规则 ,一般是Nginx 和 Haproxy 。控制器有各种类型,包括GoogleCloudLoadBalancer, Nginx,HAproxy,Traefik等。它还有各种插件,比如 cert-manager,它可以为你的服务自动提供 SSL 证书。
- Ingress: 描述具体的路由规则。
- Ingress Controller 会监听 api server上的 /ingresses 资源 并实时生效
- Ingerss 描述了一个或者多个 域名的路由规则,以 ingress 资源的形式存在
- 应用如果想要使用ingress实现负载均衡,则必须为该应用先创建service
- 在Service的三种类型中,有两种对外暴露服务的方式,分别是NodePort和LoadBalancer,但这两种方式都有这样或那样的问题,于是Ingress登场了
- NodePort方式最大的缺点是会占用很多集群机器的端口
- LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外的支持
- 而ingress则只需要一个NodePort或者一个LB就可以满足所有service对外服务的需求
- Ingress 可能是暴露服务的最强大方式,但同时也是最复杂的
- ingress 需要单独安装
安装ingress
- 下载并部署
- Ingress-Nginx-github 地址:https://github.com/kubernetes/ingress-nginx
- Ingress-Nginx 官方地址:https://kubernetes.github.io/ingress-nginx
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
wget https://github.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
- 修改镜像地址
- default-http-backend默认镜像使用:gcr.io/google_containers/defaultbackend:1.4,因被墙的原因,改为:registry.cn-hangzhou.aliyuncs.com/google_containers/defaultbackend:1.4
- 安装
kubectl apply -f mandatory.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webserver-deploy-ing
namespace: cka
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
service:
name: webserver-deploy-svc
port:
number: 80
path: /
pathType: Prefix
- host: www.example.com
http:
paths:
- backend:
service:
name: bbs-svc
port:
number: 80
path: /bbs
pathType: Prefix
- host: www.example.com
http:
paths:
- backend:
service:
name: mail-svc
port:
number: 80
path: /mail
pathType: Prefix