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

support kmesh manage in pod level #414

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

weli-l
Copy link
Contributor

@weli-l weli-l commented Jun 4, 2024

What type of PR is this?

What this PR does / why we need it:
support Kmesh manage in pod level
Which issue(s) this PR fixes:
Fixes #325

Special notes for your reviewer:

How to enable kmesh management at pod level

kubectl label pod xxx istio.io/dataplane-mode=kmesh

How to judge whether pod is managed by Kmesh

Due to the feature of the bypass, the impact of the bypass needs to be considered comprehensively

  • Label priority(From high to low)

    • kmesh.net/bypass=enabled
    • istio.io/dataplane-mode=Kmesh(pod)
    • istio.io/dataplane-mode=Kmesh(namespace)
  • Annotation priority(From high to low,and it is only be used for user to judge whether pod is managed by kmesh)

    • kmesh.net/bypass=enabled
    • kmesh.net/redirection=enabled(pod)
    • kmesh.net/redirection=enabled(namespace)

Does this PR introduce a user-facing change?:


@kmesh-bot kmesh-bot requested review from kwb0523 and nlgwcy June 4, 2024 11:10
@kmesh-bot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign hzxuzhonghu for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found 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

Copy link
Member

@hzxuzhonghu hzxuzhonghu left a comment

Choose a reason for hiding this comment

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

Please add test coverage

@codecov-commenter
Copy link

codecov-commenter commented Jun 5, 2024

Codecov Report

Attention: Patch coverage is 0% with 180 lines in your changes missing coverage. Please review.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Flag Coverage Δ
unittests 36.02% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
pkg/controller/bypass/bypass_controller.go 0.00% <0.00%> (ø)
pkg/controller/controller.go 0.00% <0.00%> (ø)
pkg/controller/netns/netns.go 0.00% <0.00%> (ø)
pkg/controller/manage/kmesh_manage.go 0.00% <0.00%> (ø)

`{"metadata":{"annotations":{"%s":null}}}`,
KmeshAnnotation,
))
annotationAddPatch = []byte(fmt.Sprintf(
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this variable is a fixed value, you can use the constant

)

var (
FS embed.FS
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this variable have to be a global variable?

Copy link
Member

Choose a reason for hiding this comment

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

move to controller if this is not shared with other components

@weli-l weli-l force-pushed the dev/kmesh_manage branch 2 times, most recently from f467e82 to 18eeb4d Compare June 7, 2024 03:43
@@ -75,7 +76,17 @@ func (c *Controller) Start() error {
if c.client.workloadController != nil {
c.client.workloadController.Processor.Sm = secertManager
}
clientset, err := utils.GetK8sclient()
Copy link
Contributor

Choose a reason for hiding this comment

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

Can the clientset be reused with bypass? and does the kmesh manager logic need to be moved before the bypass logic.

@weli-l weli-l force-pushed the dev/kmesh_manage branch 3 times, most recently from 74928c3 to 8d6d1ba Compare June 12, 2024 02:16
@kmesh-bot kmesh-bot added size/L and removed size/XL labels Jun 12, 2024
@@ -22,6 +22,7 @@ import (
"kmesh.net/kmesh/pkg/bpf"
"kmesh.net/kmesh/pkg/constants"
"kmesh.net/kmesh/pkg/controller/bypass"
kmeshmanage "kmesh.net/kmesh/pkg/controller/kmesh"
Copy link
Member

Choose a reason for hiding this comment

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

It's weired to name a sub package as kmesh


if _, ok := namespace.Labels[LabelSelectorKmesh]; ok {
log.Infof("namespace %s has label 'istio.io/dataplane-mode=Kmesh', skipping further processing", pod.GetNamespace())
return
Copy link
Member

Choose a reason for hiding this comment

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

Use constant defined above to replace 'istio.io/dataplane-mode=Kmesh'

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Use constant defined above to replace 'istio.io/dataplane-mode=Kmesh'

defined

nspath, _ := ns.GetNSpath(pod)

if err := handleKmeshManage(nspath, true); err != nil {
log.Errorf("failed to enable kmesh manage")
Copy link
Member

Choose a reason for hiding this comment

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

Use Kmesh instead of kmesh

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Use Kmesh instead of kmesh

Yes, I have modified


if _, ok := namespace.Labels[LabelSelectorKmesh]; ok {
log.Infof("namespace %s has label 'istio.io/dataplane-mode=Kmesh', skipping further processing", pod.GetNamespace())
return
Copy link
Member

Choose a reason for hiding this comment

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

ditto

}

if err := patchKmeshAnnotation(client, pod, false); err != nil {
log.Errorf("failed to add kmesh annotation, err is %v", err)
Copy link
Member

Choose a reason for hiding this comment

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

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ditto

done

}
},
}); err != nil {
return fmt.Errorf("error adding event handler to podInformer: %v", err)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return fmt.Errorf("error adding event handler to podInformer: %v", err)
return fmt.Errorf("failed to add event handler to podInformer: %v", err)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

return pod.ObjectMeta.DeletionTimestamp != nil
}

func patchKmeshAnnotation(client kubernetes.Interface, pod *corev1.Pod, oper bool) error {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
func patchKmeshAnnotation(client kubernetes.Interface, pod *corev1.Pod, oper bool) error {
func patchKmeshAnnotation(client kubernetes.Interface, pod *corev1.Pod, op bool) error {

oper is weired

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oper is weired

I have modified

return true
}

// copied from istio/cni/pkg/nodeagent/podcgroupns.go
Copy link
Member

Choose a reason for hiding this comment

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

It's better to add url

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's better to add url

done

@weli-l weli-l force-pushed the dev/kmesh_manage branch 3 times, most recently from f8d84ee to c193e52 Compare June 13, 2024 13:40
log.Errorf("expected *corev1.Pod but got %T", obj)
return
}
namespace, err := client.CoreV1().Namespaces().Get(context.TODO(), pod.GetNamespace(), metav1.GetOptions{})
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic of checking if ns has a label can be abstracted into a common function; used by AddFunc and DeleteFunc

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This logic of checking if ns has a label can be abstracted into a common function; used by AddFunc and DeleteFunc

I have deleted this logic, because it may affect the data in bpf map kmesh_manage when kmesh restart

* daemon to enable/disable kmesh manage
*/
simip := net.ParseIP("0.0.0.1")
port := 929
Copy link
Contributor

Choose a reason for hiding this comment

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

magic numbers

Copy link
Contributor Author

Choose a reason for hiding this comment

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

magic numbers

I have defined constant

return err
}
errno, ok := err.(syscall.Errno)
if ok && errno == 115 { // -EINPROGRESS, Operation now in progress
Copy link
Contributor

Choose a reason for hiding this comment

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

magic numbers

Copy link
Contributor Author

Choose a reason for hiding this comment

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

magic numbers

I have defined the constant

KmeshAnnotation = "kmesh.net/redirection"
)

func StartKmeshManageController(client kubernetes.Interface) error {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
func StartKmeshManageController(client kubernetes.Interface) error {
func NewKmeshManageController(client kubernetes.Interface) error {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

stopChan := make(chan struct{})
nodeName := os.Getenv("NODE_NAME")

informerFactory := informers.NewSharedInformerFactoryWithOptions(client, DefaultInformerSyncPeriod,
Copy link
Member

Choose a reason for hiding this comment

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

nit: we can share one factory with bypass

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nit: we can share one factory with bypass

I think it is not necessary to share the factory, because labels selector in factory is different

Copy link
Member

Choose a reason for hiding this comment

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

I donot think this is a blocking issue, file an issue though after merged, we should optimize, otherwise, it will broing double load to k8s apiserver from all nodes. Keep in mind, in a cluster, the node number can be more than 5000

SpecialIpForKmesh = "0.0.0.1"
EnableKmeshPort = 929
DisableKmeshPort = 930
LabelSelectorKmesh = "istio.io/dataplane-mode=Kmesh"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
LabelSelectorKmesh = "istio.io/dataplane-mode=Kmesh"
KmeshManagedLabelSelector = constants.DataPlaneModeLabel + DataPlaneModeKmesh

SpecialIpForKmesh = "0.0.0.1"
EnableKmeshPort = 929
DisableKmeshPort = 930
LabelSelectorKmesh = "istio.io/dataplane-mode=Kmesh"
Copy link
Member

Choose a reason for hiding this comment

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

BTW, i think we not only support Kmesh, but also kmesh. We are case insensitive, so i donot think this label selector suits here

}))

informerFactory.Start(wait.NeverStop)
informerFactory.WaitForCacheSync(wait.NeverStop)
Copy link
Member

Choose a reason for hiding this comment

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

This is blocking, so let;s move this to a Run method, so we can run all the controller's Run async without waiting each other.

@weli-l weli-l force-pushed the dev/kmesh_manage branch 3 times, most recently from 88d1a65 to ef91742 Compare June 24, 2024 08:23
Copy link
Member

@hzxuzhonghu hzxuzhonghu left a comment

Choose a reason for hiding this comment

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

Please add some tests

EnableKmeshPort = 929
DisableKmeshPort = 930
LabelSelectorKmesh = constants.DataPlaneModeLabel + "=" + constants.DataPlaneModeKmesh
KmeshAnnotation = "kmesh.net/redirection"
Copy link
Member

Choose a reason for hiding this comment

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

KmeshRedirectionAnnotation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

KmeshRedirectionAnnotation

done

return pod.ObjectMeta.DeletionTimestamp != nil
}

func patchKmeshAnnotation(client kubernetes.Interface, pod *corev1.Pod, op bool) error {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: donot use op, i would rather split into two functions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nit: donot use op, i would rather split into two functions

splited

@weli-l weli-l force-pushed the dev/kmesh_manage branch 3 times, most recently from 2365a44 to 98a37f8 Compare June 27, 2024 12:30
@kmesh-bot kmesh-bot added size/XL and removed size/L labels Jun 28, 2024
@@ -88,7 +79,7 @@ func StartByPassController(client kubernetes.Interface) error {
return
}

nspath, _ := getnspath(pod)
nspath, _ := ns.GetNSpath(pod)
Copy link
Member

Choose a reason for hiding this comment

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

nit: replace GetNSpath with GetPodNsPath

SpecialIpForKmesh = "0.0.0.1"
EnableKmeshPort = 929
DisableKmeshPort = 930
LabelSelectorKmesh = constants.DataPlaneModeLabel + "=" + constants.DataPlaneModeKmesh
Copy link
Member

Choose a reason for hiding this comment

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

As i said, we must support both kmesh and Kmesh, should be case insensitive to be consistent with previous behavior


const (
DefaultInformerSyncPeriod = 30 * time.Second
SpecialIpForKmesh = "0.0.0.1"
Copy link
Member

Choose a reason for hiding this comment

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

Please check with that from CNI, we use 0.0.0.2 now for ipv4 and for v6 ::2

We can reuse TriggerControlCommand function


done := make(chan struct{})
go func() {
wg.Wait()
Copy link
Member

Choose a reason for hiding this comment

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

I think you should not wait in a go routine

Comment on lines +101 to +109
select {
case <-done:
mu.Lock()
assert.True(t, enabled, "expected handleKmeshManage to be called for enabling Kmesh manage")
assert.False(t, disabled, "expected handleKmeshManage not to be called for disabling Kmesh manage")
mu.Unlock()
case <-time.After(1 * time.Second):
t.Fatalf("timed out waiting for handleKmeshManage to be called")
}
Copy link
Member

Choose a reason for hiding this comment

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

wrap this with a checker function, so you canreuse it below

podLister := controller.informerFactory.Core().V1().Pods().Lister()
pods, err := podLister.Pods(pod.Namespace).List(labels.Everything())
assert.NoError(t, err)
assert.Equal(t, 1, len(pods), "expected One Pod in the lister after addition")
Copy link
Member

Choose a reason for hiding this comment

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

This can be not tested in out case, this is the implement detail of k8s

mu.Lock()
enabled = false
disabled = false
mu.Unlock()
Copy link
Member

Choose a reason for hiding this comment

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

Not sure i understand why you need to lock them. Any race?

mu.Unlock()

wg.Add(1)
err = client.CoreV1().Pods("default").Delete(context.TODO(), "test-pod", metav1.DeleteOptions{})
Copy link
Member

Choose a reason for hiding this comment

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

can you add a case of removing the label first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pod granularity management
8 participants