意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

Kubernetes的Service概念

来源:恒创科技 编辑:恒创科技编辑部
2023-12-13 14:09:59

image.png
将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
使用 Kubernetes,你无需修改应用程序即可使用不熟悉的服务发现机制。 Kubernetes 为 Pod 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进行负载均衡。

Service的工作模式userspace 代理模式iptables 代理模式IPVS 代理模式多端口 Service,如以下示例:
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
    - name: https
      protocol: TCP
      port: 443
      targetPort: 9377
外部服务Service

在某些环境中,应用系统需要将一个外部数据库作为后端服务进行连接,或将另一个集群或Namespace中的服务作为服务的后端,这时可以通过创建一个无Label Selector的Service来实现。

apiVersion: v1
kind: Service
metadata:
  name: mysql-test
spec:
  ports:
    - port: 3306

(此时需要创建一个和该Service同名的Endpoint)。


Kubernetes的Service概念

apiVersion: v1
kind: Endpoints
metadata:
  name: mysql-test
  namespace: default
subsets:
  - addresses:
    - ip: 120.25.128.30
    ports:
      - port: 3306
Headless Service

在某些应用场景中,开放人员希望自己控制负载均衡的策略,不使用Service提供的默认负载均衡的功能,或者应用程序希望知道属于同组的其他实例。 此种服务不为Service设置ClusterIP,仅通过Label Selector 找后端的Pod列表返回给调用的客户端。

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
 ports:
 - port: 80
 clusterIP: None
 selector:
  app: nginx
Service的类型ClusterIP:指定Service的访问方式,默认值为ClusterIPNodePort:通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务。LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。ExternalName:通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。 无需创建任何类型代理。

ClusterIP:这个service有一个Cluster-IP,其实就一个VIP。具体实现原理依靠kubeproxy组件,通过iptables或是ipvs实现。
image.png

NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过: NodePort来访问该服务。
image.png

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort #类型
  selector:
    app.kubernetes.io/name: MyApp
  ports:
      # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
    - port: 80  # Service端口
      targetPort: 80 # 容器端口
      protocol: TCP # 协议
      # 可选字段
      # 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
      nodePort: 30007 # 对外暴露的端口,可以指定

LoadBalancer:在NodePort的基础上,借助Cloud Provider创建一个外部负载均衡器,并将请求转发到NodePort
image.png

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 192.0.2.127

ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 Kubernetes 1.7或更高版本的kube-dns才支持。

集群外部访问Pod或Service的方法将容器应用的端口号映射到物理机

通过设置容器级别的hostPort,将容器应用的端口映射到物理机上

apiVersion: v1
kind: Pod
metadata:
name: webapp
labels:
 app: webapp
spec:
 containers:
 - name: webapp
 image: tomcat
 ports:
 - containerPort: 8080
   hostPort: 8081

通过设置Pod级别的hostNetwork=true,该Pod中所以容器的端口号都被直接映射到物理机上。

apiVersion: v1
kind: Pod
metadata:
name: webapp
labels:
 app: webapp
spec:
 hostNetwork: true
 containers:
 - name: webapp
 image: tomcat
 ports:
 - containerPort: 8080
将Service的端口号映射到物理机

通过配置nodePort映射到物理机,同时设置Service的类型为NodePort

apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
  app: nginx
spec:
 type: NodePort
 ports:
 - port: 80
 targetPort: 8080
 nodePort: 8081
 selector:
app: nginx
Service中的故障排查

查看Pod的状态

kubectl get pods
kubectl describe pods <名称>

监控Pod状态的变化

kubectl get pod -w
可以看到一个 namespace 中所有的 pod 的 phase 变化。

查看Pod的日志

kubectl logs <pod名称>
kubectl logs <pod名称> -c <docker>
kubectl logs -f <pod名称>
kubectl logs -f <pod名称> -c <docker>

交互式Debug

kubectl exec <pod名称> -n <namespace >-it /bin/bash
kubectl top pod POD_NAME --containers

如有@侵权,请联系 2787950493@qq.com 改版。

上一篇: 使用虚拟机搭建本地服务器来部署一个Vue应用 下一篇: HTTP之body去哪儿了