Service常用操作


创建Service

一个Service支持暴露多个端口: 多端口 Service-yaml示例
创建Service的yaml示例


为service再发布一个service

https://blog.csdn.net/zhengzaifeidelushang/article/details/122545435

# 将nginx服务的8443端口暴露为443,并在创建一个新服务名为nginx-https
kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https

kubectl为deployment创建service

# 将一个已存在的deployment暴露为新的service
kubectl espose deployment/应用名 -–type=NodePort -—port 8080

# 为tomcatdemo的8080端口映射为80端口,暴露方式为NodePort,NodePort端口会随机生成
## --port=80 集群内部的端口
## --target-port=8080 容器中应用的端口
## --type=NodePort  暴露端口的方式,NodePort是允许外网访问
kubectl expose deployment tomcatdemo --port=80 --target-port=8080 --type=NodePort

svc暴露UDP服务端口

## --protocol=UDP 暴露UDP端口
kubectl expose deployment 应用名 --port=服务端口 --protocol=UDP --target-port=容器内端口 --type=NodePort --name=服务名-udp --save-config -o yaml --dry-run=client

yaml资源清单创建

apiVersion: v1
kind: Service
metadata:
  name: gost-udp
spec:
  selector:
    app: gost
  type: NodePort
  ports:
    - name: udp
      port: 3389
      protocol: UDP
      targetPort: 1080
    - name: tcp
      port: 3389
      protocol: UDP
      targetPort: 1080

yaml创建service

在vscode中创建yaml文件,输入service即可自动补全。
https://blog.csdn.net/omaidb/article/details/125104491
https://blog.csdn.net/omaidb/article/details/121855353


生成service的yaml资源清单
# 生成service的yaml资源清单
## --port=80 集群内部的端口
## --target-port=8080 pod中容器的端口
## --type=NodePort  暴露端口的方式,NodePort是允许外网访问
## --save-config 加到注释中
kubectl expose deployment gost --port=3389 --target-port=1080 --type=NodePort --name=gost --save-config -o yaml --dry-run=client > my-service.yaml

apply资源清单
# apply这个service的yaml资源清单
kubeclt apply -f my-server.yaml

查看创建的service

# 查看{deployment:gost}的service的端口
## NodePort外部访问的端口是随机生成的,端口在30000以上
## NodePort端口是在node宿主机上暴露的随机端口
kubectl get services gost

在这里插入图片描述

# 查看service关联的pod的ip地址和端口号
kubectl get svc,endpoints tomcatdemo
## 访问http://masterip:31102/即可成功访问到gost的页面

在这里插入图片描述

# 查看宿主机上监听的端口
netstat -tunlp|grep 31102
lsof -i:31102

在这里插入图片描述


查看svc选择的标签

# 查看指定service选择的标签
kubectl get svc gost --show-labels

在这里插入图片描述

# 通过yaml方式查看service选择的标签
kubectl get svc gost -o yaml|grep -A 2 selector

在这里插入图片描述


修改Service的端口

# 修改svc的端口
kubectl edit svc/svc名

在这里插入图片描述


删除Service

# 1.删除服务
## 1.1查看服务
kubectl get sv

## 1.2删除服务
kubectl delete svc/服务名

# 2.删除deployment
## 2.1查看deployments
kubectl get deployments
## 2.2删除deployments
kubectl delete deployments/应用名

Service(服务)概念

Service也是k8s里核心的资源对象之一, k8s里面的每个Service就是我们提起的“微服务”,之前所介绍的Pod、 RC等资源都是为Service做“嫁衣”的。


Service定义了一个服务的访问入口地址, 前端的应用( Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实例, Service与其后端Pod副本集群之间是通过Label Selector来实现“无缝对接”的。而RC的作用实际上是保证Service的服务能力和服务质量始终处于预期的标准。通过分析、识别并建模系统中的所有服务的微服务,最终我们的系统由多个提供不同业务功能而又彼此独立的微服务单元所组成,服务之间通过TCP/IP进行通信,从而形成了我们强大而又灵活的弹性网络,拥有了强大的分布式能力、弹性扩展能力、容错能力.

运行在Node节点上的kube-proxy进程其实就是一个智能的负载均衡器,他负责把Service的请求转发到后端的某个Pod实例上, 并在内部实现服务的负载均衡与会话保持机制。
但是Service不是共用一个负载均衡器的IP地址,而是每个Service分配了一个全局唯一的虚拟IP地址,这个虚拟IP地址称为Cluster IP。这样一来,每个服务就变成了具备唯一IP地址的“通信节点” ,服务调用就变成了最基础的TCP/IP网络通信问题。 Service一旦创建, k8s就会自动为期分配一个可用的Cluster IP,而且在Service的整个生命周期内,他的Cluster IP不会发生改变。只要用Service的Name与Service的Cluster IP地址做一个DNS域名映射即可完成服务发现.

k8s通过插件的方式引入了DNS系统(CoreDNS),把服务名作为DNS域名,这样程序就可以直接使用服务名来建立通信连接了。


什么是Service

参考 https://www.toutiao.com/a6938010733057688102/?log_from=815c41886752e_1646033414390

Service引入主要是解决Pod的动态变化,提供统一访问人口:

  • 防止Pod失联,找到提供同一个服务的Pod(服务发现)
  • 定义一组Pod的访问策略(负载均衡)

创建一个pod,同时也会创建一个对应的EndPoint


理解k8s系统里面的三种IP:

Node IP: Node节点的IP地址

  • Node IP是k8s集群中每个节点的物理网卡IP地址,他是一个真实存在的物理网络,所有属于这个网络的服务器之间都能通过这个网络直接通信,不管他们中是否有部分节点不属于这个k8s集群,这个也表明k8s集群之外的节点访问k8s集群内的某个节点或者TCP/IP服务时,必须使用Node IP进行通信。

Pod IP: Pod的IP地址

  • Pod IP是每一个Pod的IP,他是Docker Engine根据docker0网桥的IP地址进行分配的,通常是一个虚拟的二层网络。k8s位于不同Node上的Pod能够直接通信,所以k8s里的一个Pod里面容器访问另一个Pod里面的容器,就是通过Pod IP所在的虚拟二层网络实现通信的,而真实的TCP/IP流量则是通过Node IP所在的物理网卡流出的。

Cluster IP: Service的IP地址,cluster ip只能在容器内访问

  • Cluster IP:它也是一个虚拟的IP,更像一个“伪造”的IP地址。应用内访问使用这个IP.

Service常用三种type(NodePortLoadBalancer)

官方doc-发布服务-服务类型

  • ClusterIP:默认,分配一个集群内部可以访问的虚拟IP(VIP)
  • NodePort:在每个Node上分配一个端口作为外部访问入口
  • LoadBalancer:与NodePort类似,在每个节点上启用一个端口来暴露服务,除此之外,K8S会请求底层云平台(aliyun, aws等)上负载均衡器,将每个Node([NodeIP]:[NodePort])作为后端添加进去.创建LoadBalancer类型的Service会自动创建和绑定外部LoadBalancer到节点映射的NodePort上。

LoadBalancer 类型


Service DNS名称

官方文档: https://kubernetes.io/zh/docs/concepts/services-networking/dns-pod-service/
参考: https://kubernetes.renkeju.com/chapter_6/6.3.3.ClusterDNS_and_service_discovery.html
在这里插入图片描述
ClusterDNS配置文件

[node root ~]# cat /var/lib/kubelet/config.yaml|grep -i -A1 clusterdns
clusterDNS:
- 10.80.0.10

ClusterIP A记录格式:

<service-name>.<namespace-name>.svc.cluster.local

示例:

my-svc.my-namespace.svc.cluster.local

根据svc的ip地址查询svc域名

clusterIPService域名解析响应的DNS记录类型A记录.

nslookuphost命令来自bind-utils

# 安装bind-utils
yum install bind-utils -y

# 查询clusterDNS
[node root ~]# cat /var/lib/kubelet/config.yaml|grep -i -A1 clusterdns
clusterDNS:
- 10.80.0.10

# 使用clusterDNS根据svc的ip地址查询svc的域名
## nslookup 要反查的ip地址 指定要使用的DNS地址(clusterDNS地址)
[master root ~]# nslookup 10.83.28.128 10.80.0.10
128.28.83.10.in-addr.arpa       name = web.aliang-cka.svc.cluster.local.

# 使用host命令指定dns查询svc的域名
host ip地址 指定dnsip
[master root ~]# host 10.83.28.128 10.80.0.10
Using domain server:
Name: 10.80.0.10
Address: 10.80.0.10#53
Aliases:

128.28.83.10.in-addr.arpa domain name pointer web.aliang-cka.svc.cluster.local.

普通的 Service:

会生成servicename.namespace.svc.cluster.local域名,会解析到 Service 对应的 ClusterIP 上,
在 Pod 之间的调用可以简写成 servicename.namespace
如果处于同一个命名空间下面,甚至可以只写成 servicename 即可访问


Headless Service:

无头服务,就是把 clusterIP 设置为 None 的,会被解析为指定 Pod 的 IP 列表,同样还可以通过podname.servicename.namespace.svc.cluster.local访问到具体的某一个 Pod。


service分发策略

一种是 轮询模式
一种是会话保持模式


修改kube-proxy代理模式

在这里插入图片描述

serviceskube-proxy管理的.负载均衡默认是用的iptables;可以手动修改为ipvs.


查看负载均衡规则

# iptables模式查看负载均衡规则
iptables-save|grep service名

# ipvs模式查看负载均衡规则
ipvsadm -L -n

安装IPVS

参考 Centos安装IPVS


kubeadm方式修改为ipvs模式:

在这里插入图片描述

# 修改configmap kube-proxy
kubectl -n kube-system edit cm kube-proxy

搜索mode关键字,参数默认为“ ”

# 修改为ipvs模式
mode: "ipvs"

删除所有kube-proxy的pod,重建所有节点kube-proxy

# 重建所有kube-proxy的pod
kubectl -n kube-system delete pod kube-proxy-*

ipvs模式查看负载均衡规则

# ipvs模式查看负载均衡规则
ipvsadm -L -n

二进制安装方式修改ipvs模式

在这里插入图片描述

# 查看kube=proxy配置目录
systemctl cat kube-proxy

# 修改kube-proxy配置文件
vim kube-proxy-config.yaml

# 修改配置为ipvs
mode: ipvs
ipvs:
  scheduler: "rr "

# 重启kube-proxy服务
systemctl restart kube-proxy

ipvs模式查看负载均衡规则

# ipvs模式查看负载均衡规则
ipvsadm -L -n

蓝绿发布

参考: https://youtu.be/CLq_hA0lAd0
https://help.coding.net/docs/cd/best-practice/blue-green.html

红蓝发布就是 建两个版本的deploy,和svc,为svc打版本标签,然后选择Service Label标签对应的deploy版本

K8S中如何实现蓝绿部署


service解除nodeport端口限制

vim /etc/kubernetes/manifests/kube-apiserver.yaml

设置service-node-port-range=20000-50000,删除原有pod即可,静态pod无需自己再kubectl apply ,会自动watch到的


编辑master节点的kube-apiserver.yaml

service NodePort 模式 默认只能开放 30000-32767端口,解除限制方法:

  1. 登录 master节点 编辑文件
/etc/kubernetes/manifests/kube-apiserver.yaml
# 修改文件添加 - --service-node-port-range=0-65535

sed -i '/--service-cluster-ip-range/a\    - --service-node-port-range=0-65535' /etc/kubernetes/manifests/kube-apiserver.yaml
# ......

重启所有master节点apiserver容器

# 重启所有master节点apiserver
kubectl get pod -n kube-system | grep apiserver
kubectl delete pod -n kube-system kube-apiserver-master1


# 重启所有apiserver pod
kubectl get pod -n kube-system | grep kube-apiserver | awk '{print "kubectl -n kube-system delete pod " $1}' |bash

Svc常见故障排查

一个service无法对外提供服务的常见问题可能是?
serviceendpoint之间的label不匹配
service后端映射端口不匹配
service后端Pod状态异常

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐