-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
refactor container packages and support mounts #313
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: BenTheElder 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 |
dd61969
to
3e723af
Compare
3e723af
to
0e68020
Compare
usage: kind: Config
apiVersion: kind.sigs.k8s.io/v1alpha2
nodes:
- role: control-plane
mounts:
- container_path: /kind-source
host_path: /Users/bentheelder/go/src/sigs.k8s.io/kind
readonly: true Things to consider for the future (but I think I'd rather not do in the first PR to keep the diff down):
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems good @BenTheElder
i just need to do some quick testing for Mounts *[]cri.Mount
pkg/cluster/config/types.go
Outdated
@@ -54,6 +56,9 @@ type Node struct { | |||
// KubeadmConfigPatchesJSON6902 are applied to the generated kubeadm config | |||
// as patchesJson6902 to `kustomize build` | |||
KubeadmConfigPatchesJSON6902 []kustomize.PatchJSON6902 | |||
// Mounts describes additional mount points for the node container | |||
// These may be used to EG bind a hostpath | |||
Mounts []cri.Mount `json:"mounts,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is a weird side effect when marshaling slices with omitempty, that is already a problem in k/k, kubeadm, cluster-api. i think the safe route was to use Mounts *[]cri.Mount
json:"mounts,omitempty"` but i need to check this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
package main
import (
"fmt"
"log"
"sigs.k8s.io/yaml"
)
type A struct {
Mounts []string `json:"mounts,omitempty"`
}
func main() {
a := A{Mounts: []string{}} // <--------- [*]
fmt.Println(a.Mounts, a.Mounts == nil)
b, err := yaml.Marshal(a)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
c := A{}
err = yaml.Unmarshal(b, &c)
if err != nil {
log.Fatal(err)
}
fmt.Println(c.Mounts, c.Mounts == nil)
}
[] false
{}
[] true
[*]
so this problem is relevant only if we assign a meaning to the "empty" value of Mounts
and what is the "empty" value (is it a empty slice or nil
) and if the user is marhaling the kind Config.
if there is no default value this problem is not relevant, but just referencing this here so that we don't have this problem for the future kind config:
kubernetes/kubeadm#1358
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was it? https://play.golang.org/p/EOfDnWThpdj
Your comment hadn't loaded
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can treat empty and nil the same, the node already has mounts (tmps and one docker volume) we're just adding additional mounts here (we should clarify that in the docs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, yes. i know the existing mounts are essential for the setup to work.
so in a way we already have default mounts and these mounts are extra mounts 🤔
would it be clearer naming this ExtraMounts
and including some more notes in the field comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think that might make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renamed it 👍
}{ | ||
Alias: (*Alias)(m), | ||
} | ||
if err := json.Unmarshal(data, &aux); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ideally everything "unmarshall" should be using DisallowUnknownFields
but i leave this to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, trying to figure out if we should just do that inline or if there's a way to plumb through the option 🙄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to tackle this in a follow up, but before the next release, I'm not sure how this will interact with the rest of the decoding logic.
i'm still hopeful for getting support for that upstream in API machinery.
// If set, the mount needs SELinux relabeling. | ||
SelinuxRelabel bool `protobuf:"varint,4,opt,name=selinux_relabel,json=selinuxRelabel,proto3" json:"selinux_relabel,omitempty"` | ||
// Requested propagation mode. | ||
Propagation MountPropagation `protobuf:"varint,5,opt,name=propagation,proto3,enum=runtime.v1alpha2.MountPropagation" json:"propagation,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like these variable names need "adjustments" upstream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'm not sure if that's actually an option. I think it would probably be fine for us to match the types closely but use a different on-disk format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we still have the option to shim with getters and setters. this means some extra boiler plate.
this fixes both the field names and hides the upstream config.
create a CRI package, with types (Mount related only for now) copied from upstream
- this allows us to avoid stability concerns, if necessary we can provide our own conversion
i need to know the roadmap for CRI in terms of do they have plans to remove or rename fields, because if there are upstream API changes our local type can end up invalid and we will have to break kind users because these fields are public in the kind config.
i will leave this to you at this point if you want us to proceed, but comments from others would be appreciated too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CRI is pretty stable at this point, this type hasn't actually changed in years.
But our local type can be a shim just closely matching their type, if they diverge we will translate. As long as we are not using the client this isn't an issue.
Also for the types we expose here for on disk purposes, what they are capable of is unlikely to change. They cannot remove support for these fields without breaking Kubernetes majorly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is nice for now that they are literally the same definition, but if it diverges slightly (EG they add a field or break the type up) we can keep our changes compatible and translate.
The things we will need to expose in config like Mounts, DNS, ... those seem unlikely to change significantly.
More complex types like entire containers, those seem stable too but we don't need to expose those on disk anyhow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I adjusted our names, strangely the proto json tags were already camelCase but not the actual json tags 🤷♂️
Where possible these match user facing API fields in Kubernetes APIs
pkg/container/cri/types.go
Outdated
MountPropagation_PROPAGATION_HOST_TO_CONTAINER MountPropagation = 1 | ||
// Mounts get propagated from the host to the container and from the | ||
// container to the host ("rshared" in Linux). | ||
MountPropagation_PROPAGATION_BIDIRECTIONAL MountPropagation = 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i've missed if we are adding a linter exception for this file/package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We did, it's a separate commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, saw it.
/assign @munnerz |
per discussion in the meeting I renamed to camel case and switched to the core/v1 VolumeMount strings for the mount enum. I think we can remove the lint exception now as well. |
b863d2a
to
045244b
Compare
Re-enabled golint and fixed remaining lints. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as per the discussions today during the kind meeting LGTM.
/lgtm
/hold
// If set, the mount is read-only. | ||
Readonly bool `protobuf:"varint,3,opt,name=readonly,proto3,json=readOnly,proto3" json:"readOnly,omitempty"` | ||
// If set, the mount needs SELinux relabeling. | ||
SelinuxRelabel bool `protobuf:"varint,4,opt,name=selinux_relabel,json=selinuxRelabel,proto3" json:"selinuxRelabel,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one is not actually exposed directly in kubernetes volumes AFAICT, but from previous test-infra containerization work I remember control over this being necessary on some systems.
we should consider if we want to expose this or not, imho we can just document it well and expect the user to do the right thing, support for this shouldn't go anywhere in CRI
/hold cancel Will follow up with considerations on EG relative paths / other UX improvements. In the meantime this config is now possible: kind: Config
apiVersion: kind.sigs.k8s.io/v1alpha2
nodes:
- role: control-plane
extraMounts:
- containerPath: /kind-source
hostPath: /Users/bentheelder/go/src/sigs.k8s.io/kind
readOnly: true |
* Print build version * Fix version * Bump golang image * Fix version * Fix version
type Mount upstreamcri.Mount
and still support thisdocker.Run
, refactor docker.Run to take functional optionsThis is an alternative to #302 where we vendor CRI
cc @neolit123