微服务:kubernetes Service部署应用

郎家岭伯爵 2022年05月19日 469次浏览

背景

上一篇博文中,我们讲述了如何在Linux环境搭建kubernetes集群。但是部署应用的方式仍然存在着一些问题,例如:

  • 每次只能访问一个Pod,没有负载均衡,不会自动转发到不同的Pod。
  • 访问时需要端口转发。
  • Pod重新创建后IP变了,名称也会改变。

因此我们通过Service来解决这些问题,以便我们更好地部署应用。

实现

Service相对于kubernetes原生的应用部署方式有如下优点:

  • Service通过label关联对象的Pod。
  • Service生命周期不跟Pod绑定,不会因为Pod重新创建而改变IP。
  • 提供了负载均衡功能,自动转发流程到不同的Pod。
  • 可对集群外部提供访问端口。
  • 集群内部可通过服务名字访问。

创建Service

创建Service,要注意通过标签与test-k8s跟对应的Pod关联上。

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s
  type: ClusterIP
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口

新建service.yaml文件:

vim service.yaml

部署Service

删除原有部署

可使用如下命令查看已部署的服务:

kubectl get all

删除已部署的服务:

kubectl delete all --all

部署pod

新建或修改app.yaml文件:

vim app.yaml

app.yaml文件内容:

要注意本文中的app.yaml不同于上一篇yaml文件,对比上一篇yaml文件,增加了labels标签,用于与service关联服务。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test-k8s
  # 部署名字
  name: test-k8s
spec:
  replicas: 5
  # 用来查找关联的 Pod,所有标签都匹配才行
  selector:
    matchLabels:
      app: test-k8s
  # 定义 Pod 相关数据
  template:
    metadata:
      labels:
        app: test-k8s
    spec:
      # 定义容器,可以多个
      containers:
        - name: test-k8s # 容器名字
          image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像

部署pod命令:

kubectl apply -f app.yaml

部署Service

部署Service:

kubectl apply -f service.yaml

service的其它操作

查看service详情

kubectl describe svc test-k8s

进入pod内部访问service服务

进入pod内部:

# 注意行末的bash与双横杠之间有一个空格
kubectl exec -it test-k8s-664bdc5c58-54rxt -- bash

注:

  • 如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):kubectl port-forward service/test-k8s 8888:8080

对外暴露服务

上面我们是通过端口转发的方式可以在外面访问到集群里的服务,如果想要直接把集群服务暴露出来,我们可以使用NodePortLoadbalancer类型的Service,例如:

apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s
  # 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
  type: NodePort
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口
      nodePort: 31000   # 节点端口,范围固定 30000 ~ 32767
kubectl apply -f service.yaml

注:

  • 需在节点访问,master是访问不到的。

多端口

apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s
  type: NodePort
  ports:
    - port: 8080        # 本 Service 的端口
      name: test-k8s    # 必须配置
      targetPort: 8080  # 容器端口
      nodePort: 31000   # 节点端口,范围固定 30000 ~ 32767
    - port: 8090
      name: test-other
      targetPort: 8090
      nodePort: 32000

补充:Service的分类

ClusterIP
默认的,仅在集群内可用

NodePort
暴露端口到节点,提供了集群外部访问的入口
端口范围固定 30000 ~ 32767

LoadBalancer
需要负载均衡器(通常都需要云服务商提供,裸机可以安装 METALLB 测试)
会额外生成一个 IP 对外服务
K8S 支持的负载均衡器:负载均衡器

Headless
适合数据库
clusterIp 设置为 None 就变成 Headless 了,不会再分配 IP,后面会再讲到具体用法。

总结

本文介绍了如何“优雅”地部署服务,后续我们会继续介绍如何部署有状态的服务,例如数据库、Redis等。