Azure 上外部可见的 Kubernetes 服务

Azure 上外部可见的 Kubernetes 服务

我正在 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):

  1. 每次kubect apply新的IP 地址和规则已添加到负载均衡器的前端池。奇怪的是,以前的 IP 地址和规则仍然存在(即使我在kubectl delete namespace logging部署之前运行,这表明应该释放以前使用的 IP 地址和规则。我检查了代码这里 并且据我所知,有一些功能可以确保没有过时的公共 IP 地址和负载平衡规则。从以前的部署中添加的 IP 地址无法访问当前部署的 Kibana 服务。
  2. 我想要一个 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/负载平衡配置。

(当然,这一切都假设将所有内容放在一个文件中并不是某种硬性要求......在这种情况下,我无法立即给你一个很好的答案......)

相关内容