Kubernetes in Action笔记 - (8) 服务、Endpoint、Ingress
文章目录
什么是服务
服务是一种为一组功能相同的 pod 提供单 一 不变的接入点的资源。当服务存在时,它的 IP 地址和端口不会改变
为什么需要服务
pod 的存在是短暂的,一个 pod 可能会在任何时候消失, 或许因为它所在节点发生故障, 或许因为有人删除了 pod, 或者因为 pod 被从一个健康的节点剔除了。 当其中任何一种情况发生时, 消失的 pod 将被ReplicationController 替换为新的 pod。 新的 pod 与替换它的 pod 具有不同的 IP 地址。
这就是需要服务的地方,解决不断变化的 pod IP 地址的问题, 以及在一个固定的IP和端口对上对外暴露多个 pod。当一个服务被创建时, 它会得到一个静态的 IP, 在服务的生命周期中这个 IP不会发生改变。 客户端应该 通过固定 IP 地址连接到服务, 而不是直接连接 pod。服务会确保其中一个pod 接收连接, 而不关心 pod 当前运行在哪里(以及它的 IP 地址 是什么)。
创建服务
通过 kubectl expose 创建服务
1kubectl expose pod valid-pod --port=444 --name=frontend
通过 YAML 描述文件来创建服务
1apiVersion: v1
2kind: Service
3metadata:
4 name: kubia
5spec:
6 ports:
7 - port: 80 # 该服务的可用端口
8 targetPort: 8080 # 转发到的容器端口
9 # 选择Pod
10 selector:
11 app: kubia
服务的一些配置
会话的亲和性
如果多次执行同样的命令, 每次调用执行在随机的pod上。如果希望特定客户端产生的所有请求每次都指向同一个 pod, 可以设置服务的 sessionAffinity 属性为 ClientIP (默认值是None)。这种方式将会使服务代理将来自同 一 个 client IP 的所有请求转发至同一个pod上
同一个服务暴露多个端口
创建的服务可以暴露一个端口,也可以暴露多个端口。比如,你的 pod 监听两个端口,比如 HTTP 监听 8080 端口、HTTPS 监听 8443 端口,可以使用一个服务从端口 80 和 443 转发至 pod 端口 8080 和 8443 。
使用命名的端口
在服务 spec 中也可以给不同的端口号命名, 通过名称来指定。这样对于一些不是众所周知的端口号,使得服务 spec 更 加清晰。
最大的好处就是即使更换端口号 也无须更改服务 spec 。
1# 在 pod 的定义中指定port 名称
2kind: Pod
3 spec:
4 containers:
5 - name: kubia
6 ports :
7 - name : http
8 containerPort: 8080
9 - name : https
10 containerPort: 8443
11
12# 在服务中引用命名 pod
13apiVersion : vl
14kind: Service
15spec:
16 ports:
17 - name : http
18 port : 80
19 targetPort: http
20 - name : https
21 port: 443
22 targetPort: https
服务发现
通过环境变量发现服务
在 pod 开始运行的 时候 , k8s 会初始化一系列的环境变量指向现在存在的服务。
如果创建的服务早于客户端 pod 的创 建, pod 上的进程可以根据环境变量获得服务的 IP 地址和端口号。
如果服务的创建晚于 pod 的创建, 那么关于这个服务的环境变量并没有设置。需要删除所有的 pod 使得 ReplicationController创建全新的 pod
通过 DNS 发现服务
kube-system 的命名空间中有kube-dns的pod,它运行了 DNS 服务。在集群中的其他 pod 都被配置成使用其作为 dns ( k8s 通过修改每个容器的/etc/resolv.conf 文件实现)。
注意:从 Kubernetes v1.12 开始,CoreDNS 是推荐的 DNS 服务器,取代了 kube-dns
通过 FQDN 连接服务
FQDN,全限定域名
下面是一个例子。其中,backend-database 对应于服务名称, default 表示服务在其中定义的名称空间,而 svc.cluster.local 是在所有集群本地服务名称中使用的可配置集群域后缀。
1backend-database.default.svc.cluster.local
如果前端 pod 和数据库 pod 在同一个命名空间下,可以省略 svc.cluster.local 后缀,甚至命名空间
服务Endpoint
服务并不是和 pod 直接相连的,有一种资源介于两者之间,它就是 Endpoint 资源。kubectl describe svc xxx
命令可以看到输出的结果中有Endpoint属性值
通过完全限定名(FQDN)访问外部服务
要将资源的一个type字段设置为ExternalName。
例如, 在api.somecompany.com上有公共可用的API,可以定义一个指向它的服务。服务创建完成后,pod可以通过external-service.default.svc.cluster.local域名(甚至是external-service)连接到外部服务
1apiVersion: v1
2kind: Service
3metadata:
4 name: external-service
5spec:
6 type: ExternalName
7 externalName: someapi.somecompany.com
8 ports:
9 - port: 80
ExternalName服务仅在DNS级别实施一为服务创建了简单的CNAME DNS记录,指向完全限定的域名而不是数字 IP 地址
将服务暴露给外部客户端
(1)使用NodePort类型的服务
通过创建NodePort服务, 可以让Kubemetes在其所有节点上保留一个端口(所有节点上都使用相同的端口号), 并将传入的连接转发给作为服务部分的pod
这与常规服务类似(它们的实际类型是ClusterIP), 但是不仅可以通过服务的内部集群IP访问NodePod 服务, 还可以通过任何节点的IP和预留节点端口访问NodePort服务。
(2)通过负载均衡器将服务暴露出来
Load Badancer服务是NodePod服务的扩展。
负载均衡器拥有自己独一无二的可公开访问的 IP 地址, 并将所有连接重定向到服务。可以通过负载均衡器的 IP 地址访问服务。
(3)通过Ingress暴露服务
为什么需要 Ingress
用Ingress一个重要的原因是每个 LoadBalancer 服务都需要自己的负载均衡器, 以及独有的公有 IP 地址, 而 Ingress 只需要一个公网 IP 就能为许多服务提供访问。
Ingress 在网络栈 (HTTP) 的应用层操作, 并且可以提供一些服务不能实现的功能, 诸如基于 cookie 的会话亲和性 (session affinity) 等功能。
注意:只有 Ingress 控制器在集群中运行, Ingress 资源才能正常工作。不同的 Kubernetes 环境使用不同的控制器实现, 但有些并不提供默认控制器
为 Ingress 创建 TLS 认证
Ingress如果要处理TLS内容,需要将证书和私钥附加到 Ingress。这两个必需资源存储在称为 Secret 的 Kubernetes 资源 中,然后在 Ingress manifest 中引用它
图书资料: