回归基础:访问 Kubernetes Pod(concurrent.futures访问数据库)
mhr18 2025-05-10 23:31 3 浏览 0 评论
Kubernetes 是一头巨大的野兽。在它开始有用之前,您需要了解许多概念。在这里,学习几种访问集群外 pod 的方法。
Kubernetes 是一头巨大的野兽。在它开始有用之前,您需要了解许多不同的概念。一切都设置好后,您可能希望将一些 pod 暴露给集群外部。Kubernetes 提供了不同的方法来做到这一点:我将在这篇文章中描述它们。
设置
为了演示,我将使用kind:
kind 是一个使用 Docker 容器“节点”运行本地 Kubernetes 集群的工具。kind 主要是为测试 Kubernetes 本身而设计的,但也可以用于本地开发或 CI。
我将使用一个两节点集群:
YAML
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30800 # 1
hostPort: 30800 # 1
- role: worker # 2
- role: worker # 2
- #1:端口转发以应对 Mac 上的 Docker VM 层(见下文)
- #2:两个节点
kind create cluster -- config kind.yml
接下来,我们需要一个容器。它不应该只是运行和停止。让我们使用撰写本文时可用的最新 Nginx 映像。
使用 kind,我们必须预加载镜像以便它们可用。
docker pull nginx:1.23
kind load docker-image nginx:1.23
最后,我别名kubetcl为k:
alias k=kubectl
默认情况下无外部访问
默认情况是不提供对集群外部的访问。
k create deployment nginx --image=nginx:1.23 # 1
- #1:创建单个 pod 的部署。
让我们检查一下是否一切正常:
k get pods
纯文本
NAME READY STATUS RESTARTS AGE
nginx-6c7985744b-c7cpl 1/1 Running 0 67s
pod 有一个 IP,但我们无法在集群外访问它。
k get pod nginx-6c7985744b-c7cpl --template '{{.status.podIP}}'
纯文本
10.244.1.2
让我们通过在 pod 内部运行 shell 来确认 IP:
k exec -it nginx-6c7985744b-c7cpl -- /bin/bash
hostname -I
纯文本
10.244.1.2
我们无法在集群外成功 ping 此 IP:它是一个内部 IP。
内部 IP 不稳定
我们创建了一个部署;因此,如果我们删除单个 Pod,Kubernetes 将检测到它并创建一个新 Pod,这要归功于它的自我修复功能。
k delete pod nginx-6c7985744b-c7cpl
k get pods
纯文本
NAME READY STATUS RESTARTS AGE
nginx-6c7985744b-c6f92 1/1 Running 0 71s
让我们检查一下它的新IP:
k exec -it nginx-6c7985744b-c6f92 -- /bin/bash
hostname -I
纯文本
10.244.2.2
Kubernetes 创建了一个新的 Pod,但它的 IP 与删除的 Pod 不同。我们不能依赖这个 IP 进行 pod 到 pod 的通信。事实上,我们永远不应该直接使用 pod 的 IP。
为了解决这个问题,Kubernetes 提供了Service对象。服务代表 pod 前面的稳定接口。Kubernetes 管理服务与其 Pod 之间的映射。它绑定新的 Pod 并取消绑定已删除的 Pod。
ClusterIPService:在集群内部 IP 上公开。选择此值使Service唯一可从集群内访问。这是默认设置ServiceType。
-出版服务 (ClusterIP)
让我们使用服务公开现有部署:
k expose deployment nginx --type=ClusterIP --port=8080
k get svc
纯文本
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9m47s
nginx ClusterIP 10.96.93.97 <none> 8080/TCP 4s
从此时起,可以通过服务的ClusterIP.
全部设置为在集群内部进行访问。从外面看,这还不可能。那么我们为什么要使用ClusteIP呢?它对于您不想暴露给外界的服务非常有用:数据库、ElasticSearch 节点、Redis 节点等。
访问 Pod
当事情变得有趣时,从集群外部访问一个 pod。
我们首先需要删除现有的部署和服务。
k delete deployment nginx
k delete svc nginx
允许外部访问的最简单方法是将服务的类型更改为NodePort.
NodePort将访问端口添加到ClusterIP.
NodePort: 在每个节点的 IP 上的静态端口 (the NodePort) 上公开服务。ClusterIPService 路由到的ServiceNodePort是自动创建的。您可以NodePort通过请求从集群外部联系服务:。
- 发布服务(NodePort)
我希望 pod 返回其 IP 和主机名以进行演示。我们必须从命令行转移到专用的 Kubernetes 清单文件,因为我们必须配置 Nginx。它导致与命令行相同的状态,并添加了 Nginx 配置:
YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.23
volumeMounts: # 1
- name: conf
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
readOnly: true
volumes: # 1
- name: conf
configMap:
name: nginx-conf
items:
- key: nginx.conf
path: nginx.conf
---
apiVersion: v1 # 1
kind: ConfigMap
metadata:
name: nginx-conf
data:
nginx.conf: |
events {
worker_connections 1024;
}
http {
server {
location / {
default_type text/plain;
return 200 "host: $hostname\nIP: $server_addr\n";
}
}
}
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
type: NodePort # 2
ports:
- port: 80
nodePort: 30800
- #1:覆盖默认配置以返回主机名和 IP 地址。
- #2:NodePort将 pod 的端口映射到外部可访问的端口。
让我们应用配置:
k apply -f deployment.yml
请注意,我在 Mac 上运行;因此,Docker 周围有一个 VM 容器,就像在 Windows 中一样。出于这个原因,kind 需要将 VM 端口转发到主机。请查看有关如何实现它的文档。
一旦 Kubernetes 调度了 pod,我们就可以在配置的端口上访问它:
curl localhost:30800
纯文本
host: nginx-b69d8877c-p2s79
IP: 10.244.2.2
请求的路径如下(尽管 Mac/Windows 上有 VM 层):
- curl请求发送到任何节点。
- 请注意,在云提供商设置中,您可以针对托管部署的 pod 部分的任何 Kubernetes 节点。通过本地设置,我们定位localhost并让 VM 层以节点为目标。
- 节点看到端口30800并将请求转发到NodePort具有相关端口的服务。
- 该服务将请求转发到 pod,将端口从 转换30800为80。
现在,让我们将部署中的 pod 数量增加到两个:
k scale deployment nginx --replicas=2
k get pods -o wide
Kubernetes 平衡集群,以便每个 pod 驻留在不同的节点上:
纯文本
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-b69d8877c-w7db4 1/1 Running 0 129m 10.244.2.2 kind-worker <none> <none>
nginx-b69d8877c-z5kqs 1/1 Running 0 38m 10.244.1.2 kind-worker2 <none> <none>
请求将发送到哪个节点/pod?
while true; do curl localhost:30800; done
纯文本
host: nginx-b69d8877c-w7db4
IP: 10.244.2.2
host: nginx-b69d8877c-w7db4
IP: 10.244.2.2
host: nginx-b69d8877c-z5kqs
IP: 10.244.1.2
host: nginx-b69d8877c-z5kqs
IP: 10.244.1.2
host: nginx-b69d8877c-w7db4
IP: 10.244.2.2
host: nginx-b69d8877c-w7db4
IP: 10.244.2.2
该服务平衡所有可用 pod 之间的请求。
负载平衡抽象
NodePort允许查询任何集群节点。LoadBalancer是集群上的一个外观,它确实......负载平衡。它是 Kubernetes 提供的一个抽象对象:每个云提供商根据其特性以不同的方式实现它,尽管行为是相同的。
LoadBalancer:使用云提供商的负载均衡器在外部公开服务。自动创建外部负载均衡器路由到的 NodePort 和 ClusterIP 服务。
- 发布服务(LoadBalander)
首先,我们需要一个LoadBalancer实现。kind 与 MetalLB 具有开箱即用的集成:
MetalLB 是裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议。
-金属LB
解释 kind 关于如何安装 MetalLB的优秀文档是没有用的。我们可以相应地更新清单:
YAML
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
type: LoadBalancer
ports:
- port: 80
targetPort: 30800
让我们看看服务:
k get svc
纯文本
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4h37m
nginx LoadBalancer 10.96.216.126 127.0.0.240 8080:31513/TCP 82m # 1
- #1:它有一个外部IP!
不幸的是,正如我上面提到的,在 Mac(和 Windows)上,Docker 在 VM 中运行。因此,我们无法从主机访问“外部”IP。拥有适当 Linux 系统的读者应该可以访问它。
根据云提供商的不同,LoadBalancer可能会提供额外的专有功能。
入口,当您需要路由时
Ingress专注于将请求路由到集群中的服务。
它与以下内容共享一些方面LoadBalancer:
- 它拦截入站流量。
- 它依赖于实现,并且实现提供不同的功能:例如. , Nginx , Traefik , HAProxy等
但是,它不是一个Service.
Ingress 将来自集群外部的 HTTP 和 HTTPS 路由暴露给集群内的服务。流量路由由 Ingress 资源上定义的规则控制。
-什么是入口?
安装一个Ingress很大程度上取决于实现。唯一的共同因素是它涉及CRD。
为了演示,我将使用Apache APISIX Ingress 控制器。我不会解释Minikube 上 Ingress APISIX 的安装说明。唯一的区别是将 设置NodePort为设定值:
helm install apisix apisix/apisix \
--set gateway.type=NodePort \
--set gateway.http.nodePort=30800 \
--set ingress-controller.enabled=true \
--namespace ingress-apisix \
--set ingress-controller.config.apisix.serviceNamespace=ingress-apisix
请注意,虽然文档中提到了 Minikube,但它适用于任何本地集群,包括 kind。
命名空间中应提供以下服务ingress-apisix:
纯文本
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apisix-admin ClusterIP 10.96.98.159 <none> 9180/TCP 22h
apisix-etcd ClusterIP 10.96.80.154 <none> 2379/TCP,2380/TCP 22h
apisix-etcd-headless ClusterIP None <none> 2379/TCP,2380/TCP 22h
apisix-gateway NodePort 10.96.233.74 <none> 80:30800/TCP 22h
apisix-ingress-controller ClusterIP 10.96.125.41 <none> 80/TCP 22h
为了演示,我们将有两个服务:每个服务都有一个 pod 的底层部署。请求/left将命中一项服务并返回left;/right, right.
让我们相应地更新拓扑:
YAML
apiVersin: apps/v1
kind: Deployment
metadata:
name: left
labels:
app: left
spec:
replicas: 1
selector:
matchLabels:
app: left
template:
metadata:
labels:
app: left
spec:
containers:
- name: nginx
image: nginx:1.23
volumeMounts:
- name: conf
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
readOnly: true
volumes:
- name: conf
configMap:
name: left-conf
items:
- key: nginx.conf
path: nginx.conf
---
apiVersion: v1
kind: Service
metadata:
name: left
spec:
selector:
app: left
ports:
- port: 80
---
apiVersion: v1
kind: ConfigMap
metadata:
name: left-conf
data:
nginx.conf: |
events {
worker_connections 1024;
}
http {
server {
location / {
default_type text/plain;
return 200 "left\n";
}
}
}
上面的片段只描述了left路径。它应该包含类似的right路径配置。
此时,我们可以创建配置以将路径路由到服务:
YAML
apiVersion: apisix.apache.org/v2beta3 # 1
kind: ApisixRoute # 1
metadata:
name: apisix-route
spec:
http:
- name: left
match:
paths:
- "/left"
backends:
- serviceName: left # 2
servicePort: 80 # 2
- name: right
match:
paths:
- "/right"
backends:
- serviceName: right # 3
servicePort: 80
- 使用ApisixRoute安装创建的 CRD。
- 将请求转发到left服务。
- 将请求转发到right服务。
这是它应该是什么样子。请注意,我选择仅表示left路径和一个节点,以免图表过载。
为了检查它是否有效,让我们再次卷曲。
curl localhost:30800
纯文本
{"error_msg":"404 找不到路由"}
这是一个好兆头:APISIX 正在响应。
我们现在可以尝试 curlright路径以确保它会转发到相关的 pod。
curl localhost:30800/right
纯文本
正确的
/left,它也有效。
结论
在这篇文章中,我描述了几种访问集群外部 pod 的方法:NodePort以及LoadBalancerservices 和Ingress. 对于Ingress,您可能已经注意到该ApisixRoute对象是专有 CRD。为了避免这种情况,Kubernetes 旨在提供一个抽象:CNCF 正在开发一个网关 API项目。
我会在以后的文章中描述它。
这篇文章的完整源代码可以在GitHub上找到。
相关推荐
- Docker安装详细步骤及相关环境安装配置
-
最近自己在虚拟机上搭建一个docker,将项目运行在虚拟机中。需要提前准备的工具,FinallShell(远程链接工具),VM(虚拟机-配置网络)、CentOS7(Linux操作系统-在虚拟机上安装)...
- Linux下安装常用软件都有哪些?做了一个汇总列表,你看还缺啥?
-
1.安装列表MySQL5.7.11Java1.8ApacheMaven3.6+tomcat8.5gitRedisNginxpythondocker2.安装mysql1.拷贝mysql安装文件到...
- Nginx安装和使用指南详细讲解(nginx1.20安装)
-
Nginx安装和使用指南安装1.检查并安装所需的依赖软件1).gcc:nginx编译依赖gcc环境安装命令:yuminstallgcc-c++2).pcre:(PerlCompatibleRe...
- docker之安装部署Harbor(docker安装hacs)
-
在现代软件开发和部署环境中,Harbor作为一个企业级的容器镜像仓库,提供了高效、安全的镜像管理解决方案。通过Docker部署Harbor,可以轻松构建私有镜像仓库,满足企业对镜像存储、管理和安全性...
- 成功安装 Magento2.4.3最新版教程「技术干货」
-
外贸独立站设计公司xingbell.com经过多次的反复实验,最新版的magento2.4.3在oneinstack的环境下的详细安装教程如下:一.vps系统:LinuxCentOS7.7.19...
- 【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linu
-
学习Linux并掌握Java环境配置及SpringBoot项目部署是一个系统化的过程,以下是从零开始的详细指南,帮助你逐步掌握这些技能。一、Linux基础入门1.安装Linux系统选择发行版:推荐...
- cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务
-
cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务(yum选择的,时间不同,版本不同)如果对运维课程感兴趣,可以在b站上搜索我的账号:运维实战课程,可以关注我,学习更多免费的运...
- 时隔三月,参加2020秋招散招,终拿字节跳动后端开发意向书.
-
3个月前头条正式批笔试4道编程题只AC了2道,然后被刷了做了200多道还是太菜了,本来对字节不抱太大希望,毕竟后台竞争太大,而且字节招客户端开发比较多。后来看到有散招免笔试,抱着试一试的心态投了,然而...
- Redisson:Java程序员手中的“魔法锁”
-
Redisson:Java程序员手中的“魔法锁”在这个万物互联的时代,分布式系统已经成为主流。然而,随着系统的扩展,共享资源的争夺成为了一个棘手的问题。就比如你想在淘宝“秒杀”一款商品,却发现抢的人太...
- 【线上故障复盘】RPC 线程池被打满,1024个线程居然不够用?
-
1.故障背景昨天晚上,我刚到家里打开公司群,就看见群里有人讨论:线上环境出现大量RPC请求报错,异常原因:被线程池拒绝。虽然异常量很大,但是异常服务非核心服务,属于系统旁路,服务于数据核对任务,即使...
- 小红书取消大小周,有人不高兴了!
-
小红书宣布五一节假日之后,取消大小周,恢复为正常的双休,乍一看工作时长变少,按道理来说大家应该都会很开心,毕竟上班时间缩短了,但是还是有一些小红书的朋友高兴不起来,心情很复杂。因为没有了大小周,以前...
- 延迟任务的多种实现方案(延迟机制)
-
场景订单超时自动取消:延迟任务典型的使用场景是订单超时自动取消。功能精确的时间控制:延时任务的时间控制要尽量准确。可靠性:延时任务的处理要是可靠的,确保所有任务最终都能被执行。这通常要求延时任务的方案...
- 百度java面试真题(java面试题下载)
-
1、SpingBoot也有定时任务?是什么注解?在SpringBoot中使用定时任务主要有两种不同的方式,一个就是使用Spring中的@Scheduled注解,另一个则是使用第三方框架Q...
- 回归基础:访问 Kubernetes Pod(concurrent.futures访问数据库)
-
Kubernetes是一头巨大的野兽。在它开始有用之前,您需要了解许多概念。在这里,学习几种访问集群外pod的方法。Kubernetes是一头巨大的野兽。在它开始有用之前,您需要了解许多不同的...
- Spring 缓存神器 @Cacheable:3 分钟学会优化高频数据访问
-
在互联网应用中,高频数据查询(如商品详情、用户信息)往往成为性能瓶颈。每次请求都触发数据库查询,不仅增加服务器压力,还会导致响应延迟。Spring框架提供的@Cacheable注解,就像给方法加了一...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Docker安装详细步骤及相关环境安装配置
- Linux下安装常用软件都有哪些?做了一个汇总列表,你看还缺啥?
- Nginx安装和使用指南详细讲解(nginx1.20安装)
- docker之安装部署Harbor(docker安装hacs)
- 成功安装 Magento2.4.3最新版教程「技术干货」
- 【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linu
- cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务
- 时隔三月,参加2020秋招散招,终拿字节跳动后端开发意向书.
- Redisson:Java程序员手中的“魔法锁”
- 【线上故障复盘】RPC 线程池被打满,1024个线程居然不够用?
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)