我正在 Azure 上的 Kubernetes(v1.4.5)集群上部署 ELK 堆栈。这是创建 KibanaService
和的配置Deployment
。
# deployment.yml
---
apiVersion: v1
kind: Namespace
metadata:
name: logging
---
# elasticsearch deployment and Service
---
# logstash Deployment and Service
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kibana
namespace: logging
spec:
replicas: 1
template:
metadata:
labels:
component: kibana
spec:
containers:
- name: kibana
image: sebp/elk:521
env:
- name: "LOGSTASH_START"
value: "0"
- name: "ELASTICSEARCH_START"
value: "0"
ports:
- containerPort: 5601
name: ui
protocol: TCP
volumeMounts:
- name: config-volume
mountPath: '/opt/kibana/config/'
volumes:
- name: config-volume
configMap:
name: kibana-config
---
apiVersion: v1
kind: Service
metadata:
name: kibana
namespace: logging
labels:
component: kibana
spec:
type: LoadBalancer
ports:
- port: 5601
protocol: TCP
targetPort: ui
nodePort: 30257
selector:
component: kibana
我通过 进行部署kubectl apply -f deployment.yml
。我通过 清除整个 ELK 堆栈kubectl delete namespace logging
。Azure
上有一个负载均衡器,后端池是 k8s 代理。部署时,会向负载均衡器添加一个公共 IP 和一个规则。我可以使用负载均衡器前端地址池中的 IP 地址在浏览器中访问 kibana。
以下是问题 1) 以及我想要实现的问题 2):
- 每次
kubect apply
我新的IP 地址和规则已添加到负载均衡器的前端池。奇怪的是,以前的 IP 地址和规则仍然存在(即使我在kubectl delete namespace logging
部署之前运行,这表明应该释放以前使用的 IP 地址和规则。我检查了代码这里 并且据我所知,有一些功能可以确保没有过时的公共 IP 地址和负载平衡规则。从以前的部署中添加的 IP 地址无法访问当前部署的 Kibana 服务。 - 我想要一个 DNS 名称,ELK 堆栈的客户端(例如我的浏览器<->kibana、日志发射服务器<->logstash)可以使用它来引用 ELK 服务,而无需在客户端中硬编码 IP 地址(因此 ELK 堆栈的重新部署对客户端来说是透明的)。
我到目前为止尝试过的方法:我通过 Azure 的仪表板手动创建了一个带有 DNS 名称的公共 IP 地址。我向负载均衡器添加了负载平衡规则,这些规则看起来像在 上自动创建的规则kubectl apply
。我尝试在 下的 kibana 服务规范中使用这个手动创建的公共 IP,externalIPs
然后在loadBalancerIP
(k8s 文档)。
当 externalIPs 设置为公网 IP 时,kubectl describe service --namespace=logging
返回
Name: kibana
Namespace: logging
Labels: component=kibana
Selector: component=kibana
Type: LoadBalancer
IP: 10.x.xxx.xx
External IPs: 52.xxx.xxx.xxx <- this is the IP I manually created
LoadBalancer Ingress: 52.xxx.xxx.xxx
Port: <unset> 5601/TCP
NodePort: <unset> 30257/TCP
Endpoints: 10.xxx.x.xxx:5601
Session Affinity: None
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
15m 15m 1 {service-controller } Normal CreatingLoadBalancer Creating load balancer
14m 14m 1 {service-controller } Normal CreatedLoadBalancer Created load balancer
但是,对 DNS 名称或直接对外部 IP 的请求超时。当我loadBalancerIP
在服务规范中设置时,kubectl describe service
返回类似的输出,但没有外部 IP 行,并且再次在负载均衡器上创建一个新的公共 IP 地址 + 规则。再次无法使用我手动创建的公共 IP 的 DNS 名称/IP。
任何帮助都将非常感激:)
答案1
啊。最简单的做法是避免在每次部署之前删除服务。根据我的经验,服务往往寿命很长;它们提供了一种很好的固定方式来引用事物,而不必担心端口、ip、dns 等的动态值。
在 Kibana 服务规范中,从端口配置中删除 nodePort 条目,以便服务可以自行执行操作;少考虑一件事。不要设置 loadBalancerIP 或 externalIPs 的值。相同的规则适用于其他服务。
对于 ELK 堆栈配置文件(我不记得它们是什么样子),请通过服务名称引用其他组件:无需使用硬编码 IP 或任何其他内容。(不知道您是否这样做了,但以防万一。)
允许创建服务;获取负载均衡器外部 IP 并将其插入您的 DNS 配置。
如果您愿意,您可以继续使用命名空间,但不要删除整个命名空间来清除 ELK 组件的部署。
将 ELK 堆栈规范拆分为用于部署和服务的单独文件(从技术上讲,我不确定这是否是必需的;您可能能够摆脱这种情况),以便您可以使用:
kubectl delete -f logging-deployments.yaml
kubectl apply -f logging-deployments.yaml
或类似的命令来更新部署而不打扰服务。
如果您需要(或喜欢)在创建新的 ELK 堆栈之前以其他方式删除旧堆栈,您也可以使用:
kubectl -n logging delete deployments --all
删除日志命名空间内的所有部署。对我来说,这个选项似乎比它需要的更危险。
第二种选择是:
kubectl delete deployments kibana
kubectl delete deployments elasticsearch
kubectl delete deployments logstash
如果你不介意额外输入
另一个选择是添加一个新标签,例如:
role: application
或者
stack: ELK
到每个部署规范。然后您可以使用:
kubectl delete deployments -l stack=ELK
来限制删除的范围...但是这又看起来很危险。
我倾向于将配置拆分为 2 个以上的文件并使用:除非有其他压倒性的理由:
kubectl create -f svc-logging.yaml
kubectl create -f deploy-logging.yaml
kubectl delete -f deploy-logging.yaml
kubectl apply -f deploy-logging.yaml
...
etc
以帮助防止任何因打字错误而导致的严重事故。
我将其进一步细分,每个组件都有一个单独的文件夹,其中包含部署和服务,并嵌套在一起(更容易保存在存储库中,如果多个人需要更改相关但独立的组件则更容易),并且通常使用 bash 创建/销毁脚本来提供类似文档的东西......但你明白了。
通过这种方式设置,您应该能够更新任何或所有部署组件,而不会破坏您的 DNS/负载平衡配置。
(当然,这一切都假设将所有内容放在一个文件中并不是某种硬性要求......在这种情况下,我无法立即给你一个很好的答案......)