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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)