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

[JUJU-2847] Open port per unit4sidecar #15225

Merged
merged 14 commits into from
Mar 3, 2023

Conversation

ycliuhw
Copy link
Member

@ycliuhw ycliuhw commented Feb 24, 2023

This PR changes the application (vs machine) level opened ports to be grouped per unit for sidecar applications:

  • Allow open-port to happen from any unit, and Juju would open the ports (in the K8s service definition) that are the union of all ports that any unit has opened. So if unit/1 opened port 8080 and unit/2 opened port 4000, we'd tell K8s to open both. This would be unusual but supported.
  • Kind of the opposite for close-port: Juju would only close the port in the K8s service definition once all units had asked for that port to be closed.
  • Remove the check for is-leader.
  • Add model upgrades steps and model migration strategy to deal with the port ranges changed from application scope (3.1.0) to unit scope.

Checklist

  • Code style: imports ordered, good names, simple structure, etc
  • Comments saying why design decisions were made
  • Go unit tests, with comments saying what you're testing
  • Integration tests, with comments saying what you're testing
  • doc.go added or updated in changed packages

QA steps

juju deploy prometheus-k8s --trust
Located charm "prometheus-k8s" in charm-hub, revision 103
Deploying "prometheus-k8s" from charm-hub charm "prometheus-k8s", revision 103 in channel stable on ubuntu@20.04/stable

juju scale-application prometheus-k8s 2

juju exec --unit prometheus-k8s/0 -- open-port 3000

juju exec --unit prometheus-k8s/1 -- open-port 3000

juju exec --unit prometheus-k8s/1 -- open-port 3001

juju exec --unit prometheus-k8s/0 -- opened-ports
3000/tcp

juju exec --unit prometheus-k8s/1 -- opened-ports
3000/tcp
3001/tcp

mkubectl -nt1 get service/prometheus-k8s -o json | jq '.spec.ports'
[
  {
    "name": "prometheus-k8s",
    "port": 9090,
    "protocol": "TCP",
    "targetPort": 9090
  },
  {
    "name": "juju-3000-tcp",
    "port": 3000,
    "protocol": "TCP",
    "targetPort": 3000
  },
  {
    "name": "juju-3001-tcp",
    "port": 3001,
    "protocol": "TCP",
    "targetPort": 3001
  }
]

juju exec --unit prometheus-k8s/1 -- close-port 3001

mkubectl -nt1 get service/prometheus-k8s -o json | jq '.spec.ports'
[
  {
    "name": "prometheus-k8s",
    "port": 9090,
    "protocol": "TCP",
    "targetPort": 9090
  },
  {
    "name": "juju-3000-tcp",
    "port": 3000,
    "protocol": "TCP",
    "targetPort": 3000
  }
]

juju exec --unit prometheus-k8s/1 -- close-port 3000

mkubectl -nt1 get service/prometheus-k8s -o json | jq '.spec.ports'
[
  {
    "name": "prometheus-k8s",
    "port": 9090,
    "protocol": "TCP",
    "targetPort": 9090
  },
  {
    "name": "juju-3000-tcp",
    "port": 3000,
    "protocol": "TCP",
    "targetPort": 3000
  }
]

juju exec --unit prometheus-k8s/0 -- close-port 3000

mkubectl -nt1 get service/prometheus-k8s -o json | jq '.spec.ports'
[
  {
    "name": "prometheus-k8s",
    "port": 9090,
    "protocol": "TCP",
    "targetPort": 9090
  }
]
  • upgrade controller from 3.1.0 -> 3.1.1 (application opened ports should be copied across all the units.)
juju status --relations --color --storage -m k1:t1
Model  Controller  Cloud/Region        Version  SLA          Timestamp
t1     k1          microk8s/localhost  3.1.0    unsupported  21:54:23+11:00

App             Version  Status  Scale  Charm           Channel  Rev  Address        Exposed  Message
prometheus-k8s  2.33.5   active      2  prometheus-k8s  stable   103  10.152.183.82  no

Unit               Workload  Agent  Address      Ports  Message
prometheus-k8s/0*  active    idle   10.1.97.236
prometheus-k8s/1   active    idle   10.1.97.238

Relation provider                Requirer                         Interface         Type  Message
prometheus-k8s:prometheus-peers  prometheus-k8s:prometheus-peers  prometheus_peers  peer

Storage Unit      Storage ID  Type        Pool        Mountpoint                        Size    Status    Message
prometheus-k8s/0  database/0  filesystem  kubernetes  /var/lib/juju/storage/database/0  1.0GiB  attached  Successfully provisioned volume pvc-f1549b23-7f2d-44c2-8bbb-87834316a
715
prometheus-k8s/1  database/1  filesystem  kubernetes  /var/lib/juju/storage/database/0  1.0GiB  attached  Successfully provisioned volume pvc-d31094c3-3deb-46c0-bdf8-179fa04b1
371

juju exec --unit prometheus-k8s/1 -- close-port 3000
this unit is not the leader

juju exec --unit prometheus-k8s/0 -- opened-ports
3000/tcp

juju exec --unit prometheus-k8s/1 -- opened-ports
3000/tcp

juju:PRIMARY> db.openedPorts.find().pretty()
{
	"_id" : "d83ce064-96e9-4521-82f6-bae42cd69d53:a#prometheus-k8s",
	"model-uuid" : "d83ce064-96e9-4521-82f6-bae42cd69d53",
	"application-name" : "prometheus-k8s",
	"port-ranges" : {
		"" : [
			{
				"fromport" : 3000,
				"toport" : 3000,
				"protocol" : "tcp"
			}
		]
	},
	"txn-revno" : 2
}

juju upgrade-controller -c k1 --agent-version 3.1.1
best version:
    3.1.1
started upgrade to 3.1.1

juju upgrade-model -m t1
best version:
    3.1.1
started upgrade to 3.1.1

juju:PRIMARY> db.openedPorts.find().pretty()
{
	"_id" : "d83ce064-96e9-4521-82f6-bae42cd69d53:a#prometheus-k8s",
	"model-uuid" : "d83ce064-96e9-4521-82f6-bae42cd69d53",
	"application-name" : "prometheus-k8s",
	"port-ranges" : {

	},
	"txn-revno" : NumberLong(3),
	"unit-port-ranges" : {
		"prometheus-k8s/0" : {
			"" : [
				{
					"fromport" : 3000,
					"toport" : 3000,
					"protocol" : "tcp"
				}
			]
		},
		"prometheus-k8s/1" : {
			"" : [
				{
					"fromport" : 3000,
					"toport" : 3000,
					"protocol" : "tcp"
				}
			]
		}
	}
}

juju exec --unit prometheus-k8s/0 -- opened-ports
3000/tcp

juju exec --unit prometheus-k8s/1 -- opened-ports
3000/tcp

juju exec --unit prometheus-k8s/1 -- close-port 3000

juju:PRIMARY> db.openedPorts.find().pretty()
{
	"_id" : "3899fbb4-bc47-43d6-82af-bf35dc626ac2:a#prometheus-k8s",
	"model-uuid" : "3899fbb4-bc47-43d6-82af-bf35dc626ac2",
	"application-name" : "prometheus-k8s",
	"port-ranges" : {

	},
	"txn-revno" : NumberLong(4),
	"unit-port-ranges" : {
		"prometheus-k8s/1" : {

		},
		"prometheus-k8s/0" : {
			"" : [
				{
					"fromport" : 3000,
					"toport" : 3000,
					"protocol" : "tcp"
				}
			]
		}
	}
}

juju exec --unit prometheus-k8s/0 -- opened-ports
3000/tcp

juju exec --unit prometheus-k8s/1 -- opened-ports

Documentation changes

Now, sidecar and machine applications are same for open[/close]-port

Bug reference

https://bugs.launchpad.net/juju/+bug/2007334

go.mod Outdated Show resolved Hide resolved
@ycliuhw ycliuhw changed the title Open port per unit4sidecar [JUJU-2847] Open port per unit4sidecar Feb 24, 2023
@ycliuhw ycliuhw force-pushed the open-port-per-unit4sidecar branch 3 times, most recently from ab387dd to 14c9dbd Compare February 27, 2023 05:19
state/migration_import.go Outdated Show resolved Hide resolved
@ycliuhw ycliuhw force-pushed the open-port-per-unit4sidecar branch 2 times, most recently from 01ba750 to 86dd3f8 Compare February 28, 2023 06:14
Copy link
Member

@wallyworld wallyworld left a 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 discuss naming things in the state layer. The methods and entities used can be confusing - eg we are modelling ports opened by a unit but referring to application ports. We have an application ports doc but we can have methods on it that real just with units right? I'm also confused about the additions to the all watcher.

api/agent/uniter/uniter.go Outdated Show resolved Hide resolved
apiserver/facades/agent/uniter/uniter.go Outdated Show resolved Hide resolved
apiserver/facades/agent/uniter/uniter.go Outdated Show resolved Hide resolved
apiserver/facades/agent/uniter/uniter_test.go Outdated Show resolved Hide resolved
state/allwatcher.go Show resolved Hide resolved
worker/uniter/runner/context/ports_test.go Show resolved Hide resolved
state/machine_ports.go Show resolved Hide resolved
state/unit.go Outdated Show resolved Hide resolved
state/unit.go Outdated Show resolved Hide resolved
@ycliuhw ycliuhw force-pushed the open-port-per-unit4sidecar branch 3 times, most recently from 735adc3 to 1df2780 Compare March 1, 2023 07:01
@ycliuhw ycliuhw requested a review from wallyworld March 1, 2023 22:27
Copy link
Member

@wallyworld wallyworld left a comment

Choose a reason for hiding this comment

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

Thank you for all great changes. One issue though - I think we are missing the uniter facade bump since we are replacing a method.

api/agent/uniter/uniter.go Outdated Show resolved Hide resolved
}

// OpenedPortRangesByEndpoint returns the port ranges opened by the unit.
func (u *UniterAPI) OpenedPortRangesByEndpoint() (params.OpenPortRangesByEndpointResults, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Don't we need to bump the facade version?

Copy link
Member Author

Choose a reason for hiding this comment

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

This method is new and we keep the existing method OpenedApplicationPortRangesByEndpoint.
So it should be ok without a facade version bump?

Results: make([]params.OpenPortRangesByEndpointResult, 1),
}

authTag := u.auth.GetAuthTag()
Copy link
Member

Choose a reason for hiding this comment

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

Aren't we missing a permission check like accessUnit() here?

Copy link
Member Author

Choose a reason for hiding this comment

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

This facade method does not have an arg, we are using the authTag to access its own unit.
So I think we are ok here.

Comment on lines +17 to +19
peers:
ring:
interface: cockroachdb
Copy link
Member

Choose a reason for hiding this comment

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

Is this needed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, we do. This was added for the new sidecar test.#15225 (comment)

state/unit_ports.go Outdated Show resolved Hide resolved
@wallyworld
Copy link
Member

With the changes, would be worth testing again:

  • older model on newer controller
  • migration

@ycliuhw ycliuhw force-pushed the open-port-per-unit4sidecar branch 2 times, most recently from d5d2924 to 6c0aa8f Compare March 2, 2023 03:28
@ycliuhw
Copy link
Member Author

ycliuhw commented Mar 2, 2023

/build

@ycliuhw ycliuhw force-pushed the open-port-per-unit4sidecar branch 2 times, most recently from be1d5bd to 9b813e9 Compare March 3, 2023 04:31
@ycliuhw ycliuhw force-pushed the open-port-per-unit4sidecar branch from 9b813e9 to 06e8c21 Compare March 3, 2023 04:48
@ycliuhw ycliuhw force-pushed the open-port-per-unit4sidecar branch from 06e8c21 to 10de1fe Compare March 3, 2023 05:16
@ycliuhw
Copy link
Member Author

ycliuhw commented Mar 3, 2023

With the changes, would be worth testing again:

  • older model on newer controller
  • migration

Works fine to upgrade from 3.1.0 to 3.1.1.
But I can't fully test model migration because these two bugs:

Copy link
Member

@wallyworld wallyworld left a comment

Choose a reason for hiding this comment

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

I think we should move the app ports to each unit, not copy.
Every unit will typically open the same port in say a start hook. This will be how it works till we add --app later.

Id: doc.DocID,
Update: bson.D{
{Name: "$set", Value: bson.D{
{Name: "port-ranges", Value: doc.PortRanges},
Copy link
Member

Choose a reason for hiding this comment

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

Do we need "port-ranges"? We are just treating the ports as being the same for all units right?
So we copy the ports to all units and leave any application ports empty till next cycle.

Copy link
Member Author

Choose a reason for hiding this comment

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

doc.PortRanges has already set to nil.

upgrades/steps_311.go Outdated Show resolved Hide resolved
@ycliuhw ycliuhw force-pushed the open-port-per-unit4sidecar branch from ff24f25 to 37e9de9 Compare March 3, 2023 05:57
@ycliuhw ycliuhw force-pushed the open-port-per-unit4sidecar branch from 37e9de9 to d79bab1 Compare March 3, 2023 08:03
@ycliuhw
Copy link
Member Author

ycliuhw commented Mar 3, 2023

/merge

@jujubot jujubot merged commit 7dfbd61 into juju:3.1 Mar 3, 2023
@wallyworld wallyworld mentioned this pull request Mar 7, 2023
jujubot added a commit that referenced this pull request Mar 7, 2023
#15263

Merge 3.1

#15220 [from manadart/2.9-revert-omit-match](4c1503b)
#15201 [from toabctl/develop-aws-new-regions](125496e)
#15196 [from hmlanigan/fix-refresh-resource-no-char…](344de3f)
#15224 [from wallyworld/handle-terminated-hooks](c1618b5)
#15238 [from hmlanigan/fix-local-refresh-with-resou…](7b871e7)
#15247 [from hmlanigan/new-merge-from-2.9](7587d44)
#15246 [from nvinuesa/juju-2951](3272e11)
#15248 [from manadart/2.9-into-3.0](91165d3)
#15241 [from hmlanigan/update-refresh-help](f0e4b1b)
#15252 [from hmlanigan/merge-from-2.9](992f040)
#15253 [from hpidcock/fix-install-step](95c2db7)
#15254 [from wallyworld/merge-3.0-20230303](ce6a255)
#15225 [from ycliuhw/open-port-per-unit4sidecar](7dfbd61)
#15256 [from jack-w-shaw/JUJU-2899_fix_bug_in_ec2_t…](1b2c08f)
#15257 [from jack-w-shaw/2.9-into-3.0](bfaa9ed)
#15228 [from jack-w-shaw/JUJU-2897_back_ssh_allowli…](18349be)
#15261 [from wallyworld/secret-consumer-watcher-fix](1837f71)
#15262 [from wallyworld/merge-3.0-20230307](4451c9c)

Conflicts were for deleted code or code that needed to be removed.

```
# Conflicts:
# api/client/firewallrules/client_test.go
# api/client/firewallrules/package_test.go
# state/upgrades.go
# state/upgrades_test.go
# upgrades/backend.go
# upgrades/steps_311.go
# upgrades/steps_311_test.go

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