mirror of https://github.com/k3s-io/k3s
Merge pull request #5814 from vmarmol/net-host
Add HostNetworking container option to API.pull/6/head
commit
f1872d36cf
|
@ -300,6 +300,7 @@ type ContainerPort struct {
|
|||
// in a pod must have a unique name.
|
||||
Name string `json:"name,omitempty"`
|
||||
// Optional: If specified, this must be a valid port number, 0 < x < 65536.
|
||||
// If HostNetwork is specified, this must match ContainerPort.
|
||||
HostPort int `json:"hostPort,omitempty"`
|
||||
// Required: This must be a valid port number, 0 < x < 65536.
|
||||
ContainerPort int `json:"containerPort"`
|
||||
|
@ -601,6 +602,10 @@ type PodSpec struct {
|
|||
// the the scheduler simply schedules this pod onto that host, assuming that it fits
|
||||
// resource requirements.
|
||||
Host string `json:"host,omitempty"`
|
||||
// Uses the host's network namespace. If this option is set, the ports that will be
|
||||
// used must be specified.
|
||||
// Optional: Default to false.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty"`
|
||||
}
|
||||
|
||||
// PodStatus represents information about the status of a pod. Status may trail the actual
|
||||
|
|
|
@ -602,6 +602,7 @@ func init() {
|
|||
}
|
||||
out.DNSPolicy = DNSPolicy(in.DNSPolicy)
|
||||
out.Version = "v1beta2"
|
||||
out.HostNetwork = in.HostNetwork
|
||||
return nil
|
||||
},
|
||||
func(in *ContainerManifest, out *newer.PodSpec, s conversion.Scope) error {
|
||||
|
@ -615,6 +616,7 @@ func init() {
|
|||
return err
|
||||
}
|
||||
out.DNSPolicy = newer.DNSPolicy(in.DNSPolicy)
|
||||
out.HostNetwork = in.HostNetwork
|
||||
return nil
|
||||
},
|
||||
|
||||
|
|
|
@ -69,11 +69,17 @@ func init() {
|
|||
if obj.DNSPolicy == "" {
|
||||
obj.DNSPolicy = DNSClusterFirst
|
||||
}
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
}
|
||||
},
|
||||
func(obj *ContainerManifest) {
|
||||
if obj.DNSPolicy == "" {
|
||||
obj.DNSPolicy = DNSClusterFirst
|
||||
}
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
}
|
||||
},
|
||||
func(obj *LivenessProbe) {
|
||||
if obj.TimeoutSeconds == 0 {
|
||||
|
@ -102,3 +108,14 @@ func init() {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
// With host networking default all host ports to container ports.
|
||||
func defaultHostNetworkPorts(containers *[]Container) {
|
||||
for i := range *containers {
|
||||
for j := range (*containers)[i].Ports {
|
||||
if (*containers)[i].Ports[j].HostPort == 0 {
|
||||
(*containers)[i].Ports[j].HostPort = (*containers)[i].Ports[j].ContainerPort
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,3 +80,28 @@ func TestSetDefaultNamespace(t *testing.T) {
|
|||
t.Errorf("Expected phase %v, got %v", current.NamespaceActive, s2.Status.Phase)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultContainerManifestHostNetwork(t *testing.T) {
|
||||
portNum := 8080
|
||||
s := current.ContainerManifest{}
|
||||
s.HostNetwork = true
|
||||
s.Containers = []current.Container{
|
||||
{
|
||||
Ports: []current.ContainerPort{
|
||||
{
|
||||
ContainerPort: portNum,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
obj2 := roundTrip(t, runtime.Object(¤t.ContainerManifestList{
|
||||
Items: []current.ContainerManifest{s},
|
||||
}))
|
||||
sList2 := obj2.(*current.ContainerManifestList)
|
||||
s2 := sList2.Items[0]
|
||||
|
||||
hostPortNum := s2.Containers[0].Ports[0].HostPort
|
||||
if hostPortNum != portNum {
|
||||
t.Errorf("Expected container port to be defaulted, was made %d instead of %d", hostPortNum, portNum)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,10 @@ type ContainerManifest struct {
|
|||
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
|
||||
// Optional: Set DNS policy. Defaults to "ClusterFirst"
|
||||
DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty" description:"DNS policy for containers within the pod; one of 'ClusterFirst' or 'Default'"`
|
||||
// Uses the host's network namespace. If this option is set, the ports that will be
|
||||
// used must be specified.
|
||||
// Optional: Default to false.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty" description:"host networking requested for this pod"`
|
||||
}
|
||||
|
||||
// ContainerManifestList is used to communicate container manifests to kubelet.
|
||||
|
@ -194,6 +198,7 @@ type ContainerPort struct {
|
|||
// in a pod must have a unique name.
|
||||
Name string `json:"name,omitempty" description:"name for the port that can be referred to by services; must be a DNS_LABEL and unique without the pod"`
|
||||
// Optional: If specified, this must be a valid port number, 0 < x < 65536.
|
||||
// If HostNetwork is specified, this must match ContainerPort.
|
||||
HostPort int `json:"hostPort,omitempty" description:"number of port to expose on the host; most containers do not need this"`
|
||||
// Required: This must be a valid port number, 0 < x < 65536.
|
||||
ContainerPort int `json:"containerPort" description:"number of port to expose on the pod's IP address"`
|
||||
|
@ -1111,6 +1116,10 @@ type PodSpec struct {
|
|||
// the the scheduler simply schedules this pod onto that host, assuming that it fits
|
||||
// resource requirements.
|
||||
Host string `json:"host,omitempty" description:"host requested for this pod"`
|
||||
// Uses the host's network namespace. If this option is set, the ports that will be
|
||||
// used must be specified.
|
||||
// Optional: Default to false.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty" description:"host networking requested for this pod"`
|
||||
}
|
||||
|
||||
// List holds a list of objects, which may not be known by the server.
|
||||
|
|
|
@ -462,6 +462,7 @@ func init() {
|
|||
}
|
||||
out.DNSPolicy = DNSPolicy(in.DNSPolicy)
|
||||
out.Version = "v1beta2"
|
||||
out.HostNetwork = in.HostNetwork
|
||||
return nil
|
||||
},
|
||||
func(in *ContainerManifest, out *newer.PodSpec, s conversion.Scope) error {
|
||||
|
@ -475,6 +476,7 @@ func init() {
|
|||
return err
|
||||
}
|
||||
out.DNSPolicy = newer.DNSPolicy(in.DNSPolicy)
|
||||
out.HostNetwork = in.HostNetwork
|
||||
return nil
|
||||
},
|
||||
|
||||
|
|
|
@ -71,11 +71,17 @@ func init() {
|
|||
if obj.DNSPolicy == "" {
|
||||
obj.DNSPolicy = DNSClusterFirst
|
||||
}
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
}
|
||||
},
|
||||
func(obj *ContainerManifest) {
|
||||
if obj.DNSPolicy == "" {
|
||||
obj.DNSPolicy = DNSClusterFirst
|
||||
}
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
}
|
||||
},
|
||||
func(obj *LivenessProbe) {
|
||||
if obj.TimeoutSeconds == 0 {
|
||||
|
@ -104,3 +110,14 @@ func init() {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
// With host networking default all container ports to host ports.
|
||||
func defaultHostNetworkPorts(containers *[]Container) {
|
||||
for i := range *containers {
|
||||
for j := range (*containers)[i].Ports {
|
||||
if (*containers)[i].Ports[j].HostPort == 0 {
|
||||
(*containers)[i].Ports[j].HostPort = (*containers)[i].Ports[j].ContainerPort
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,3 +80,28 @@ func TestSetDefaultNamespace(t *testing.T) {
|
|||
t.Errorf("Expected phase %v, got %v", current.NamespaceActive, s2.Status.Phase)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultContainerManifestHostNetwork(t *testing.T) {
|
||||
portNum := 8080
|
||||
s := current.ContainerManifest{}
|
||||
s.HostNetwork = true
|
||||
s.Containers = []current.Container{
|
||||
{
|
||||
Ports: []current.ContainerPort{
|
||||
{
|
||||
ContainerPort: portNum,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
obj2 := roundTrip(t, runtime.Object(¤t.ContainerManifestList{
|
||||
Items: []current.ContainerManifest{s},
|
||||
}))
|
||||
sList2 := obj2.(*current.ContainerManifestList)
|
||||
s2 := sList2.Items[0]
|
||||
|
||||
hostPortNum := s2.Containers[0].Ports[0].HostPort
|
||||
if hostPortNum != portNum {
|
||||
t.Errorf("Expected container port to be defaulted, was made %d instead of %d", hostPortNum, portNum)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,7 @@ type ContainerPort struct {
|
|||
// in a pod must have a unique name.
|
||||
Name string `json:"name,omitempty" description:"name for the port that can be referred to by services; must be a DNS_LABEL and unique without the pod"`
|
||||
// Optional: If specified, this must be a valid port number, 0 < x < 65536.
|
||||
// If HostNetwork is specified, this must match ContainerPort.
|
||||
HostPort int `json:"hostPort,omitempty" description:"number of port to expose on the host; most containers do not need this"`
|
||||
// Required: This must be a valid port number, 0 < x < 65536.
|
||||
ContainerPort int `json:"containerPort" description:"number of port to expose on the pod's IP address"`
|
||||
|
@ -1133,6 +1134,10 @@ type ContainerManifest struct {
|
|||
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
|
||||
// Optional: Set DNS policy. Defaults to "ClusterFirst"
|
||||
DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty" description:"DNS policy for containers within the pod; one of 'ClusterFirst' or 'Default'"`
|
||||
// Uses the host's network namespace. If this option is set, the ports that will be
|
||||
// used must be specified.
|
||||
// Optional: Default to false.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty" description:"host networking requested for this pod"`
|
||||
}
|
||||
|
||||
// ContainerManifestList is used to communicate container manifests to kubelet.
|
||||
|
@ -1173,6 +1178,10 @@ type PodSpec struct {
|
|||
// the the scheduler simply schedules this pod onto that host, assuming that it fits
|
||||
// resource requirements.
|
||||
Host string `json:"host,omitempty" description:"host requested for this pod"`
|
||||
// Uses the host's network namespace. If this option is set, the ports that will be
|
||||
// used must be specified.
|
||||
// Optional: Default to false.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty" description:"host networking requested for this pod"`
|
||||
}
|
||||
|
||||
// List holds a list of objects, which may not be known by the server.
|
||||
|
|
|
@ -67,6 +67,9 @@ func init() {
|
|||
if obj.RestartPolicy == "" {
|
||||
obj.RestartPolicy = RestartPolicyAlways
|
||||
}
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
}
|
||||
},
|
||||
func(obj *Probe) {
|
||||
if obj.TimeoutSeconds == 0 {
|
||||
|
@ -101,3 +104,14 @@ func init() {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
// With host networking default all container ports to host ports.
|
||||
func defaultHostNetworkPorts(containers *[]Container) {
|
||||
for i := range *containers {
|
||||
for j := range (*containers)[i].Ports {
|
||||
if (*containers)[i].Ports[j].HostPort == 0 {
|
||||
(*containers)[i].Ports[j].HostPort = (*containers)[i].Ports[j].ContainerPort
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,3 +97,29 @@ func TestSetDefaultNamespace(t *testing.T) {
|
|||
t.Errorf("Expected phase %v, got %v", current.NamespaceActive, s2.Status.Phase)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultPodSpecHostNetwork(t *testing.T) {
|
||||
portNum := 8080
|
||||
s := current.PodSpec{}
|
||||
s.HostNetwork = true
|
||||
s.Containers = []current.Container{
|
||||
{
|
||||
Ports: []current.ContainerPort{
|
||||
{
|
||||
ContainerPort: portNum,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
pod := ¤t.Pod{
|
||||
Spec: s,
|
||||
}
|
||||
obj2 := roundTrip(t, runtime.Object(pod))
|
||||
pod2 := obj2.(*current.Pod)
|
||||
s2 := pod2.Spec
|
||||
|
||||
hostPortNum := s2.Containers[0].Ports[0].HostPort
|
||||
if hostPortNum != portNum {
|
||||
t.Errorf("Expected container port to be defaulted, was made %d instead of %d", hostPortNum, portNum)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -312,6 +312,7 @@ type ContainerPort struct {
|
|||
// in a pod must have a unique name.
|
||||
Name string `json:"name,omitempty" description:"name for the port that can be referred to by services; must be a DNS_LABEL and unique without the pod"`
|
||||
// Optional: If specified, this must be a valid port number, 0 < x < 65536.
|
||||
// If HostNetwork is specified, this must match ContainerPort.
|
||||
HostPort int `json:"hostPort,omitempty" description:"number of port to expose on the host; most containers do not need this"`
|
||||
// Required: This must be a valid port number, 0 < x < 65536.
|
||||
ContainerPort int `json:"containerPort" description:"number of port to expose on the pod's IP address"`
|
||||
|
@ -602,6 +603,10 @@ type PodSpec struct {
|
|||
// the the scheduler simply schedules this pod onto that host, assuming that it fits
|
||||
// resource requirements.
|
||||
Host string `json:"host,omitempty" description:"host requested for this pod"`
|
||||
// Uses the host's network namespace. If this option is set, the ports that will be
|
||||
// used must be specified.
|
||||
// Optional: Default to false.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty" description:"host networking requested for this pod"`
|
||||
}
|
||||
|
||||
// PodStatus represents information about the status of a pod. Status may trail the actual
|
||||
|
|
|
@ -641,6 +641,20 @@ func validateDNSPolicy(dnsPolicy *api.DNSPolicy) errs.ValidationErrorList {
|
|||
return allErrors
|
||||
}
|
||||
|
||||
func validateHostNetwork(hostNetwork bool, containers []api.Container) errs.ValidationErrorList {
|
||||
allErrors := errs.ValidationErrorList{}
|
||||
if hostNetwork {
|
||||
for _, container := range containers {
|
||||
for _, port := range container.Ports {
|
||||
if port.HostPort != port.ContainerPort {
|
||||
allErrors = append(allErrors, errs.NewFieldInvalid("containerPort", port.ContainerPort, "containerPort must match hostPort if hostNetwork is set to true"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
// ValidatePod tests if required fields in the pod are set.
|
||||
func ValidatePod(pod *api.Pod) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
|
@ -663,6 +677,7 @@ func ValidatePodSpec(spec *api.PodSpec) errs.ValidationErrorList {
|
|||
allErrs = append(allErrs, validateRestartPolicy(&spec.RestartPolicy).Prefix("restartPolicy")...)
|
||||
allErrs = append(allErrs, validateDNSPolicy(&spec.DNSPolicy).Prefix("dnsPolicy")...)
|
||||
allErrs = append(allErrs, ValidateLabels(spec.NodeSelector, "nodeSelector")...)
|
||||
allErrs = append(allErrs, validateHostNetwork(spec.HostNetwork, spec.Containers).Prefix("hostNetwork")...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
|
|
@ -712,6 +712,16 @@ func TestValidatePodSpec(t *testing.T) {
|
|||
Host: "foobar",
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
{ // Populate HostNetwork.
|
||||
Containers: []api.Container{
|
||||
{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", Ports: []api.ContainerPort{
|
||||
{HostPort: 8080, ContainerPort: 8080, Protocol: "TCP"}},
|
||||
},
|
||||
},
|
||||
HostNetwork: true,
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
}
|
||||
for i := range successCases {
|
||||
if errs := ValidatePodSpec(&successCases[i]); len(errs) != 0 {
|
||||
|
@ -745,6 +755,16 @@ func TestValidatePodSpec(t *testing.T) {
|
|||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
"with hostNetwork hostPort not equal to containerPort": {
|
||||
Containers: []api.Container{
|
||||
{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", Ports: []api.ContainerPort{
|
||||
{HostPort: 8080, ContainerPort: 2600, Protocol: "TCP"}},
|
||||
},
|
||||
},
|
||||
HostNetwork: true,
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
}
|
||||
for k, v := range failureCases {
|
||||
if errs := ValidatePodSpec(&v); len(errs) == 0 {
|
||||
|
|
Loading…
Reference in New Issue