1.1 svc 服务的概念
将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名,也就是服务名, 并且可以在它们之间进行负载平衡。这就是服务
svc 的原理:
逻辑上的一组 Pod, 称为微服务
这组 Pod 能够通过 Service 访问到,通常是通过 标签选择器
svc 发现这组服务后,会根据负载均衡规则,将负载发给每一个 Pod
svc 本质就是一个 负载均衡器
svc 将负载转发给后端的 Pod ,是通过 kube-proxy 转发的
1.2 svc 服务的创建
如果没有指明 svc 的名字,svc 的名字是控制器的名字
–selector 选项用来指明,该 svc 控制哪些 Pod 做负载均衡,如果没指定,则是根据控制器的 标签 来选择
只要新启动的 Pod 的标签与 svc 管理 Pod 的标签相同,那么这个新建的 Pod 也会被该 svc 管理。
port 是暴露在 clusterIP 上的端口,供集群内部使用,targetPort 是容器内部的端口,nodePort 是暴露在 Node 节点上的端口,供外部访问 svc
例如:
2. Service 服务发现
服务发现概念:
当 kubentes 中的一个 Pod 要访问 另一个服务的时候,这时候就要用到服务发现。
这个服务有可能是一个 Pod ,也可能是一组 Pod
这个服务就需要 让 Pod 能够访问到,因此称为服务发现
服务发现的类型有:
clusterIP
环境变量
方法:
在创建出服务后,默认的服务类型为 ClusterIP,可以通过 ClusterIP:Port 来访问对应的 svc 服务。
缺点:
服务需要先创建,才能查看 clsterIP
服务如果重建,ip 会变化,那么后面需要访问该服务的所有 Pod 都需要改变 clsterIP
例如:
当 Pod 运行在 Node 上,kubelet 会为每个活跃的 Service 添加一组环境变量。
常用的 svc 的环境变量有::
{SVCNAME}_SERVICE_HOST : 表示服务的 ClusterIP
{SVCNAME}_SERVICE_PORT : 表示服务的 Port
缺点:
Pod 只能发现同一个命名空间里的服务
例如:
nginx 的服务为:
DNS(推荐)
原理
在 kube-system 命名空间中,创建了coredns,可以自动发现所有命名空间中服务的 clusterIP
只要创建了一个服务,不管该服务在哪个命名空间中创建的,都回自动向 kube-system 命名空间下的 coredns 注册
因此,在同一个命名空间中,一个服务访问另一个服务的时候,可以直接通过服务名来访问
如果是不同命名空间,一个服务访问另一个服务的时候,可以通过 服务名.命名空间名 来访问
例如:
nginx 的 服务为:
服务名.命名空间名,来访问服务
3. Service 服务发布
:对一些应用(如 Frontend)的某些部分,可能希望通过外部(Kubernetes 集群外部)IP 地址暴露 Service。
ServiceTypes 允许指定一个需要的类型的 Service,默认是 ClusterIP 类型。
ServiceTypes 服务发布的类型有:
ClusterIP :通过集群的内部 IP 暴露服务
选择该值,服务只能够在集群内部可以访问
ClusterIP 是默认的 ServiceType。
NodePort :通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。
NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。
通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 NodePort 服务。
LoadBalancer :使用云提供商的负载均衡器,可以向外部暴露服务。
外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。
没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。
svc 服务发布的另一种形式:Ingress
Ingress 不是服务类型,但它充当集群的入口点。
Ingress 可以将路由规则整合到一个资源中,因为它可以在同一IP地址下公开多个服务。
3.1
ClusterIP 类型 只能是在集群内部访问,多用于服务发现。
3.2 NodePort 类型
NodePort 类型,是将 容器 暴露出的端口 targetPort 映射到 node (worker)节点上,名为 nodePort,是的可以通过 nodeIP:NodePort 来访问 服务。
Kubernetes 控制平面将在 –service-node-port-range 标志指定的范围内分配端口(默认值:30000-32767)
注意:
targetPort : 容器需要暴露出来的端口
port : 表示用于集群内部使用的 端口,一般与 targetPort 相同
nodePort : 表示 容器端口映射到 node 节点的 端口,范围:30000-32767
3.3
LoadBalancer 类型,需要从运行商获取到公网地址,也就是暴露在互联网上 ip 地址,这样才能够为外部访问,通过将 svc 绑定一个公网 ip,用户就可以通过这个公网 ip 来直接访问服务。
LoadBalancer 类型需要借助第三方工具来实现,可以通过 MetalLB 这个工具实现,官网地址为:https://metallb.universe.tf/
安装方法:
创建命名空间:
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
创建 secret
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
创建 MetalLB 的相关 Pod
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
配置使用方法:
创建 地址池 的 yaml 文件:(简单示例,使用 Layer 2 Configuration)
kubectl expose deployment web1 --name=mysvc --type=LoadBalancer --port=80
创建 loadBalancer 类型的 svc 后,可以看到 该 svc 服务与一个地址池中的公网 ip 绑定
3.4
3.4.1
Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
Ingress 相当于一个 nginx 反向代理,通过不同的 path 指定到不同的 pod 上。
注意:
可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。
Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的服务。
3.4.2 安装方法
Ingress 的安装方法:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml -O ingress-nginx.yaml
kubectl apply -f ingress-nginx.yaml
在 ingress-nginx 命名空间中,创建 deployment 的服务 svc ,将 deployment 暴露出去,这样外部才可以通过这个代理访问服务
3.4.3
ingress 其实就是个路由器,通过不同的 网址站点以及 path 转发给不同的 service
说明:
host : 可选的,
如果未指定 host,表示通过指定 IP 地址的所有入站 HTTP 通信。 如果提供了 host,则 rules 适用于该 host。
paths : 路径列表
例如,/testpath, 每个路径都有一个由 serviceName 和 servicePort 定义的关联后端。
在负载均衡器将流量定向到引用的服务之前,主机和路径都必须匹配传入请求的内容。
backend : 后端
服务和端口名称的组合。 与规则的 host 和 path 匹配的对 Ingress 的 HTTP(和 HTTPS )请求将发送到列出的 backend。
backend 也就是对应的 service
pathType : 路径类型
ImplementationSpecific : 匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。
Exact : 精确匹配 URL 路径,且区分大小写。
Prefix : 基于以 / 分隔的 URL 路径前缀匹配。区分大小写,并且对路径中的元素逐个完成。
示例:
创建 nginx pod 和 服务svc:
可以看到,通过不同的服务,可以访问不同的 内容
查看 ingress-nginx 创建的 svc 的 端口
在 /etc/hosts 中添加 dns 映射
评论