service 对象介绍

  • 为什么需要service 每个 pod都有自己的 ip地址,但是 deployment 中,同一时刻运行的 Pod集合可能与稍后运行该应用程序的Pod集合不同。 这导致了一个问题: 如果一组 Pod (被称为后端) 为群集内的其他 Pod (称为 “前端”) 提供功能, 那么前端如何找出并跟踪要连接的Ip地址, 以便于前端可以使用后端部分。

  • service 定义

  • 将运行在一组 Pods上的应用程序公开为网络服务的抽象方法,使用 kubernates 服务无需要修改应用程序就可以使用通用的服务发现机制。 Kubernates为 Pods 提供自己的ip地址,并且为一组Pod提供相同的DNS名, 并且可以在它们之间进行负载均衡。

  • 定义 service

  • service 在 kubernates中是一个 rest 对象,和 Pod类型, 像所有的rest 对象一样,service 定义可以基于 POST方式,请求ApiServer 创建新的实例。

访问service,由service 将请求路由到某个地方。

service 能够提供负载均衡的能力, service通常是通过 label selector 来访问 pod组, 是一种可以访问 Pod逻辑分组的策略。 用户访问应用的流量,都是 通过访问 pod service , 再由service 负载均衡流量转发到某个 Pod 的服务上。

service 的几种类型

  • service cluster模式
  • service loadbalancer模式

参考博客

k8s service 配置 样例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
apiVersion: v1
kind: Service
metadata:
    name: my-service
spec:
    selector:
      app: myapp
    ports:
    - port: 80
      targetPort: 9376

代码配置如上面所示, 这里创建了一个 my-service 的对象,将请求代理到使用 TCP端口 9376,并且具有标签 app=myapp的 pod上,kubernates为该服务分配一个 IP地址(有时候成为集群IP), 该ip地址由服务代理使用, 通过 selector 将请求定向到 容器的某个端口

1
2
3
4
alias kc=kubectl
alias kcsys=kubectl -n kube-system
# 上面命令写入到 ~/.bashrc 配置文件里面
source ~/.bashrc
1
2
3
kubectl create -f service.yaml

kubectl get svc

用 service 暴露 Pod服务地址

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
    name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx # 只要容器 加上了 my-nginx 这个标签,就会被选中
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx # 模板里面的容器会被 selector 选择器选中
    spec:
      containers:
        - name: my-nginx # 容器名称可以随便写
          image: nginx
          ports:
            -containerPort:80
1
2
3
4
# kubectl apply -f ./my-y-nginx.yaml
k create -f myginx-deployment
k get pods -l run=my-nginx -o wide
k get all
1
2
k get pods -l run=my-nginx -o yaml |grep PodIP
# 参考 Pod 的 ip地址

service 配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
apiVersion: v1
kind: Service
metadata:
    name: my-nginx
spec:
    selector:
        run: my-nginx
    ports:
    - port: 80
      targetPort: 80
1
2
3
4
k create -f nginxservice.yaml
k get svc
k describe svc my-nginx
# curl my-nginx:80

service 用来固定虚拟地址【相当于微服务里面的服务发现这种】

集群内 Pod 通信机制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
k get po

k exec -it my-ngixn-xxx sh

k create -f nginx-service3.yaml

k get svc # 查看 创建的 service

k exec -it mynginx-  sh

printenv

# 要现有 service,再创建 pod

k delete -f nginx-deployment.yaml
k create -f nginx-deployment.yaml
k exec -it  nginx-xxx sh

printenv 
# 打印容器内部的 变量

DNS 服务

每个 Pod可以通过 DNS域名 自动的解析服务

一些特殊的Pod ,ip是不会变的,我们需要给一个 pod提供 固定的域名的时候,就用这个。

从集群外部访问 service

  1. clusterIp

仅仅使用一个集群内部的Ip地址- 这是默认值。 选择这个值意味着你只想这个服务在集群内部才可以访问到。 2. NodePort

在集群内部 ip的基础上, 在集群的每一个节点端口开放这个服务。 你可以在任意 NodePort 访问到这个容器。

  1. loadbalancer

在一个集群内部ip地址和 NodePort 上开放一个服务之外,先云提供商申请一个 负载均衡器, 让流量转发到这个在每个节点上以 :NodePort 的形式开放的服务上。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
    labels:
        app: nginx
    name: nginx-deployment
spec:
    replicas: 1
    selector:
        matchLabels:
            app: nginx
    template:
        metadata:
            labels:
                app: nginx
        spec:
            containers:
                - image: nginx
                name: nginx

创建 NodePort 类型的 service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: apps/v1
kind: Service
metadata:
    labels:
        app: nginx
    name: nginx-deployment
spec:
    selector:
        app: nginx
    type: nodePort
    ports:
     - port: 80
       targetPort: 8080
1
2
3
4
5
6
7
8
9

k get all
k create -f nodePort.yaml

k get node

# 在外部通过 访问节点 ip, 去访问内部 的 pod 网络
k describe pod  
k get svc