k8s-服务发布(label、service、ingress)

1.1 Label 和 Selector

1.1.1定义 Label

应用案例:公司与 xx 银行有一条专属的高速光纤通道,此通道只能与 192.168.7.0 网段进行通信,因此只能将与 xx 银行通信的应用部署到 192.168.7.0 网段所在的节点上,此时可以对节点添加 Label:

[root@k8s-master01 ~]# kubectl label node k8s-node02 region=subnet7
node/k8s-node02 labeled

然后可以通过 Selector 对其筛选:

[root@k8s-master01 ~]# kubectl get node -l region=subnet7
NAME         STATUS   ROLES    AGE   VERSION
k8s-node02   Ready    <none>   18d   v1.24.0

最后在 Deployment 或其他控制器中指定将 Pod 部署到该节点:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeSelector:			##节点选择器
        region: subnet7		##标签
      containers:
      - name: nginx
        image: nginx:1.15.12
        ports:
        - name: http
          containerPort: 80

查看pod所在节点:

也可以用同样的方式对 Service 添加 Label:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80 
    
#kubectl apply -f svc.yaml
[root@k8s-master01 2-4]# kubectl label svc nginx region=subnet7
service/nginx labeled

查看该 Service 的标签:

[root@k8s-master01 2-4]# kubectl get svc nginx --show-labels

查看region=subnet7的svc:

[root@k8s-master01 2-4]# kubectl get svc -l region=subnet7
NAME    TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   192.168.169.115   <none>        80/TCP    14d

上述演示了对节点、Service 添加自定义标签,对于其他资源的 Label 方式相同。

1.1.2 Selector 选择器

首先使用--show-labels 查看指定资源目前已有的 Label:

[root@k8s-master01 2-4]# kubectl get svc --show-labels
NAME         TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE   LABELS
kubernetes   ClusterIP   192.168.0.1       <none>        443/TCP   18d   component=apiserver,provider=kubernetes
nginx        ClusterIP   192.168.169.115   <none>        80/TCP    15d   region=subnet7

选择匹配 app 为 nginx或者 …… 的 Service:

[root@k8s-master01 2-4]# kubectl get svc -l  'region in (subnet7)' --show-labels
NAME    TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE   LABELS
nginx   ClusterIP   192.168.169.115   <none>        80/TCP    15d   region=subnet7

选择 region不等于subnet7的 svc:

[root@k8s-master01 2-4]# kubectl get svc -l region!=subnet7 --show-labels
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   LABELS
kubernetes   ClusterIP   192.168.0.1   <none>        443/TCP   18d   component=apiserver,provider=kubernetes

选择 label 的 key 名为 app 的 svc:

[root@k8s-master01 2-4]# kubectl get svc -l region --show-labels
NAME    TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE   LABELS
nginx   ClusterIP   192.168.169.115   <none>        80/TCP    15d   region=subnet7

1.1.3 修改标签(Label)

比如将 region=subnet7 改为 region=subnet8

[root@k8s-master01 2-4]# kubectl label svc nginx region=subnet8 --overwrite
service/nginx labeled
[root@k8s-master01 2-4]# kubectl get svc nginx --show-labels
NAME    TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE   LABELS
nginx   ClusterIP   192.168.169.115   <none>        80/TCP    15d   region=subnet8

1.1.4 删除标签(Label

删除 key 名为 region的svc的标签:

[root@k8s-master01 2-4]# kubectl label svc nginx region-
service/nginx unlabeled

1.2 Service

1.2.1 定义 Service

定义 Service 的 yaml 文件如下:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

创建服务:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.12
        ports:
        - name: http
          containerPort: 80

​ 该示例为 my-service:80 即可访问到具有 app=myapp 标签的 Pod 的 80 端口上。

​ 需要注意的是,Service 能够将一个接收端口映射到任意的 targetPort,如果 targetPort 为空,targetPort 将被设置为与 Port 字段相同的值。targetPort 可以设置为一个字符串,引用 backend Pod 的一个端口的名称,这样的话即使更改了 Pod 的端口,也不会对 Service 的访问造成影响。

Kubernetes Service 能够支持 TCP、UDP、SCTP 等协议,默认为 TCP 协议。

1.2.2 Service 类型

Kubernetes Service Type(服务类型)主要包括以下几种:

➢ ClusterIP:在集群内部使用,默认值,只能从集群中访问。

➢ NodePort:在所有安装了 Kube-Proxy 的节点上打开一个端口,此端口可以代理至后端Pod,可以通过 NodePort 从集群外部访问集群内的服务,格式为 NodeIP:NodePort。

➢ LoadBalancer:使用云提供商的负载均衡器公开服务,成本较高。

➢ ExternalName:通过返回定义的 CNAME 别名,没有设置任何类型的代理,需要 1.7 或更高版本 kube-dns 支持。

1.2.3 NodePort 类型

​ 如果将 Service 的 type 字段设置为 NodePort,则 Kubernetes 将从--service-node-port-range 参数指定的范围(默认为 30000-32767)中自动分配端口,也可以手动指定 NodePort,创建该 Service后,集群每个节点都将暴露一个端口,通过某个宿主机的 IP+端口即可访问到后端的应用。

​ 定义一个 NodePort 类型的 Service 格式如下:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30000
  type: NodePort

1.2.4 使用 Service 代理 K8s 外部服务

使用场景:

​ ➢ 希望在生产环境中使用某个固定的名称而非 IP 地址访问外部的中间件服务;

​ ➢ 希望 Service 指向另一个 Namespace 中或其他集群中的服务;

​ ➢ 正在将工作负载转移到 Kubernetes 集群,但是一部分服务仍运行在 Kubernetes 集群之外的 backend。

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-svc-external
  name: nginx
spec:
  ports:
  - protocol: TCP
    name: http
    port: 80
    targetPort: 80
  type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: nginx-svc-external
  name: nginx
subsets:
  - addresses:
    - ip: 42.193.106.66
    ports:
    - name: http
      port: 80
      protocol: TCP

​ 访问没有 Selector 的 Service 与有 Selector 的 Service 的原理相同,通过 Service 名称即可访问,请求将被路由到用户定义的 Endpoint。

1.2.5 ExternalName Service

​ ExternalName Service 是 Service 的特例,它没有 Selector,也没有定义任何端口和 Endpoint,它通过返回该外部服务的别名来提供服务。

​ 比如可以定义一个 Service,后端设置为一个外部域名,这样通过 Service 的名称即可访问到该域名。使用 nslookup 解析以下文件定义的 Service,集群的 DNS 服务将返回一个值为my.database.example.com 的 CNAME 记录:

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: default
spec:
  type: ExternalName
  externalName: www.wangming.link

1.2.6 多端口 Service

例如将 Service 的 80 端口代理到后端的 9376,443 端口代理到后端的 9377:

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: myapp
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 9376
  - name: https
    protocol: TCP
    port: 443
    targetPort: 9377

1.3 Ingress

1.3.1 Ingress Controller 安装

官方安装文档:https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal-clusters

[root@k8s-master01 2-4]# kubectl apply -f deploy-ingress.yaml 
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created

1.3.2 使用域名发布 K8s 的服务

创建一个 web 服务:

kubectl create deploy nginx -image=registry.cnbeijing.aliyuncs.com/dotbalo/nginx:1.15.12

暴露服务:

kubectl expose deploy nginx --port 80

创建 Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: www.nginx.com
    http:
      paths:
      #访问网址目录
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80
      - path: /ingress
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80

◆ pathType:路径的匹配方式,目前有 ImplementationSpecific、Exact 和 Prefix 方式

◆ Exact:精确匹配,比如配置的 path 为/bar,那么/bar/将不能被路由;

◆ Prefix:前缀匹配,基于以 / 分隔的 URL 路径。比如 path 为/abc,可以匹配到/abc/bbb 等,比较常用的配置;

◆ ImplementationSpecific:这种类型的路由匹配根据 Ingress Controller 来实现,可以当做一个单独的类型,也可以当做 Prefix 和 Exact。ImplementationSpecific是 1.18 版本引入 Prefix 和 Exact 的默认配置;

1.3.3 Ingress 特例:不配置域名发布服务

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress-no-host
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /no-host
        pathType: ImplementationSpecific

posted @   wangyetao  阅读(75)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示