mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 12:43:23 +00:00
Merge pull request #28239 from ApsOps/kubectl-expose-headless-svc
Automatic merge from submit-queue Add a flag for `kubectl expose`to set ClusterIP and allow headless services - Use `--cluster-ip=None` to create a headless service - Fixes #10294
This commit is contained in:
commit
44ea855713
@ -58,6 +58,7 @@ cloud-provider
|
||||
cluster-cidr
|
||||
cluster-dns
|
||||
cluster-domain
|
||||
cluster-ip
|
||||
cluster-name
|
||||
cluster-tag
|
||||
cluster-monitor-period
|
||||
|
@ -120,6 +120,7 @@ func NewCmdExposeService(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmd.Flags().String("overrides", "", "An inline JSON override for the generated object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field.")
|
||||
cmd.Flags().String("name", "", "The name for the newly created object.")
|
||||
cmd.Flags().String("session-affinity", "", "If non-empty, set the session affinity for the service to this; legal values: 'None', 'ClientIP'")
|
||||
cmd.Flags().String("cluster-ip", "", "ClusterIP to be assigned to the service. Leave empty to auto-allocate, or set to 'None' to create a headless service.")
|
||||
|
||||
usage := "Filename, directory, or URL to a file identifying the resource to expose a service"
|
||||
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
|
||||
|
@ -198,6 +198,70 @@ func TestRunExposeService(t *testing.T) {
|
||||
},
|
||||
status: 200,
|
||||
},
|
||||
{
|
||||
name: "expose-service-cluster-ip",
|
||||
args: []string{"service", "baz"},
|
||||
ns: "test",
|
||||
calls: map[string]string{
|
||||
"GET": "/namespaces/test/services/baz",
|
||||
"POST": "/namespaces/test/services",
|
||||
},
|
||||
input: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"app": "go"},
|
||||
},
|
||||
},
|
||||
flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "cluster-ip": "10.10.10.10", "dry-run": "true"},
|
||||
output: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "", Labels: map[string]string{"svc": "test"}},
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
Port: 14,
|
||||
TargetPort: intstr.FromInt(14),
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{"func": "stream"},
|
||||
ClusterIP: "10.10.10.10",
|
||||
},
|
||||
},
|
||||
expected: "service \"foo\" exposed",
|
||||
status: 200,
|
||||
},
|
||||
{
|
||||
name: "expose-headless-service",
|
||||
args: []string{"service", "baz"},
|
||||
ns: "test",
|
||||
calls: map[string]string{
|
||||
"GET": "/namespaces/test/services/baz",
|
||||
"POST": "/namespaces/test/services",
|
||||
},
|
||||
input: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"app": "go"},
|
||||
},
|
||||
},
|
||||
flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "cluster-ip": "None", "dry-run": "true"},
|
||||
output: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "", Labels: map[string]string{"svc": "test"}},
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
Port: 14,
|
||||
TargetPort: intstr.FromInt(14),
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{"func": "stream"},
|
||||
ClusterIP: api.ClusterIPNone,
|
||||
},
|
||||
},
|
||||
expected: "service \"foo\" exposed",
|
||||
status: 200,
|
||||
},
|
||||
{
|
||||
name: "expose-from-file",
|
||||
args: []string{},
|
||||
|
@ -72,6 +72,7 @@ func paramNames() []GeneratorParam {
|
||||
{"target-port", false},
|
||||
{"port-name", false},
|
||||
{"session-affinity", false},
|
||||
{"cluster-ip", false},
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,5 +226,12 @@ func generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
||||
return nil, fmt.Errorf("unknown session affinity: %s", params["session-affinity"])
|
||||
}
|
||||
}
|
||||
if len(params["cluster-ip"]) != 0 {
|
||||
if params["cluster-ip"] == "None" {
|
||||
service.Spec.ClusterIP = api.ClusterIPNone
|
||||
} else {
|
||||
service.Spec.ClusterIP = params["cluster-ip"]
|
||||
}
|
||||
}
|
||||
return &service, nil
|
||||
}
|
||||
|
@ -303,6 +303,66 @@ func TestGenerateService(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
generator: ServiceGeneratorV2{},
|
||||
params: map[string]interface{}{
|
||||
"selector": "foo=bar,baz=blah",
|
||||
"name": "test",
|
||||
"port": "80",
|
||||
"protocol": "TCP",
|
||||
"container-port": "1234",
|
||||
"cluster-ip": "10.10.10.10",
|
||||
},
|
||||
expected: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "test",
|
||||
},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
"baz": "blah",
|
||||
},
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Port: 80,
|
||||
Protocol: "TCP",
|
||||
TargetPort: intstr.FromInt(1234),
|
||||
},
|
||||
},
|
||||
ClusterIP: "10.10.10.10",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
generator: ServiceGeneratorV2{},
|
||||
params: map[string]interface{}{
|
||||
"selector": "foo=bar,baz=blah",
|
||||
"name": "test",
|
||||
"port": "80",
|
||||
"protocol": "TCP",
|
||||
"container-port": "1234",
|
||||
"cluster-ip": "None",
|
||||
},
|
||||
expected: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "test",
|
||||
},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
"baz": "blah",
|
||||
},
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Port: 80,
|
||||
Protocol: "TCP",
|
||||
TargetPort: intstr.FromInt(1234),
|
||||
},
|
||||
},
|
||||
ClusterIP: api.ClusterIPNone,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
generator: ServiceGeneratorV1{},
|
||||
params: map[string]interface{}{
|
||||
|
Loading…
Reference in New Issue
Block a user