Initial state transfer - #2
Conversation
930f39d to
72793fb
Compare
|
Added a null/socat transport to demonstrate swapping out. Could be useful in cases where the transfer utility provides encryption too. I did this with a load balancer. I believe using a rsync/socat/route combo wouldn't work due to route limitations like we hit when working with pvc migrate, but I'll confirm later... There might be need for a compatibility matrix... I'd like to add rclone to the mix as well, but I need to sit down and learn some about rclone. |
6eacd67 to
a503346
Compare
| ) | ||
|
|
||
| // Quiesce applications on source cluster | ||
| func QuiesceApplications(cfg *rest.Config, ns string) error { |
There was a problem hiding this comment.
I wired up this example to use the scale subresource instead of patching the objects on each GVR separately , if it helps you in anyway to make this modular https://gist.github.com/alaypatel07/4c1494f70b3cebad1f9534c1c0fde639#file-scale-go-L151.
I would have strongly urged to do this way but I think it will not work with jobs and deploymentconfig is doubtful so it is kind of up to you.
There was a problem hiding this comment.
Update 1: I verified, deploymentconfigs works with generic approach in the gist
There was a problem hiding this comment.
@alaypatel07 thank you for investigating. I was talking to Shawn late yesterday and I think it would be nice if we had an interface for quiesce as well. We could have simple, scaler, and / or others. It may be beneficial to have multiple options like with the other interfaces; here I could even see potential for perhaps running multiple quiesce options on one cluster if we become able to handle different classes of applications better or worse.
For now I was looking to mimic what MTC does so I can do a quiesced data migration so the thought here is less well formed.
0b85235 to
18cafdb
Compare
|
Added rclone transfer and a README.md with a compatibility matrix. |
1b37e06 to
21de238
Compare
shawn-hurley
left a comment
There was a problem hiding this comment.
Looking good, the implementation looks right, I think we should take a second on the interfaces though WDYT?
| var labels = map[string]string{"app": "crane2"} | ||
|
|
||
| type Transfer interface { | ||
| SetSource(*rest.Config) |
There was a problem hiding this comment.
I wonder if instead of this, should we create an initializer that creates a Transfer object, but the sources are set in stone? same with PVC/Endpoint/Transport...
I wonder if a builder pattern with an options struct might be an interesting UX here?
There was a problem hiding this comment.
That might make sense. I'll admit to not being 100% certain on what the best/simplest way to build up an entire transfer would be.
|
|
||
| func createLoadBalancerService(c client.Client, r *LoadBalancerEndpoint, t Transfer) error { | ||
| serviceSelector := labels | ||
| serviceSelector["pvc"] = t.PVC().Name |
There was a problem hiding this comment.
since the label selector will only work when pods have this label. If the name of PVC is larger than 63 chars, this would be an invalid label. We would have to make sure we get the labels truncated or hashed.
| } | ||
|
|
||
| //FIXME. Seems to take a moment, probably something better to do than wait 5 seconds | ||
| time.Sleep(5 * time.Second) |
There was a problem hiding this comment.
probably split this into two methods, CreateEndpoint simply tries to create the service. The other method, ValidateEndpoint checks if the valid status is present? Once the valid status is populated, we can call the r.SetHostname and r.SetPort
| return err | ||
| } | ||
|
|
||
| //FIXME. Seems to take a moment, probably something better to do than wait 5 seconds |
There was a problem hiding this comment.
you can use a poller, it will be slightly better. https://github.com/kubernetes/kubernetes/blob/2453f07e933a6d2ac0be1eb35061a2154ccce5b8/test/e2e/framework/util.go#L269
| rcloneConfigMap := &v1.ConfigMap{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Namespace: r.PVC().Namespace, | ||
| Name: rcloneConfigPrefix + r.PVC().Name, |
There was a problem hiding this comment.
you probably want to be using something more narrow-scoped for not running into shared config with same named PVC accross two namespaces.
DVM uses md5hash(rcloneConfigPrefix + r.PVC().Name + r.PVC().Namespace), we got bugs in DVM where PVC name was the same across two namespaces and the config was shared and failed DVM
There was a problem hiding this comment.
I don't fully understand, but sure, if this produces something unique, it works for me. That's all I was after.
|
|
||
| err := createRcloneServerConfig(c, r) | ||
| if err != nil { | ||
| return err |
There was a problem hiding this comment.
might want to check if this error is IsAlreadyExists(err)
If the config exists the right things to do is to update/patch with the desired configuration
|
|
||
| func (r *RcloneTransfer) createTransferServer(c client.Client) error { | ||
| deploymentLabels := labels | ||
| deploymentLabels["pvc"] = r.PVC().Name |
There was a problem hiding this comment.
same as the previous comment about PVC names greater than 63 chars
| return err | ||
| } | ||
|
|
||
| r.SetHostname(route.Spec.Host) |
There was a problem hiding this comment.
Probably wanna check if the route is admitted before using the hostname. https://github.com/konveyor/mig-controller/blob/219b97f79d92613dcb032cd5ccf54174b90955b8/pkg/controller/directvolumemigration/rsync.go#L777-L780
alaypatel07
left a comment
There was a problem hiding this comment.
I wonder if we could have subpackages for each major component. The pattern I have seen is something like this:
state_transfer/endpoint/*
state_transfer/transport/*
state_transfer/transfer/*
and then each package has an interface.go which would declare the interface, other files can be implementation or helpers for implementation.
|
@jmontleon I am sorry I clicked the "Ready for review" button by mistake. |
8973fbb to
0c72d75
Compare
0c72d75 to
1240609
Compare
1240609 to
5529834
Compare
|
@alaypatel07 @shawn-hurley i would vote merge from here so we can start working in earnest. I feel like the client scheme setup and stuff is creating a couple unnecessary functions but maybe one of you can lend some wizardry after it's merged. |
|
Sounds good to me on the merge. |
I haven't fixed a lot of the stuff you mentioned here. I'll parse them out into Issues so we don't forget. They make sense. Just not sure it should hold up getting code in so we can start improving. |
|
I think that's all of them. |
shawn-hurley
left a comment
There was a problem hiding this comment.
I agree on merging and starting to work in parallel
Not ready for merge. Publishing a PR for visibility and to allow feedback.
https://github.com/jmontleon/crane-test makes use of this library as a simple test.
It provides interfaces for a transfer method such as rsync (potentiall rclone and others), a transport like stunnel, and endpoint such as route and loadbalancer
I've run tests with: