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

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
简介: 开发 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
    ]
}
相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
Kubernetes Cloud Native 容器
完全免费的K8S学习平台:在线集群环境助力你的云原生之路!
完全免费的K8S学习平台:在线集群环境助力你的云原生之路!
158 1
|
2月前
|
Kubernetes 开发工具 Docker
微服务实践k8s与dapr开发部署实验(2)状态管理
微服务实践k8s与dapr开发部署实验(2)状态管理
63 3
微服务实践k8s与dapr开发部署实验(2)状态管理
|
2月前
|
存储 Kubernetes API
使用Kubernetes管理容器化应用的深度解析
【5月更文挑战第20天】本文深度解析Kubernetes在管理容器化应用中的作用。Kubernetes是一个开源平台,用于自动化部署、扩展和管理容器,提供API对象描述应用资源并维持其期望状态。核心组件包括负责集群控制的Master节点(含API Server、Scheduler、Controller Manager和Etcd)和运行Pod的工作节点Node(含Kubelet、Kube-Proxy和容器运行时环境)。
|
9天前
|
Kubernetes 算法 API
K8S 集群认证管理
【6月更文挑战第22天】Kubernetes API Server通过REST API管理集群资源,关键在于客户端身份认证和授权。
|
2月前
|
弹性计算 Kubernetes 监控
【阿里云弹性计算】阿里云 ECS 与 Kubernetes 集成:轻松管理容器化应用
【5月更文挑战第28天】阿里云ECS与Kubernetes集成,打造强大容器管理平台,简化应用部署,实现弹性扩展和高效资源管理。通过Kubernetes声明式配置在ECS上快速部署,适用于微服务和大规模Web应用。结合监控服务确保安全与性能,未来将深化集成,满足更多业务需求,引领容器化应用管理新趋势。
214 2
|
2月前
|
运维 Kubernetes Linux
Kubernetes详解(七)——Service对象部署和应用
Kubernetes详解(七)——Service对象部署和应用
49 3
|
2月前
|
Kubernetes Go Perl
k8s 怎么精准获取deployment关联的pods?
该内容是关于Kubernetes中通过标签获取Deployment管理的Pod的流程和代码示例。首先,Deployment创建ReplicaSets,然后ReplicaSets创建Pod。获取Pod的步骤包括:1) 使用标签选择器获取ReplicaSets;2) 过滤出属于特定Deployment的ReplicaSets;3) 通过标签选择器获取Pod;4) 过滤出属于特定ReplicaSets的Pod。提供的Go代码展示了如何实现这一过程。
|
2月前
|
Kubernetes Docker 微服务
微服务实践k8s&dapr开发部署实验(3)订阅发布
微服务实践k8s&dapr开发部署实验(3)订阅发布
50 0
|
2月前
|
Kubernetes Cloud Native Go
Golang深入浅出之-Go语言中的云原生开发:Kubernetes与Docker
【5月更文挑战第5天】本文探讨了Go语言在云原生开发中的应用,特别是在Kubernetes和Docker中的使用。Docker利用Go语言的性能和跨平台能力编写Dockerfile和构建镜像。Kubernetes,主要由Go语言编写,提供了方便的客户端库与集群交互。文章列举了Dockerfile编写、Kubernetes资源定义和服务发现的常见问题及解决方案,并给出了Go语言构建Docker镜像和与Kubernetes交互的代码示例。通过掌握这些技巧,开发者能更高效地进行云原生应用开发。
86 1
|
2月前
|
Kubernetes 测试技术 Docker
K8S中Deployment控制器的概念、原理解读以及使用技巧
K8S中Deployment控制器的概念、原理解读以及使用技巧