-
Notifications
You must be signed in to change notification settings - Fork 38
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
Issue 61: Support external connectivity #77
Conversation
Signed-off-by: Adrian Moreno <[email protected]>
- Allow only one SegmentStore pod per node Signed-off-by: Adrian Moreno <[email protected]>
- Allow only one Bookie pod per node Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
5ed9e5e
to
90e50b2
Compare
@maddisondavid @EronWright @arvindkandhare can you please review the PR? Thanks! |
It would be great to see the output of |
@EronWright thanks for the review. I'll make some changes based on your comments. |
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
I've made the changes suggested by @EronWright and updated the PR description. |
@EronWright @maddisondavid can you please review the PR again after the changes? |
Signed-off-by: Adrian Moreno <[email protected]>
Signed-off-by: Adrian Moreno <[email protected]>
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.
LGTM, my only concern is that IF external access is enabled then the LoadBalancer IP will be given to any clients inside the cluster if connecting to Pravega.
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.
+1
Change log description
This PR adds support for external connectivity (i.e. connectivity from outside the Kubernetes cluster). Below is a detailed description of the changes made and the reason why they were made.
Create a headless service for the Segmentstore set
As with the Bookies, Segmentstores are managed by a
StatefulSet
. Headless services provide DNS records for the Segmentstore set that can be used for intra-cluster communication, i.e., segmentstore pods can be access using the<statefulset_name>-<ordinal>.<headless_service_name>
hostname (e.g.pravega-segmentstore-1.pravega-segmentstore-headless
would resolve to the IP of second pod in the set).Create an external service per Segmentstore pod
Pravega clients need to be able to directly reach every Segmentstore instance. We found multiple ways to achieve this:
NodePort
services.NodePort
services allocate a free port (within the 30000-32767 range) in each Kubernetes node and forwards the traffic to the backend pod. However, this requires extra configuration on the external networking layer to allocate IP addresses, and allow and forward external traffic to the service. In addition,NodePort
services are not yet supported on PKS w/ vSphere and NSX-T, which is our main platform.Ingress
resource. Ingress configures an HTTP server with routing rules to allow external communication with a service. However, most Ingress implementations do not support non-HTTP traffic, making it not an option for our HTTP2-gRPC traffic.LoadBalancer
services. ALoadBalancer
service configures an external load balancer (e.g. NSX-T in our platform) to allow external communication and provides an external IP once it's allocated by the external load balancer. It can handle any TCP connections or UDP flows, so it works for our use case.This PR implements support for
LoadBalancer
andNodePort
service types. Configured inexternalAccess.type
. The operator creates one external service per Segment Store instance.In addition, these services are created with the
externalTrafficPolicy
option enabled. By default,LoadBalancer
services route traffic to any backend pod in the cluster, however, with this option, services route traffic only to node-local pods.Create
ClusterRole
permissionsWhen external access is enabled and configured with
NodePort
, the pod needs to find the node IP using the Kubernetes API. To achieve this, the service account needs to haveClusterNode
read permissions on thenode
resource.Segmentstore instance to advertise external address
By default, a Segmentstore instance uses it's local address when it registers with the Controller. However, the local pod address is only reachable from within the cluster (or namespace, depending on the environment).
We need to initialize each Segmentstore instance with the external address allocated by the corresponding
LoadBalancer
service. To achieve this, the Pravega Docker imageentrypoint.sh
needs to modified to obtain the external service IP and port and configure it as system properties before starting the segmentstore process.The Segmentstore container needs to know the service name and the namespace to introspect and find its external IP. By naming convention, the
LoadBalancing
service name is the same as the pod name. So this is information can be easily made available to the pod by leveraging the Downward API. Two environment variables (POD_NAME
andPOD_NAMESPACE
) are passed to the pod to allow the pods to find their information via the Kubernetes API. How the container uses this information is being addressed in the Pravega project PR pravega/pravega#3062.Ability to configure external access
Exposing the Pravega cluster to the outside is a possibility for users, but it's not enforced. For security reasons, by default a Pravega cluster will still be accessible only within the Kubernetes cluster. To enable external access, users need to explicitly create the
externalAccess
structure and set theenabled
field totrue
, otherwise the cluster will not be exposed. E.g.:Purpose of the change
How to test the change
Assuming you already have access to a Kubernetes environment (GKE, PKS, Minikube...), follow the instructions in the README file to deploy ZooKeeper, the NFS server provisioner, and the Pravega Tier 2 PVC. Skip the deployment of the Pravega operator.
Check out this branch.
Update the Pravega operator image to use an image built with the PR changes. Open the
deploy/operator.yaml
file and replace the container image frompravega/pravega-operator:latest
toadrianmo/pravega-operator:v0.1.0-23-dirty
.Deploy the operator.
Create a
pravega.yaml
that will use the updated images that contain the changes made to obtain and advertise the external service IP (ref: pravega/pravega#3062) and the newexternalAccess
field.Copy the contents above to a
pravega.yaml
file and deploy the Pravega cluster:Watch the Pravega cluster being created...
Until the Controller and all Segmentstore services have been allocated an external address in the
EXTERNAL-IP
column.Then, copy the Controller External IP and connect to it with the Pravega client. You can use the samples in the Pravega samples repositories.
Signed-off-by: Adrian Moreno [email protected]