Create Cluster
Get Kubeconfig
| gcloud container clusters get-credentials ${CLUSTER_NAME} --region ${REGION}
|
JX Boot
kubectl create secret generic external-dns-gcp-sa --from-file=credentials.json
- download jx
- configure cloud dns
- run
cjx boot
to initialize
- update
jx-requirements.yaml
- run
cjx boot
again to start the rest
JX Boot - CJXD
- configure cloud dns
- create CloudDNS Zone -> create a zone for each subdomain
- "forward" domain to Zone's Domain Servers (NS entry, add the four servers)
kubectl create secret generic external-dns-gcp-sa --from-file=credentials.json
- download cjxd
- run
jx profile cloudbees
- run
jx boot
to initialize
- update
jx-requirements.yaml
- replace environments
- replace ingress
- replace cluster
- change google project for cloud dns config (different project)
- CJXD's
cloudbees-jenkins-x-boot-config
version is 1.0.14
- run
jx boot
again to start the rest
- do not upgrade
- seems to crash immediatly
- create storage buckets
- confirm it is correct:
jx status
Clone Faillure
| ? Do you want to clone the Jenkins X Boot Git repository? Yes
Cloning https://github.com/cloudbees/cloudbees-jenkins-x-boot-config.git @ 1.0.36 to cloudbees-jenkins-x-boot-config
error: setting HEAD to origin/1.0.36: git output: fatal: ambiguous argument 'origin/1.0.36': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]': failed to run 'git reset --hard origin/1.0.36' command in directory 'cloudbees-jenkins-x-boot-config', output: 'fatal: ambiguous argument 'origin/1.0.36': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]''
|
Helm Apply Issue
| Modified file /Users/joostvdg/Projects/Personal/Github/vasimos/jx/cjxd/gke/jxboot/cloudbees-jenkins-x-boot-config/env/Chart.yaml to set the chart to version 1
Ignoring templates/.gitignore
Applying the kubernetes overrides at ../kubeProviders/gke/values.tmpl.yaml
Verifying the helm requirements versions in dir: . using version stream URL: https://github.com/cloudbees/cloudbees-jenkins-x-versions.git and git ref: v0.0.15
error: failed to lint the chart '/var/folders/f_/mpwdv8s16r7_zt43r3r7k20w0000gn/T/jx-helm-apply-578543501/env': failed to run 'helm lint' command in directory '/var/folders/f_/mpwdv8s16r7_zt43r3r7k20w0000gn/T/jx-helm-apply-578543501/env', output: '==> Linting .
[ERROR] Chart.yaml: apiVersion is required
|
TLS - CloudDNS
For each environment we have to setup the issuer and certificate.
Easiest way I found, was to copy the yaml from the issuer and certificate in the jx namespace. You then remove the unnecesary elements, those generated by Kubernetes itself (such as creation date, status, etc).
You have to change the domain name and hosts values, as they should now point to the subdomain corresponding to this environment (unless its production). Once the files are good, you add them to your environment. You do so, by adding them to the templates folder -> env/templates.
| kubectl -n jx get issuer letsencrypt-prod -o yaml
|
| kubectl -n jx get certificate tls-<unique to your cluster>-p -o yaml
|
Add Support For Multiple Subdomains
If you want to support multiple subdomains, such as dev.cjxd.example.com
and staging.cjxd.example.com
you need multiple entries in the external dns controller for the domain.
ImagePullBackup
| events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 18m default-scheduler Successfully assigned jx-staging/jx-jx-qs-spring-boot-6-58b75446b4-pkd7x to gke-joost-cjxd-pool2-54e21b2f-hlhd
Normal Pulling 16m (x4 over 18m) kubelet, gke-joost-cjxd-pool2-54e21b2f-hlhd Pulling image "gcr.io/ps-dev-201405/jx-qs-spring-boot-6:0.0.1"
Warning Failed 16m (x4 over 18m) kubelet, gke-joost-cjxd-pool2-54e21b2f-hlhd Failed to pull image "gcr.io/ps-dev-201405/jx-qs-spring-boot-6:0.0.1": rpc error: code = Unknown desc = Error response from daemon: unauthorized: You don't have the needed permissions to perform this operation, and you may have invalid credentials. To authenticate your request, follow the steps in: https://cloud.google.com/container-registry/docs/advanced-authentication
Warning Failed 16m (x4 over 18m) kubelet, gke-joost-cjxd-pool2-54e21b2f-hlhd Error: ErrImagePull
Normal BackOff 8m24s (x42 over 18m) kubelet, gke-joost-cjxd-pool2-54e21b2f-hlhd Back-off pulling image "gcr.io/ps-dev-201405/jx-qs-spring-boot-6:0.0.1"
Warning Failed 3m18s (x64 over 18m) kubelet, gke-joost-cjxd-pool2-54e21b2f-hlhd Error: ImagePullBackOff
|
Then you're missing scopes in your GKE Node's.
1
2
3
4
5
6
7
8
9
10
11
12
13 | resource "google_container_node_pool" "nodepool2" {
...
node_config {
machine_type = "n2-standard-2"
oauth_scopes = [
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring",
]
}
...
}
|
Add CJXD UI
| jx add app jx-app-ui --version=0.1.2
|
This will make a PR, which, when merged launches a Master Promotion build.
| jx get activities --watch --filter environment-joost-cjxd-dev
|
Unable To Enable DNS API
| valid: there is a Secret: external-dns-gcp-sa in namespace: jx
error: unable to enable 'dns' api: failed to run 'gcloud services list --enabled --project XXXXXX' command in directory '', output: 'ERROR: (gcloud.services.list) User [XXXXXX857-compute@developer.gserviceaccount.com] does not have permission to access project [XXXXXX] (or it may not exist): Request had insufficient authentication scopes.'
|
| valid: there is a Secret: external-dns-gcp-sa in namespace: jx
error: unable to enable 'dns' api: failed to run 'gcloud services list --enabled --project GCP PROJECT B' command in directory '', output: 'ERROR: (gcloud.services.list) User [389413650857-compute@developer.gserviceaccount.com] does not have permission to access project [GCP PROJECT B] (or it may not exist): Request had insufficient authentication scopes.'
Pipeline failed on stage 'release' : container 'step-create-install-values'. The execution of the pipeline has stopped.
|
| oauth_scopes = [
"https://www.googleapis.com/auth/cloud-platform"
]
|
Reset Installation
Remove Environment Repos
- go to git and remove environment repo
- clear jx boot config folder
- clear cloud dns config (if used)
- clear requirements from env repo's if re-used
Clean GCP Resources
Disks
Buckets
Others?
Clear Local Data
Recreate Git Token
If for some reason the git token is invalid, you can recreate it with the commands below.
| jx delete git token -n github <yourUserName>
jx create git token -n github <yourUserName>
|
Debug
TLS Configuration
Cert Manager
| kubectl get pods -n cert-manager
|
| kubectl logs -f -n cert-manager cm-cert-manager-885695c9f-bxhvk
|
External DNS Controller
kubectl logs -f exdns-external-dns-56948bff8-fq692
| NAMESPACE NAME HOSTS ADDRESS PORTS AGE
jx jx-vault-joost-cjxd vault.dev.cjxd.kearos.net 35.204.54.193 80, 443 5m46s
|
The address from the ingress resource should match the address returned from the nslookup
.
| nslookup vault.dev.cjxd.kearos.net
|
| Server: 192.168.178.1
Address: 192.168.178.1#53
Non-authoritative answer:
Name: vault.dev.cjxd.kearos.net
Address: 35.204.54.193
|
Certificate Resources
- certificate issuer
- certificate
- certificate secret
- cloud dns secret (
credentials.json
)
If the certificate is correct, it looks like this:
| NAME READY SECRET AGE
tls-dev-cjxd-kearos-net-p True tls-dev-cjxd-kearos-net-p 4m31s
|
Create new Environment
Create CloudBees Environment
- copy existing resources into new (
env/templates/
)
- update values to suit new environment
- execute
jx boot
- configure cloud dns
- cloud dns zone
- external dns secret
- dns domain forward
- add cert and issuer to env repo
- configure secrets
- add requirements to repo
- edit
exdns-external-dns
deployment
kubectl edit deployment -n jx exdns-external-dns
Get Resources
| kubectl get env staging -oyaml > env/templates/cb.yaml
kubectl get sr joostvdg-env-cjxd-staging -oyaml > env/templates/cb-sr.yaml
|
Create Cloud DNS Zone
| ZONE_NAME=cb-cjxd-kearos-net
DESCRIPTION="joostvdg - cb env for cjxd"
DNS_NAME=cb.cjxd.kearos.net
|
| gcloud dns managed-zones create ${ZONE_NAME} --description=${DESCRIPTION} --dns-name=${DNS_NAME}
|
| kubectl get issuer -n jx letsencrypt-prod -oyaml > env/templates/issuer.yaml
kubectl get cert -n jx tls-dev-cjxd-kearos-net-p -oyaml > env/templates/certificate.yaml
|
- Rename the namespace to your namespace
- remove
status
segment
- remove kubernetes managed fields (
uuid
, timestamps, etc)
| git add env/
git commit -m "add certs"
|
| git push
jx get activities -w
|
| kubectl get secret -n jx exdns-external-dns-token-cq5mv -oyaml > exdns-external-dns-token-env-cb.yaml
kubectl get secret -n jx external-dns-gcp-sa -oyaml > external-dns-gcp-sa-env-cb.yaml
|
- Rename the namespace to your namespace
- remove
status
segment
- remove kubernetes managed fields (
uuid
, timestamps, etc)
| kubectl apply -f exdns-external-dns-token-env-cb.yaml
kubectl apply -f external-dns-gcp-sa-env-cb.yaml
|
Confirm Certificate Works
| kubectl get cert -n cloudbees
|
Add CloudBees Core
env/requirements.yaml
| - name: cloudbees-core
version: 3.6.0+4d2e34de1e86
repository: https://charts.cloudbees.com/public/cloudbees
alias: core
|
env/values.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | core:
OperationsCenter:
HostName: core.cb.cjxd.kearos.net
Ingress:
Annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/app-root: https://$best_http_host/cjoc/teams-check/
nginx.ingress.kubernetes.io/proxy-body-size: 50m
nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
tls:
Enable: true
Host: core.cb.cjxd.kearos.net
SecretName: tls-cb-cjxd-kearos-net-p
ServiceType: ClusterIP
nginx-ingress:
Enabled: false
|
cb env
cb source repository
jx-requirements
| - ingress:
domain: cb.cjxd.kearos.net
externalDNS: true
namespaceSubDomain: .
tls:
email: joostvdg@gmail.com
enabled: true
production: true
key: cb
repository: env-cjxd-cb
|
TLS Unique DNS
If you want to make sure each environment has its own unique address, the external dns controller needs to filter on multiple domains.
Luckily, it is able to do so.
Unfortunately, it seems Jenkins X (with jx boot
) doesn't seem to do this out of the box.
To do so, make sure each environment has its own domain, as shown in jx-requirements
.
Then, edit the exdns
deployment via kubectl edit exdn...
and add an additional - --domain-filter=
line at the args for each domain.
jx-requirements
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 | - ingress:
domain: staging.gke.kearos.net
externalDNS: true
namespaceSubDomain: ""
tls:
email: joostvdg@gmail.com
enabled: true
production: true
key: staging
repository: env-gke-staging
- ingress:
domain: prod.gke.kearos.net
externalDNS: true
namespaceSubDomain: ""
tls:
email: joostvdg@gmail.com
enabled: true
production: true
key: production
repository: env-gke-production
gitops: true
ingress:
cloud_dns_secret_name: external-dns-gcp-sa
domain: jx.gke.kearos.net
externalDNS: true
namespaceSubDomain: -jx.
tls:
email: joostvdg@gmail.com
enabled: true
production: true
- ingress:
domain: staging.gke.kearos.net
externalDNS: true
namespaceSubDomain: ""
tls:
email: joostvdg@gmail.com
enabled: true
production: true
key: staging
repository: env-gke-staging
- ingress:
domain: prod.gke.kearos.net
externalDNS: true
namespaceSubDomain: ""
tls:
email: joostvdg@gmail.com
enabled: true
production: true
key: production
repository: env-gke-production
gitops: true
ingress:
cloud_dns_secret_name: external-dns-gcp-sa
domain: jx.gke.kearos.net
externalDNS: true
namespaceSubDomain: -jx.
tls:
email: joostvdg@gmail.com
enabled: true
production: true
|
exdns deployment config
| - args:
- --log-level=info
- --domain-filter=jx.gke.kearos.net
- --domain-filter=staging.gke.kearos.net
- --policy=upsert-only
- --provider=google
- --registry=txt
- --interval=1m
- --source=ingress
- --google-project=kearos-gcp
|
Certmanager complaining about the wrong domain
In case Cert-Manager is complaining that while validating x.y.example.com
it cannot find example.com
.
See: https://github.com/jetstack/cert-manager/issues/1507
| I1104 09:13:33.884549 1 base_controller.go:187] cert-manager/controller/challenges "level"=0 "msg"="syncing item" "key"="cloudbees/tls-cb-cjxd-kearos-net-p-2383487961-0"
I1104 09:13:33.884966 1 dns.go:104] cert-manager/controller/challenges/Present "level"=0 "msg"="presenting DNS01 challenge for domain" "dnsName"="cloudbees.cjxd.kearos.net" "domain"="cloudbees.cjxd.kearos.net" "resource_kind"="Challenge" "resource_name"="tls-cb-cjxd-kearos-net-p-2383487961-0" "resource_namespace"="cloudbees" "type"="dns-01"
E1104 09:13:34.141122 1 base_controller.go:189] cert-manager/controller/challenges "msg"="re-queuing item due to error processing" "error"="No matching GoogleCloud domain found for domain kearos.net." "key"="cloudbees/tls-cb-cjxd-kearos-net-p-2383487961-0"
|
References