Service是什么

  • 其实就是k8s中的服务注册与负载均衡。

  • 最终能够实现,提供一个唯一的地址,供我们来访问地址,而不需要具体的去了解,这个服务起的Pod的ip是什么

Service存在的意义

Service引入主要是解决Pod的动态变化,提供统一访问入口

  • 防止Pod失联,准备找到提供同一个服务的Pod(服务发现)
  • 定义一组Pod的访问策略(负载均衡)
    在这里插入图片描述

Pod与Service的关系

  • Service通过标签关联一组Pod
  • Service使用iptables或者ipvs为一组Pod提供负载均衡能力

在这里插入图片描述

Service定义与创建

  • 创建service
kubectl apply -f service.yaml
  • 查看service
kubectl get service

自定义Service

  • ClusterlP:默认,分配一个稳定的IP地址,即VIP,只能在集群内部访问。

在这里插入图片描述

---
apiVersion: v1
kind: Service
metadata:
  name: web1
  namespace: default
spec:
  ports:
  - port: 80		#Service端口
    protocol: TCP	#协议
    targetPort: 80	#容器端口
  selector:
    app: httpd		#指定关联Pod的标签
  type: ClusterIP	#服务类型
...					#文件结束用...
  • NodePort:在每个节点上启用一个端口来暴露服务,可以在集群外部访问。也会分配一个稳定内部集群IP地址。
    访问地址:<任意NodelP> :<NodePort>
    端口范围:30000-32767
    在这里插入图片描述
---
apiVersion: v1
kind: Service
metadata:
  name: web1
  namespace: default
spec:
  ports:
  - port: 80		#Service端口
    protocol: TCP	#协议
    targetPort: 80	#容器端口
    nodePort: 30000	#指定暴露端口号
  selector: 
    app: httpd		#指定关联Pod的标签
  type: NodePort	#服务类型
  • LoadBalancer:与NodePort类似,在每个节点上启用一个端口来暴露服务。除此之外,Kubernetes会请求底层云平台(例如阿里云、腾讯云、AWS等)上的负载均衡器,将每个Node
    ([NodelP]:[NodePort])作为后端添加进去。
    在这里插入图片描述

Service三种类型

  • ClusterIP:集群内部使用;clusterIP也是kubernetes service的默认类型
[root@master test]# cat test.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd  
        image: 1314444/httpd:v0.1
        imagePullPolicy: IfNotPresent

---
apiVersion: v1
kind: Service
metadata:
  name: web1
  namespace: default
spec:
  ports:
  - port: 80		#Service端口
    protocol: TCP	#协议
    targetPort: 80	#容器端口
  selector:
    app: httpd		#指定关联Pod的标签
  type: ClusterIP	#服务类型
...					#文件结束用...

[root@master test]# kubectl apply -f test.yml 
deployment.apps/web created
service/web1 created
[root@master test]# kubectl get pod,svc
NAME                      READY   STATUS    RESTARTS   AGE
pod/web-9b8f648df-7vrjb   1/1     Running   0          9s
pod/web-9b8f648df-cktwk   1/1     Running   0          9s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   7d3h
service/web1         ClusterIP   10.100.228.232   <none>        80/TCP    9s

[root@master test]# curl 10.100.228.232
test page on jjyy

//利用域名访问
[root@master test]# kubectl run -it b1 --image busybox -- /bin/sh
/ # wget -q -O - http://web1
test page on jjyy
  • NodePort:在每个节点上都监听一个同样的端口号(30000-32767),ClusterIP和路由规则会自动创建。对外暴露应用(集群内外都可使用)
[root@master ~]# cat test/test.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd  
        image: 1314444/httpd:v0.1
        imagePullPolicy: IfNotPresent

---
apiVersion: v1
kind: Service
metadata:
  name: web1
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    nodePort: 30000
    targetPort: 80
  selector:
    app: httpd
  type: NodePort

[root@master ~]# kubectl apply -f test/test.yml 
deployment.apps/web unchanged
service/web1 configured
[root@master ~]# kubectl get pod,svc
NAME                      READY   STATUS    RESTARTS   AGE
pod/web-9b8f648df-7vrjb   1/1     Running   0          16m
pod/web-9b8f648df-cktwk   1/1     Running   0          16m

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        7d3h
service/web1         NodePort    10.100.228.232   <none>        80:30000/TCP   16m

[root@master ~]# curl 10.100.228.232
test page on jjyy

ip+31015
在这里插入图片描述

  • LoadBalancer:使用外部负载均衡。其实也是NodePort,只不过会把:自动添加到公有云的负载均衡当中。对外暴露应用,适用公有云

Service代理模式

在这里插入图片描述
kubeadm方式修改ipvs模式

[root@master ~]# kubectl edit configmap kube-proxy -n kube-system
...
mode: "ipvs "
...
[root@master ~]# kubectl delete pod kube-proxy-btz4p -n kube-system:
1、kube-proxy配置文件以configmap方式存储
2、如果让所有节点生效,需要重建所有节点kube-proxy pod

二进制方式修改ipvs模式

[root@master ~]# vi kube-proxy-config.ymlmode: ipvs
ipvs:
scheduler: "rr "
[root@master ~]# systemctl restart kube-proxy:参考不同资料,文件名可能不同。

流程包流程
客户端->NodePort/ClusterlP (iptables/lpvs负载均衡规则)->分布在各节点Pod

查看负载均衡规则

iptables模式
iptables-save lgrep <SERVICE-NAME>
ipvs模式
ipvsadm -L -n

Service工作流程图
在这里插入图片描述
lptables和IPVS的对比
lptables

  • 灵活,功能强大
  • 规则遍历匹配和更新,呈线性时延

lPVS

  • 工作在内核态,有更好的性能
  • 调度算法丰富: rr, wrr,lc,wlc,ip hash…

Service DNS名称

CoreDNS

  • 是一个DNS服务器,Kubernetes默认采用,以Pod部署在集群中,CoreDNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析。

CoreDNS YAML文件

ClusterlP A记录格式

  • <service-name>.<namespace-name>.svc.cluster.local示例: my-svc.my-namespace.svc.cluster.local

在这里插入图片描述

[root@master ~]#  kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        7d5h
web1         NodePort    10.101.173.65   <none>        80:30009/TCP   18m

[root@master ~]# kubectl run -it b1 --image busybox -- /bin/sh
If you don't see a command prompt, try pressing enter.
/ # nslookup web1.default.svc.cluster.local
Server:         10.96.0.10
Address:        10.96.0.10:53

Name:      web1.default.svc.cluster.local
Address:   10.101.173.65

操作小练习

1、创建一个deployment副本数3,然后滚动更新镜像版本,并记录这个更新记录,最后再回滚到上一个版本

[root@master ~]# vi test/test.yml 
[root@master ~]# cat test/test.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels: 
    app: httpd
  name: web
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd  
        image: 1314444/httpd:v0.1
        imagePullPolicy: IfNotPresent
//升级(kubectl set image deployment.apps/{deployment名称} {镜像名称}:={镜像名称}:{版本}[root@master ~]# kubectl set image deployment.apps/web httpd=1314444/httpd:v0.2
deployment.apps/web image updated
[root@master ~]# kubectl get pod
NAME                  READY   STATUS        RESTARTS   AGE
web-7bcffb4f6-5hqsm   1/1     Running       0          12s
web-7bcffb4f6-66gjp   1/1     Running       0          13s
web-7bcffb4f6-jfzbm   1/1     Running       0          11s
web-9b8f648df-5mzk4   1/1     Terminating   0          9m7s
web-9b8f648df-nbhvk   1/1     Terminating   0          9m7s
web-9b8f648df-tgbb8   1/1     Terminating   0          9m7s
[root@master ~]# kubectl get deployment
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    3/3     3            3           9m16s

//回滚默认情况下, Deployment 的上线记录都会保留在系统中,以便可以随时回滚,查看 Deployment 的上线历史记录
[root@master ~]# kubectl rollout history deployment web
deployment.apps/web 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

//查看版本
[root@master ~]# kubectl rollout history deployment web --revision=2
deployment.apps/web with revision #2
Pod Template:
  Labels:       app=httpd
        pod-template-hash=7bcffb4f6
  Containers:
   httpd:
    Image:      1314444/httpd:v0.2
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>

//回滚到上一个版本
[root@master ~]# kubectl rollout undo deployment web --to-revision=1
deployment.apps/web rolled back
[root@master ~]# kubectl rollout history deployment web
deployment.apps/web 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

2、给一个应用扩容副本数为5

[root@master ~]# kubectl scale deploy/web --replicas=5
deployment.apps/web scaled
[root@master ~]# kubectl get pod
NAME                  READY   STATUS              RESTARTS   AGE
web-9b8f648df-c4rzm   1/1     Running             0          2m45s
web-9b8f648df-h7gmp   1/1     Running             0          2m43s
web-9b8f648df-q8p2f   0/1     ContainerCreating   0          2s
web-9b8f648df-q9m56   0/1     ContainerCreating   0          2s
web-9b8f648df-wjtmf   1/1     Running             0          2m44s

3、创建一个pod,其中运行着nginx、redis、memcached 3个容器

[root@master test]# cat pod.yml 
apiVersion: v1
kind: Pod
metadata:
  name: test
  labels:
    app: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  - name: redis
    image: redis
    imagePullPolicy: IfNotPresent
  - name: memcached
    image: memcached
    imagePullPolicy: IfNotPresent

[root@master test]# kubectl apply -f pod.yml 
pod/test created
[root@master test]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
test   3/3     Running   0          40s

4、给一个pod创建service,并可以通过ClusterlP/NodePort访问

[root@master ~]# cat test/test.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd  
        image: 1314444/httpd:v0.1
        imagePullPolicy: IfNotPresent

---
apiVersion: v1
kind: Service
metadata:
  name: web1
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    nodePort: 30009
    targetPort: 80
  selector:
    app: httpd
  type: NodePort

[root@master ~]# kubectl apply -f test/test.yml 
deployment.apps/web created
service/web1 created
[root@master ~]# kubectl get pod,svc
NAME                      READY   STATUS    RESTARTS   AGE
pod/web-9b8f648df-jdm8g   1/1     Running   0          8s
pod/web-9b8f648df-qtm47   1/1     Running   0          8s

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        7d5h
service/web1         NodePort    10.109.3.154   <none>        80:30009/TCP   8s
[root@master ~]# curl 10.109.3.154
test page on jjyy
[root@master ~]# curl 192.168.129.250:30009
test page on jjyy

5、创建deployment和service,使用busybox容器nslookup解析service

[root@master ~]#  kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        7d5h
web1         NodePort    10.101.173.65   <none>        80:30009/TCP   18m

[root@master ~]# kubectl run -it b1 --image busybox -- /bin/sh
If you don't see a command prompt, try pressing enter.
/ # nslookup web1.default.svc.cluster.local
Server:         10.96.0.10
Address:        10.96.0.10:53

Name:      web1.default.svc.cluster.local
Address:   10.101.173.65
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐