Service的功能:::::::::::::::::::::
服务发现:发现pod的变化,宕机的不转发
对外发布:让外部访问到内部,稳定的对外映射一个端口号nodeport
Service有两个ip,第一个是service内部访问用的
一个是向外提供服务的clusterip
定位dns,用dns解析
实例文件:nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
把这三个pod做一个集群:
[root@server1 ~]# vim nginxsvc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginxsvc
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 80
selector:
app: frontend
Service集群是依靠标签的
ports:
- protocol: TCP #选择协议TCP
port: 8080 #service的端口号
targetPort: 80 #容器内部的端口号
selector: #选择标签转给哪些pod
app: frontend
[root@server1 ~]# curl 10.111.185.117:8080 #这样就可以访问到集群ip了
[root@server1 ~]# kubectl describe service nginxsvc 查看集群详细信息
当带有frontend标签的pod发生变化service中映射的容器接入点(endpoints)会立马发生变化,不管是删除pod还是增加pod
Endpoints #service要把数据转发给哪些pod
Service是如何把集群ip转到容器中的,以及如何将数据转发容器中
默认依靠ip地址进行转发,具体:
这就是转发的过程,iptables的转发是概率+dnat达到轮询的
缺点,当pod有一千个,就需要将iptables换成ipvs转发,因为iptables条目太多就运行缓慢了
[root@server1 ~]# kubectl run box --rm -it --image busybox:1.28 /bin/sh
完整的nslookup命令
Dns
配置信息只有dns是通过挂载的方式进入容器,而其他的参数都是通过env环境变量来设置的
跨空间使用service访问::::::::::::
[root@server1 ~]# kubectl create namespace test #创建一个空间(删除就把create换成delete)
写一个文件:vim test-ns.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ns-nginx
namespace: test
spec:
replicas: 3
selector:
matchLabels:
app: nstest
template:
metadata:
labels:
app: nstest
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: ns-svc
namespace: test
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 80
selector:
app: nstest
namespace: test #pod所在的空间
[root@server1 ~]# kubectl get service --namespace test #直接get pod是看不到的
[root@server1 ~]# kubectl run box --rm -it --image busybox:1.28 /bin/sh
测试dns,--rm是退出容器立马删除容器的意思
/ # nslookup ns-svc.test #跨空间访问的方式必须是metadata标签名称.空间名称
/ # wget ns-svc.test:8080
除了系统内部的dns,自己做一个dns地址
文件:
apiVersion: v1
kind: Pod
metadata:
name: bbox1
labels:
tier: busybox
spec:
hostname: busybox-1
subdomain: default-subdomain
containers:
- name: busybox
image: busybox:1.28
imagePullPolicy: IfNotPresent
command:
- sleep
- "9999999"
---
apiVersion: v1
kind: Pod
metadata:
name: bbox2
labels:
tier: busybox
spec:
hostname: busybox-2
subdomain: default-subdomain
containers:
- name: busybox
image: busybox:1.28
imagePullPolicy: IfNotPresent
command:
- sleep
- "9999999"
---
apiVersion: v1
kind: Service
metadata:
name: default-subdomain
spec:
selector:
name: busybox
clusterIP: None
ports:
- name: li
port: 1234
targetPort: 1234
Service之间的通讯都是依靠dns
如何设置k8s容器的dns地址:::::
clusterIP: None #如果定义了子域名是可以使用None的,kube-proxy不会进行负载均衡或路由
如果clusterip=None 就是Headless service 无头服务:不需要负载均衡的时候或者单独使用serviceIP,无头服务不会分配clusterip
Dns的数据分配完全依靠service的selector
subdomain: default-subdomain #指定子域名(无头service要求subdomain和service名字要一致,不一致的话解析不到)
[root@server1 ~]# kubectl apply -f dname.yaml 登录解析
/ # nslookup busybox-1.default-subdomain
小结论:
如果无头service与某pod在同一个namespace中,且他们具有相同的子域名,集群的dns服务器与会给该pod的主机返回A记录
DNS解析的内容为:
[hostName].[serviceName]/[subdomainName].[namespaceName].svc.kubernetes.local
添加参数:
添加这个参数的话hostnmae和域名就一样了
删除上一条参数,重新添加参数:
pod1也添加hostNetwork
hostNetwork:true #这样会和宿主机共用一个网络
加dnspolicy和不加的区别(如果写了hostNetwork:true的话,还想使用k8s内部service做解析那么就要加这条参数,不加解析不到k8s的service)
做了dnspolicy就可以解析k8s内部的service,不做解析不了
手动指定dns地址:
dnsPolicy: None
dnsConfig: #设置dns
nameservers:
- 8.8.8.8
searches: #定义主机域名的默认搜索域
- ns1.li.my.dns.search.suffix
不加手动指定dns的pod:
解析外网使用的就是我们设置的8.8.8.8
实验:会话保持(让所有访问都在一个节点上)
[root@server1 ~]# kubectl explain service.spec.sessionAffinity 查看会话保持的参数
在service的yaml文件中进行修改:vim nginxsvc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginxsvc
spec:
sessionAffinity: ClientIP
ports:
- protocol: TCP
port: 8080
targetPort: 80
selector:
app: frontend
一直访问service的ip
然后查看效果:效果就是只有其中一个pod的日志产生访问记录
[root@server1 ~]# kubectl logs frontend-5ccf5785d5-6x65q
再次修改nginxsvc
apiVersion: v1
kind: Service
metadata:
name: nginxsvc
spec:
sessionAffinity: ClientIP
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 80
- name: https
protocol: TCP
port: 8443
targetPort: 443
selector:
app: frontend
这样就映射了两个端口了
Dns对外部的实验::::::::::::::::::::::::::::::::::;
外部想要访问内部需要做映射
编辑:nginxsvc
apiVersion: v1
kind: Service
metadata:
name: nginxsvc
spec:
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
selector:
app: frontend
externalIPs:
- 10.101.254.90
- 192.168.1.11
这个的转发过程依然使用dnat
- name: http
protocol: TCP
port: 80 #service的端口号
targetPort: 80 #pod的端口号
externalIPs: #虚拟的
- 10.101.254.90
- 192.168.1.11
外网可以访问到虚拟ip了
Pod如何访问到server2物理机的httpd
实验:
在server2下载httpd,正常提供访问即可
[root@server1 ~]# vim ex-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: 192.168.1.20
ports:
- port: 80
#写外部访问的svc
- ip: 192.168.1.20 #需要连接到的物理机的IP
访问设置的serviceip,就可以访问到物理机
修改文件:nginxsvc
apiVersion: v1
kind: Service
metadata:
name: nginxsvc
spec:
type: NodePort
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
selector:
app: frontend
type: NodePort
效果是在所有节点上开启端口映射
[root@server1 ~]# curl 192.168.1.10:31067
默认打开的端口不好看,修改端口号范围:
[root@server1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --service-node-port-range=40000-50000
也可以指定外网访问的端口: nodePort: 40080
apiVersion: v1
kind: Service
metadata:
name: nginxsvc
spec:
type: NodePort
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 40080
selector:
app: frontend
看得到端口已经是指定的端口号了
现在的转发模式是iptables,现在把转发模式改成ipvs
导入模块:::::::
[root@server1 ~]# modprobe -- ip_vs_sh
[root@server1 ~]# modprobe -- ip_vs_rr
[root@server1 ~]# modprobe -- ip_vs_wrr
[root@server1 ~]# modprobe -- ip_contrack_ipv4
装插件:
[root@server1 ~]# dnf install ipset ipvsadm -y
[root@server1 ~]# kubectl edit configmaps -n kube-system kube-proxy
48行mode的value值添加成ipvs
kubectl get pod --namespace kube-system | grep proxy #查看系统空间
kubectl delete pod --namespace kube-system kube-proxy-2p2r9 #这个pod是查看到的名称
kubectl delete pod --namespace kube-system kube-proxy-97vbh
kubectl delete pod --namespace kube-system kube-proxy-hbnrm
kubectl get pod --namespace kube-system | grep proxy #过滤后发现pod变化了
kubectl delete -f nginxsvc.yaml #重新部署
kubectl apply -f nginxsvc.yaml
kubectl get service
ipvsadm -Ln
最后输完这条命令,会发现都是rr轮询了文章来源:https://www.toymoban.com/news/detail-772449.html
文章来源地址https://www.toymoban.com/news/detail-772449.html
到了这里,关于k8s&service服务发现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!