0
点赞
收藏
分享

微信扫一扫

k8s 之service

少_游 2022-08-27 阅读 169

Service 也是一种资源对象,service 解决pod 集群对外访问的统一性问题,

一个pod 集群对外暴露统一的接口,供集群外访问和调用,该资源的抽象就是

service


Service 的三种类型 ClusterIP、NodePort 和 LoadBalancer

​ClusterIP

默认的service 类型,service 通过该ip 对外提供服务, 只有culster 内的节点和pod 可访问

ClusterIP 是一种虚拟IP,他并不是真是存在,它由k8s的iptables规则所管理, 他不能被ping 通

NodePort

Service 通过设置NodePort 将Pod的端口映射到节点物理机上。这样外部系统可以通过node ip 加 该端口来访问 Service。

通过NodePort的形式,将我们的Pod服务通过集群节点的真实IP提供给集群外部系统进行访问。


LoadBalancer

Service 可以通过LoadBalancer 映射到云服务商提供的LoadBalancer 地址。

这种方式需要我们将kubernetes集群部署在公有云上,然后通过这些云供应商提供的一个LoadBalancer IP地址,将外部访问流量通过LoadBalancer 的IP地址进行负载均衡和路由转发。


基本原理:

k8s 通过service CLUSTER-IP 访问 pod, 是通过访问endpoint 这个对象实现的, 新创建的pod 如果被svc 的标签选择器选中,则会自动生成endpoint 对象,加入到svc 当中,并且给pod加入必要的环境变量。且看如下例子

先创建一个svc,我们没有指定svc 的type ,默认就是ClusterIP 类型

[root@k8s-master1 test]# cat nginx-svc.yaml

apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
clusterIP: 10.96.173.64
ports:
- protocol: TCP
port: 8000
targetPort: 80
selector:
app: nginx

备注: clustIP 可以手动指定,也可以从ip 池中由dhcp 服务自动分配

此时我们去查endpoints ,还有describe svc

                k8s 之service_service

                k8s 之service_service_02

接下来我们创建两个标签选择器为nginx 的pod,来看svc 发生的变化

[root@k8s-master1 test]# cat nginx1.yaml

apiVersion: v1
kind: Pod
metadata:
name: nginx1
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

[root@k8s-master1 test]# cat nginx2.yaml

apiVersion: v1
kind: Pod
metadata:
name: nginx2
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

我们发现这个endpoint 对象生成了,这也就意味这我们这个svc 网络打通了, 现在通过访问svc 的clustip 就能访问到集群内的两个pod

                k8s 之service_svc_03

pod 内环境变量中加入了svc 的clustip 和端口

                k8s 之service_service_04

我们登录进两个nginx pod 内将nginx1 的默认访问页改为nginx1, nginx2的默认访问页改为nginx2, 用curl 访问集群ip 测试下:

[root@k8s-master1 test]# kubectl exec -it nginx1 -- bash
root@nginx1:/# echo "nginx1" >/usr/share/nginx/html/index.html
root@nginx1:/# exit
[root@k8s-master1 test]# kubectl exec -it nginx2 -- bash
root@nginx2:/# echo "nginx2" >/usr/share/nginx/html/index.html
root@nginx2:/# exit

curl 10.96.173.64:8000

发现已成功访问到集群内部,

                k8s 之service_svc_05

再来看下nodeport

先创建一个Nodetype 类型的svc

[root@k8s-master1 test]# cat webapp.yaml

apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
type: NodePort
ports:
- port: 8001
targetPort: 80
selector:
app: webapp

如上yaml 所示,添加 type: NodePort ,这样就可以将pod 的端口映射到节点物理机上,这种物理机和pod 的网络是一种桥接的模式

                k8s 之service_k8s_06

如上所示,此时tcp 列多了一个映射端口,现在集群外,通过访问node ip 加 该端口, 就能访问到后台的pod应用

我们创建一个标签选择器为webapp 的nginx3 pod 来实验下

[root@k8s-master1 test]# cat nginx3.yaml  

apiVersion: v1
kind: Pod
metadata:
name: nginx3
labels:
app: webapp
spec:
containers:
- name: nginx
image: nginx:1.14.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

更改pod nginx3 的默认访问页,分别用clust IP和 node IP访问下:

                k8s 之service_k8s_07

最后一个知识点:

k8s 内部,由svc 名称构成的域名通过k8s dns 服务,比如core-dns 解析到集群ip 上

apiVersion: v1
kind: Pod
metadata:
name: busybox
labels:
app: webapp
spec:
containers:
- name: busybox
image: busybox:1.34
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
restartPolicy: Always

                k8s 之service_service_08

举报

相关推荐

0 条评论