in mysqloperator/controller/innodbcluster/router_objects.py [0:0]
def prepare_router_deployment(cluster: InnoDBCluster, logger, *,
init_only: bool = False) -> dict:
# Start the router deployment with 0 replicas and only set it to the desired
# value once the cluster is ONLINE, otherwise the router bootstraps could
# timeout and fail unnecessarily.
spec = cluster.parsed_spec
(router_bootstrap_options, router_tls_exists, ca_and_tls) = get_bootstrap_and_tls_options(cluster)
router_command = ['mysqlrouter', *spec.router.options]
router_target = fqdn.idc_service_fqdn(cluster, logger)
tmpl = f"""
apiVersion: apps/v1
kind: Deployment
metadata:
name: {spec.name}-router
label:
tier: mysql
mysql.oracle.com/cluster: {spec.name}
app.kubernetes.io/name: mysql-innodbcluster
app.kubernetes.io/instance: mysql-innodbcluster-{spec.name}-router
app.kubernetes.io/component: router
app.kubernetes.io/managed-by: mysql-operator
app.kubernetes.io/created-by: mysql-operator
spec:
replicas: {spec.router.instances or 1 if not init_only else 0}
selector:
matchLabels:
component: mysqlrouter
tier: mysql
mysql.oracle.com/cluster: {spec.name}
app.kubernetes.io/name: mysql-router
app.kubernetes.io/instance: mysql-innodbcluster-{spec.name}-router
app.kubernetes.io/component: router
app.kubernetes.io/managed-by: mysql-operator
app.kubernetes.io/created-by: mysql-operator
template:
metadata:
labels:
component: mysqlrouter
tier: mysql
mysql.oracle.com/cluster: {spec.name}
app.kubernetes.io/name: mysql-router
app.kubernetes.io/instance: mysql-innodbcluster-{spec.name}-router
app.kubernetes.io/component: router
app.kubernetes.io/managed-by: mysql-operator
app.kubernetes.io/created-by: mysql-operator
spec:
serviceAccountName: {spec.serviceAccountName}
securityContext:
runAsUser: 999
runAsGroup: 999
fsGroup: 999
runAsNonRoot: true
containers:
- name: router
image: {spec.router_image}
imagePullPolicy: {spec.router_image_pull_policy}
securityContext:
# These can't go to spec.template.spec.securityContext
# See: https://pkg.go.dev/k8s.io/api@v0.26.1/core/v1#PodTemplateSpec / https://pkg.go.dev/k8s.io/api@v0.26.1/core/v1#PodSpec
# See: https://pkg.go.dev/k8s.io/api@v0.26.1/core/v1#PodSecurityContext - for pods (top level)
# See: https://pkg.go.dev/k8s.io/api@v0.26.1/core/v1#Container
# See: https://pkg.go.dev/k8s.io/api@v0.26.1/core/v1#SecurityContext - for containers
allowPrivilegeEscalation: false
privileged: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
env:
- name: MYSQL_HOST
value: {router_target}
- name: MYSQL_PORT
value: "3306"
- name: MYSQL_USER_FILE
value: /.routeruser
- name: MYSQL_PASSWORD_FILE
value: /.routerpw
- name: MYSQL_CREATE_ROUTER_USER
value: "0"
volumeMounts:
- name: tmpdir
mountPath: /tmp
- name: initconfdir
subPath: router-entrypoint-run.sh.tpl
mountPath: /run.sh
readOnly: true
- name: routercredentials
subPath: routerUsername
mountPath: /.routeruser
readOnly: true
- name: routercredentials
subPath: routerPassword
mountPath: /.routerpw
readOnly: true
{utils.indent(spec.extra_router_volume_mounts if router_tls_exists else spec.extra_router_volume_mounts_no_cert, 8)}
ports:
- containerPort: {spec.router_rwport}
name: mysqlrw
- containerPort: {spec.router_rwxport}
name: mysqlxrw
- containerPort: {spec.router_rwsplitport}
name: mysqlrwsplit
- containerPort: {spec.router_roport}
name: mysqlro
- containerPort: {spec.router_roxport}
name: mysqlxro
- containerPort: {spec.router_httpport}
name: http
readinessProbe:
exec:
command:
- cat
- /tmp/mysqlrouter/mysqlrouter.conf
livenessProbe:
failureThreshold: 3
httpGet:
path: /api/20190715/swagger.json
port: http
scheme: HTTPS
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
volumes:
- name: tmpdir
emptyDir: {{}}
- name: initconfdir
configMap:
name: {spec.name}-initconf
defaultMode: 0755
- name: routercredentials
secret:
secretName: {spec.name}-router
# the files are created by root but belonging to mysqlrouter group,
# thus we need read access for the group
defaultMode: 0440
{utils.indent(spec.extra_router_volumes if router_tls_exists else spec.extra_router_volumes_no_cert, 6)}
"""
deployment = yaml.safe_load(tmpl)
container = deployment["spec"]["template"]["spec"]["containers"][0]
container["args"] = router_command
container["env"].append({
"name": "MYSQL_ROUTER_BOOTSTRAP_EXTRA_OPTIONS",
"value": router_bootstrap_options
})
metadata = {}
if spec.router.podAnnotations:
metadata['annotations'] = spec.router.podAnnotations
if spec.router.podLabels:
metadata['labels'] = spec.router.podLabels
if len(metadata):
utils.merge_patch_object(deployment["spec"]["template"], {"metadata" : metadata })
if spec.router.podSpec:
utils.merge_patch_object(deployment["spec"]["template"]["spec"],
spec.router.podSpec, "spec.router.podSpec")
# Cache the sha256 of the certs and keys we start it. This will prevent that when
# the sidecar sees the unhandled secrets it will patch the deployment with the same hashes
# and this won't restart the deployment. If however the TLS data has changed during IC boot
# the handler will get the new values, hash them and this will trigger the reboot.
if ca_and_tls:
# the annotation keys should be the same as in restart_deployment_for_tls()
tls_hashes_patch = {"spec": { "template": { "metadata": { "annotations": { }}}}}
ca_pem = ca_and_tls.get(ca_and_tls.get("CA", "ca.pem"))
ca_pem_sha256 = utils.sha256(ca_pem) if ca_pem else None
if ca_pem_sha256:
tls_hashes_patch['spec']['template']['metadata']['annotations']['mysql.oracle.com/ca.pem.sha256'] = ca_pem_sha256
crl_pem = ca_and_tls.get('crl.pem')
crl_pem_sha256 = utils.sha256(crl_pem) if crl_pem else None
if crl_pem_sha256:
tls_hashes_patch['spec']['template']['metadata']['annotations']['mysql.oracle.com/crl.pem.sha256'] = crl_pem_sha256
router_tls_crt = ca_and_tls.get('router_tls.crt')
router_tls_crt_sha256 = utils.sha256(router_tls_crt) if router_tls_crt else None
if router_tls_crt_sha256:
tls_hashes_patch['spec']['template']['metadata']['annotations']['mysql.oracle.com/router_tls.crt.sha256'] = router_tls_crt_sha256
router_tls_key = ca_and_tls.get('router_tls.key')
router_tls_key_sha256 = utils.sha256(router_tls_key) if router_tls_key else None
if router_tls_key_sha256:
tls_hashes_patch['spec']['template']['metadata']['annotations']['mysql.oracle.com/router_tls.key.sha256'] = router_tls_key_sha256
utils.merge_patch_object(deployment, tls_hashes_patch)
return deployment