K8S ,k8s initContainers

K8S 在Micro Service的治理中。
有两个很重要的点,
集群外部的用户/service 如何访问集群内的 入口服务(例如UI service)集群内的service A 如何 访问 集群内的ser

在微服务治理中。

有两点非常重要。

集群外的用户/服务如何访问集群内的入口服务(如UI服务)?集群内的服务A如何访问集群内的服务B?

为什么会出现上述问题呢?

无非是:

集群中的所有服务都是多个实例。每个服务实例都分配有一个单独的IP。

如图所示:

Spring Cloud 是如何就解决这两个问题的

集群外 to 集群内

使用Spring Cloud Gateway 反向代理集群中的外部服务,例如图中的服务A。其他服务如果没有配置网关,则无法从集群外部直接访问,因此更加安全。 通常情况下,该API网关所在服务器有双网卡,1个外网IP,1个集群内网IP。

Spring Cloud Gateway也有自己的负载均衡器功能(基于Spring CloudLoadbalancer),所以即使你暴露的服务有多个实例,也可以按照指定的规则将Gateway分发到不同的实例。

集群内 Service A to Service B

要使用Eureke作为注册中心并为每个服务的多个实例获取公共服务名称,您必须向Eureke注册。 Forwarding Ribbon(继承于Eureka)作为负载均衡器。

如图所示:

k8s 是如何就解决这两个问题的

K8S 服务有许多不同类型。

ingress、nodeport、clusterIp、externalName都属于服务

集群外 to 集群内

使用Ingress 或NodePort 作为垂直流量代理,Ingress 和NodePort 都带有自己的负载均衡器。

什么是垂直流量和水平流量?

参考

使用ClusterIP 作为服务B 的反向代理。 ClusterIP的服务带有负载均衡器功能,因此服务A可以通过ClusterIP服务的DNS名称访问服务B。

k8s 并不使用Eureka 或Nacos 等注册中心,但k8s 的服务列表实际上是一个注册中心。

原理如图所示。

ClusterIP 的定义和简单介绍

内部集群通信:ClusterIP 提供服务的虚拟内部IP 地址,用于服务与Kubernetes 集群中其他组件之间的通信。其他Pod 可以通过虚拟IP 地址和服务端口访问该服务。内部负载均衡:ClusterIP 基于轮询算法实现负载均衡,将请求均匀分配到与您的服务关联的后端Pod。这意味着无论后端Pod 的数量如何,所有Pod 都可以同等访问,从而实现负载平衡和高可用性。

无法从集群外部访问:ClusterIP 分配的IP 地址仅在Kubernetes 集群内部可见,无法从集群外部访问。 IP 地址无法从集群外部直接访问,因为它没有直接暴露于外部网络。适合内部服务:ClusterIP适合内部服务,即只需要在Kubernetes集群内部访问的服务。这些服务通常用于应用程序的内部组件之间的通信,例如数据库连接和队列服务。可以与其他类型的服务一起使用:ClusterIP可以用作其他类型服务(例如NodePort、LoadBalancer和Ingress)的后端服务。您可以配置其他类型的服务以使用ClusterIP 类型的服务将请求转发到ClusterIP 提供的虚拟IP 地址。

总的来说,ClusterIP是Kubernetes集群内的服务发现和负载均衡机制,用于实现集群内部的通信和服务访问。为您的服务提供虚拟IP地址,并通过负载均衡算法将请求分发到相关后端Pod。 ClusterIP适合内部服务,不直接暴露给外界。

NodePort 和 ClusterIP 的具体例子

解决问题后,我们将在接下来的k8s服务A上演示如何使用NodePort和ClusterIP访问服务B。

为什么从集群外部访问时不使用ingress呢?那是因为k8s博客系列中还没有提到ingress。

粗略框架

在这个例子中

部署:

服务A: bq-api-service

服务B: 云用户

节点端口服务: 节点端口-bq-api-service

集群IP服务: 集群IP云用户

这两个服务位于何处并不重要。您可以将它们视为两个简单的springboot 服务,没有Spring Cloud 框架集成。

cleanup

目前的k8s环境是干净的

[gateman@manjaro-x13 bq-api-service]$ kubectl 获取所有-o Wide

名称类型集群IP 外部IP 端口期限选择器

服务/kubernetes ClusterIP 10.96.0.1 无443/TCP 77d 无

部署 Service B , cloud-user service

更新info 接口让其return hostname

首先,更新/actuator/info 接口,使其返回当前服务所在的服务器/容器的主机名。

@成分

@slf4j

公共类AppVersionInfo 实现InfoContributor {

@Value(\’${pom.version}\’) //https://stackoverflow.com/questions/3697449/retrieve-version-from-maven-pom-xml-in-code

私有字符串appVersion;

@Autowired

私有字符串主机名。

@Value(\’${spring.datasource.url}\’)

私有字符串dbUrl;

@覆盖

公共无效提交(Info.Builder构建器){

log.info(\’AppVersionInfo: 贡献.\’);

builder.withDetail(\’应用程序\’, \’云用户API\’)

.withDetail(\’版本\’, appVersion)

.withDetail(\’主机名\’,主机名)

.withDetail(\’dbUrl\’, dbUrl)

.withDetail(\’description\’, \’这是一个简单的Spring Boot 应用程序,用于演示在GCP 上使用BigQuery。\’);

}

}

检测结果:

[gateman@manjaro-x13 bq-api-service]$curl127.0.0.1:8080/actuator/info

{\’app\’:\’云用户API\’,\’版本\’:\’0.0.1\’,\’主机名\’:\’manjaro-x13\’,\’dbUrl\’:\’jdbc:mysql://34.39.2.90:6033/demo_cloud_user?useUnicode=truecharacterEncoding=utf -8useSSL=falseallowPublicKeyRetrieval=true\’,\’description\’:\’这是一个简单的Spring Boot 应用程序,用于演示在GCP 上使用BigQuery。 \’}

[gateman@manjaro-x13 bq-api-服务]$

利用cloudbuild 和 其trigger 让其自动部署docker image 到GAR (google artifact repository)

云构建-gar.yaml

# 只需将docker 镜像更新为GAR 的pom.xml 版本

步骤:

– 运行id: maven 安装

name: maven:3.9.6-sapmachine-17 # https://hub.docker.com/_/maven

入口点: bash

参数:

-“-C”

– |

我是谁

设置-x

残疾人

MVN安装

cat pom.xml | grep -m 1 \’版本\’ sed -e \’s/.*版本\\([^]*\\)\\/版本.*/\\1/\’ /workspace/version.txt

echo \’Version: $(cat /workspace/version.txt)\’

– 构建并推送id: docker 镜像

name: \’gcr.io/cloud-builders/docker\’

入口点: bash

参数:

-“-C”

– |

设置-x

echo \’使用tag: $(cat /workspace/version.txt) 构建Docker 镜像\’

docker build -t $_GAR_BASE/$PROJECT_ID/$_DOCKER_REPO_NAME/${_APP_NAME}:$(cat /workspace/version.txt)。

docker推送$_GAR_BASE/$PROJECT_ID/$_DOCKER_REPO_NAME/${_APP_NAME}:$(cat /workspace/version.txt)

logsBucket: gs://jason-hsbc_cloudbuild/logs/

options: #https://cloud.google.com/cloud-build/docs/build-config#options

logging: GCS_ONLY # 或CLOUD_LOGGING_ONLY https://cloud.google.com/cloud-build/docs/build-config#logging

替换:

_DOCKER_REPO_NAME: my-docker-repo

_APP_NAME: 云用户

_GAR_BASE: europe-west2-docker.pkg.dev

云构建触发器:

地形:

# 参考https://registry.terraform.io/providers/hachicorp/google/latest/docs/resources/cloudbuild_trigger

资源“google_cloudbuild_trigger”“cloud-user-gar-trigger”{

name=\’cloud-user-gar-trigger\’ # 不能包含下划线

位置=var.region_id

# 如果你使用github则必须使用trigger_template

github {

名称=\’demo_cloud_user\’

所有者=\’nvd11\’

推{

分支=\’主\’

invert_regex=false # 表示在分支上触发

}

}

文件名=\’cloudbuild-gar.yaml\’

# 项目/jason-hsbc/serviceAccounts/terraform@jason-hsbc.iam.gserviceaccount.com

service_account=data.google_service_account.cloudbuild_sa.id

}

这样,一旦提交被推送到Github 主分支,

Cloudbuild自动将Docker镜像打包到指定的GAR仓库中。

网址:

Europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/cloud-user:xxx

这里xxx是pom.xml中定义的版本号。

使用此镜像路径对于以后部署到k8s 很有用。

编写yaml 脚本

部署clouduser.yaml

apiVersion: 应用程序/v1

部署kind:

元数据:

label: # 此部署的标签

app:云用户#自定义

作者: nvd11

name:deployment-cloud-user # 此部署的名称

命名空间: 的默认值

规格:

plicas: 4 # 所需的副本数。请注意,部署中的副本Pod 通常分布在多个节点上。

reviationHistoryLimit: 10 # 保留以允许回滚的旧ReplicaSet 数量

选择器: # 部署正在管理的Pod 的标签,这是必需的。如果没有这个,您将收到此错误。

# 数据验证错误: ValidationError(Deployment.spec.selector): io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector 缺少必填字段\’matchLabels\’ .

匹配标签:

app: 云用户

Strategy: #更新策略

type: RollingUpdate # 滚动更新或重新创建

滚动更新:

maxSurge: 25% # 可以创建的最大pod 数量超过更新期间所需的pod 数量。

maxUnavailable: 25% # 更新期间不可用的最大Pod 数量

template: # Pod 模板

元数据:

标签:

app: cloud-user # 部署管理的pod 的标签必须与选择器匹配。否则,你会得到一个错误:invalid value : map[string]string{\’app\’:\’bq-api-xxx\’}: `selector`。与模板“标签”不匹配

规格:

集装箱:

– image: europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/cloud-user:1.0.1 # 容器镜像

imagePullPolicy: 如果不存在

name: 容器云用户

env: # 设置环境变量

– name: APP_ENVIRONMENT

价值:个产品

restartPolicy: Always # 重启Pod 中所有容器的策略

TerminationGracePeriodSeconds: 10 # 为Pod 正常终止指定的时间段(以秒为单位)

部署yaml

[gateman@manjaro-x13 云用户]$ kubectl apply -fdeployment-cloud-user.yaml

创建了deployment.apps/deployment-cloud-user

[gateman@manjaro-x13 云用户]$ kubectl get pods -o Wide

名称就绪状态重启年龄IP 节点指定节点就绪门

Deployment-cloud-user-65fb8d79fd-28vmn 1/1 运行0 104 秒10.244.2.133 k8s-node0 无无

Deployment-cloud-user-65fb8d79fd-9rjln 1/1 运行0 104 秒10.244.2.134 k8s-node0 无无

Deployment-cloud-user-65fb8d79fd-m8xv4 1/1 运行0 104 秒10.244.1.67 k8s-node1 无无

Deployment-cloud-user-65fb8d79fd-ndvjb 1/1 运行0 104 秒10.244.3.76 k8s-node3 无无

可以看到有4个pod在运行

初步测试

部署了cloud-user,但是nodeport、clusterIP等服务没有配置,无法被node服务访问。

虽然上面的Pod 信息显示了IP 地址,但这些IP 地址是容器级别的,只能从另一个容器访问。

在这种情况下,您可以通过进入新容器来测试:

新建dns-test 测试pod

[gateman@manjaro-x13 云用户]$ kubectl run dns-test –image=odise/busybox-curl –restart=Never — /bin/sh -c \’while true;end\’

Pod/DNS 测试已创建

这样,dns-test pod就创建成功了。添加while 循环是为了防止pod 自动完全终止。

进入测试容器

[gateman@manjaro-x13 云用户]$ kubectl get pods -o Wide

名称就绪状态重启年龄IP 节点指定节点就绪门

Deployments-Cloud-Users-65fb8d79fd-28vmn 1/1 运行0 15 分钟10.244.2.133 k8s-node0 &lt

;none> <none>
deployment-cloud-user-65fb8d79fd-9rjln 1/1 Running 0 15m 10.244.2.134 k8s-node0 <none> <none>
deployment-cloud-user-65fb8d79fd-m8xv4 1/1 Running 0 15m 10.244.1.67 k8s-node1 <none> <none>
deployment-cloud-user-65fb8d79fd-ndvjb 1/1 Running 0 15m 10.244.3.76 k8s-node3 <none> <none>
dns-test 1/1 Running 0 6s 10.244.2.135 k8s-node0 <none> <none>

[gateman@manjaro-x13 cloud-user]$ kubectl exec -it dns-test — /bin/sh
/ #

十分简单

在容器内调用各个pod的api

/ # curl 10.244.2.133:8080/actuator/info
{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-28vmn\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”}/ #
/ #
/ # curl 10.244.2.134:8080/actuator/info
{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-9rjln\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”}/ #
/ #
/ #
/ # curl 10.244.1.67:8080/actuator/info
{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-m8xv4\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”}/ #
/ #
/ # curl 10.244.3.76:8080/actuator/info
{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-ndvjb\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”}/ #
/ #
/ #

可以见到4个pod的 service 都可以被dns-test 容器内call 通, 能分别return 它们的hostname, 但是调用时要指定ip , 无法做到统一入口 和 load balance

部署 ClusterIP – clusterip-cloud-user

编写yaml

clusterip-cloud-user.yaml

apiVersion: v1
kind: Service
metadata:
name: clusterip-cloud-user
spec:
selector:
app: cloud-user # for the pods that have the label app: cloud-user
ports:
– protocol: TCP
port: 8080
targetPort: 8080
type: ClusterIP

由于加上了selector , 所以endpoint 也会自动创建

部署yaml

[gateman@manjaro-x13 cloud-user]$ kubectl create -f clusterip-cloud-user.yaml
service/clusterip-cloud-user created

检查一下:

[gateman@manjaro-x13 cloud-user]$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
clusterip-cloud-user ClusterIP 10.96.11.18 <none> 8080/TCP 29s app=cloud-user
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 77d <none>
[gateman@manjaro-x13 cloud-user]$ kubectl get ep -o wide
NAME ENDPOINTS AGE
clusterip-cloud-user 10.244.1.67:8080,10.244.2.133:8080,10.244.2.134:8080 + 1 more… 2m36s
kubernetes 192.168.0.3:6443 77d

可以见到1个cluster ip service 已被创建

名字是 clusterip-cloud-user, 类型是ClusterIP, Cluster-IP 就是所谓的虚拟ip

在endpoints 里面, 可以见到这个clusterip service 代理的是 4个 ip和端口的组合, 它们实际上就是 cloud-user 的4个pods

初步测试

ClusterIP 和 NodePort 不一样, 是无法从容器外部直接访问的,
所以我们还是需要进入测试容器类测试

kubectl exec -it dns-test — /bin/sh

之后我们可以用 $serviceName:$\\port 去访问endpoints里的service了

/ # nslookup clusterip-cloud-user
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: clusterip-cloud-user
Address 1: 10.96.11.18 clusterip-cloud-user.default.svc.cluster.local
`
/ # ping clusterip-cloud-user
PING clusterip-cloud-user (10.96.11.18): 56 data bytes
^C
— clusterip-cloud-user ping statistics —
10 packets transmitted, 0 packets received, 100% packet loss
/ # curl clusterip-cloud-user:8080/actuator/info
{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-m8xv4\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPub/ # curl clusterip-cloud-user:8080/actuator/info
{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-28vmn\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPub/ # curl clusterip-cloud-user:8080/actuator/info
{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-9rjln\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPub/ # curl clusterip-cloud-user:8080/actuator/info
{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-9rjln\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”}

虽然ping 是无法ping 通的, 可能没开通ICMP 协议

但是我们的确可以通过 clusterip的service 去访问 cloud-user 的4个instance , 而且是随机分配的, 时间了load balance的功能!

部署 Service A – bq-api-service

修改配置

部署之前, 我们在 bq-api-service 先增加1个接口 /ext-service/user-service/info
在这个接口内, 会调用 cloud-user 的 /actuator/info 接口

方便测试

Controller

@Autowired
private UserService userService;
@GetMapping(\”/user-service/info\”)
public ResponseEntity<ApiResponse<ServiceInfoDao>> userServiceInfo() {
ServiceInfoDao userServiceInfo = null;
try {
userServiceInfo = this.userService.getServiceInfo();
ApiResponse<ServiceInfoDao> response = new ApiResponse<>();
response.setData(userServiceInfo);
response.setReturnCode(0);
response.setReturnMsg(\”user service is running in the host: \” + userServiceInfo.getHostname());
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error(\”Error in getUserById…\”, e);
ApiResponse<ServiceInfoDao> response = new ApiResponse<>();
response.setReturnCode(-1);
response.setReturnMsg(\”Error in getting user service info: \” + e.getMessage());
return ResponseEntity.status(500).body(response);
}
}

Service

@Override
public ServiceInfoDao getServiceInfo() {
log.info(\”getServiceInfo()…\”);
return userClient.getServiceInfo();
}

feignclient:

@FeignClient(name = \”demo-cloud-user\”, url=\”${hostIp.cloud-user}\”)
public interface UserClient {
@GetMapping(\”/actuator/info\”)
ServiceInfoDao getServiceInfo();
}

在feign client里见到 ip address 是配置在配置文件中的。
正好, 我们增加1个新的application-k8s 配置文件
application-k8s.yaml

## 其他配置
hostIp:
cloud-user: clusterip-cloud-user:8080

关键我们不需要再指定 cloud-user 部署在哪里的ip了, 也不用关心它有多少instance, 跟spring cloud 用法很类似, 只需要提供1个名字

在spring cloud 中我们需要提供cloud-user 在eureka注册的名字
在k8s 我们需要提供用于反向代理的 clusterIP service 的名字

部署docker image 上GAR

同样的方法
url: europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/bq-api-service:xxx

编写yaml

deployment-bq-api-service.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
labels: # label of this deployment
app: bq-api-service # custom defined
author: Jason
name: deployment-bq-api-service # name of this deployment
namespace: default
spec:
replicas: 4 # desired replica count, Please note that the replica Pods in a Deployment are typically distributed across multiple nodes.
revisionHistoryLimit: 10 # The number of old ReplicaSets to retain to allow rollback
selector: # label of the Pod that the Deployment is managing,, it\’s mandatory, without it , we will get this error
# error: error validating data: ValidationError(Deployment.spec.selector): missing required field \”matchLabels\” in io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector ..
matchLabels:
app: bq-api-service
strategy: # Strategy of upodate
type: RollingUpdate # RollingUpdate or Recreate
rollingUpdate:
maxSurge: 25% # The maximum number of Pods that can be created over the desired number of Pods during the update
maxUnavailable: 25% # The maximum number of Pods that can be unavailable during the update
template: # Pod template
metadata:
labels:
app: bq-api-service # label of the Pod that the Deployment is managing. must match the selector, otherwise, will get the error Invalid value: map[string]string{\”app\”:\”bq-api-xxx\”}: `selector` does not match template `labels`
spec:
containers:
– image: europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/bq-api-service:1.2.1 # image of the container
imagePullPolicy: IfNotPresent
name: container-bq-api-service
env: # set env varaibles
– name: APP_ENVIRONMENT
value: k8s
restartPolicy: Always # Restart policy for all containers within the Pod
terminationGracePeriodSeconds: 10 # The period of time in seconds given to the Pod to terminate gracefully

同样4个实例, 注意的是环境变量要正确地 配置成 k8s`

env: # set env varaibles
– name: APP_ENVIRONMENT
value: k8s

部署yaml

deployment.apps/deployment-bq-api-service created
[gateman@manjaro-x13 bq-api-service]$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-bq-api-service-778cf8f54-677vl 1/1 Running 0 34s 10.244.2.136 k8s-node0 <none> <none>
deployment-bq-api-service-778cf8f54-nfzhg 1/1 Running 0 34s 10.244.3.77 k8s-node3 <none> <none>
deployment-bq-api-service-778cf8f54-q9lfx 1/1 Running 0 34s 10.244.1.68 k8s-node1 <none> <none>
deployment-bq-api-service-778cf8f54-z72dr 1/1 Running 0 34s 10.244.3.78 k8s-node3 <none> <none>
deployment-cloud-user-65fb8d79fd-28vmn 1/1 Running 0 121m 10.244.2.133 k8s-node0 <none> <none>
deployment-cloud-user-65fb8d79fd-9rjln 1/1 Running 0 121m 10.244.2.134 k8s-node0 <none> <none>
deployment-cloud-user-65fb8d79fd-m8xv4 1/1 Running 0 121m 10.244.1.67 k8s-node1 <none> <none>
deployment-cloud-user-65fb8d79fd-ndvjb 1/1 Running 0 121m 10.244.3.76 k8s-node3 <none> <none>
dns-test 1/1 Running 0 105m 10.244.2.135 k8s-node0 <none> <none>

可以见到 4个 bq-api-service 的pods 也起来了

初步测试

因为没有nodeport , 我们还是需要进入测试容器

kubectl exec -it dns-test — /bin/sh

还是单独地测试1个instance, 先记住2个ip 10.244.2.136, 10.244.3.77

先测试该service 的info

/ # curl 10.244.2.136:8080/actuator/info
{\”app\”:\”Sales API\”,\”version\”:\”1.2.1\”,\”hostname\”:\”deployment-bq-api-service-778cf8f54-677vl\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”}

可以见到是已经启动了

然后在测试它的 /ext-service/user-service/info 接口

/ # curl 10.244.3.77:8080/ext-service/user-service/info
{\”returnCode\”:0,\”returnMsg\”:\”user service is running in the host: deployment-cloud-user-65fb8d79fd-m8xv4\”,\”data\”:{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-m8xv4\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowP/ # curl 10.244.3.77:8080/ext-service/user-service/info
{\”returnCode\”:0,\”returnMsg\”:\”user service is running in the host: deployment-cloud-user-65fb8d79fd-m8xv4\”,\”data\”:{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-m8xv4\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowP/ # curl 10.244.3.77:8080/ext-service/user-service/info
{\”returnCode\”:0,\”returnMsg\”:\”user service is running in the host: deployment-cloud-user-65fb8d79fd-m8xv4\”,\”data\”:{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-m8xv4\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowP/ # curl 10.244.3.77:8080/ext-service/user-service/info
{\”returnCode\”:0,\”returnMsg\”:\”user service is running in the host: deployment-cloud-user-65fb8d79fd-m8xv4\”,\”data\”:{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-m8xv4\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowP/ # curl 10.244.2.136:8080/ext-service/user-service/info
{\”returnCode\”:0,\”returnMsg\”:\”user service is running in the host: deployment-cloud-user-65fb8d79fd-28vmn\”,\”data\”:{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-28vmn\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowP/ # curl 10.244.2.136:8080/ext-service/user-service/info
{\”returnCode\”:0,\”returnMsg\”:\”user service is running in the host: deployment-cloud-user-65fb8d79fd-28vmn\”,\”data\”:{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-28vmn\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowP/ # curl 10.244.2.136:8080/ext-service/user-service/info
{\”returnCode\”:0,\”returnMsg\”:\”user service is running in the host: deployment-cloud-user-65fb8d79fd-28vmn\”,\”data\”:{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-28vmn\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowP/ # curl 10.244.2.136:8080/ext-service/user-service/info
{\”returnCode\”:0,\”returnMsg\”:\”user service is running in the host: deployment-cloud-user-65fb8d79fd-28vmn\”,\”data\”:{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-28vmn\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true\”}}/ #

可见bq-api-service 已经成功 通过 cluster ip 去访问 后面的cloud-user service 了, 根据返回的host name

可以看出
clusterip 的loadbalancer 不会无脑随机转发

从 10.244.3.77 访问的bq-api-service 会访问 deployment-cloud-user-65fb8d79fd-m8xv4 里的cloud-user
从 10.244.2.136 访问的就会访问 deployment-cloud-user-65fb8d79fd-28vmn

为什么? 因为clusterip 会智能地优先访问 同1个node的后台服务!

到这了这一步, 我们已经成功demo了 ClusterIP 的主要功能了
service A 已经能通过 cluster ip 访问service B 只是差了NodePort 无法从集群外测试

部署 NodePort nodeport-bq-api-service

注意这个nodeport 是for service A(bq-api-service)的而不是 service B, 如上图

编写yaml

nodeport-bq-api-service.yaml

apiVersion: v1 # api version can be v1 or apps/v1
kind: Service
metadata:
name: nodeport-bq-api-service # name of the service
labels:
app: bq-api-service # label of the service itself
spec:
selector: # Label of the Pod that the Service is selecting , all the pods not matter the pods are belong to which deployment, as long as the pods have the label app: bq-api-service
app: bq-api-service # if the pod do not have the label app: bq-api-service, the pod could not be selected by the service
ports:
– port: 8080 # port of the service itself. we could also use serviceip:port to access the pod service,
# but we use the nodeip:nodePort to access the service it. this nodePort is generated by k8s ramdomly
targetPort: 8080 # port of the Pod
name: 8080-port # name of the port
type: NodePort # type of the service, NodePort, ClusterIP, LoadBalancer
# Ramdomly start a port (30000-32767) on each node, and forward the request to the service port (32111) on the pod
# and it could also be use to expose the service to the external world, but it\’s not recommended for production, because it\’s not secure and low efficient

部署yaml

[gateman@manjaro-x13 bq-api-service]$ kubectl create -f nodeport-bq-api-service.yaml
service/nodeport-bq-api-service created
[gateman@manjaro-x13 bq-api-service]$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
clusterip-cloud-user ClusterIP 10.96.11.18 <none> 8080/TCP 86m app=cloud-user
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 77d <none>
nodeport-bq-api-service NodePort 10.106.59.100 <none> 8080:32722/TCP 13s app=bq-api-service
[gateman@manjaro-x13 bq-api-service]$ kubectl get ep -o wide
NAME ENDPOINTS AGE
clusterip-cloud-user 10.244.1.67:8080,10.244.2.133:8080,10.244.2.134:8080 + 1 more… 86m
kubernetes 192.168.0.3:6443 77d
nodeport-bq-api-service 10.244.1.68:8080,10.244.2.136:8080,10.244.3.77:8080 + 1 more… 19s

从nodeport service 的信息得出, 1个随机端口 32722 生成用于外部访问

E2E 测试

既然所有components 都部署了, 现在我们可以直接从集群外部测试
34.142.xxxxxx 是k8s-master 的公网ip

[gateman@manjaro-x13 bq-api-service]$ curl 34.142.xxxxxx:32722/actuator/info
{\”app\”:\”Sales API\”,\”version\”:\”1.2.1\”,\”hostname\”:\”deployment-bq-api-service-778cf8f54-z72dr\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”}[gateman@manjaro-x13 bq-api-service]$ curl 34.142.35.168:32722/ext-service/user-service/info
{\”returnCode\”:0,\”returnMsg\”:\”user service is running in the host: deployment-cloud-user-65fb8d79fd-9rjln\”,\”data\”:{\”app\”:\”Cloud User API\”,\”version\”:\”1.0.1\”,\”description\”:\”This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.\”,\”hostname\”:\”deployment-cloud-user-65fb8d79fd-9rjln\”,\”dbUrl\”:\”jdbc:mysql://192.168.0.42:3306/demo_cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true\”}}[gateman@manjaro-x13 bq-api-service]$

#以上关于K8S 的相关内容来源网络仅供参考,相关信息请以官方公告为准!

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91842.html

Like (0)
CSDN的头像CSDN
Previous 2024年6月23日
Next 2024年6月23日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注