使用AWS Elastic LoadBalancer公开kubernetes应用

时间:2019-01-28 20:34:37

标签: kubernetes amazon-elb google-kubernetes-engine aws-load-balancer aws-application-load-balancer

我创建了一个内部AWS弹性应用程序负载平衡器,并在AWS控制台中将其状态显示为活动。 请注意,我使用jenkins作业创建了该ALB,并在该作业中指定了配置为Kubernetes主服务器的AWS EC2实例服务器。

成功完成工作后,我可以看到以下详细信息。

在AWS控制台的说明下,我可以看到以下详细信息-

DNS  internal-myservices-987070943.us-east-1.elb.amazonaws.com
Scheme  internal
Type  application
IP address type  ipv4

然后有一个“侦听器”选项卡,在其中可以看到HTTPS侦听器ID:443

还显示具有以下2条规则的规则-

IF Path is /*  THEN Forward to myservices-LB
IF Requests otherwise not routed  THEN Forward to myservices-LB

此外,我还会看到其他标签,例如“监视”,“集成服务”和“标签”。

现在,我有一个kubernetes集群,其中包含使用Type:LoadBalancer创建的以下服务- (来源参考:https://github.com/kenzanlabs/kubernetes-ci-cd/blob/master/applications/hello-kenzan/k8s/manual-deployment.yaml

apiVersion: v1
Kind: Service
metadata:
 name: hello-kenzan
 labels:
 app: hello-kenzan
spec:
 ports:
  - port: 80
    targetPort: 80
 selector:
   app: hello-kenzan
   tier: hello-kenzan
 type: LoadBalancer

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-kenzan
  labels:
    app: hello-kenzan
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: hello-kenzan
        tier: hello-kenzan
    spec:
      containers:
      - image: gopikrish81/hello-kenzan:latest
        name: hello-kenzan
        ports:
        - containerPort: 80
          name: hello-kenzan

使用-创建服务后

kubectl apply -f k8s/manual-deployment.yaml
kubectl get svc

它将外部IP显示为<pending> 但是既然我已经创建了一个loadbalancer类型,为什么不创建一个ip呢?

仅供参考,我可以使用curl <master node>:<nodeport>访问该应用 甚至我也可以通过代理转发来访问它。

因此,如果没有创建IP,就不可能使用DNS公开我的应用程序,对吗?请建议我可以做些什么,以便可以使用DNS名称internal-myservices-987070943.us-east-1.elb.amazonaws.com

公开我的服务。

我需要使用http://internal-myservices-987070943.us-east-1.elb.amazonaws.com/#之类的DNS名称公开该应用

预先感谢

更新于29/1

我按照这篇帖子kube-controller-manager don't start when using "cloud-provider=aws" with kubeadm

所述的答案进行操作

1)我通过在[服务]下添加以下命令来修改文件“ /etc/systemd/system/kubelet.service.d/10-kubeadm.conf”

Environment="KUBELET_EXTRA_ARGS=--cloud-provider=aws --cloud-config=/etc/kubernetes/cloud-config.conf

然后我如下创建了这个cloud-config.conf-

[Global]
KubernetesClusterTag=kubernetes
KubernetesClusterID=kubernetes

我不确定该标签和ID指的是什么,但是当我运行以下命令时,我可以看到输出中提到clusterName为“ kubernetes”

kubeadm config view

那我确实执行了,

systemctl daemon-reload
system restart kubelet

2)然后,如前所述,我在kube-controller-manager.yaml和kube-apiserver.yaml中都添加了--cloud-provider=aws

3)我还在应用程序的manual-deployment.yaml中添加了以下注释

annotations:
  service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0

https://github.com/kenzanlabs/kubernetes-ci-cd/blob/master/applications/hello-kenzan/k8s/manual-deployment.yaml

现在,当我使用kubectl apply -f k8s/manual-deployment.yaml进行部署时,当我使用kubectl get po --all-namespaces检查时,pod本身并没有被创建

所以我尝试删除上面的步骤2,然后再次进行部署,现在成功创建了pod。但是当我执行<pending>

时,它仍显示EXTERNAL-IP的kubectl get svc

我什至将我的主节点和工作节点重命名为与EC2实例专用DNS相同:ip-10-118-6-35.ec2.internal和ip-10-118-11-225.ec2.internal,如在下面的帖子中,并重新配置了群集,但是仍然没有运气。 https://medium.com/jane-ai-engineering-blog/kubernetes-on-aws-6281e3a830fe(在“正确的节点名称”部分下)

此外,在我的EC2实例中,我可以看到附加了IAM角色,当看到其详细信息时,可以看到有8个策略应用于该角色。在其中一项策略中,我可以在下面看到此内容,还有许多其他操作,我没有在此处发布-

{
   "Action": "elasticloadbalancing:*",
   "Resource": "*",
   "Effect": "Allow"
}

如果缺少其他设置,我一无所知。请提出建议!

更新截至30/1

我执行了此博客中提到的以下其他步骤-https://blog.scottlowe.org/2018/09/28/setting-up-the-kubernetes-aws-cloud-provider/

1)将AWS标签添加到我所有的EC2实例(主节点和工作节点)中,例如“ kubernetes.io/cluster/kubernetes”和我的安全组

2)我没有在配置文件中手动添加apiServerExtraArgs,controllerManagerExtraArgs和nodeRegistration。但是我要做的是完全使用"sudo kubeadm reset -f"重置集群,然后将其添加到主节点和工作节点的kubeadm conf文件中-

Environment="KUBELET_EXTRA_ARGS=--cloud-provider=aws --cloud-config=/etc/kubernetes/cloud-config.conf

cloud-config.conf-

[Global]
KubernetesClusterTag=kubernetes.io/cluster/kubernetes
KubernetesClusterID=kubernetes

然后在主节点和工作节点中执行-

systemctl daemon-reload
system restart kubelet

3)现在,我在主节点中使用以下命令创建了集群

sudo kubeadm init --pod-network-cidr=192.168.1.0/16 --apiserver-advertise-address=10.118.6.35

4)然后,我能够将工作程序节点成功加入集群并部署了法兰绒CNI。

此后,获取节点显示为就绪状态。

需要注意的重要一点是/ etc / kubernetes / manifests路径中有kube-apiserver.yaml和kube-controller-manager.yaml文件。

当我在这两个yaml文件中添加--cloud-provider=aws时,都没有进行部署,也没有创建pod。因此,当我从kube-apiserver.yaml中删除标签--cloud-provider=aws时,部署和pod成功。

并且按照Matthew的要求,当我确实为kube-apiserver和kube-controller-manager修改了yaml时,两个pod都再次成功创建。但是由于未创建Pod,因此我仅从kube-apiserver.yaml中删除了标签。

我还用kubectl logs kube-controller-manager-ip-10-118-6-35.ec2.internal -n kube-system

检查了日志

但是我看不到任何异常或异常。我可以在最后一部分看到这一点-

IO130 19:14:17.444485    1 event.go:221] Event(v1.ObjectReference{Kind:"Deployment", Namespace:"default", Name:"hello-kenzan", UID:"c........", APIVersion:"apps/v1", ResourceVersion:"16212", FieldPath:""}): type: 'Normal' reason: 'SuccessfulCreate' Created pod: hello-kenzan-56686879-ghrhj

甚至尝试将以下注释添加到manual-deployment.yaml,但仍显示相同的<Pending>

service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0

更新为1/31

终于取得了一些进步!! 问题看起来像标签映射。在aws标签的键值映射中,我将键命名为KubernetesCluster,将值作为k8s,但是在配置文件中,我将键映射为值而不是值。

但是现在我可以在kube-controller-manager pod中看到以下日志-

` 1 aws.go:1041]构建AWS云提供商

1 aws.go:1007]在配置文件中未指定区域;查询AWS元数据服务

1控制器manager.go:208]构建控制器上下文时出错:无法初始化云提供程序:无法初始化云提供程序“ aws”:查找实例i-02dbgfghjf3e7时出错:“列出AWS实例时出错:\“ RequestError:发送请求失败\ n原因:发布https://ec2.us-east-1.amazonaws.com/:拨打tcp 54.239.28.176:443:输入/输出超时\“” `

最新更新

我没有使用* .amazonaws.com的代理,似乎现在已连接。我通过检查仅在以下日志中看到的日志来表示“似乎要连接”,而没有在添加此无代理之前发生的超时错误。我还确保控制器吊舱已通过我的编辑和保存重新启动。然后,我在下面看到日志-

` 1 aws.go:1041]构建AWS云提供商

1 aws.go:1007]在配置文件中未指定区域;查询AWS元数据服务 `

所以我认为我的控制器能够连接到AWS Cloud,对吗?但是不幸的是,当我再次创建服务时仍然得到<pending>:(

更新为01/02

为了简单起见,我创建了aws应用程序负载平衡器myservices,并获得了aws控制台中列出的DNS名称-internal-myservices-987070943.us-east-1.elb.amazonaws.com

我还创建了目标组,并在“说明”下显示在下面- 名称为myservices-LB,协议为HTTPS,端口为443,目标类型为实例,负载均衡器为myservices 在“目标”选项卡下,我可以看到注册的目标,其实例ID显示为i-02dbf9b3a7d9163e7,端口为443,以及其他详细信息。此实例ID是我的ec2实例,已将其配置为kubernetes集群的主节点。

现在,当我尝试直接使用URL访问LB DNS名称时-internal-myservices-987070943.us-east-1.elb.amazonaws.com/api/v1/namespace s / default / services 我收到“无法访问此网站”

如果我使用kubectl代理从主节点实例转发代理-地址0.0.0.0 --accept-hosts'。*' 然后,如果我直接访问我的主节点ip,如下所示,我可以浏览- 10.118.6.35:8001/api/v1/namespaces/default/services

是否可以使用直接AWS Loadbalancer DNS名称访问以NodePort或Loadbalancer Type部署的kubernetes服务? 我什至使用tracert internal-myservices-987070943.us-east-1.elb.amazonaws.com测试了连通性 我可以在18跳中成功到达目的地10.118.12.196

但是从我的ec2主节点实例来看,它不是跟踪。通常,我使用以下命令设置了代理-“导出{http,https,ftp} _proxy = http://proxy.ebiz.myorg.com:80” 而且我甚至可以访问外部URL。 这可能是个问题吗?

1 个答案:

答案 0 :(得分:0)

您在这里将两个单独的问题混为一谈。

  

它显示External-IP为,但是既然我创建了负载均衡器类型,为什么不创建ip?

假设它显示<pending>的时间足以让您撰写一个SO问题,这意味着您的controller-manager窗格没有命令行标志--cloud-provider=aws及其附带的内容--cloud-config=/the/path/here,和/或没有使这些Pod代表您创建负载均衡器的IAM实例角色。

但是,话虽如此:修复该问题将创建一个负载均衡器,并且不会使用您的现有 ALB。这是双重事实,因为type: LoadBalancer将创建经典的ELB,除非annotated to do otherwise

  

我创建了一个内部AWS弹性应用程序负载平衡器,并在AWS控制台中将其状态显示为活动。请注意,我使用jenkins作业创建了该ALB,并在该作业中指定了配置为Kubernetes主服务器的AWS EC2实例服务器。

最重要的是,通常您应该从轮换中省略大师,因为每个NodePort都暴露在集群中的每个工人上,而且几乎永远不会想要更多负载和更多流量流过群集中的主服务器。另外,除非另行配置,否则为服务提供字节服务的实际Pod不会在主服务器上运行,因此无论如何都必须重新路由网络流量。

此外,您想要将服务更改为type: NodePort,并将ALB目标组指向该端口

spec:
 ports:
  - port: 80
    targetPort: 80
 selector:
   app: hello-kenzan
   tier: hello-kenzan
 type: NodePort

如果愿意,您可以随意在该nodePort:项目中实际包含一个ports:节,或者可以将其保留为空白,并且kubernetes可以为其分配一个,很可能从顶部开始NodePort端口分配范围并开始工作。您可以通过kubectl get -o yaml svc hello-kenzan

找出它选择了哪一个