【Kubernetes基础--Service深入理解】--查阅笔记4

news2025/4/18 21:47:25

目录

  • Service 的用法
    • docker 对外提供服务
    • service 对外提供服务
  • 从集群外部访问 Pod 或 Service
    • 将容器应用的端口号映射到物理机
    • 将 Service 的端口号映射到物理机
  • Ingress:HTTP 7层路由机制
    • 创建Ingress Controller和默认的backend服务

k8s 通过创建 Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上。

Service 的用法

docker 对外提供服务

一般来说,对外提供服务的应用程序,对于容器应用最简便的方式就是通过 TCP/IP 机制及监听 IP 和端口号来实现。例如,定义一个提供Web 服务的 RC,由两个 Tomcat 容器副本组成,每个容器都通过 containerPort 设置提供服务的端口号为 8080:

# webapp-rc.yaml

apiVersion: v1
kind: ReplicationController
metadata:
  name: webapp
spec:
  replicas: 2
  template:
    metadata:
      name: webapp
      labels:
      app: webapp
    spec:
      containers:
      - name: webapp
      image: tomcat
      ports:
      - containerPort: 8080

创建 RC,获取 IP:

kubectl create -f webapp-rc.yaml

kubectl get pods -l app=webapp -o yaml | grep podIP
# podIP: 172.17.1.3
# podIP: 172.17.1.4

可以通过这两个 Pod 的 IP 地址和端口号访问 Tomcat 服务:

curl 172.17.1.3:8080

curl 172.17.1.4:8080

但是,这种方式是不可靠的。例如当 Pod 所在的 Node 发生故障,Pod 将被 k8s 重新调度到另一个 Node,Pod 的 IP 地址将发生变化。我们着重考虑的是,如果容器应用本身是分布式的部署方式,通过多个实例共同提供服务,就需要在这些实例的前端设置一个负载均衡器来实现请求的分发。k8s 中的 Service 就是用于解决这些问题的核心组件。

service 对外提供服务

以上面的 webapp 为例,为了访问 Tomcat Pod 实例,我们来创建一个 Service 提供服务:

kubectl expose rc webapp
# service "webapp" exposed
# 查看新创建的 Service,可以看到系统为它分配了一个虚拟的IP地址(ClusterIP)​,Service 所需的端口号则从 Pod 中的 containerPort 复制而来:
kubectl get svc
# NAME         CLUSTER-IP         EXTERNAL-IP    PORT(S)     AGE
# webapp      169.169.235.79    <none>          8080/TCP    3s

curl 169.169.235.79:8080

这里,对 Service 地址 169.169.235.79:8080 的访问被自动负载分发到了后端两个 Pod 之一:172.17.1.3:8080或172.17.1.4:8080。

除了使用 kubectl expose 命令创建 Service,也可以通过配置文件定义 Service,再通过 kubectl create 命令进行创建:

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  ports:
  - port: 8081
    targetPort: 8080
  selector:
    app: webapp

Service 定义中的关键字段是 ports 和 selector。上面 ports 定义部分指定了 Service 所需的虚拟端口号为 8081,由于与 Pod 容器端口号8080 不一样,所以需要再通过 targetPort 来指定后端 Pod 的端口号。selector 定义部分设置的是后端 Pod所拥有的 label:app=webapp。

创建该Service并查看其 ClusterIP 地址:

kubectl create -f webapp-svc.yaml
# service "webapp" created
kubectl get svc
# NAME         CLUSTER-IP         EXTERNAL-IP    PORT(S)     AGE
# webapp      169.169.28.190    <none>          8081/TCP    3s

curl 169.169.28.190:8081

目前 k8s 提供了两种负载分发策略:RoundRobin 和 SessionAffinity:

  • RoundRobin:轮询模式(默认),即轮询将请求转发到后端的各个 Pod 上
  • SessionAffinity:基于客户端 IP 地址进行会话保持的模式,即第1次将某个客户端发起的请求转发到后端的某个 Pod 上,之后从相同的客户端发起的请求都将被转发到后端相同的 Pod 上

在默认情况下,k8s 采用 RoundRobin 模式对客户端请求进行负载分发,也可以通过设置 service.spec.sessionAffinity=ClientIP 来启用SessionAffinity 策略。这样,同一个客户端 IP 发来的请求就会被转发到后端固定的某个 Pod 上了。通过 Service 的定义,k8s 实现了一种分布式应用统一入口的定义和负载均衡机制。

从集群外部访问 Pod 或 Service

Pod 和 Service 都是 k8s 的虚拟概念,集群外的客户端系统无法通过 Pod 的 IP 地址或者 Service 的虚拟 IP 地址和虚拟端口号访问他们。我们需要将 Pod 或 Service 的端口号映射到宿主机,以使客户端应用能够通过物理机访问容器应用。

将容器应用的端口号映射到物理机

  1. 通过设置容器级别的 hostPort,将容器应用的端口号映射到物理机上:
# pod-hostport.yaml
apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  containers:
  - name: webapp
    image: tomcat
    ports:
    - containerPort: 8080
      hostPort: 8081
kubectl create -f pod-hostport.yaml # pod "webapp" created

curl 192.168.18.3:8081 # 宿主机ip
  1. 通过设置 Pod 级别的 hostNetwork=true,该 Pod 中所有容器的端口号都将被直接映射到物理机上。在设置 hostNetwork=true 时需要注意,在容器的 ports 定义部分如果不指定 hostPort,则默认 hostPort 等于 containerPort,如果指定了 hostPort,则 hostPort 必须等于containerPort 的值:
# pod-hostnetwork.yaml
apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  hostNetwork: true  # 设置宿主机网络
  containers:
  - name: webapp
    image: tomcat
    imagePullPolicy: Never
    ports:
    - containerPort: 8080
kubectl create -f pod-hostnetwork.yaml  # pod "webapp" created

curl 192.168.18.4:8080

将 Service 的端口号映射到物理机

  1. 通过设置 nodePort 映射到物理机,同时设置 Service 的类型为 NodePort:
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: NodePort # service 类型设置为 NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 8081 # 指定 nodePort 端口号
  selector:
    app: webapp
kubectl create -f webapp-svc-nodeport.yaml
# service "webapp" created
# 注意,这里系统提示:由于要使用物理机的端口号,所以需要在防火墙上做好相应的配置,以使外部客户端能够访问到该端口
curl 192.168.18.4:8081        
  1. 通过设置 LoadBalancer 映射到云服务商提供的 LoadBalancer 地址。这种用法仅用于在公有云服务提供商的云平台上设置 Service 的场景。
    示例中,status.loadBalancer.ingress.ip 设置的 146.148.47.155 为云服务商提供的负载均衡器的 IP 地址。对该 Service 的访问请求将会通过 LoadBalancer 转发到后端 Pod 上,负载分发的实现方式则依赖于云服务商提供的 LoadBalancer 的实现机制:
kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
    nodePort: 30061
  clusterIP: 10.0.171.239
  loadBalancerIP: 78.11.24.19
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 146.148.47.155

Ingress:HTTP 7层路由机制

如前所述,Service 的表现形式为 IP:Port,即工作在 TCP/IP 层。而对于基于 HTTP 的服务来说,不同的 URL 地址经常对应到不同的后端服务或者虚拟服务器(Virtual Host)​,这些应用层的转发机制仅通过 k8s 的 Service 机制是无法实现的。

Ingress 资源对象,可以将不同 URL 的访问请求转发到后端不同的 Service,以实现 HTTP 层的业务路由机制。k8s 使用了一个 Ingress 策略定义和一个具体的 Ingress Controller,两者结合并实现了一个完整的 Ingress 负载均衡器。代理不同后端 Service 而设置的负载均衡服务,就是 k8s 里的 Ingress 服务。

可以这样理解:Ingress 就是 Service 的 “Service”,是“反向代理”的一种抽象。

使用 Ingress 进行负载分发时,Ingress Controller 基于 Ingress 规则将客户端请求直接转发到 Service 对应的后端 Endpoint(Pod)上,这样会跳过 kube-proxy 的转发功能,kube-proxy 不再起作用。如果 Ingress Controller 提供的是对外服务,则实际上实现的是边缘路由器的功能。

为使用 Ingress,需要创建 Ingress Controller(带一个默认 backend 服务)和 Ingress 策略设置来共同完成。

创建Ingress Controller和默认的backend服务

在定义 Ingress 策略前,先部署 Ingress Controller,来实现为所有后端 Service 提供统一入口。Ingress Controller 需要实现基于不同 HTTP URL 向后转发的负载分发规则,并可以灵活设置7层负载分发策略。如果公有云服务商能够提供该类型的 HTTP 路由 LoadBalancer,则也可设置其为 Ingress Controller。

下面示例中,使用谷歌提供的 nginx-ingress-controller 镜像来创建 Ingress Controller。该 Ingress Controller 以 daemonset 的形式进行创建,在每个 Node 上都将启动一个Nginx服务。

Nginx 容器设置了 hostPort,将容器应用监听的 80 和 443 端口号映射到物理机上,使得客户端应用可以通过 URL 地址“http://物理机IP:80”或“https://物理机IP:443”来访问该 Ingress Controller。这使得 Nginx 类似于通过 NodePort 映射到物理机的 Service,成为代替 kube-proxy的 HTTP 层的 Load Balancer:

# nginx-ingress-daemonset.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
 name: nginx-ingress-lb
 labels:
   name: nginx-ingress-lb
 namespace: kube-system
spec:
 template:
   metadata:
     labels:
       name: nginx-ingress-lb
   spec:
     terminationGracePeriodSeconds: 60
     containers:
     - image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.2
       name: nginx-ingress-lb
       readinessProbe:
         httpGet:
           path: /healthz
           port: 10254
           scheme: HTTP
       livenessProbe:
         httpGet:
           path: /healthz
           port: 10254
           scheme: HTTP
           initialDelaySeconds: 10
           timeoutSeconds: 1
         ports:
         - containerPort: 80
           hostPort: 80  # 映射到主机80端口
         - containerPort: 443
           hostPort: 443
         env:
           - name: POD_NAME
             valueFrom:  # Downward API,将Pod信息注入为环境变量
               fieldRef:
                 fieldPath: metadata.name
           - name: POD_NAMESPACE
             valueFrom:
               fieldRef:
                 fieldPath: metadata.namespace
         args:
         - /nginx-ingress-controller
         - --default-backend-service=$(POD_NAMESPACE)/default-http-backend

为了让 Ingress Controller 正常启动,我们配置一个默认的 backend,用于在客户端访问的 URL 地址不存在时,返回404。这个 backend 服务用任何应用实现都可以,只要满足对根路径“/”的访问返回404应答,并且提供 /healthz 路径以使 kubelet 完成对它的健康检查。另外,由于 Nginx 通过 default-backend-service 的服务名称(Service Name)去访问它,所以需要 DNS 服务正确运行:

# default-backend.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: default-http-backend
  labels:
    k8s-app: default-http-backend
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
      k8s-app: default-http-backend
    spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
  image: gcr.io/google_containers/defaultbackend:1.0
  livenessProbe:
    httpGet:
      path: /healthz
      port: 8080
      scheme: HTTP
    initialDelaySeconds: 30
    timeoutSeconds: 5
  ports:
  - containerPort: 8080
  resources:
    limits:
      cpu: 10m
      memory: 20Mi
    requests:
      cpu: 10m
      memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
  namespace: kube-system
  labels:
    k8s-app: default-http-backend
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    k8s-app: default-http-backend

创建 backend 服务,并且创建 nginx-ingress-controller:

kubectl create -f default-backend.yaml
# deployment "default-http-backend" created
# service "default-http-backend" created

kubectl create -f nginx-ingress-daemonset.yaml # daemonset "nginx-ingress-lb" created

# 查看 default-http-backend 和 nginx-ingress-controller 容器是否正确运行
kubectl get pod --namespace=kube-system
# NAME                                     READY     STATUS    RESTARTS   AGE
# default-http-backend-1132503640-84lnv   1/1       Running   0          3m
# kube-dns-v11-z3cb0                      4/4       Running   0         10m
# nginx-ingress-lb-5jbwv                 1/1       Running   0          3m
# nginx-ingress-lb-60j7h                 1/1       Running   0          3m
# nginx-ingress-lb-dttr9                 1/1       Running   0          3m

# 用 curl 访问任意 Node 的 80 端口号,验证 nginx-ingress-controller 和 default-http-backend 服务正常工作:
curl k8s-node-2 # default backend -404

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2337560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

yolov8复现

Yolov8的复现流程主要包含环境配置、下载源码和验证环境三大步骤&#xff1a; 环境配置 查看电脑状况&#xff1a;通过任务管理器查看电脑是否有独立显卡&#xff08;NVIDIA卡&#xff09;。若有&#xff0c;后续可安装GPU版本的pytorch以加速训练&#xff1b;若没有&#xff0…

RestSharp和Newtonsoft.Json结合发送和解析http

1.下载RestSharp和Newtonsoft.Json 2编写ApiRequest和ApiResponse和调用工具类HttpRestClient 请求模型 /// <summary>/// 请求模型/// </summary>public class ApiRequest{/// <summary>/// 请求地址/api路由地址/// </summary>public string Route {…

【Pytorch之一】--torch.stack()方法详解

torch.stack方法详解 pytorch官网注释 Parameters tensors&#xff1a;张量序列&#xff0c;也就是要进行stack操作的对象们&#xff0c;可以有很多个张量。 dim&#xff1a;按照dim的方式对这些张量进行stack操作&#xff0c;也就是你要按照哪种堆叠方式对张量进行堆叠。dim的…

数据中台(大数据平台)之数据资源目录

数据资源目录是数据管理的账本&#xff0c;是数据应用的基础&#xff0c;更是是数据治理成果的体现&#xff0c;因此数据中台产品应提供数据资源目录编制、发布、资源挂载、下架的管理能力。 1.数据资源目录分类 资源目录能够支持基于业务特点创建和维护基础目录分类和特色目…

【随身WiFi】随身WiFi Debian系统优化教程

0.操作前必看 本教程基于Debian系统进行优化&#xff0c;有些操作对随身WiFi来说可能会带来负优化&#xff0c;根据需要选择。 所有操作需要在root用户环境下运行&#xff0c;否则都要加sudo 随身wifi Debian系统&#xff0c;可以去某安的随声WiFi模块自行搜索刷机 点赞&am…

JAVA Web_定义Servlet2_学生登录验证Servlet

题目 页面StudentLogin.html中有一HTML的表单代码如下&#xff1a; <form action"studentLogin" method"post">学生姓名&#xff1a;<input type"text" name"stuName" value""><br>登录密码&#xff1a;…

Unity入门笔记(缘更)

内容来源SiKi学院的Luna’s Fantasy 文章目录 一、基础知识1.准备2.基础知识1.层级(Layer)2.轴心点3.预制体(Prefab)4.刚体组件(Rigidbody)5.碰撞器组件(BoxCollider) 二、代码1.移动 一、基础知识 1.准备 Unity安装&#xff1a; https://unity.cn 2.基础知识 1.层级(Layer…

【Python】用Python写一个俄罗斯方块玩玩

【Python】用Python写一个俄罗斯方块玩玩 一、引言1.成品效果展示 二、思考准备1.思考设计2.代码设计2.1 游戏页面2.2 控件设计2.2.1 方块生成2.2.2 方块碰撞2.2.3 方块消融2.2.4 游戏主循环2.2.5 游戏窗口 三、游戏完整版 一、引言 今日看到侄子在玩游戏&#xff0c;凑近一看…

记录一次生产中mysql主备延迟问题处理

登录库&#xff1a; mysql -uXXXX -pXXXX -P3306 -hXXXXXX -A 备库上执行&#xff1a;show slave status\G 查看 seconds_Behind_Master&#xff0c;延迟 2705s&#xff0c;而且还一直在增加。 SHOW CREATE TABLE proc_i_income_temp; -- 查看表的结构 show index from proc…

ffmpeg无损转格式的命令行

将ffmpeg.exe拖入命令行窗口 c:\users\zhangsan>D:\ffmpeg-2025-03-11\bin\ffmpeg.exe -i happy.mp4 -c:v copy -c:a copy 格式转换后.mkv -c:v copy 仅做拷贝视频,不重新编码 -c:a copy 仅做拷贝音频 ,不重新编码

强化学习算法系列(五):最主流的算法框架——Actor-Critic算法框架

强化学习算法 &#xff08;一&#xff09;动态规划方法——策略迭代算法(PI)和值迭代算法(VI) &#xff08;二&#xff09;Model-Free类方法——蒙特卡洛算法(MC)和时序差分算法(TD) &#xff08;三&#xff09;基于动作值的算法——Sarsa算法与Q-Learning算法 &#xff08;四…

设计模式(结构型)-桥接模式

目录 摘要 定义 类图 角色 具体实现 优缺点 优点 缺点 使用场景 使用案例 JDBC 和桥接模式 总结 摘要 在软件开发领域&#xff0c;随着系统规模和复杂性的不断攀升&#xff0c;如何设计出具有良好扩展性、灵活性以及可维护性的软件架构成为关键挑战。桥接模式作为一…

【MySQL】MySQL数据库 —— 简单认识

目录 1. 数据库的介绍 1.1 什么是数据库 1.2 数据库和数据结构之间关系 2. 数据库分类 2.1 关系型数据库&#xff08;RDBMS&#xff09; 2.2 非关系型数据库 2.3 区别 一些行内名词简单解释&#xff1a; 3. 关于mysql 主要学什么 4. MySQL中重要的概念 4.1 概念 4…

RNN - 语言模型

语言模型 给定文本序列 x 1 , … , x T x_1, \ldots, x_T x1​,…,xT​&#xff0c;语言模型的目标是估计联合概率 p ( x 1 , … , x T ) p(x_1, \ldots, x_T) p(x1​,…,xT​)它的应用包括 做预训练模型&#xff08;eg BERT&#xff0c;GPT-3&#xff09;生成本文&#xff…

过拟合、归一化、正则化、鞍点

过拟合 过拟合的本质原因往往是因为模型具备方差很大的权重参数。 定义一个有4个特征的输入&#xff0c;特征向量为,定义一个模型&#xff0c;其只有4个参数&#xff0c;表示为。当模型过拟合时&#xff0c;这四个权重参数的方差会很大&#xff0c;可以假设为。当经过这个模型后…

【python画图】:从入门到精通绘制完美柱状图

目录 Python数据可视化&#xff1a;从入门到精通绘制完美柱状图一、基础篇&#xff1a;快速绘制柱状图1.1 使用Matplotlib基础绘制1.2 使用Pandas快速绘图 二、进阶篇&#xff1a;专业级柱状图定制2.1 多系列柱状图2.2 堆叠柱状图2.3 水平柱状图 三、专业参数速查表Matplotlib …

基础知识:离线安装docker、docker compose

(1)离线安装docker 确认版本:Ubuntu 18.04 LTS - bionic 确认架构:X86_64 lsb_release -a uname -a 官方指南:https://docs.docker.com/engine/install/ 选择Ubuntu,发现页面上最低是Ubuntu20.04, 不要紧

畅游Diffusion数字人(27):解读字节跳动提出主题定制视频生成技术Phantom

畅游Diffusion数字人(0):专栏文章导航 前言:主题定制视频生成,特别是zero-shot主题定制视频生成,一直是当前领域的一个难点,之前的方法效果很差。字节跳动提出了一个技术主题定制视频生成技术Phantom,效果相比于之前的技术进步非常显著。这篇博客详细解读一下这一工作。 …

《Adaptive Layer-skipping in Pre-trained LLMs》- 论文笔记

作者&#xff1a;Xuan Luo, Weizhi Wang, Xifeng Yan Department of Computer Science, UC Santa Barbara xuan_luoucsb.edu, weizhiwangucsb.edu, xyancs.ucsb.edu 1. 引言与动机 1.1 背景 LLM 的成功与挑战: 大型语言模型 (LLMs) 在翻译、代码生成、推理等任务上取得巨大成…

微信小程序实现table样式,自带合并行合并列

微信小程序在代码编写过程好像不支持原生table的使用&#xff0c;在开发过程中偶尔又得需要拿table来展示。 1.table效果展示 1.wxml <view class"table-container"><view class"table"><view class"table-row"><view cla…