Service

使用版本1.23

1,什么是k8s service

  • 是发现后端pod服务;
  • 是为一组具有相同功能的容器提供一个统一的入口地址;
  • 是将请求进行负载分发到后端各个容器应用上的控制器;
  • 是k8s 中的一种资源抽象,定义了一组pod的逻辑集合和一个用于访问它们的策略——有时也被称之为微服务;Service 的目标pod集合通常是有Label Selector 来决定的。

2,对于Service的访问来源

请求来源主要有两种: k8s集群内部的程序(Pod)和 k8s集群外部的程序。

3,service类型

采用微服务架构,作为服务所有者,除了实现自身业务逻辑外,还需要考虑如何把服务发布到k8s 集群或者集群外部,使这些服务能够被k8s 集群内的应用、其它k8s集群的应用以及外部应用使用。因此k8s提供了灵活的服务发布方式,用户可以通过serviceType 来指定如何来发布服务;
service在k8s中有以下四种类型:

  • Cluster Ip: 自动分配一个仅Cluster 内部可以访问的虚拟IP(service 默认类型)
  • NodePort: 在ClusterIP 基础上为Service在每台Node 上绑定一个端口,这样集群外部的应用程序就可以通过:NodePort 来访问该服务。
  • LoadBalancer: 在NodePort基础上,借助cloud provider 创建一个外部负载均衡器,并将请求转发到:NodePort
  • ExternalName: 把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这个只有在kubernetes1.7 或更高版本kube-dns 中才支持

service 负载分发策略
service负载分发策略有两种:

RoundRobin: 轮询模式,即轮询将请求转发到后端的各个pod上(默认模式);
SessionAffinity: 基于客户端IP地址进行会话保持的模式,第一次客户端访问后端某个pod, 之后的请求都转发到这个pod上。

查看k8s集群kube-proxy的代理模式

curl localhost:10249/proxyMode
kubectl get cm kube-proxy -n kube-system -o yaml | grep mode

修改kube-proxy的代理模式为ipvs

安装ipvs

yum install -y ipset ipvsadm #(master 、node 节点)

cat << 'EOF' > /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
ipvs_modules=(ip_vsip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_ship_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack_ipv4)
forkernel_module in ${ipvs_modules[*]}; do
/sbin/modinfo -Ffilename ${kernel_module} > /dev/null 2>&1
if [ $? -eq 0 ];then
/sbin/modprobe${kernel_module}
fi
done
EOF

chmod +x /etc/sysconfig/modules/ipvs.modules
lsmod |grep ip_vs

配置更新kube-proxy

修改配置

kubectl -n kube-system edit cm kube-proxy

mode: “ipvs” # 修改mode模式为ipvs

在这里插入图片描述

更新kube-proxy

kubectl get pod -n kube-system |grep kube-proxy |awk ‘{system(“kubectl delete pod “$1” -n kube-system”)}’ # 更新kube-proxy pod

ipvsadm -ln # 查看是否生效
在这里插入图片描述

service 工作图

在这里插入图片描述

实例1:

ClusterIp,集群ip
默认类型,自动分配一个仅Cluster 内部可以访问的虚拟IP
ClusterIp 只在集群内部能被访问到
在这里插入图片描述

ClusterIP 主要在每个node 节点使用iptables/ipvs,将发送到clusterIP对应端口的数据转发到kube-proxy 中。然后kube-proxy自己内部实现有负载均衡的方法,并通过查询到这个service下对应pod的地址和端口,进而把数据转发给对应的pod的地址和端口。

在这里插入图片描述
为了实现图上的功能,主要需要以下几个组件的协同工作:

  • apiserver 用户 通过kubectl 命令向apiserver发送创建 service 的命令,apiserver 接收到请求后将数据存储到etcd 中
  • kube-proxy k8s 中的每个节点中都有一个kube-proxy 的进程,这个进程负责感知service,pod 的变化,并将变化的信息写入到本地的iptables/ipvs 规则中
  • iptables /ipvs 使用NAT等技术将virtualIP的流量转至endpoint中

创建deployment

cat  >>  svc-deployment.yaml <<  EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: dev
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      release: stabe1
  template:
    metadata:
      labels:
        app: myapp
        release: stabe1
        env: test
    spec:
      containers:
      - name: myapp
        image: nginx:1.20.2
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
EOF      

kubectl apply -f svc-deployment.yaml

创建svc

cat  >> svc.yaml  << EOF
apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: dev
spec:
  type: ClusterIP
  selector:
    app: myapp
    release: stabe1
  ports:
  - name: http
    port: 889
    targetPort: 80
EOF

kubectl apply -f svc.yaml
kubectl get al -n dev
kubectl get svc -n dev
curl ClusterIp: clusterPort
在这里插入图片描述

Headless Service 无头服务

有的时候不需要或是不想要负载均衡,以及单独的ServiceIP。 遇到这种情况,可以通过指定的ClusterIP(spec.clusterIP)的值为‘None’来创建Headless Service。 这类Service 并不会分配ClusterIP ,kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由

cat  >> svc-headless.yaml  << EOF 
apiVersion: v1
kind: Service
metadata:
  name: myapp-headless
  namespace: dev
spec:
  selector:
    app: myapp
  clusterIP: "None"
  ports:
  - port: 999
    targetPort: 80
EOF    

kubectl apply -f svc-headless.yaml
kubectl get svc -n dev
dig -t A myapp-headless.dev.svc.cluster.local. @10.6.0.28
在这里插入图片描述

实例2:NodePort

NodePort: 在ClusterIP的基础上为Service在每台机器上绑定一个端口,这样集群外部就可以通过:NodePort 来访问该服务
nodeport 的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy ,然后有kube-proxy 进一步给到对应的pod 中。
创建一个实例:

cat >>  nodeports.yaml  << EOF
apiVersion: v1
kind: Service
metadata:
  name: myapp-nodeport
  namespace: dev
spec:
  type: NodePort
  selector:
    app: myapp
    release: stabe1
  ports:
  - name: http
    port: 666
    targetPort: 80
EOF    

kubectl apply -f nodeports.yaml
kubectl get all -n dev
kubectl get svc -n dev
在这里插入图片描述
curl http://192.168.6.111:30777/
在这里插入图片描述

实例3:LoadBalancer

实例4: ExternalName

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值