K8s: Service对象以及与Pod之间的通信关系
在用这种方式创建的时候,先把之前创建的 Service 删除。1 )配置 Deployment 对象用来维护 Pod。这样就会创建2个pod, 之后,创建 Service。上面等价于通过 yaml 文件创建 Service。现在创建 svc-my-nginx.yaml 文件。新建 dep-my-nginx.yaml。可以看到,多了一个 deploment。2.2 基于yaml文件来处理。2 ) 定
Service 对象
1 )概述
- 每个 Pod 都有自己的 IP 地址,但是在 Deployment 中
- 注意,实际在部署我们服务的时候创建的是 Deployment 而非 pod
- Deployment 是控制器的一种
- 在同一时刻运行的 Pod 集合可能与稍后运行该应用程序的 Pod 集合不同
- 这导致了一个问题: 如果一组 Pod(比如: “后端”)即有3个pod提供同一个微服务
- 这是微服务的多实例,也是 K8s 的核心作用
- 后端为群集内的其他 Pod(比如: “前端”)提供功能
- 在这种情况下,如果后端的一组pod失效
- 它会无缝漂移到其他节点上重新启动,这时候服务的ip地址就变了
- 这时候,外部访问pod(前端)如何找出并跟踪要连接的 IP 地址
- 以便前端可以继续使用后端部分
- 为了应对这个问题,K8s 提供了一个资源对象 Service
- Service 将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法
- 简单来说,K8s 通过 Service 来暴露 Pod 对外服务的一个地址
- 通过集群外部访问pod的时候,不应该访问 Pod 的ip地址,而是访问为pod提供的DNS域名
- Service 负责把请求从后端路由到对应的Pod
- 使用 K8s 服务无需修改应用程序即可使用通用的服务发现机制
- K8s 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名
- 并且可以在它们之间进行负载均衡
2 ) 定义 Service
- Service 在 K8s 中是一个 REST 对象,和 Pod 类似
- 像所有的 REST 对象一样,Service 定义可以基于 POST 方式,请求 API server 创建新的实例
- 例如,假定有一组 Pod,它们对外暴露了 9376 端口,同时还被打上 app=MyApp 标签
- 示例说明
apiVersion: v1 kind: Service metadata: name: my-service # 这里的名称将来会被用作请求的域名来被集群外部和内部对象使用 spec: selector: # 选择器,Service 会通过满足选择器的Pod去建立和Pod的映射关系,一般是1对多 app: xxx # 会找对应 这个 xxx label 的 Pod ports: - protocol: TCP port: 80 # 对外暴露的端口,集群内部可访问 targetPort: 9376 # 容器底层的端口,如果不配置这个,默认使用和上面的 port 一致的
- 创建 my-service.yaml
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: sss-app ports: - protocol: TCP port: 80 targetPort: 9376
- 可以看到,它没有创建任何容器,它就是虚拟的对象
- 它只负责建立一系列的规则来访问 Service
- $
kubectl create -f my-service.yaml
service/my-service created
- $
kubectl get svc
kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 2d8h my-service ClusterIP 10.1.38.99 <none> 80/TCP 35s
用Service暴露Pod的服务地址
1 )配置 Deployment 对象用来维护 Pod
-
新建 dep-my-nginx.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: my-dep-nginx # 这个是 Deployment 对象的名称 spec: selector: matchLabels: # 匹配标签 run: my-dep-nginx # 运行匹配的 my-nginx 容器 replicas: 2 # 2个副本,会创建 2个 pod template: # 定义模板 metadata: labels: run: my-dep-nginx spec: # 模板说明 containers: - name: my-dep-nginx image: nginx resources: limits: memory: "32Mi" cpu: "100m" ports: - containerPort: 80
-
$
kubectl apply -f dep-my-nginx.yaml
deployment.apps/my-nginx created
-
这样就会创建2个pod, 之后,创建 Service
-
$
kubectl get po | grep my-dep
查看相关 podmy-dep-nginx-7776c5d85c-crtgj 1/1 Running 0 24s my-dep-nginx-7776c5d85c-ljztm 1/1 Running 0 37s
- 注意这里,上面两个pod我们不知道其ip和域名
- 即使知道了,也访问不了,因为不应该被外部访问,因为其ip地址随时可能变化
- 如果需要访问的话,就需要下面的 Service
-
$
kubectl get all
可以看到,多了一个 deplomentNAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-dep-nginx 2/2 2 2 6m42s
-
$
kubectl get pods -l run=my-dep-nginx -o yaml
通过 label 来查看- 这里输出过多,不便于在此展示,可以看到 pod 很多详细信息
- 比如 pod ip 我们可以过滤来看 $
kubectl get pods -l run=my-dep-nginx -o yaml | grep podIP
- 再比如,通过 $
ip addr | grep 10.244
可以看到网段是从 flannel.1 和 cni 中来的 - 这里 10.244 是上面输出的,在 ip addr 作为过滤条件
- 通过这个ip网段,底层容器间就可以相互通信了
2 )创建 Service
- 这里通常有两种方式
2.1 使用 命令通过 Development 来暴露
- $
kubectl expose deployment.apps/my-dep-nginx
这里的 deployment 是从上面获取的service/my-dep-nginx exposed
- 执行完成后,服务就暴露出来了
- $
kubectl get svc my-dep-nginx
验证暴露出的 ServiceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-dep-nginx ClusterIP 10.1.128.101 <none> 80/TCP 76s
2.2 基于yaml文件来处理
-
上面等价于通过 yaml 文件创建 Service
-
在用这种方式创建的时候,先把之前创建的 Service 删除
-
$
kubectl delete service my-dep-nginx
service "my-dep-nginx" deleted
-
现在创建 svc-my-nginx.yaml 文件
apiVersion: v1 kind: Service metadata: name: my-svc-nginx labels: run: my-dep-nginx # 注意这里和上面 deployment 匹配 spec: ports: - port: 80 protocol: TCP selector: run: my-dep-nginx # 注意这里和上面 deployment 匹配
-
$
kubectl create -f svc-my-nginx.yaml
创建 Serviceservice/my-svc-nginx created
-
$
kubectl get svc my-svc-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-svc-nginx ClusterIP 10.1.231.159 <none> 80/TCP 59s
-
$
kubectl describe svc my-svc-nginx
Name: my-svc-nginx Namespace: default Labels: run=my-dep-nginx Annotations: <none> Selector: run=my-dep-nginx Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.1.231.159 IPs: 10.1.231.159 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 10.244.2.22:80,10.244.2.23:80 Session Affinity: None Events: <none>
- 这里 Endpoints 也是 K8s 对象
- 如果 Service 创建之后,如果匹配到 Pod Label 之后
- 会为 Label 创建 Endpoint 对象
- 这个 Endpoint 值就是ip, 端口就是port
-
看下: $
curl 10.1.231.159
这里端口 80 是默认,不用添加<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
-
看到上面显示是服务通了
更多推荐
所有评论(0)