开发 k8s 管理平台 - k8sailor 19. 为 Deployment 创建 Service

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 开发 k8s 管理平台 - k8sailor 19. 为 Deployment 创建 Service

开发 k8s 管理平台 - k8sailor 19. 为 Deployment 创建 Service

原文地址: https://tangx.in/posts/books/k8sailor/chapter02/19-create-service/

tag: https://github.com/tangx/k8sailor/tree/feat/19-create-service

https://kubernetes.io/zh/docs/concepts/services-networking/service/#externalname
kubectl create service clusterip nginx-web --clusterip="port:targetPort"
kubectl create service clusterip nginx-web --clusterip="8082:80"
kubectl create service nodeport  nginx-web --clusterip="8081:80"

需要注意, 使用 kubectl get service 查看到的 Ports 的展示结果为 port:nodePort, 而 targetPort 不展示。

# kubectl get service
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
demo-nginx-nodeport-3   NodePort    10.43.181.29    <none>        80:32425/TCP    4s

port, targetPort, nodePort

nodeport-port-targetport

端口映射中的四个 比较关键 的要素:

  1. name: 避免端口相同时,默认名字冲突
  2. port: service 对外提供服务的端口
  3. targetPort: service 指向的 pod 的端口, 即 pod 对外服务的端口。
  4. nodePort: node 对外提供服务的端口, 通过 kube-proxy 修改 iptables 将流量转发到 service 上。

其中, targetPort 可以是 string / int32 的复合类型, 定义如下。

// k8s.io/api@v0.21.4/core/v1/types.go

// ServicePort contains information on service's port.
type ServicePort struct {
    // Number or name of the port to access on the pods targeted by the service.
    // Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.
    // If this is a string, it will be looked up as a named port in the
    // target Pod's container ports. If this is not specified, the value
    // of the 'port' field is used (an identity map).
    // This field is ignored for services with clusterIP=None, and should be
    // omitted or set equal to the 'port' field.
    // More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service
    // +optional
    TargetPort intstr.IntOrString `json:"targetPort,omitempty" protobuf:"bytes,4,opt,name=targetPort"`
}

apimachinery(k8s.io/apimachinery@v0.21.4/pkg/util/) 包中, 提供了很多针对 k8s 对象的常用方法。

解析 port

为了能简化 api 请求的参数, 因此对 clusterIp 和 nodePort 使用了符号表示: 默认为 clusterIp, 如果有 叹号! 则为 nodePort。

port    // clusterIp, port 与 targetPort 一致
port:targetPort // clusterIp, port 与 targetPort 可能不一致

!port:targetPort // nodeport, 端口号随机: port 与 targetPort 可能不一致
!nodePort:port:targetPort // nodeport, 指定端口号, 端口可能因为被使用而创建失败

headless service

对 statefuleset 有效, 对 deployment 无效

https://kubernetes.io/zh/docs/concepts/workloads/controllers/statefulset/

service-headless

使用 headless 之后, k8s 将不再创建 service 进行 pod 的负载均衡。 取而代之的是 DNS 将每个 pod 直接解析暴露, 域名规则 podName.serviceName.namespace.Cluster

注意: statefuleSet 对与绑定的 serviceName 是有强力约束的。 只有匹配名字的 service 才能提供响应的服务。
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx 
  serviceName: "nginx" # 约束只能匹配名为 `nginx` 的 service
  replicas: 3
  template:
  # .... 省略

解析 Headless Port

kubectl create service clusterip my-nginx-web  --clusterip="None" --tcp=8088:80

从 kubectl 的命令中可以看到, Headless Service 可以被认为 clusterip 的一个子类, 其特殊之处就是 ClusterIp: None

鉴于此, 对之前的 Port 规则进行了一定扩展。

规则基本类似, 采用了的新的符号 # 表示 Headless 服务。 # 在很多地方表示注释, 注释对外看不见,因此用以表示 Headless

#port:targetPort // headless 

本身 NodePort 和 Headless 就是不兼容的, 由于 #, ! 在同一个位置, 也一定程度上避免了 误写

external name

externalName service 就是 k8s 集群通过 coredns 实现的 CNAME 服务, 从而实现了 在集群内部不依赖外部地址 的内聚效果。

无论依赖资源地址是否发生变化(例如 迁移), 客户端服务都不需要进行任何变更,只需要通过外部配置更新 service 的 externalName 即可完成切换。

service-external-name

kubectl create service externalname my-ns --external-name www.baidu.com
# kgs my-ns -o yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-ns
  name: my-ns
  namespace: default
spec:
  externalName: www.baidu.com
  # selector:   # external 是不需要选择器的
  #   app: my-ns
  sessionAffinity: None
  type: ExternalName

通过 ping 命令可以看到, my-nswww.baidu.com 结果是一样的。

# ping my-ns
PING www.a.shifen.com (110.242.68.4) 56(84) bytes of data.
64 bytes from 110.242.68.4 (110.242.68.4): icmp_seq=1 ttl=48 time=12.2 ms
64 bytes from 110.242.68.4 (110.242.68.4): icmp_seq=2 ttl=48 time=12.1 ms

# ping www.baidu.com
PING www.a.shifen.com (110.242.68.3) 56(84) bytes of data.
64 bytes from 110.242.68.3 (110.242.68.3): icmp_seq=1 ttl=48 time=11.2 ms
64 bytes from 110.242.68.3 (110.242.68.3): icmp_seq=2 ttl=48 time=11.2 ms

解析 externalName

由于 externalName 是完全的 DNS 行为。 1. 没有 pod 映射, 2. 也不需要 label selector 选择后端的提供服务的 Pod。 因此, 之前的 port:targetPort 规则也就用不上了。

对于 externalName 引入了新的符号 at @@ 本身也有 到、去 目的地的意思。

@external.name

总结

# k create service --help
Available Commands:
  clusterip    Create a ClusterIP service.
  externalname Create an ExternalName service.
  loadbalancer 创建一个 LoadBalancer service.
  nodeport     创建一个 NodePort service.

自此 kubectl 创建 service 常用的几个子命令已经实现了。

  1. clusterip:

    • normal: port:targetPort
    • headless: #port:targetPort
  2. externalname: @external.com
  3. nodeport:

    • 指定 nodePort 端口: !nodeport:port:targetPort
    • 随机 nodePort 端口: !port:targetPort

demo

services 中的参数互斥, 不能共用。

### CREATE servcie , Headless
POST http://127.0.0.1:8088/k8sailor/v0/services/demo-nginx-211?namespace=default
Content-Type: application/json

{
    "services":[
        "80:8088",         # clusterip
        "#80:80",          # headless
        "!31234:80:8088",  # nodeport
        "@www.baidu.com",  # external name
    ]
}
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
Kubernetes 容器
K8S的Service的LoadBanlance之Metallb解决方案
本文介绍了如何在Kubernetes中使用MetalLB来实现Service的LoadBalancer功能,包括MetalLB的部署、配置、以及通过创建地址池和部署服务来测试MetalLB的过程。
35 1
K8S的Service的LoadBanlance之Metallb解决方案
|
2月前
|
Kubernetes 容器 Perl
在K8S中,Deployment⽀持扩容吗?它与HPA有什么区别?
在K8S中,Deployment⽀持扩容吗?它与HPA有什么区别?
|
2月前
|
Kubernetes Docker Perl
在K8S中,如果是因为开发写的镜像问题导致pod起不来该怎么排查?
在K8S中,如果是因为开发写的镜像问题导致pod起不来该怎么排查?
|
2月前
|
Kubernetes 网络安全 容器
在K8S中,有个服务使用service的nodeport进行暴露,发现访问不到如何排查?
在K8S中,有个服务使用service的nodeport进行暴露,发现访问不到如何排查?
|
2月前
|
Kubernetes 负载均衡 网络协议
在K8S中,Service的类型有哪几种,请说⼀下他们的用途?
在K8S中,Service的类型有哪几种,请说⼀下他们的用途?
|
2月前
|
Kubernetes 监控 API
在k8S中,Metric Service是什么?
在k8S中,Metric Service是什么?
|
2月前
|
Kubernetes 负载均衡 网络协议
在k8S中,Headless Service是什么?
在k8S中,Headless Service是什么?
|
2月前
|
Kubernetes 负载均衡 网络协议
在K8S中,Service的类型有哪些?
在K8S中,Service的类型有哪些?
|
2月前
|
存储 Kubernetes 网络协议
在K8S中,Deployment和Statefulset有何区别?
在K8S中,Deployment和Statefulset有何区别?
|
2月前
|
Kubernetes API 开发工具
在K8S中,Deployment的升级过程是什么?
在K8S中,Deployment的升级过程是什么?
下一篇
无影云桌面