Kubernetes 部署动态端口转发
Kubernetes Deployment dynamic port forwarding
我正在将 Docker 映像从 Docker 移动到 K8s 部署。我有自动缩放规则,所以它从 5 开始,但可以到 12。K8s 上的 Docker 图像完美地开始,前面有一个 k8s 服务来集群部署。
现在每个容器都有自己的 JVM,其中有一个 Prometheus 应用程序可以检索其统计信息。在 Docker 中,这没有问题,因为提供 Prometheus 信息的端口是动态创建的,起始端口为 8000,因此 docker-compose.yml 会根据端口数量增加 1图片已启动。
问题是我无法在 K8s [deployment].yml 文件中找到如何执行此操作。因为 Deployment pods 是动态的,我原以为会有一些方法可以根据启动的容器数量来设置起始 HOST 端口。
也许我看错了,所以任何澄清都会有所帮助,同时我会继续在 Google 中搜索有关此类事情的任何信息。
理想情况下,您应该对所有副本使用 JVM 的平均值。如果您是 运行 单个 相同的 Docker 图像 ,那么使用不同的 端口 创建不同的部署是没有意义的在所有 副本中 。
我认为将资源需求设置为部署的单个部署是最佳实践。
您可以获得所有 运行 副本的 JVM 平均值
sum(jvm_memory_max_bytes{area="heap", app="app-name",job="my-job"}) / sum(kube_pod_status_phase{phase="Running"})
因为你是 运行 所有副本和 K8s 服务的相同 Docker 映像默认情况下将管理负载平衡,平均利用率将是一个监控选项。
不过,如果您想过滤并获得不同的值,您可以创建不同的 deployments(这不是很好的方法)或使用 stateful sets.
您还可以在 Prometheus 中通过 主机名(POD 名称) 过滤数据,这样会得到每个副本的使用情况。
好吧,在读了又读又读了这么多之后我得出的结论是 K8s 不负责为 Docker 图像打开端口或在一些奇怪的端口上为您的应用程序提供入口,这不是它的责任. K8s 部署只是部署您请求的 Pods。您可以在 DEPLOYMENT -> SPEC -> CONTAINERS -> PORTS 上设置 Ports 选项,就像 Docker 一样只是提供信息。但这允许您使用可用的 Prometheus 端口对所有 PODS(容器)进行 JSONPath 查询。这将允许您重建 Prometheus.yaml 文件中的“目标”值。现在有了这些目标,Grafana 就可以使用它们来创建仪表板。
就是这样,非常简单。我把事情复杂化了,因为我不明白。我附上了一个我快速编写的脚本,让您自行承担使用风险。
顺便说一句,我交替使用Pod和Container。
#!/usr/bin/env bash
#set -x
_MyappPrometheusPort=8055
_finalIpsPortArray=()
_prometheusyamlFile=prometheus.yml
cd /docker/images/prometheus
#######################################################################################################################################################
#One container on the K8s System is weave and it holds the subnet we need to validate against.
#weave-net-lwzrk 2/2 Running 8 (7d3h ago) 9d 192.168.2.16 accl-ffm-srv-006 <none> <none>
_weavenet=$(kubectl get pod -n kube-system -o wide | grep weave | cut -d ' ' -f1 )
echo "_weavenet: $_weavenet"
#The default subnet is the one that lets us know the conntainer is part of kubernetes network.
# Range: 10.32.0.0/12
# DefaultSubnet: 10.32.0.0/12
_subnet=$( kubectl exec -n kube-system $_weavenet -c weave -- /home/weave/weave --local status | sed -En "s/^(.*)(DefaultSubnet:\s)(.*)?//p" )
echo "_subnet: $_subnet"
_cidr2=$( echo "$_subnet" | cut -d '/' -f2 )
echo "_cidr2: /$_cidr2"
#######################################################################################################################################################
#This is an array of the currently monitored containers that prometheus was sstarted with.
#We will remove any containers form the array that fit the K8s Weavenet subnet with the myapp prometheus port.
_targetLineFound_array=($( egrep '^\s{1,20}-\s{0,5}targets\s{0,5}:\s{0,5}\[.*\]' $_prometheusyamlFile | sed -En "s/(.*-\stargets:\s\[)(.*)(\]).*//p" | tr "," "\n"))
for index in "${_targetLineFound_array[@]}"
do
_ip="${index//\'/$''}"
_ipTocheck=$( echo $_ip | cut -d ':' -f1 )
_portTocheck=$( echo $_ip | cut -d ':' -f2 )
#We need to check if the IP is within the subnet mask attained from K8s.
#The port must also be the prometheus port in case some other port is used also for Prometheus.
#This means the IP should be removed since we will put the list of IPs from
#K8s currently in production by Deployment/AutoScale rules.
#Network: 10.32.0.0/12
_isIpWithinSubnet=$( ipcalc $_ipTocheck/$_cidr2 | sed -En "s/^(.*)(Network:\s+)([0-9]{1}[0-9]?[0-9]?\.[0-9]{1}[0-9]?[0-9]?\.[0-9]{1}[0-9]?[0-9]?\.[0-9]{1}[0-9]?[0-9]?)(\/[0-9]{1}[0-9]{1}.*)?//p" )
if [[ "$_isIpWithinSubnet/$_cidr2" == "$_subnet" && "$_portTocheck" == "$_MyappPrometheusPort" ]]; then
echo "IP managed by K8s will be deleted: _isIpWithinSubnet: ($_ip) $_isIpWithinSubnet"
else
_finalIpsPortArray+=("$_ip")
fi
done
#######################################################################################################################################################
#This is an array of the current running myapp App containers with a prometheus port that is available.
#From this list we will add them to the prometheus file to be available for Grafana monitoring.
readarray -t _currentK8sIpsArr < <( kubectl get pods --all-namespaces --chunk-size=0 -o json | jq '.items[] | select(.spec.containers[].ports != null) | select(.spec.containers[].ports[].containerPort == '$_MyappPrometheusPort' ) | .status.podIP' )
for index in "${!_currentK8sIpsArr[@]}"
do
_addIPToMonitoring=${_currentK8sIpsArr[index]//\"/$''}
echo "IP Managed by K8s as myapp app with prometheus currently running will be added to monitoring: $_addIPToMonitoring"
_finalIpsPortArray+=("$_addIPToMonitoring:$_MyappPrometheusPort")
done
######################################################################################################################################################
#we need to recreate this string and sed it into the file
#- targets: ['192.168.2.13:3201', '192.168.2.13:3202', '10.32.0.7:8055', '10.32.0.8:8055']
_finalPrometheusTargetString="- targets: ["
i=0
# Iterate the loop to read and print each array element
for index in "${!_finalIpsPortArray[@]}"
do
((i=i+1))
_finalPrometheusTargetString="$_finalPrometheusTargetString '${_finalIpsPortArray[index]}'"
if [[ $i != ${#_finalIpsPortArray[@]} ]]; then
_finalPrometheusTargetString="$_finalPrometheusTargetString,"
fi
done
_finalPrometheusTargetString="$_finalPrometheusTargetString]"
echo "$_finalPrometheusTargetString"
sed -i -E "s/(.*)-\stargets:\s\[.*\]/$_finalPrometheusTargetString/" ./$_prometheusyamlFile
docker-compose down
sleep 4
docker-compose up -d
echo "All changes were made. Exiting"
exit 0
我正在将 Docker 映像从 Docker 移动到 K8s 部署。我有自动缩放规则,所以它从 5 开始,但可以到 12。K8s 上的 Docker 图像完美地开始,前面有一个 k8s 服务来集群部署。
现在每个容器都有自己的 JVM,其中有一个 Prometheus 应用程序可以检索其统计信息。在 Docker 中,这没有问题,因为提供 Prometheus 信息的端口是动态创建的,起始端口为 8000,因此 docker-compose.yml 会根据端口数量增加 1图片已启动。
问题是我无法在 K8s [deployment].yml 文件中找到如何执行此操作。因为 Deployment pods 是动态的,我原以为会有一些方法可以根据启动的容器数量来设置起始 HOST 端口。
也许我看错了,所以任何澄清都会有所帮助,同时我会继续在 Google 中搜索有关此类事情的任何信息。
理想情况下,您应该对所有副本使用 JVM 的平均值。如果您是 运行 单个 相同的 Docker 图像 ,那么使用不同的 端口 创建不同的部署是没有意义的在所有 副本中 。
我认为将资源需求设置为部署的单个部署是最佳实践。
您可以获得所有 运行 副本的 JVM 平均值
sum(jvm_memory_max_bytes{area="heap", app="app-name",job="my-job"}) / sum(kube_pod_status_phase{phase="Running"})
因为你是 运行 所有副本和 K8s 服务的相同 Docker 映像默认情况下将管理负载平衡,平均利用率将是一个监控选项。
不过,如果您想过滤并获得不同的值,您可以创建不同的 deployments(这不是很好的方法)或使用 stateful sets.
您还可以在 Prometheus 中通过 主机名(POD 名称) 过滤数据,这样会得到每个副本的使用情况。
好吧,在读了又读又读了这么多之后我得出的结论是 K8s 不负责为 Docker 图像打开端口或在一些奇怪的端口上为您的应用程序提供入口,这不是它的责任. K8s 部署只是部署您请求的 Pods。您可以在 DEPLOYMENT -> SPEC -> CONTAINERS -> PORTS 上设置 Ports 选项,就像 Docker 一样只是提供信息。但这允许您使用可用的 Prometheus 端口对所有 PODS(容器)进行 JSONPath 查询。这将允许您重建 Prometheus.yaml 文件中的“目标”值。现在有了这些目标,Grafana 就可以使用它们来创建仪表板。
就是这样,非常简单。我把事情复杂化了,因为我不明白。我附上了一个我快速编写的脚本,让您自行承担使用风险。
顺便说一句,我交替使用Pod和Container。
#!/usr/bin/env bash
#set -x
_MyappPrometheusPort=8055
_finalIpsPortArray=()
_prometheusyamlFile=prometheus.yml
cd /docker/images/prometheus
#######################################################################################################################################################
#One container on the K8s System is weave and it holds the subnet we need to validate against.
#weave-net-lwzrk 2/2 Running 8 (7d3h ago) 9d 192.168.2.16 accl-ffm-srv-006 <none> <none>
_weavenet=$(kubectl get pod -n kube-system -o wide | grep weave | cut -d ' ' -f1 )
echo "_weavenet: $_weavenet"
#The default subnet is the one that lets us know the conntainer is part of kubernetes network.
# Range: 10.32.0.0/12
# DefaultSubnet: 10.32.0.0/12
_subnet=$( kubectl exec -n kube-system $_weavenet -c weave -- /home/weave/weave --local status | sed -En "s/^(.*)(DefaultSubnet:\s)(.*)?//p" )
echo "_subnet: $_subnet"
_cidr2=$( echo "$_subnet" | cut -d '/' -f2 )
echo "_cidr2: /$_cidr2"
#######################################################################################################################################################
#This is an array of the currently monitored containers that prometheus was sstarted with.
#We will remove any containers form the array that fit the K8s Weavenet subnet with the myapp prometheus port.
_targetLineFound_array=($( egrep '^\s{1,20}-\s{0,5}targets\s{0,5}:\s{0,5}\[.*\]' $_prometheusyamlFile | sed -En "s/(.*-\stargets:\s\[)(.*)(\]).*//p" | tr "," "\n"))
for index in "${_targetLineFound_array[@]}"
do
_ip="${index//\'/$''}"
_ipTocheck=$( echo $_ip | cut -d ':' -f1 )
_portTocheck=$( echo $_ip | cut -d ':' -f2 )
#We need to check if the IP is within the subnet mask attained from K8s.
#The port must also be the prometheus port in case some other port is used also for Prometheus.
#This means the IP should be removed since we will put the list of IPs from
#K8s currently in production by Deployment/AutoScale rules.
#Network: 10.32.0.0/12
_isIpWithinSubnet=$( ipcalc $_ipTocheck/$_cidr2 | sed -En "s/^(.*)(Network:\s+)([0-9]{1}[0-9]?[0-9]?\.[0-9]{1}[0-9]?[0-9]?\.[0-9]{1}[0-9]?[0-9]?\.[0-9]{1}[0-9]?[0-9]?)(\/[0-9]{1}[0-9]{1}.*)?//p" )
if [[ "$_isIpWithinSubnet/$_cidr2" == "$_subnet" && "$_portTocheck" == "$_MyappPrometheusPort" ]]; then
echo "IP managed by K8s will be deleted: _isIpWithinSubnet: ($_ip) $_isIpWithinSubnet"
else
_finalIpsPortArray+=("$_ip")
fi
done
#######################################################################################################################################################
#This is an array of the current running myapp App containers with a prometheus port that is available.
#From this list we will add them to the prometheus file to be available for Grafana monitoring.
readarray -t _currentK8sIpsArr < <( kubectl get pods --all-namespaces --chunk-size=0 -o json | jq '.items[] | select(.spec.containers[].ports != null) | select(.spec.containers[].ports[].containerPort == '$_MyappPrometheusPort' ) | .status.podIP' )
for index in "${!_currentK8sIpsArr[@]}"
do
_addIPToMonitoring=${_currentK8sIpsArr[index]//\"/$''}
echo "IP Managed by K8s as myapp app with prometheus currently running will be added to monitoring: $_addIPToMonitoring"
_finalIpsPortArray+=("$_addIPToMonitoring:$_MyappPrometheusPort")
done
######################################################################################################################################################
#we need to recreate this string and sed it into the file
#- targets: ['192.168.2.13:3201', '192.168.2.13:3202', '10.32.0.7:8055', '10.32.0.8:8055']
_finalPrometheusTargetString="- targets: ["
i=0
# Iterate the loop to read and print each array element
for index in "${!_finalIpsPortArray[@]}"
do
((i=i+1))
_finalPrometheusTargetString="$_finalPrometheusTargetString '${_finalIpsPortArray[index]}'"
if [[ $i != ${#_finalIpsPortArray[@]} ]]; then
_finalPrometheusTargetString="$_finalPrometheusTargetString,"
fi
done
_finalPrometheusTargetString="$_finalPrometheusTargetString]"
echo "$_finalPrometheusTargetString"
sed -i -E "s/(.*)-\stargets:\s\[.*\]/$_finalPrometheusTargetString/" ./$_prometheusyamlFile
docker-compose down
sleep 4
docker-compose up -d
echo "All changes were made. Exiting"
exit 0