K8s Service服务发布方式
作者:大新屋
一、Label和Selector
- Label:Label(标签)可以对K8s的一些对象,如Pod和节点进行“分组”。通过添加key=value格式的标签,用于区分同样的资源不同的分组。
- Selector:Selector(标签选择器)可以通过根据资源的标签查询出精确的对象信息。
1、创建Pod标签
(1)、Deployment自定义Pod标签参数说明
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy spec: replicas: 1 selector: matchLabels: app: nginx # Deployment标签选择器进行选择自定义的Pod标签,不同的Deployment不能有相同的标签,与.spec.template.metadata.labelsc参数值匹配 template: metadata: labels: app: nginx # 自定义Pod标签,与.spec.selector.matchLabels参数值匹配 spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26 name: nginx
(2)、创建两个不同标签的Pod
mkdir -p /data/yaml/label cat > /data/yaml/label/nginx-deploy.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: default spec: replicas: 1 selector: matchLabels: app: nginx disktype: hdd template: metadata: labels: app: nginx disktype: hdd spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24 name: nginx01 ports: - containerPort: 80 EOF cat > /data/yaml/label/redis-deploy.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: labels: app: redis-deploy name: redis-deploy namespace: default spec: replicas: 1 selector: matchLabels: app: redis disktype: ssd template: metadata: labels: app: redis disktype: ssd spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/redis:6.2.16 name: redis01 ports: - containerPort: 6379 EOF kubectl create -f /data/yaml/label/ kubectl get pods -n defaul kubectl get pods -n default
(3)、Pod查询标签操作
### 查询default命名空间下Pod标签键值对 kubectl get pods -n default --show-labels ### 查询defalut命名空间下Pod标签键值对匹配app=nginx kubectl get pods -n default --show-labels -l app=nginx ### 查询default命名空间下Pod标签键值对匹配app=redis的Pod(正则过滤) kubectl get pods -l 'app in (redis)' -n default --show-labels ### 查询default命名空间下Pod标签键值对匹配app=redis并且disktype!=hhd(正则过滤) kubectl get pods -l 'app in (redis)' -n default --show-labels ### 查询default命名空间下Pod标签键(key)名匹配disktype kubectl get pods -n default --show-labels -l disktype
2、创建Service标签
(1)、创建一个Deployment Service
mkdir -p /data/yaml/label cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF' apiVersion: v1 kind: Service metadata: labels: app: nginx-service name: nginx-service namespace: default spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: default spec: replicas: 1 selector: matchLabels: app: nginx disktype: hdd template: metadata: labels: app: nginx disktype: hdd spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24 name: nginx01 ports: - containerPort: 80 EOF kubectl create -f /data/yaml/label/nginx-deploy-service.yaml kubectl get deploy -n default kubectl get deploy -n default kubectl get service -n default -owide
(2)、Service查询标签操作
### 查询Service已创建的标签键值对 kubectl get services -n default --show-labels kubectl get svc -n default --show-labels ### 查询Service标签键值对匹配app=nginx-service kubectl get Services -n default --show-labels -l app=nginx-service
3、创建节点标签
(1)、K8s节点创建标签
### 选择k8s集群k8s-node01、k8s-node02、k8s-node03创建自定义标签,app=erp-test自定义的labels标签键值对 kubectl get nodes kubectl label nodes k8s-node01 k8s-node02 k8s-node03 app=erp-test kubectl get nodes -l app=erp-test -owide
(2)、节点查询标签操作
### 查看节点已定义的所有标签 kubectl get node --show-labels ### 查看节点已定义的标签键值对(key=values)为app=erp-test kubectl get node --show-labels -l app=erp-test kubectl get nodes -l app=erp-test -owide ### 选择标签匹配app=erp-test的node节点(正则过滤) kubectl get node -l 'app in (erp-test)' --show-labels ### 选择标签匹配app=erp-test并且disktype!=ssd的node节点(正则过滤) kubectl get node -l 'disktype!=ssd,app in (erp-test)' --show-labels ### 选择lable的键(key)名为app的节点 kubectl get node --show-labels -l app
4、修改节点指定标签
### 修改指定节点名称的标签 kubectl label node k8s-node01 k8s-node02 subnet=30 --overwrite kubectl get node --show-labels -l subnet=30 ### 修改指定节点标签key kubectl label node -l subnet subnet=40 --overwrite kubectl get node --show-labels -l subnet=40
5、删除节点指定标签
### 删除指定节点的标签 kubectl label node k8s-node01 subnet- kubectl get node --show-labels -l subnet=40 ### 删除指定节点标签key kubectl label node -l subnet subnet- kubectl get node --show-labels -l subnet=40
6、节点创建标签并应用到Deployment和Service
(1)、K8s节点创建标签
### k8s-node01、k8s-node02、k8s-node03节点创建自定义标签system=erp kubectl get node kubectl label node k8s-node01 k8s-node02 k8s-node03 system=erp
(2)、创建Deployment和Service并匹配节点标签
### Deployment参数.spec.template.spec.nodeSelector参数添加节点自定义标签system=erp cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF' apiVersion: v1 kind: Service metadata: labels: app: nginx-service name: nginx-service namespace: default spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: nginx disktype: hdd template: metadata: labels: app: nginx disktype: hdd spec: nodeSelector: system: erp containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24 name: nginx01 ports: - containerPort: 80 EOF kubectl create -f /data/yaml/label/nginx-deploy-service.yaml kubectl get pods -n default kubectl get deploy -n default kubectl get svc -n default
(3)、检查标签
### 检查节点标签 kubectl get node --show-labels kubectl get node --show-labels -l system=erp ### 检查Pod标签 kubectl get pods -n default --show-labels kubectl get pods -n default --show-labels -l app=nginx ### 检查Service标签 kubectl get svc -n default --show-labels kubectl get svc -n default --show-labels -l app=nginx-service
二、Service
提示:Kubernetes 官网Service说明文档: https://kubernetes.io/docs/concepts/services-networking/service/
每个Pod都会获取到它自己的IP地址,但是这些IP地址不总是稳定和可依赖的,这样就会导致一个问题:在Kubernetes集群中,如果一组Pod(比如后端的Pod)为其他Pod(比如前端的Pod)提供服务,那么如果它们之间使用Pod的IP地址进行通信,在Pod重建后,将无法再进行连接。
于是Kubernetes引用了Service这样一种抽象概念:逻辑上的一组Pod,即一种可以访问Pod的策略。这一组Pod能够被Service通过标签选择器访问到,之后就可以使用Service进行通信。
1、Service参数说明
apiVersion: v1 # 填写API资源版本号,通过kubectl api-resources | grep Service命令查询API资源版本号 kind: Service # 指定资源类型,Service资源类型是Service metadata: # 包含Service的元数据 labels: # 设置Service标签 app: nginx-service # 自定义Service标签键值对 name: nginx-service # 自定义Service名称 spec: # 设置Service的规格 selector: # 设置Service调用Pod,必须与Deployment参数.spec.template.metadata.labels参数值匹配 app:nginx ports: # 设置端口组 - protocol: TCP # 设置使用的协议,Service支持TCP、UDP、SCTP等协议,默认TCP协议 port: 80 # 自定义Service端口号,K8s集群内部访问使用的端口 targetPort: 80 # 指定Pod端口,如果targetPort为空,targetPort将被设置与Deployment参数.template.spec.containers.ports.containerPort:字段相同的值 type: ClusterIP # 设置Service类型,ClusterIP只允许K8s集群内部访问,NodePort允许K8s集群内部和外部访问,默认ClusterIP类型 ### Service Type(服务类型)主要包括以下几种: ClusterIP # K8s集群对内发布服务,只能K8s集群内部访问,默认值 NodePort # K8s集群对外发布服务,允许K8s集群外部和内部访问,通过kube-apiserver服务参数--service-node-port-range=30000-32767设置的端口范围内随机一个NodePort端口(也可以手动指定,但端口范围由kube-apiserver服务参数决定),通过kube-proxy服务把NodePort端口可以代理至后端Pod,可以通过NodePort从K8s集群外部访问到K8s集群内部的服务,格式为NodeIP:NodePort LoadBalance # 使用云厂商提供的负载均衡器公开服务,成本较高 ExternalName # 通过返回定义的CNAME别名,没有设置任何类型的代理,需要K8s 1.7以上版本kube-dns支持
2、创建Service(ClusterIP,K8s集群对内发布服务)
提示:删除Deployment后,再重新创建Deployment,Servicer IP是不会发生变化,除非删除Service重新创建Service,这时Service IP就会发生变化
mkdir -p /data/yaml/label cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF' apiVersion: v1 kind: Service metadata: labels: app: nginx-service name: nginx-service namespace: default spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24 name: nginx01 ports: - containerPort: 80 EOF kubectl create -f /data/yaml/label/nginx-deploy-service.yaml kubectl get pods -n default kubectl get deploy -n default kubectl get service -n default ### 查看指定Service yaml文件参数配置 kubectl get svc nginx-service -n default -oyaml ### K8s集群内部访问Service格式,相同NameSpace命名空间下Pod访问格式:Service名称 + 端口,不相同NameSpace命名空间下Pod访问格式:Service名称 + 端口 + NameSpace名称 curl 10.96.107.232 kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://nginx-service kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://10.96.107.232 kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl nginx-service.default
3、创建Service(NodePort随机产生端口,K8s集群对外发布服务)
提示:删除Deployment后,再重新创建Deployment,Servicer IP是不会发生变化,除非删除Service重新创建Service,这时Service IP就会发生变化
提示:Service type参数值NodePort 是设置K8s集群对外发布服务,允许K8s集群外部和内部访问,通过kube-apiserver服务参数--service-node-port-range=30000-32767设置的端口范围内随机一个NodePort端口(也可以手动指定,但端口范围由kube-apiserver服务参数决定),通过kube-proxy服务把NodePort端口可以代理至后端Pod,可以通过NodePort从K8s集群外部访问到K8s集群内部的服务,格式为NodeIP:NodePort`
mkdir -p /data/yaml/label cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF' apiVersion: v1 kind: Service metadata: labels: app: nginx-service name: nginx-service namespace: default spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: NodePort --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24 name: nginx01 ports: - containerPort: 80 EOF kubectl create -f /data/yaml/label/nginx-deploy-service.yaml kubectl get pods -n default kubectl get deploy -n default kubectl get service -n default ### 查看指定Service yaml文件参数配置 kubectl get svc nginx-service -n default -oyaml ### K8s集群外部主机访问Service格式: 任意一台K8s集群节点IP + 随机的NodePort端口 curl http://172.20.235.201:30926 ### K8s集群内部访问Service格式(K8s集群内部包括节点和Pod):相同NameSpace命名空间下Pod访问格式:Service名称 + 端口,不相同NameSpace命名空间下Pod访问格式:Service名称 + 端口 + NameSpace名称 curl 10.96.107.232 kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://nginx-service kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://10.96.107.232 kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl nginx-service.default ### (kubernetes二进制安装)NodePort对外发布服务产生的30926是从/usr/lib/systemd/system/kube-apiserver.service配置文件--service-cluster-ip-range参数端口范围内随机产生 [root@k8s-master01 ~]# cat /usr/lib/systemd/system/kube-apiserver.service | egrep "service-node-port-range" --service-node-port-range=30000-32767 \
4、创建Service(NodePort手动指定端口,K8s集群对外发布服务)
提示:删除Deployment后,再重新创建Deployment,Servicer IP是不会发生变化,除非删除Service重新创建Service,这时Service IP就会发生变化
提示:Service type参数值NodePort 是设置K8s集群对外发布服务,允许K8s集群外部和内部访问,通过kube-apiserver服务参数--service-node-port-range=30000-32767设置的端口范围内随机一个NodePort端口(也可以手动指定,但端口范围由kube-apiserver服务参数决定),通过kube-proxy服务把NodePort端口可以代理至后端Pod,可以通过NodePort从K8s集群外部访问到K8s集群内部的服务,格式为NodeIP:NodePort
mkdir -p /data/yaml/label cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF' apiVersion: v1 kind: Service metadata: labels: app: nginx-service name: nginx-service namespace: default spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 31000 type: NodePort --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24 name: nginx01 ports: - containerPort: 80 EOF kubectl create -f /data/yaml/label/nginx-deploy-service.yaml kubectl get pods -n default kubectl get deploy -n default kubectl get service -n default ### 查看指定Service yaml文件参数配置 kubectl get svc nginx-service -n default -oyaml ### K8s集群外部主机访问Service格式: 任意一台K8s集群节点IP + 手动指定的NodePort端口 curl http://172.20.235.201:31000 ### K8s集群内部访问Service格式(K8s集群内部包括节点和Pod):相同NameSpace命名空间下Pod访问格式:Service名称 + 端口,不相同NameSpace命名空间下Pod访问格式:Service名称 + 端口 + NameSpace名称 curl 10.96.107.232 kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://nginx-service kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://10.96.107.232 kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl nginx-service.default ### (kubernetes二进制安装)NodePort对外发布服务产生的31000是从/usr/lib/systemd/system/kube-apiserver.service配置文件--service-cluster-ip-range参数端口范围内手动指定 [root@k8s-master01 ~]# cat /usr/lib/systemd/system/kube-apiserver.service | egrep "service-node-port-range" --service-node-port-range=30000-32767 \
三、Endpoint
Endpoint的定义
- Endpoint是Kubernetes中的一种资源,用于描述Service的实际访问点。它包含了提供服务的Pod的IP地址和端口信息。
- 这些信息是Kubernetes实现服务发现和流量分发的关键依据,通过记录具体Pod的网络信息,让外部请求能够准确找到提供服务的实例。
Endpoint的作用
- Endpoint的主要作用是将Service与后端Pod关联起来。当一个Service被创建时,Kubernetes会自动创建对应的Endpoint,将Service的流量分发到后端Pod。
- 它就像是一座桥梁,连接了抽象的服务访问入口(Service)和实际提供服务的工作负载(Pod),确保服务请求能够被正确地路由到可用的Pod实例上,实现了服务的高可用性和负载均衡。
1、Service与Endpoint参数说明
apiVersion: v1 kind: Service metadata: labels: # Service的metadata.labels参数值与Endpoints的metadata.labels参数值一样 app: erp-service name: erp-service # Service的metadata.name参数值与Endpoints的metadata.name参数值一样 namespace: default spec: ports: - name: http # Service的spec.ports.name参数值与Endpoints的subsets.ports.name参数值一样 port: 80 # Service的spec.ports.port参数值与Endpoints的subsets.ports.port参数值一样 protocol: TCP # Service的sepc.ports.protocol参数值与Endpoints的subsets.ports.protocol参数值一样 targetPort: 80 type: ClusterIP --- apiVersion: v1 kind: Endpoints metadata: labels: # Endpoints的metadata.labels参数值与Service的metadata.labels参数值一样 app: erp-service name: erp-service # Endpoints的metadata.name参数值与Service的metadata.name参数值一样 namespace: default subsets: # 包含一个或多个子集,每个子集都有一个地址列表和一个端口列表 - addresses: # 包含IP 地址列表 - ip: 172.17.253.111 # K8s集群外部的一台Nginx服务器 ports: - name: http # Endpoints的subsets.ports.name参数值与Service的spec.ports.name参数值一样 port: 80 # Endpoints的subsets.ports.port参数值与Service的spec.ports.port参数值一样 protocol: TCP # Endpoints的subsets.ports.protocol参数值与Service的sepc.ports.protocol参数值一样
2、创建Service与Endpoint代理K8s集群外部服务(IP方式)
使用场景: 通过Service与Endpoint代理K8s集群外部服务指定Service名称让K8s集群内Pod都能访问到指定Service
mkdir -p /data/yaml/label cat > /data/yaml/label/erp-endpint.yaml << 'EOF' apiVersion: v1 kind: Service metadata: labels: app: erp-service name: erp-service namespace: default spec: ports: - name: http port: 80 protocol: TCP targetPort: 80 type: ClusterIP --- apiVersion: v1 kind: Endpoints metadata: labels: app: erp-service name: erp-service namespace: default subsets: - addresses: - ip: 172.17.253.111 ports: - name: http port: 80 protocol: TCP EOF kubectl create -f /data/yaml/label/erp-endpint.yaml kubectl get svc -n default kubectl get ep -n default ### K8s集群内部Pod访问Service格式(K8s集群内部包括节点和Pod):相同NameSpace命名空间下Pod访问格式:Service名称 + 端口,不相同NameSpace命名空间下Pod访问格式:Service名称 + 端口 + NameSpace名称 kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl http://10.96.97.222 kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl http://erp-service kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl http://erp-service.default
3、创建Service代理K8s集群外部服务(域名方式)
提示:Service ExternalName参数是 Service 的一个特例,它没有 Selector,也没有定义任何端口和 Endpoint,它通过返回该外部服务的别名来提供服务。比如可以定义一个 Service,后端设置为一个外部域名,这样通过 Service 的名称即可访问到该域名
注意:需要访问Service ExternalName的Pod需要与创建Service ExternalName在同一个namespace命名空间
mkdir -p /data/yaml/label cat > /data/yaml/label/nginx-service-externalname.yaml << 'EOF' apiVersion: v1 kind: Service metadata: name: erp-service-url namespace: default spec: type: ExternalName externalName: erp.test.com #externalName: erp.test.com.kube-system.cluster.local # 让kube-system命名空间下的Pod能访问到default命名空间下的Service ExternalName EOF kubectl create -f /data/yaml/label/nginx-service-externalname.yaml kubectl get svc -n default ### 进入到任意一个Pod测试访问K8s集群外部服务 kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl erp-service-url kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl erp-service-url.default
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。