Service概念

会话保持

多端口设置

Service暴露到集群外部

服务发现

Service概念

Service主要用于提供网络服务,通过Service的定义,能够为客户端应用提供稳定的访问地址(域名或IP地址)和负载均衡功能,以及屏蔽后端Endpoint的变化,是k8s实现微服务的核心资源。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: d1
spec:
  selector:
    matchLabels:
      app: v1 
  replicas: 2  
  template:
    metadata:
      labels:
        app: v1
    spec:
      containers:
        - name: myapp01
          image: 192.168.180.129:9999/myharbor/myapp:v1
          imagePullPolicy: IfNotPresent
          ports:
            - name: tomcatport
              containerPort: 8080
          command: ["nohup","java","-jar","/usr/local/test/dockerdemo.jar","&"]

创建了两个pod,如果要访问pod内部的接口,只能是根据pod的ip:port

基于k8s 微服务 k8s python微服务_jar

定义Service主要注意的是两个端口还有Service的标签选择器选择的是pod不是deployment。

apiVersion: v1
kind: Service
metadata:
  name: svc1
spec:
  ports:
  - protocol: TCP
    port: 18080 #service自身的端口,对应客户端的端口
    targetPort: 8080 #对应容器内的端口
  selector:
    app: v1

查看service详细信息和对应后端的endpoints列表。

kubectl describe svc svc1

kubectl get svc

kubectl get endpoints

基于k8s 微服务 k8s python微服务_IP_02

通过访问Service的ip,将请求转发到后端pod,请求访问了两次,分别转发到了两个不同的pod容器。

基于k8s 微服务 k8s python微服务_jar_03

会话保持

Sercice可以通过设置做到首次将某个客户端来源IP发起的请求转发到后端的某个pod上,之后从相同的客户端IP发起的请求都将被转发到相同的后端Pod上。同时用户可以设置会话保持的最长时间,在此时间之后重置客户端来源ip的保持规则。

apiVersion: v1
kind: Service
metadata:
  name: svc1
spec:
  ports:
  - protocol: TCP
    port: 18080 #service自身的端口,对应客户端的端口
    targetPort: 8080 #对应容器内的端口
  selector:
    app: v1
  sessionAffinity: ClientIP #会话保持
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 60 #单位秒

apply和create的区别是apply是更新操作。可以看出三次访问都转发到了同一个pod,后边的三次78的是过了一分钟后,会话重置了。

基于k8s 微服务 k8s python微服务_IP_04

多端口设置

pod中存在多个容器时,每个容器对应各自的端口,此时就需要用到service多端口映射。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: d1
spec:
  selector:
    matchLabels:
      app: v1 
  replicas: 2  
  template:
    metadata:
      labels:
        app: v1
    spec:
      containers:
        - name: myapp01
          image: 192.168.180.129:9999/myharbor/myapp:v1
          imagePullPolicy: IfNotPresent
          ports:
            - name: tomcatport
              containerPort: 8080
          command: ["nohup","java","-jar","/usr/local/test/dockerdemo.jar","&"]
        - name: nginx
          image: nginx
          ports:
            - name: nginxport
              containerPort: 80

在service中配置多个映射内部容器的端口,多端口情况下需要配置name字段。

apiVersion: v1
kind: Service
metadata:
  name: svc1
spec:
  ports:
  - name: p1
    protocol: TCP
    port: 18080 #service自身的端口,对应客户端的端口
    targetPort: 8080 #对应容器内的端口
  - name: p2
    protocol: TCP
    port: 28080 #service自身的端口,对应客户端的端口
    targetPort: 80 #对应容器内的端口
  selector:
    app: v1

基于k8s 微服务 k8s python微服务_jar_05

Service暴露到集群外部

ClusterIP

默认类型,虚拟服务IP地址,该地址用于K8S集群内部的pod访问。

NodePort

使用宿主机的端口,外部客户端通过任意Node的IP和设定的端口都可以访问服务。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: d1
spec:
  selector:
    matchLabels:
      app: v1 
  replicas: 2  
  template:
    metadata:
      labels:
        app: v1
    spec:
      containers:
        - name: myapp01
          image: 192.168.180.129:9999/myharbor/myapp:v1
          imagePullPolicy: IfNotPresent
          ports:
            - name: tomcatport
              containerPort: 8080
          command: ["nohup","java","-jar","/usr/local/test/dockerdemo.jar","&"]
apiVersion: v1
kind: Service
metadata:
  name: svc1
spec:
  type: NodePort
  ports:
  - name: p1
    protocol: TCP
    port: 18080 #service自身的端口,对应客户端的端口
    targetPort: 8080 #对应容器内的端口
    nodePort: 30000 #将这个端口映射到每一台node上,通过任意一个nodeIp:nodePort都能映射到容器内部
  selector:
    app: v1

基于k8s 微服务 k8s python微服务_客户端_06

基于k8s 微服务 k8s python微服务_jar_07

基于k8s 微服务 k8s python微服务_基于k8s 微服务_08

服务发现

环境变量方式

声明两个Deployment每个有两个pod副本,在创建两个Service。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: d1
spec:
  selector:
    matchLabels:
      app: v1 
  replicas: 2  
  template:
    metadata:
      labels:
        app: v1
    spec:
      containers:
        - name: myapp01
          image: 192.168.180.129:9999/myharbor/myapp:v1
          imagePullPolicy: IfNotPresent
          ports:
            - name: tomcatport
              containerPort: 8080
          command: ["nohup","java","-jar","/usr/local/test/dockerdemo.jar","&"]
apiVersion: apps/v1
kind: Deployment
metadata:
  name: d2
spec:
  selector:
    matchLabels:
      app: v2 
  replicas: 2  
  template:
    metadata:
      labels:
        app: v2
    spec:
      containers:
        - name: myapp01
          image: 192.168.180.129:9999/myharbor/myapp:v1
          imagePullPolicy: IfNotPresent
          ports:
            - name: tomcatport
              containerPort: 8080
          command: ["nohup","java","-jar","/usr/local/test/dockerdemo.jar","&"]
apiVersion: v1
kind: Service
metadata:
  name: svc1
spec:
  ports:
  - protocol: TCP
    port: 18080 #service自身的端口,对应客户端的端口
    targetPort: 8080 #对应容器内的端口
  selector:
    app: v1
apiVersion: v1
kind: Service
metadata:
  name: svc2
spec:
  ports:
  - protocol: TCP
    port: 28080 #service自身的端口,对应客户端的端口
    targetPort: 8080 #对应容器内的端口
  selector:
    app: v1

基于k8s 微服务 k8s python微服务_客户端_09

进入d1中的一个pod,查看环境变量。可以看到SVC1和SVC2的IP和端口。

基于k8s 微服务 k8s python微服务_客户端_10

使用环境变量中的IP和端口访问Service

基于k8s 微服务 k8s python微服务_基于k8s 微服务_11

DNS方式

直接使用Service的名称访问服务也可以。

基于k8s 微服务 k8s python微服务_IP_12