As someone deploying Quay to Kubernetes, I want to provide a config bundle directory with the services I want and receive k8s manifests which are kubectl create
ready in order to declaratively manage my Quay deployment.
- Use any form of templating (writing k8s YAML is enough)
- Application lifecycle management (beyond what native k8s controllers provide)
This repository is intended as a template for your unique Quay installation. Create a copy, add your secrets, values, and certs, choose which features you want enabled, and deploy!
Be sure to git commit
your changes to adhere to configuration-as-code!
You can use git-crypt
to protect your secrets, like database credentials and access keys.
go
v1.14+kubectl
and a Kubernetes cluster
- Use the
app/
directory to "kustomize" your Quay deployment.
- Uncomment items under
resources
to include them in your deployment - Add other Quay config fields to
bundle/config.yaml
- Add custom SSL cert files to
bundle/ssl.key
andbundle/ssl.cert
and uncomment them undersecretGenerator
inkustomization.yaml
- Add extra SSL cert files needed by Quay to talk to external services to
bundle
directory and add them tosecretGenerator
inkustomization.yaml
- When you are ready to generate the final deployment files, run the following:
$ mkdir ./output
$ go run main.go
This is a small Go program which internally uses kustomize
as a library, then properly formats the quay-config-secret
.
- Now you can simply use
kubectl
or any other Kubernetes client to deploy Quay:
$ kubectl create -n quay-enterprise -f ./output
Say you want to make changes to your Quay's configuration, like adding a new superuser.
- Add/modify the desired field in
app/bundle/config.yaml
- Commit your changes to source control to maintain a history and be able to revert if needed:
$ git add . && git commit -m "adding new superuser"
- Generate new Kubernetes manifests by running:
$ rm -rf output/* && go run main.go
Note that if you look in the output/
directory, you can see an new Quay Secret
has been created with a different suffix hash in metadata.name
.
The Quay Deployment
has been updated to reference this new Secret
, which is what will trigger a rolling deploy.
- Apply the new resources to your cluster:
$ kubectl apply -n quay-enterprise -f ./output
Note that this will trigger a rolling deploy. Because the old config Secret
is still present on the cluster (because we created a new one rather than updating it),
we can easily roll back the deploy to point at the previous secret in case something goes wrong.
Say you deployed a basic Quay initially, and you've heard how awesome container security scanning is with Clair! Let's add it to your deployment.
- Update
app/kustomization.yaml
to include theclair
component:
components:
- ...
- ../components/clair
- Commit your changes to source control to maintain a history and be able to revert if needed:
$ git add . && git commit -m "adding clair security scanner"
- Generate new Kubernetes manifests by running:
$ rm -rf output/* && go run main.go
Note that if you look in the output/
directory, you can see new manifests for Clair have been created, as well as an updated Quay Secret
with the Clair-specific fields (FEATURE_SECURITY_SCANNER
).
- Apply the new resources to your cluster:
$ kubectl apply -n quay-enterprise -f ./output
Note that this will trigger a rolling deploy. Because the old config Secret
is still present on the cluster (because we created a new one rather than updating it),
we can easily roll back the deploy to point at the previous secret in case something goes wrong.
Now, say that your team is cutting-edge and has a fork of Clair that adds new features and want to point your Quay to use it. The purpose of this project is to provide an opinionated install of Quay, so there is no supported way to configure managed services like Clair. However, you are welcome to bring your own service.
Say you have your custom Clair service deployed separately at http://custom-clair
, you can point Quay to it.
- Update
app/kustomization.yaml
to remove theclair
component - Update
app/bundle/config.yaml
to include Clair-specific fields to point to your service:
FEATURE_SECURITY_SCANNER: true
SECURITY_SCANNER_V4_ENDPOINT: http://custom-clair
SECURITY_SCANNER_V4_NAMESPACE_WHITELIST: [admin]
- Generate new Kubernetes manifests by running:
$ rm -rf output/* && go run main.go
Note that if you look in the output/
directory, you can see the Clair manifests have been removed.
- Apply the new resources to your cluster:
$ kubectl apply -n quay-enterprise -f ./output
Note that this will trigger a rolling deploy. Because the old config Secret
is still present on the cluster (because we created a new one rather than updating it),
we can easily roll back the deploy to point at the previous secret in case something goes wrong.
Your Quay instance is now pointing to your custom Clair service, which must be managed by you.
Teardown is as simple as running:
$ kubectl delete -n quay-enterprise -f ./output
- This tool does not provide validation of the resulting
quay-config-secret
- If you choose to use an unmanaged external service (database/storage/Redis/Clair), you must add the appropriate
<CONFIG_FIELD>: <value>
entries toapp/bundle/config.yaml
- On OCP, you need to run
oc adm policy add-scc-to-user anyuid system:serviceaccount:quay-enterprise:default
before deploying - Need to manually point DNS to the created Quay
Service
withtype: LoadBalancer
(ensure it matchesSERVER_HOSTNAME
inconfig.yaml
) - Cannot modify configuration of managed services (like Clair) because this is an opinionated deployment
- Use
kustomize
as a library instead of CLI - Use Kustomize
components
instead ofvariants
for more DRY code - Zero downtime upgrades with database migrations
- Use other Operators to provide external services (like CrunchyDB Postgres Operator, Redis Operator, etc...)
- Refactor into Go module which can be imported by other tools
- Quay Operator which provides application lifecycle management using this tool
- Add
ownerReferences
to all created resources for easy tracking and cleanup