PoC: Rollout application server
What does this MR do?
Similar to GitLab Chart, Puma and Workhorse run together in a single Pod. The workload is managed by a Deployment and exposed through a Service and Ingress resource.
This change enables controller to create the Deployment, Service, and Ingress resources for the application server.
Validation
To validate this PoC, follow these steps:
- Deploy a minimal GitLab instance with GitLab Chart, including its external dependencies, i.e. PostgreSQL, Redis, and MinIO.
- Install GitLab Operator V2 and
v2alpha1
CRD from source and the manifest of this MR. - Remove Puma and Workhorse resources (Deployment, Service, Ingress, etc) that GitLab Chart is created.
- Create a
v2alpha1
GitLab custom resource. - Allow Operator to install Puma and Workhorse.
- Check the GitLab instance is still functioning.
Step 1
export RELEASE='operator-v2-dev-kit'
export NAMESPACE='operator-v2-test'
CHART_VERSION='7.11.2' # GitLab 16.11.2
# Enter your domain name and email address for GitLab instance
read -s DOMAIN
read -s EMAIL
# Running Helm command to install the GitLab instance.
# The unused components are disabled.
helm upgrade "${RELEASE}" gitlab/gitlab \
--version "${CHART_VERSION}" \
--install \
--create-namespace \
-n "${NAMESPACE}" \
--timeout 600s \
--set "global.hosts.domain=${DOMAIN}" \
--set "certmanager-issuer.email=${EMAIL}" \
--set 'gitlab.gitlab-shell.enabled=false' \
--set 'gitlab.mailroom.enabled=false' \
--set 'global.kas.enabled=false' \
--set 'global.pages.enabled=false' \
--set 'global.registry.enabled=false' \
--set 'global.spamcheck.enabled=false' \
--set 'gitlab-runner.install=false' \
--set 'prometheus.install=false'
# Wait for GitLab instance to start ⏳
# Checking logs of webservice Pods ...
stern -n ${NAMESPACE} webservice -s 2s
Step 2
First, checkout the source from the branch of this MR.
TAG='rollout-app-server-deployment'
# This is the image tag for the PoC
make build \
deploy \
TAG="${TAG}"
# Check GitLab CRD and Operator's controller-manager logs
kubectl api-resources | grep gitlab
OPERATOR_NAMESPACE='gitlab-operator-v2-system'
stern -n ${OPERATOR_NAMESPACE} -c manager controller-manager
Port Secrets before Step 3
The current implementation in the PoC does not generate Secrets. Therefore, before creating a GitLab custom resource, you need port some of the Secrets that GitLab Chart has generated:
-
For PostgreSQL and Redis authentication, V2 uses
kubernetes.io/basic-auth
Secret type. We need to copy the content fromOpaque
types. -
Rails and Workhorse Secrets must be copied as well. This is a shortcoming of the PoC and will be fixed in the next iteration.
There is a also minor difference between Chart and Operator that requires renaming Secret keys.
## Helper functions for porting Secrets
get_secret_value() {
local secret_name="${1}"
local field_name="${2}"
kubectl -n "${NAMESPACE}" get secret "${RELEASE}-${secret_name}" \
-o jsonpath="{.data.${field_name}}" | base64 -d
}
create_basic_auth_secret() {
local secret_name="${1}"
local username="${2}"
local password="${3}"
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: ${secret_name}
namespace: ${NAMESPACE}
type: kubernetes.io/basic-auth
stringData:
username: ${username}
password: ${password}
EOF
}
create_opaque_secret() {
local secret_name="${1}"
local key="${2}"
local value="${3}"
kubectl -n ${NAMESPACE} create secret generic ${secret_name} --from-literal "${key}=${value}"
Use the helper functions to port Secrets:
# PostgreSQL password authentication. Username is `gitlab`.
create_basic_auth_secret 'example-1-postgresql-auth' \
'gitlab' "$(get_secret_value 'postgresql-password' 'postgresql\-password')"
# Redis password authentication. Username is empty (``), i.e. default user.
create_basic_auth_secret 'example-1-redis-auth' \
'' "$(get_secret_value 'redis-secret' 'secret')"
# Copying `secrets.yml` key of Rails Secret to a new Secret with `secrets.yaml` key
create_opaque_secret 'example-1-rails-secret' \
'secrets.yaml' "$(get_secret_value 'rails-secret' 'secrets\.yml')"
# Moving `shared_secret` key of Workhorse Secret to a new Secret with `secret` key
create_opaque_secret 'example-1-workhorse-secret' \
'secret' "$(get_secret_value 'gitlab-workhorse-secret' 'shared_secret')"
Define a default IngressClass before Step 3
The PoC does not integrate with an Ingress provider. Therefore, it needs a default IngressClass to function properly.
kubectl annotate ingressclasses --overwrite -l release=${RELEASE} \
'ingressclass.kubernetes.io/is-default-class'='true'
Step 3
Remove Puma and Workhorse resources that GitLab Chart created.
kubectl -n ${NAMESPACE} delete ingress -l app=webservice
kubectl -n ${NAMESPACE} delete service -l app=webservice
kubectl -n ${NAMESPACE} delete hpa -l app=webservice
kubectl -n ${NAMESPACE} delete deployment -l app=webservice
Step 4
Use the following GitLab resource:
# example-1.yaml
apiVersion: gitlab.com/v2alpha1
kind: GitLab
metadata:
name: example-1
spec:
version: 16.11.2
externalUrl: https://gitlab.<DOMAIN>
# Using TLS certificate from CertManager that
# is created with GitLab Chart installation.
tls:
certificate:
name: operator-v2-dev-kit-gitlab-tls
postgresql:
name: default
provider:
# This PostgreSQL is installed with GitLab Chart.
service:
name: operator-v2-dev-kit-postgresql
authentication:
# This is the Secret that we ported before.
basic:
name: example-1-postgresql-auth
redis:
name: default
provider:
# This Redis is installed with GitLab Chart.
service:
name: operator-v2-dev-kit-redis-master
authentication:
# This is the Secret that we ported before.
basic:
name: example-1-redis-auth
# Gitaly
repository:
name: default
provider:
# This Gitaly is installed with GitLab Chart.
service:
name: operator-v2-dev-kit-gitaly
# Reusing the same Secret from GitLab Chart.
authentication:
token:
name: operator-v2-dev-kit-gitaly-secret
key: token
appServer:
# See how we use a PodTemplateSpec to define the template
# of the workload.
podTemplate:
spec:
containers: []
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
appConfig:
objectStore:
provider:
# Use MinIO that is installed with GitLab Chart.
aws:
accessKeyId:
name: operator-v2-dev-kit-minio-secret
key: accesskey
accessKeySecret:
name: operator-v2-dev-kit-minio-secret
key: secretkey
region: 'local'
endpoint: http://operator-v2-dev-kit-minio-svc.operator-v2-test.svc:9000
destinations:
artifacts:
bucketName: example-1-artifacts
externalDiffs:
bucketName: example-1-external-diffs
lfs:
bucketName: example-1-lfs
uploads:
bucketName: example-1-uploads
packages:
bucketName: example-1-packages
dependencyProxy:
bucketName: example-1-dependency-proxy
terraformStates:
bucketName: example-1-terraform-states
ciSecureFiles:
bucketName: example-1-ci-secure-files
And apply the changes:
kubectl apply -f example-1.yaml
kubectl get gitlabs
Step 5
Allow Operator to install Puma and Workhorse.
stern -n ${OPERATOR_NAMESPACE} -c manager controller-manager
Wait for GitLab reconciler to finish
Step 6
Check the resources that the controller created.
kubectl -n ${NAMESPACE} get secret | grep ${RESOURCE_NAME}
kubectl -n ${NAMESPACE} get deployment -l 'app.kubernetes.io/component'='application-server'
kubectl -n ${NAMESPACE} get service -l 'app.kubernetes.io/component'='application-server'
kubectl -n ${NAMESPACE} get ingress -l 'app.kubernetes.io/component'='application-server'
And verify the instance is still working with the existing data:
stern -n ${NAMESPACE} application-server -s 10m
Further work
- Generate Puma and Workhorse Secrets.
- Integrate with Ingress provider.
Author's Checklist
For anything in this list which will not be completed, please provide a reason in the MR discussion.
Required
-
Ensure a release milestone is set. -
MR title and description are up to date, accurate, and descriptive. -
MR targeting the appropriate branch. -
MR has a green pipeline on GitLab.com. -
When ready for review, MR is labeled workflowready for review per the MR workflow.
Expected
-
Test plan indicating conditions for success has been posted and passes. -
Documentation is created or updated. -
Tests are added.
Related issues
Related to #2