Skip to content

Commit

Permalink
Merge pull request #855 from vdhanan/imds
Browse files Browse the repository at this point in the history
instance metadata issue fix
  • Loading branch information
wongma7 committed Apr 28, 2021
2 parents 2ab89fd + 0b61573 commit 5c8f1d8
Show file tree
Hide file tree
Showing 220 changed files with 22,467 additions and 32 deletions.
2 changes: 2 additions & 0 deletions Makefile
Expand Up @@ -142,8 +142,10 @@ verify-vendor:
generate-kustomize: bin/helm
cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/clusterrole-attacher.yaml > ../../deploy/kubernetes/base/clusterrole-attacher.yaml
cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/clusterrole-provisioner.yaml > ../../deploy/kubernetes/base/clusterrole-provisioner.yaml
cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/clusterrole-csi-node.yaml > ../../deploy/kubernetes/base/clusterrole-csi-node.yaml
cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/clusterrolebinding-attacher.yaml > ../../deploy/kubernetes/base/clusterrolebinding-attacher.yaml
cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/clusterrolebinding-provisioner.yaml > ../../deploy/kubernetes/base/clusterrolebinding-provisioner.yaml
cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/clusterrolebinding-csi-node.yaml > ../../deploy/kubernetes/base/clusterrolebinding-csi-node.yaml
cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/controller.yaml -f ../../deploy/kubernetes/values/controller.yaml > ../../deploy/kubernetes/base/controller.yaml
cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/csidriver.yaml > ../../deploy/kubernetes/base/csidriver.yaml
cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/node.yaml -f ../../deploy/kubernetes/values/controller.yaml > ../../deploy/kubernetes/base/node.yaml
Expand Down
11 changes: 11 additions & 0 deletions charts/aws-ebs-csi-driver/templates/clusterrole-csi-node.yaml
@@ -0,0 +1,11 @@
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ebs-csi-node-role
labels:
{{- include "aws-ebs-csi-driver.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get"]
@@ -0,0 +1,15 @@
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ebs-csi-node-binding
labels:
{{- include "aws-ebs-csi-driver.labels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: {{ .Values.serviceAccount.node.name }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: ebs-external-attacher-role
apiGroup: rbac.authorization.k8s.io
4 changes: 4 additions & 0 deletions charts/aws-ebs-csi-driver/templates/node.yaml
Expand Up @@ -65,6 +65,10 @@ spec:
env:
- name: CSI_ENDPOINT
value: unix:/csi/csi.sock
- name: CSI_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
{{- if .Values.proxy.http_proxy }}
- name: HTTP_PROXY
value: {{ .Values.proxy.http_proxy | quote }}
Expand Down
12 changes: 12 additions & 0 deletions deploy/kubernetes/base/clusterrole-csi-node.yaml
@@ -0,0 +1,12 @@
---
# Source: aws-ebs-csi-driver/templates/clusterrole-csi-node.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ebs-csi-node-role
labels:
app.kubernetes.io/name: aws-ebs-csi-driver
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get"]
16 changes: 16 additions & 0 deletions deploy/kubernetes/base/clusterrolebinding-csi-node.yaml
@@ -0,0 +1,16 @@
---
# Source: aws-ebs-csi-driver/templates/clusterrolebinding-csi-node.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ebs-csi-node-binding
labels:
app.kubernetes.io/name: aws-ebs-csi-driver
subjects:
- kind: ServiceAccount
name: ebs-csi-node-sa
namespace: default
roleRef:
kind: ClusterRole
name: ebs-external-attacher-role
apiGroup: rbac.authorization.k8s.io
4 changes: 4 additions & 0 deletions deploy/kubernetes/base/node.yaml
Expand Up @@ -51,6 +51,10 @@ spec:
env:
- name: CSI_ENDPOINT
value: unix:/csi/csi.sock
- name: CSI_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- name: kubelet-dir
mountPath: /var/lib/kubelet
Expand Down
74 changes: 70 additions & 4 deletions pkg/cloud/metadata.go
Expand Up @@ -17,14 +17,20 @@ limitations under the License.
package cloud

import (
"context"
"fmt"
"os"
"regexp"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/klog"
)

Expand Down Expand Up @@ -69,13 +75,73 @@ func (m *Metadata) GetOutpostArn() arn.ARN {
func NewMetadata() (MetadataService, error) {
sess := session.Must(session.NewSession(&aws.Config{}))
svc := ec2metadata.New(sess)
return NewMetadataService(svc)
// creates the in-cluster config
config, err := rest.InClusterConfig()
if err != nil && !svc.Available() {
return nil, err
}
// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil && !svc.Available() {
return nil, err
}
metadataService, err := NewMetadataService(svc, clientset)
if err != nil {
return nil, fmt.Errorf("error getting information from metadata service or node object: %w", err)
}
return metadataService, err
}

// NewMetadataService returns a new MetadataServiceImplementation.
func NewMetadataService(svc EC2Metadata) (MetadataService, error) {
func NewMetadataService(svc EC2Metadata, clientset kubernetes.Interface) (MetadataService, error) {
if !svc.Available() {
return nil, fmt.Errorf("EC2 instance metadata is not available")
klog.Warningf("EC2 instance metadata is not available")
nodeName := os.Getenv("CSI_NODE_NAME")
if nodeName == "" {
return nil, fmt.Errorf("instance metadata is unavailable and CSI_NODE_NAME env var not set")
}

// get node with k8s API
node, err := clientset.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
if err != nil {
return nil, err
}

providerID := node.Spec.ProviderID
if providerID == "" {
return nil, fmt.Errorf("node providerID empty, cannot parse")
}

awsRegionRegex := "([a-z]{2}(-gov)?)-(central|(north|south)?(east|west)?)-[0-9]"
awsAvailabilityZoneRegex := "([a-z]{2}(-gov)?)-(central|(north|south)?(east|west)?)-[0-9][a-z]"
awsInstanceIDRegex := "i-[a-z0-9]+$"

re := regexp.MustCompile(awsRegionRegex)
region := re.FindString(providerID)
if region == "" {
return nil, fmt.Errorf("did not find aws region in node providerID string")
}

re = regexp.MustCompile(awsAvailabilityZoneRegex)
availabilityZone := re.FindString(providerID)
if availabilityZone == "" {
return nil, fmt.Errorf("did not find aws availability zone in node providerID string")
}

re = regexp.MustCompile(awsInstanceIDRegex)
instanceID := re.FindString(providerID)
if instanceID == "" {
return nil, fmt.Errorf("did not find aws instance ID in node providerID string")
}

metadata := Metadata{
InstanceID: instanceID,
InstanceType: "", // we have no way to find this, so we leave it empty
Region: region,
AvailabilityZone: availabilityZone,
}

return &metadata, nil
}

doc, err := svc.GetInstanceIdentityDocument()
Expand All @@ -96,7 +162,7 @@ func NewMetadataService(svc EC2Metadata) (MetadataService, error) {
}

if len(doc.AvailabilityZone) == 0 {
return nil, fmt.Errorf("could not get valid EC2 availavility zone")
return nil, fmt.Errorf("could not get valid EC2 availability zone")
}

outpostArn, err := svc.GetMetadata(OutpostArnEndpoint)
Expand Down

0 comments on commit 5c8f1d8

Please sign in to comment.