目录
一、Service基本概念
1、Pod的特征
2.解决pod进行如此多变化时的解决方案
2、Service
Kubernetes Service 定义了这样一种抽象:
Service的实现类型
3、Service模型
4、Endpoint Controller
5、Kube-proxy iptables
6、Kube-proxy IPVS
二、服务发现
1、创建后端Deployment
2、创建Service
3、整理文件并创建
4、查看Service
2.测试service是否正常提供服务
5、创建可供外部访问的Service
三、集群中的DNS
1、CoreDNS
2、查看服务的完整域名
3、DNS记录
四、Headless Service(无头服务)
1、Headless Service
2、创建Headless Service
3、使用Headless Service
1.查看Headless Service的信息,可以看到没有IP地址
2.使用的时候利用DNS功能,通过访问“Headless-svc”或“headless-svc.default”来访问服务
一、Service基本概念 1、Pod的特征 1. Pod等资源的概念
①.Pod有自己独立的IP
②.Pod可以被创建,销毁
③.当扩容时,pod的数量会发生变更(可以扩、缩容)
④.当pod故障时,replicaset会创建新的pod
2.解决pod进行如此多变化时的解决方案
一组pod对应一个服务,通过服务访问后端
2、Service 1. Kubernetes Service 定义了这样一种抽象:
逻辑上的一组Pod,一种可以访问它们的策略 — — 通常称为微服务。
这一组Pod能够被Service访问到,通常是通过Label Selector 实现的
3、Service模型
每个节点都有一个Kube-Proxy服务,负责iptables(路由);
Endpoint Controller负责映射关系,通过其知道内部IP地址,内部IP映射到服务
最终通过Kube-proxy组件进行工作
4、Endpoint Controller
1.负责生成和维护所有endpoint对象的控制器
2.负责监听service和对应pod的变化
3.监听到service被删除,则删除和该service同名的endpoint对象
4.监听到新的service被创建,
则根据新建service信息获取相关pod列表,然后创建对应endpoint对象
5.监听到service被更新,
则根据更新后的service信息获取相关pod列表,然后更新对应endpoint对象
6.监听到pod事件,则更新对应的service的endpoint对象,将pod IP 记录到endpoint中
endpoint其实就是个列表
5、Kube-proxy iptables
集群内部的Client可以访问服务IP,通过服务IP可以找到集群内部的Pod
6、Kube-proxy IPVS
从k8s的1.8版本开始,kube-proxy引入了IPVS模式,IPVS模式与iptables实现方式类似,但是采用的hash表,因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能
Service基数 1 5,000 20,000
Rules基数 8 40,000 160,000
增加1条iptables规则 50us 11min 5hour
增加1条ipvs规则 30us 50us 70us
二、服务发现 1、创建后端Deployment
创建一个deployment,特别注意其中的几个选项要和service匹配
- Template 选项必须配置labels,示例中配置参数为“app:httpd”,该配置和service匹配
- Pod的属性中Ports选项指定pod对外提供服务的容器端口,图例中为"containerPort:80",该端口需要和service匹配
apiVersion: apps/v1 #版本
kind: Deployment
metadata: #元数据
name: httpd
spec: #描述
replicas: 3 #三副本
selector: #选择器
matchLabels: #匹配标签
app: httpd
template: #模板
metadata: #模板元数据
labels: #模板标签
app: httpd
spec: #针对template的描述
containers: #容器
- name: httpd
image: httpd
ports:
- containerPort: 80
参考文档: Deployments | Kubernetes
2、创建Service
创建一个httpd-service.yaml,在编写时需要注意以下几点:
- spec参数中添加selector字段,指定一组label的键值对,该值在示例中为"app:httpd",和上一步创建的deployment匹配
- Port参数中,需要指定两个端口
- Ports为该service的端口,客户端访问该服务时使用
- targetPort 为后端pod的端口,需要与之前创建的pod提供服务端口一致
apiVersion: v1
kind: Service #类型为service
metadata:
name: httpd-svc
spec:
selector:
app: httpd #要和上一个文件标签要对上
ports:
- protocol: TCP
port: 8080 #对应service端口
targetPort: 80 #对应pod端口
参考文档: 服务(Service) | Kubernetes
3、整理文件并创建
$ kubectl apply -f- <
4、查看Service 1. 查看service简明信息,可以获取service提供服务的ip地址和端口
$ kubectl get deployments.apps httpd
NAME READY UP-TO-DATE AVAILABLE AGE
httpd 3/3 3 3 76s
$ kubectl get service httpd-svc #查看service,集群类型默认就是Cluster-IP
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-svc ClusterIP 10.100.160.205 8080/TCP 107s
$ kubectl get endpoints httpd-svc #查看后端对应IP
NAME ENDPOINTS AGE
httpd-svc 172.16.126.7:80,172.16.194.102:80,172.16.194.103:80 16m
$ kubectl get pod -owide #列出pod所在节点,纯文本格式输出,包含所有附加信息
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
k8s-worker2
httpd-7cd5646885-9rkwj 1/1 Running 0 32m 172.16.126.7 k8s-worker2
httpd-7cd5646885-jzd5z 1/1 Running 0 32m 172.16.194.102 k8s-worker1
httpd-7cd5646885-n6t7s 1/1 Running 0 32m 172.16.194.103 k8s-worker1
2.测试service是否正常提供服务
$ curl 10.100.160.205:8080
It works!
3. 使用describe命令可以查看service详细信息
如:endpoints信息,显示service关联pod的地址和服务端口
$ kubectl describe service httpd-svc
Name: httpd-svc
Namespace: default
Labels:
Annotations:
Selector: app=httpd
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.160.205
IPs: 10.100.160.205
Port: 8080/TCP
TargetPort: 80/TCP
Endpoints: 172.16.126.7:80,172.16.194.102:80,172.16.194.103:80
Session Affinity: None
Events:
5、创建可供外部访问的Service
1.如果需要service可供外部进行访问,可以使用Nodeport的方式
2.编辑Yaml文件时,添加type(类型)参数
3.可以在使用nodeport字段指定对外服务端口,如果不进行指定,系统会自动分配空闲端口
4.访问时通过访问 “节点IP地址:端口” 进行服务使用
$ vim http_service.yml
apiVersion: v1
kind: Service
metadata:
name: httpd-svc
spec:
type: NodePort
selector:
app: httpd
ports:
- protocol: TCP
port: 8080
targetPort: 80
nodePort: 30144 #指明对外节点端口,不指明时随机
5.测试
$ kubectl get service httpd-svc #查看类型已经变为NodePort,端口号也改变
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-svc NodePort 10.100.160.205 8080:30144/TCP 18h
kiosk@k8s-master:~$ curl k8s-worker1:30144
It works!
kiosk@k8s-master:~$ curl k8s-worker2:30144
It works!
参考文档: 服务(Service) | Kubernetes
三、集群中的DNS 1、CoreDNS
1.CoreDNS是一个轻量级的DNS服务器,通过插件的形式在Kubernetes集群内实现,提供服务发现功能,使得用户除了可以用IP访问服务外,也可用域名来访问服务
2.从1.13版本的Kubernetes开始CoreDNS取代了原有的kubeDNS,成为了kubernetes集群内部的默认DNS组件
$ kubectl get pods -n kube-system | grep dns #查看coredns的pod
coredns-74586cf9b6-fcmv6 1/1 Running 13 (27h ago) 25d
coredns-74586cf9b6-wfbn4 1/1 Running 13 (27h ago) 25d
$ kubectl get pods -o wide -n kube-system | grep dns
coredns-74586cf9b6-fcmv6 1/1 Running 13 (27h ago) 25d 172.16.235.232 k8s-master
coredns-74586cf9b6-wfbn4 1/1 Running 13 (27h ago) 25d 172.16.235.234 k8s-master
$ kubectl get deployments.apps -n kube-system #经过名称反推coredns为deployment创建出来
NAME READY UP-TO-DATE AVAILABLE AGE
calico-kube-controllers 1/1 1 1 25d
coredns 2/2 2 2 25d
metrics-server 1/1 1 1 23d
2、查看服务的完整域名
1.创建一个clientpod,用于查看httpd服务的完整名字
2.在记录总可以看到,服务的IP地址对应的名称是httpd-svc.default.svc.cluster.local
$ kubectl apply -f- <
3.测试
$ kubectl get service #查看集群IP地址
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-svc NodePort 10.100.160.205 8080:30144/TCP 23h
kubernetes ClusterIP 10.96.0.1 443/TCP 25d #k8s自身的集群
$ nslookup 10.100.160.205 #查询DNS名
** server can’t find 205.160.100.10.in-addr.arpa: NXDOMAIN
无法解析,要在pod当中查,因为coredns是在集群内部
$ kubectl exec -it clientpod – /bin/sh #进入pod
/ # nslookup 10.100.160.205
Server: 10.96.0.10 #服务器相关信息
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: 10.100.160.205 #地址dns对应的是谁
Address 1: 10.100.160.205 httpd-svc.default.svc.cluster.local
/ # nslookup httpd-svc.default.svc.cluster.local #一样可以解析
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: httpd-svc.default.svc.cluster.local
Address 1: 10.100.160.205 httpd-svc.default.svc.cluster.local
/ # wget httpd-svc.default.svc.cluster.local:8080
Connecting to httpd-svc.default.svc.cluster.local:8080 (10.100.160.205:8080)
index.html 100% |**************************************************| 45 0:00:00 ETA
/ # cat index.html #验证可以正常工作
It works!
参考文档: 为容器设置启动时要执行的命令和参数 | Kubernetes
3、DNS记录
1.服务的DNS记录名称为:
<服务名称>..svc.cluster.local
2.服务后端的deployment中Pod的DNS记录名称为:
.<服务名称>..svc.cluster.local
3.ClientPod访问服务时,可以使用<服务名称>.便携抵达服务、甚至在ClientPod与服务在同一namespace时,直接使用<服务名称>进行访问
/ # nslookup 172.16.126.7 #反向解析,查看podIP通过谁来解析
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: 172.16.126.7
Address 1: 172.16.126.7 172-16-126-7.httpd-svc.default.svc.cluster.local
四、Headless Service(无头服务) 1、Headless Service
$ kubectl apply -f- <
3、使用Headless Service 1.查看Headless Service的信息,可以看到没有IP地址
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
headless-svc ClusterIP None 80/TCP 9s
…
$ kubectl get endpoints
NAME ENDPOINTS AGE
headless-svc 172.16.126.7:80,172.16.194.102:80,172.16.194.103:80 2m38s
…
2.使用的时候利用DNS功能,通过访问“Headless-svc”或“headless-svc.default”来访问服务
观察看出,域名解析到的IP地址其实是Pod的IP地址
$ kubectl exec -it clientpod – /bin/sh
/ # nslookup headless-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: headless-svc #解析出了3个IP
Address 1: 172.16.126.7 172-16-126-7.httpd-svc.default.svc.cluster.local
Address 2: 172.16.194.102 172-16-194-102.httpd-svc.default.svc.cluster.local
Address 3: 172.16.194.103 172-16-194-103.httpd-svc.default.svc.cluster.local
'解析到了后端Pod的IP,通过名字访问,访问的就是后端的Pod,只是做了转发功能
文章转自:kubernetes-Service服务发现_Java-答学网
作者:答学网,转载请注明原文链接:http://www.dxzl8.com/