-
Notifications
You must be signed in to change notification settings - Fork 77
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
Deploying VTAdmin in Vtop #272
Conversation
…y crds Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
…create a keyspace Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
…nds in the docker image of vtadmin Signed-off-by: Manan Gupta <manan@planetscale.com>
…nt variables Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
|
||
- name: "VTAdmin Test" | ||
command: | ||
- apk add g++ make bash curl mysql mysql-client chromium |
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 line is different from the other test setup lines. It is also installing chromium browser. We need this to run it in a headless mode to download the VTAdmin web pages. We can't use curl
(which we use for the API pages) or wget
because they do not support JavaScript, so a headless browser was the easiest solution.
if len(vt.Spec.Images.Vtadmin) == 0 { | ||
log.Error("Not deploying vtadmin since image is unspecified") | ||
return resultBuilder.Result() | ||
} | ||
|
||
if len(vt.Spec.VtAdmin.APIAddresses) == 0 { | ||
log.Errorf("Not deploying vtadmin since api addresses field is not specified. Atleast 1 value is required") | ||
} | ||
|
||
if len(vt.Spec.VtAdmin.APIAddresses) != 1 && len(vt.Spec.VtAdmin.APIAddresses) != len(vt.Spec.VtAdmin.Cells) { | ||
log.Errorf("Not deploying vtadmin since api addresses field doesn't align with cells field") | ||
} |
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.
These are user input validations. There exist 3 -
- The VTAdmin image should be specifically provided. We do not add a default for
vitess:lite
since that won't work - There should be at least 1 APIAddress provided
- If more than 1 APIAddresses are provided, then the length of this list should match the length of the cells list.
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.
That makes sense to me
// We have already checked that atleast 1 value should be available in APIAddresses | ||
apiAddress := vt.Spec.VtAdmin.APIAddresses[0] | ||
if len(vt.Spec.VtAdmin.APIAddresses) > 1 { | ||
apiAddress = vt.Spec.VtAdmin.APIAddresses[idx] | ||
} |
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 is safe because of the user input validation above
discoveryVal := fmt.Sprintf(`{ | ||
"vtctlds": [ | ||
{ | ||
"host": { | ||
"fqdn": "%s:%d", | ||
"hostname": "%s:%d" | ||
} | ||
} | ||
], | ||
"vtgates": [ | ||
{ | ||
"host": { | ||
"hostname": "%s:%d" | ||
} | ||
} | ||
] | ||
}`, vtctldServiceIP, vtctldServiceWebPort, vtctldServiceIP, vtctldServiceGrpcPort, vtgateServiceIP, vtgateServiceGrpcPort) | ||
secretName := vtadmin.DiscoverySecretName(vt.Name, cell.Name) |
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.
The discovery configuration file is autogenerated using the global service of vtctld
and per cell service of vtgates
.
configKey := vtadmin.WebConfigFileName | ||
configVal := fmt.Sprintf(`window.env = { | ||
'REACT_APP_VTADMIN_API_ADDRESS': "%s", | ||
'REACT_APP_FETCH_CREDENTIALS': "omit", | ||
'REACT_APP_ENABLE_EXPERIMENTAL_TABLET_DEBUG_VARS': false, | ||
'REACT_APP_BUGSNAG_API_KEY': "", | ||
'REACT_APP_DOCUMENT_TITLE': "", | ||
'REACT_APP_READONLY_MODE': %s, | ||
};`, apiAddress, convertReadOnlyFieldToString(vt.Spec.VtAdmin.ReadOnly)) | ||
secretName := vtadmin.WebConfigSecretName(vt.Name, cell.Name) |
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.
Some parameters of the config are not user controllable like REACT_APP_ENABLE_EXPERIMENTAL_TABLET_DEBUG_VARS
is always set to false. Since we do not have a good way of discovering vttablets yet, this doesn't work. http-tablet-url-tmpl
is not flexible to allow this right now. To enable this, we would have to setup services for all the vttablets and then encode them in the flag. Other complexities like new vttablets requiring change in config, etc will also have to be dealt with.
Similarly, REACT_APP_FETCH_CREDENTIALS
is always set to omit
because we aren't enabling CORS. If we did want to do that, then we would also need to ask the user to provide the hosts that are allowed to access the API server
// AbsolutePath stores the absolute path to use instead of the generated path | ||
// with /vt/secret as the prefix | ||
AbsolutePath string |
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 had to be added to allow mounting files to a specific path instead of the /vt/secrets
where they usually are. For the Vtadmin web config, the path has to be /vt/web/vtadmin/build/config
updateRbac(spec, apiFlags, vtadminAPIContainer, &obj.Spec.Template.Spec) | ||
updateDiscovery(spec, apiFlags, vtadminAPIContainer, &obj.Spec.Template.Spec) |
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.
Adds the file mounts for Rbac and discovery config
VolumeMounts: spec.ExtraVolumeMounts, | ||
Env: spec.ExtraEnv, | ||
} | ||
updateWebConfig(spec, vtadminWebContainer, &obj.Spec.Template.Spec) |
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.
Adds the file mount for the web config
Also, the vtadmin test needs to restarted after the image |
…with root Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
if len(vt.Spec.Images.Vtadmin) == 0 { | ||
log.Error("Not deploying vtadmin since image is unspecified") | ||
return resultBuilder.Result() | ||
} | ||
|
||
if len(vt.Spec.VtAdmin.APIAddresses) == 0 { | ||
log.Errorf("Not deploying vtadmin since api addresses field is not specified. Atleast 1 value is required") | ||
} | ||
|
||
if len(vt.Spec.VtAdmin.APIAddresses) != 1 && len(vt.Spec.VtAdmin.APIAddresses) != len(vt.Spec.VtAdmin.Cells) { | ||
log.Errorf("Not deploying vtadmin since api addresses field doesn't align with cells field") | ||
} |
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.
That makes sense to me
log.Errorf("Not deploying vtadmin since api addresses field doesn't align with cells field") | ||
} | ||
|
||
key := client.ObjectKey{Namespace: vt.Namespace, Name: vtadmin.ServiceName(vt.Name)} |
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.
can vtadmin have no service name? if it's not deployed under a k8s service for example
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.
That is a function which deterministically gives the service name to use. We are creating the service just down below. We always create services for vtctld and vtgates in cells, so that if there are multiple deployments then users can just assign a public IP address to the service and it will load balance across all the available pods
// Symlinks are required because the web config file is mounted as a | ||
// secret which happens to be mounted as symlink instead of an actual file | ||
"--symlinks", |
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.
👍🏻
Description
This PR adds VTAdmin to the operator and associated tests.
Currently only the specific vtadmin image can be used for deploying VTAdmin, but we'll get
vitess/lite
image working too later.An example config looks like the following -
The VTAdmin spec includes the following fields -
Rbac
as a secret source. It is the role based access control rules to use for VTAdmin APICells
as a list of strings. It is the cells where VTAdmin must be deployed. Defaults to deploying everywhereAPIAddresses
as a list of strings. Since the VTAdmin web UI runs on the client side, it needs the API address to use to query the API. We can't use the internal kubernetes service address or the ip of the pod, since they aren't visible outside the cluster. The API Address must be provided by the user based on how they export the service of VTAdmin API. In our tests we port-forward the service to port14001
and therefore that is the address provided here. This value is a list because the address to be used for VTAdmin web in each cell might be different. If only 1 value is provided then, that is used for all the cells. The ideal way to deploy this would be to export each individual VTAdmin service (that we create) in each cell and attach external IPs to them and provide those IPs here.Replicas
- Number of VTAdmin deployments required per cell. We setup a service on top of the web and API connections, so load-balancing comes out of the boxWebResources
- Resource requests and limits for the container running the VTAdmin web serverAPIResources
- Resource requests and limits for the container running the VTAdmin API serverReadOnly
- Configuration to set the VTAdmin web UI to be read only.Documentation
vitessio/website#1073