1
0
Fork 0
Commit Graph

30 Commits (master)

Author SHA1 Message Date
Dustin 5869afa923 jenkins: Add PVC for airplaypi Buildroot job
Buildroot jobs really benefit from having a persistent workspace volume
instead of an ephemeral one.  This way, only the packages, etc. that
have changed since the last build need to be built, instead of the whole
toolchain and operating system.
2025-09-07 12:24:11 -05:00
Dustin cbed5a8d13 jenkins: Drop Gentoo Portage distribution
Now that Aimee OS is based on Buildroot instead of Gentoo, we don't need
to keep syncing and sharing the Gentoo repository.
2025-09-07 08:27:19 -05:00
Dustin 16dec1cdec ssh-host-keys: Do not specify a namespace
We don't want to hard-code a namespace for the `ssh-known-hosts`
ConfigMap because that makes it less useful for other projects besides
Jenkins.  Instead, we omit the namespace specification and allow
consumers to specify their own.

The _jenkins_ project doesn't have a default namespace, since it
specifies resources in the `jenkins` and `jenkins-jobs` namespaces, we
need to create a sub-project to set the namespace for the
`ssh-known-hosts` ConfigMap.
2025-07-21 11:47:39 -05:00
Dustin edec79aaae ssh-known-hosts: Move ConfigMap to its own project
This will allow multiple projects to have a ConfigMap with the same
`ssh_known_hosts` contents without duplicating the source file in the
repository.
2025-02-08 11:56:34 -06:00
Dustin 79995801e2 jenkins: ssh_known_hosts: Add OVH VPS host key 2025-02-01 18:16:10 -06:00
Dustin 1392a7c181 jenkins: Add storage for Gentoo Portage/binpkgs
Jenkins that build Gentoo-based systems, like Aimee OS, need a
persistent storage volume for the Gentoo ebuild repository. The Job
initially populates the repository using `emerge-webrsync`, and then the
CronJob keeps it up-to-date by running `emaint sync` daily.

In addition to the Portage repository, we also need a volume to store
built binary packages.  Jenkins job pods can mount this volume to make
binary packages they build available for subsequent runs.

Both of these volumes are exposed to use cases outside the cluster using
`rsync` in daemon mode.  This can be useful for e.g. local builds.
2025-01-09 20:15:46 -06:00
Dustin 72d3f222c5 jenkins: Trust SSHCA for pyrocufflink.black
The new machines have names in the _pyrocufflink.black_ zone.  We need
to trust the SSHCA certificate to sign keys for these names in order to
connect to them and manage them with Ansible.
2024-11-26 03:35:21 +00:00
Dustin fa80b15a71 jenkins: Remove Argo CD sync hook
Since Jenkins no longer uses a Longhorn volume, this sync hook is not
useful.
2024-07-04 06:53:58 -05:00
Dustin 98651cf9d9 jenkins: Force iSCSI volume on specific nodes
Instead of routing iSCSI traffic from the Kubernetes network, through
the firewall, to the storage network, nodes now have a second network
adapter connected to directly to the storage network.  The nodes with
such an adapter are labelled `network.du5t1n.me/storage`, so we can pin
the Jenkins PersistentVolume to them via a node affinity rule.
2024-06-26 18:29:49 -05:00
Dustin 7f3287297b jenkins: Migrate to iSCSI persistent volume
Managing the Jenkins volume with Longhorn has become increasingly
problematic.  Because of its large size, whenever Longhorn needs to
rebuild/replicate it (which happens often for no apparent reason), it
can take several hours.  While the synchronization is happening, the
entire cluster suffers from degraded performance.

Instead of using Longhorn, I've decided to try storing the data directly
on the Synology NAS and expose it to Kubernetes via iSCSI.  The Synology
offers many of the same features as Longhorn, including
snapshots/rollbacks and backups.  Using the NAS allows the volume to be
available to any Kubernetes node, without keeping multiple copies of
the data.

In order to expose the iSCSI service on the NAS to the Kubernetes nodes,
I had to make the storage VLAN routable.  I kept it as IPv6-only,
though, as an extra precaution against unauthorized access.  The
firewall only allows nodes on the Kubernetes network to access the NAS
via iSCSI.

I originally tried proxying the iSCSI connection via the VM hosts,
however, this failed because of how iSCSI target discovery works.  The
provided "target host" is really only used to identify available LUNs;
follow-up communication is done with the IP address returned by the
discovery process.  Since the NAS would return its IP address, which
differed from the proxy address, the connection would fail.  Thus, I
resorted to reconfiguring the storage network and connecting directly
to the NAS.

To migrate the contents of the volume, I temporarily created a PVC with
a different name and bound it to the iSCSI PersistentVolume.  Using a
pod with both the original PVC and the new PVC mounted, I used `rsync`
to copy the data.  Once the copy completed, I deleted the Pod and both
PVCs, then created a new PVC with the original name (i.e. `jenkins`),
bound to the iSCSI PV.  While doing this, Longhorn, for some reason,
kept re-creating the PVC whenever I would delete it, no matter how I
requested the deletion.  Deleting the PV, the PVC, or the Volume, using
either the Kubernetes API or the Longhorn UI, they would all get
recreated almost immediately.  Fortunately, there was actually enough of
a delay after deleting it before Longhorn would recreate it that I was
able to create the new PVC manually.  Once I did that, Longhorn seemed
to give up.
2024-06-23 09:53:15 -05:00
Dustin 20ef2a287b jenkins: Update to 2.426.2 2024-01-22 18:01:03 -06:00
Dustin 2f9d8ad618 jenkins: Add CA key to ssh_known_hosts
Since (almost) all managed hosts have SSH certificates signed by SSHCA
now, the need to maintain a pseudo-dynamic SSH key list is winding down.
If we include the SSH CA key in the global known hosts file, and
explicitly list the couple of hosts that do not have a certificate, we
can let Ansible use that instead of fetching the host keys on each run.
2024-01-22 17:52:35 -06:00
Dustin ad65a12b66 jenkins: Allow Jenkins to read pod logs
Jenkins needs permission to read pod logs so it can display output from
the JNLP agent if it crashes.
2023-12-27 15:33:36 -06:00
Dustin 95d2dba039 jenkins: Add credentials to sign, publish RPMs
The *jenkins-repohost* Secret contains an SSH private key Jenkins jobs
can use to publish RPM packages to the Yum repo host on
*files.pyrocufflink.blue*.

The *rpm-gpg-key* and *rpm-gpg-key-passphrase* Secrets contain the GnuPG
private key and its encryption passphrase, respectively, that can be
used to sign RPM packages.  This key is trusted by managed nodes on the
Pyrocufflink network.
2023-11-10 15:31:55 -06:00
Dustin 12d3c32855 jenkins: RBAC for K8s Credentials Provider
The [Kubernetes Credentials Provider][0] plugin for Jenkins allows
Jenkins to expose Kubernetes Secret resources as Jenkins Credentials.
Jobs can use them like normal Jenkins credentials, e.g. using
`withCredentials`, `sshagent`, etc.  The only drawback is that every
credential exposed this way is available to every job, at least until
[PR #40][1] is merged.  Fortunately, jobs managed by this Jenkins
instance are all trusted; no anonymous pull requests are possible, so
the risk is mitigated.

[0]: https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/
[1]: https://github.com/jenkinsci/kubernetes-credentials-provider-plugin/pull/40
2023-11-10 15:27:38 -06:00
Dustin 29150f54bb jenkins: Add files.p.b SSH host key
This will allow jobs that need to publish to *files.pyrocufflink.blue*
to verify its SSH host key.
2023-11-10 15:17:06 -06:00
Dustin c5188d042b jenkins: Add default imagePullSecrets for jobs
Setting the `imagePullSecrets` property on the default service account
for the *jenkins-jobs* namespace allows jobs to run from private
container images automatically, without additional configuration in the
pipeline definitions.
2023-11-10 15:13:19 -06:00
Dustin 0e7bd36d34 jenkins: Pin to x86_64 nodes
The Raspberry Pi usually has the most free RAM of all the Kubernetes
nodes, so pods tend to get assigned there even when it would not be
appropriate.  Jenkins, for example definitely does not need to run
there, so let's force it to run on the bigger nodes.
2023-10-22 22:07:22 -05:00
Dustin 52153d0e20 jenkins: Update to 2.414.3 2023-10-22 21:58:47 -05:00
Dustin 7797da19f9 jenkins: Add Argo CD pre-sync hook
Argo CD will delete and re-create this Job each time it synchronizes the
*jenkins* application.  The job creates a snapshot of the Jenkins volume
using an HTTP request to the Longhorn UI.
2023-10-22 21:50:25 -05:00
Dustin 860bfb1e2c jenkins: Set instance label for Argo CD
Argo CD wants every resource managed by an application to have that
application's name as the value of the `app.kubernetes.io/instance`
label.
2023-10-14 07:24:42 -05:00
Dustin 0c8480ba21 jenkins: Update to v2.401.3 2023-08-09 14:04:23 -05:00
Dustin b13479a297 jenkins: Remove dockerconfigjson
This is no longer necessary.
2022-12-28 11:05:40 -06:00
Dustin 10ee364612 jenkins: Add ssh_known_hosts ConfigMap
When cloning/fetching a Git repository in a Jenkins pipeline, the Git
Client plugin uses the configured *Host Key Verification Strategy* to
verify the SSH host key of the remote Git server.  Unfortunately, there
does not seem to be any way to use the configured strategy from the
`git` command line in a Pipeline job, so e.g. `git push` does not
respect it.  This causes jobs to fail to push changes to the remote if
the container they're using does not already have the SSH host key for
the remote in its known hosts database.

This commit adds a ConfigMap to the *jenkins-jobs* namespace that can be
mounted in containers to populate the SSH host key database.
2022-12-10 12:19:33 -06:00
Dustin 889cd29a3c jenkins: Update to 2.375.1
I don't want Jenkins updating itself whenever the pod restarts, so I'm
going to pin it to a specific version.  This way, I can be sure to take
a snapshot of the data volume before upgrading.
2022-12-02 22:15:11 -06:00
Dustin b8ccbd0b09 jenkins: Avoid SELinux relabel of data dir
Setting a static SELinux level for the container allows CRI-O to skip
relabeling all the files in the persistent volume each time the
container starts.  For this to work, the pod needs a special annotation,
and CRI-O itself has to be configured to respect it:

```toml
[crio.runtime.runtimes.runc]
allowed_annotations = ["io.kubernetes.cri-o.TrySkipVolumeSELinuxLabel"]
```

This *dramatically* improves the start time of the Jenkins container.
Instead of taking 5+ minutes, it now starts instantly.

https://github.com/cri-o/cri-o/issues/6185#issuecomment-1334719982
2022-12-01 21:35:02 -06:00
Dustin 404fadc68a jenkins: Run Jenkins in Kubernetes
Running Jenkins in Kubernetes is relatively straightforward.  The
Kubernetes plugin automatically discovers all the connection and
authentication configuration, so a `kubeconfig` file is no longer
necessary.  I did set the *Jenkins tunnel* option, though, so that
agents will connect directly to the Jenkins JNLP port instead of going
through the ingress controller.

Jobs now run in pods in the *jenkins-job* namespace instead of the
*jenkins* namespace.  The latter is now where the Jenkins controller
runs, and the controller should not have permission to modify its own
resources.
2022-11-25 13:38:10 -06:00
Dustin 19ad5023b8 jenkins: Restrict role permissions
Jenkins doesn't really need full control of all resources in its
namespace.  Rather, it only needs to be able to manage Pod and
PersistentVolumeClaim resources.
2022-11-18 13:52:25 -06:00
Dustin ac4d9c1f21 jenkins: Fix typo in README 2022-07-31 00:42:42 -05:00
Dustin 70cb9186a6 Add Jenkins setup resources 2022-07-25 17:52:55 -05:00