Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CSM NEG support. #827

Merged
merged 4 commits into from
Aug 29, 2019
Merged

Add CSM NEG support. #827

merged 4 commits into from
Aug 29, 2019

Conversation

cadmuxe
Copy link
Member

@cadmuxe cadmuxe commented Aug 15, 2019

No description provided.

@k8s-ci-robot
Copy link
Contributor

Welcome @cadmuxe!

It looks like this is your first PR to kubernetes/ingress-gce 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/ingress-gce has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Aug 15, 2019
@k8s-ci-robot
Copy link
Contributor

Hi @cadmuxe. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Aug 15, 2019
@cadmuxe
Copy link
Member Author

cadmuxe commented Aug 15, 2019

/cc @freehan

@cadmuxe
Copy link
Member Author

cadmuxe commented Aug 15, 2019

This is a draft, need add tests.

@rramkumar1
Copy link
Contributor

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Aug 16, 2019
@freehan freehan self-assigned this Aug 16, 2019
cmd/glbc/main.go Outdated
@@ -197,7 +205,7 @@ func runControllers(ctx *ingctx.ControllerContext) {
fwc := firewalls.NewFirewallController(ctx, flags.F.NodePortRanges.Values())

// TODO: Refactor NEG to use cloud mocks so ctx.Cloud can be referenced within NewController.
negController := neg.NewController(negtypes.NewAdapter(ctx.Cloud), ctx, lbc.Translator, ctx.ClusterNamer, flags.F.ResyncPeriod, flags.F.NegGCPeriod, neg.NegSyncerType(flags.F.NegSyncerType), flags.F.EnableReadinessReflector)
negController := neg.NewController(negtypes.NewAdapter(ctx.Cloud), ctx, lbc.Translator, ctx.ClusterNamer, flags.F.ResyncPeriod, flags.F.NegGCPeriod, neg.NegSyncerType(flags.F.NegSyncerType), flags.F.EnableReadinessReflector, flags.F.EnableCSM)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactor neg.NewController to take controller context

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed offline, will keep this by now.

import "encoding/json"

// PortSubsetNegMap is the mapping between service port:subset to NEG name
type PortSubsetNegMap map[string]string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you probably need map[string]map[string]string?


"cloud.google.com/neg-status": `{         
  "network_endpoint_groups": {              
       "v1": {                 
                    "9080": "somehash-default-reviews-v1-9080",               
         }              
        "v2": {
                   "9080": "somehash-default-reviews-v2-9080",               
          }
}




Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

// NEGWithSubset returns the gce neg name based on the service namespace, name
// target port and Istio:DestinationRule subset if provided. NEG naming convention:
//
// {prefix}{version}-{clusterid}-{namespace}-{name}-{service port}[-subset]-{hash}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{prefix}{version}-{clusterid}-{namespace}-{name}-{subset}-{service port}-{hash}?

Copy link
Contributor

@freehan freehan Aug 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider spliting the namer NegForServicePort and NegForDestinationRule

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

Address code review feedback.
change the neg status to map[string]map[string]string
@@ -544,3 +656,53 @@ func getIngressServicesFromStore(store cache.Store, svc *apiv1.Service) (ings []
}
return
}

func castToDestinationRule(drus *unstructured.Unstructured) (*istioV1alpha3.DestinationRule, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment

return servicePortMap
}

func getDestinationRulesFromStore(store cache.Store, svc *apiv1.Service) (drs map[namespaceNamePair]*istioV1alpha3.DestinationRule) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment

// syncTracker tracks the latest time that service and endpoint changes are processed
syncTracker utils.TimeTracker

// reflector handles NEG readiness gate and conditions for pods in NEG.
reflector readiness.Reflector
}

type namespaceNamePair struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use types.NamespacedName, no need to have a new structure

}
targetServiceNamespace := drUnstructed.GetNamespace()
drHost := dr.Host
if strings.Contains(dr.Host, ".") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add an example here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

klog.Errorf("Failed to convert informer object to DestinationRule")
return
}
targetServiceNamespace := drus.GetNamespace()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a util function for parsing hosts in DestinationRule. Return namespace/name of service

shared the util function with getDestinationRulesFromStore

Subset string

// Subset label, should set together with Subset.
SubsetLabels string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use map[string]string?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay. Got it. If it is simpler, then just do it this way.

if c.enableCSM {
// Find all destination rules that using this service.
destinationRules := getDestinationRulesFromStore(c.destinationRuleLister, service)
servicePorts := gatherPortMappingFromService(service)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, this only creates NEGs per each (destination rule subsets X service ports)

If c.enableCSM, you also need to create NEGs for each service port. Except for kube-system services and kubernetes.default service

destinationRules := getDestinationRulesFromStore(c.destinationRuleLister, service)
servicePorts := gatherPortMappingFromService(service)
for destinationRuleNN, destinationRule := range destinationRules {
destinationRulePortInfoMap := negtypes.NewPortInfoMapWithDestinationRule(namespace, name, servicePorts, c.namer, true, destinationRule)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to validate if the destinationRule has unique subset names. If not, error out.

I confirmed with the Istio team that they want user to create unique subset names but did not enforce it with validation.

@@ -422,6 +472,44 @@ func (c *Controller) syncNegStatusAnnotation(namespace, name string, portMap neg
return err
}

func (c *Controller) syncDestinationRuleNegStatusAnnotation(namespace, destinationRuleName string, portmap negtypes.PortInfoMap) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment

@@ -463,6 +551,30 @@ func (c *Controller) enqueueIngressServices(ing *v1beta1.Ingress) {
}
}

func (c *Controller) enqueueDestinationRule(obj interface{}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a comment

@@ -101,6 +108,15 @@ func NewControllerContext(
healthChecks: make(map[string]func() error),
}

if config.EnableCSM && dynamicClient != nil {
destrinationGVR := schema.GroupVersionResource{Group: "networking.istio.io", Version: "v1alpha3", Resource: "destinationrules"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add a WARNING here.
The destinationRule group version is v1alpha3 in group networking.istio.io. Need to update as istio API graduates.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks

destinationRules := getDestinationRulesFromStore(c.destinationRuleLister, service)
// Fill all service ports into portinfomap
servicePorts := gatherPortMappingFromService(service)
for destinationRuleNN, destinationRule := range destinationRules {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: s/destinationRuleNN/namespacedName ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

type PortSubsetNegMap map[string]map[string]string

type DestinationRuleNEGStatus struct {
NetworkEndpointGroups PortSubsetNegMap `json:"network_endpoint_groups,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean move the comment from above to here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}
}
// If no destionationRules for this service, create one NEG for every ports.
if len(destinationRules) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to create it anyway. Remove the if statement here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

@@ -324,9 +377,15 @@ func (c *Controller) processService(key string) error {
if err = c.syncNegStatusAnnotation(namespace, name, portInfoMap); err != nil {
return err
}
// Merge destinationRule related NEG after the Service NEGStatus Sync, we don't want DR related NEG status go into service.
if err := portInfoMap.Merge(csmPortInfoMap); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider flag gating this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not needed

…reated.

more comments
update the gke-self-managed.sh script to support CSM mode.
Copy link
Contributor

@freehan freehan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 29, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cadmuxe, freehan

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 29, 2019
@k8s-ci-robot k8s-ci-robot merged commit d793ae8 into kubernetes:master Aug 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants