云其它

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > 云其它 > K8s Service服务发布

K8s Service服务发布方式

作者:大新屋

文章介绍了Kubernetes中标签(Label)用于资源分组,标签选择器(Selector)用于精准匹配;Service作为服务抽象,通过标签选择器关联Pod,提供稳定访问入口(ClusterIP/NodePort);Endpoint记录Pod网络信息,实现服务发现与流量分发

一、Label和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的作用

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文