k8s&service服务发现

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轮询了


  • 19
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值