diff --git a/.github/actions/spelling/README.md b/.github/actions/spelling/README.md
new file mode 100644
index 000000000000..dcd237ba23dc
--- /dev/null
+++ b/.github/actions/spelling/README.md
@@ -0,0 +1,15 @@
+# check-spelling/check-spelling configuration
+
+File | Purpose | Format | Info
+-|-|-|-
+[dictionary.txt](dictionary.txt) | Replacement dictionary (creating this file will override the default dictionary) | one word per line | [dictionary](https://github.com/check-spelling/check-spelling/wiki/Configuration#dictionary)
+[allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow)
+[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject)
+[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)
+[only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only)
+[patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
+[expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)
+[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)
+
+Note: you can replace any of these files with a directory by the same name (minus the suffix)
+and then include multiple files inside that directory (with that suffix) to merge multiple files together.
diff --git a/.github/actions/spelling/advice.md b/.github/actions/spelling/advice.md
new file mode 100644
index 000000000000..c83423a8ef61
--- /dev/null
+++ b/.github/actions/spelling/advice.md
@@ -0,0 +1,25 @@
+
+If the flagged items do not appear to be text
+
+If items relate to a ...
+* well-formed pattern.
+
+ If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
+ try adding it to the `patterns.txt` file.
+
+ Patterns are Perl 5 Regular Expressions - you can [test](
+https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
+
+ Note that patterns can't match multiline strings.
+
+* binary file.
+
+ Please add a file path to the `excludes.txt` file matching the containing file.
+
+ File paths are Perl 5 Regular Expressions - you can [test](
+https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
+
+ `^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
+../tree/HEAD/README.md) (on whichever branch you're using).
+
+
diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt
new file mode 100644
index 000000000000..44d9f7015e62
--- /dev/null
+++ b/.github/actions/spelling/excludes.txt
@@ -0,0 +1,45 @@
+# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
+(?:^|/)(?i)COPYRIGHT
+(?:^|/)(?i)LICEN[CS]E
+(?:^|/)go\.sum$
+(?:^|/)package(?:-lock|)\.json$
+(?:^|/)vendor/
+ignore$
+\.ai$
+\.avi$
+\.bmp$
+\.bz2$
+\.crt$
+\.DS_Store$
+\.eot$
+\.gif$
+\.gitattributes$
+\.graffle$
+\.gz$
+\.icns$
+\.ico$
+\.jar$
+\.jpe?g$
+\.key$
+\.lock$
+\.map$
+\.min\..
+\.mod$
+\.mp[34]$
+\.ocf$
+\.otf$
+\.pdf$
+\.pem$
+\.png$
+\.psd$
+\.svg$
+\.tgz$
+\.ttf$
+\.wav$
+\.woff2?$
+\.zip$
+^THIRD_PARTY_LICENSES$
+^\.github/
+^\Q.gitmodules\E$
+^\Qcharts/index.yaml\E$
+^\Qwebsite/static/favicons/browserconfig.xml\E$
diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt
new file mode 100644
index 000000000000..748dbeea57b4
--- /dev/null
+++ b/.github/actions/spelling/expect.txt
@@ -0,0 +1,433 @@
+addon
+adfdb
+admissionregistration
+alertmanager
+amazonaws
+amd
+amdgpu
+amiid
+api
+apiextensions
+apimachinery
+apiobject
+apiserver
+apps
+args
+Arns
+asciicheck
+Atoi
+authn
+authz
+Autoconfigure
+autogenerated
+autoscaler
+autoscaling
+aws
+awscli
+AWSEC
+awserr
+awsmanpol
+AWSTo
+azs
+baseurl
+battletest
+baz
+binpack
+binpacking
+blackfriday
+blog
+bootstrappers
+breadcrumb
+brightgreen
+btn
+Burstable
+bwagner
+calcs
+CAPI
+Catmull
+cce
+cfn
+cidr
+clg
+clientgoscheme
+Clientset
+cloudformation
+cloudprovider
+cloudprovidermetrics
+Cmp
+cmw
+CNCF
+cni
+codebase
+codegen
+colocation
+config
+configmap
+containerd
+controllerruntime
+coveraged
+coverpkg
+coverprofile
+crd
+crmetrics
+csv
+ctx
+currentpath
+daemonset
+datasource
+Debugf
+deckarep
+deepcopy
+defragmentation
+deletecopy
+deprov
+deprovision
+deprovisioning
+deserialize
+Deserializer
+dirname
+dirs
+disjoiner
+distro
+dkr
+dns
+DNSIP
+Dnz
+docsy
+dropdown
+Ebs
+ecr
+eks
+eksctl
+elif
+ellistarn
+emr
+ENABLEGITINFO
+eni
+entitlements
+envtest
+errcheck
+Errorf
+errorlint
+etarn
+ETCD
+evictable
+expr
+FAQs
+farbox
+fargate
+Fatalf
+favicon
+fcd
+FFD
+fileno
+filepath
+finalizer
+finditer
+Fpga
+fullname
+func
+fzipp
+gci
+gcp
+gcr
+getcwd
+github
+gnet
+GOARCH
+gocyclo
+GOFLAGS
+golang
+golangci
+goldmark
+golicense
+gomega
+google
+GOPATH
+gosec
+gpu
+gpuapp
+grafana
+grep
+Groupless
+gvk
+Hashi
+hashicorp
+hashstructure
+haspopup
+healthz
+heatmap
+hebdf
+highlighter
+homepage
+hostname
+HPC
+href
+html
+http
+hvm
+Hypervisor
+iam
+iamidentitymapping
+iamserviceaccount
+ianlewis
+ical
+ico
+ics
+Idempotently
+iface
+imdario
+IMDS
+img
+Impl
+Infof
+injectabletime
+instancegroup
+instancetype
+intstr
+irsa
+itemgetter
+jbk
+JJc
+jjones
+json
+jsonencode
+jsonpath
+Jvd
+karpenter
+kcm
+kld
+KMGTPE
+knative
+knativeinjection
+kube
+kubebuilder
+Kubecon
+kubeconfig
+kubectl
+kubelet
+kubernetes
+labelledby
+ldflags
+len
+lifecycle
+linenos
+linewidth
+linting
+linux
+localhost
+loglevel
+logr
+LRMHZ
+MAKECMDGOALS
+markdownify
+maxskew
+mergo
+metadata
+MGTPE
+mikefarah
+minheap
+mitchellh
+mkdir
+mktemp
+mmap
+Mmpl
+Mugp
+multierr
+mutatingwebhookconfigurations
+Mutex
+myapp
+mygpucontainer
+mygpupod
+myimage
+myprofile
+namespace
+namespaced
+namespacedname
+navbar
+netural
+nilset
+nindent
+njtran
+Nlc
+nodekubernetesioinstance
+nodeselector
+nolint
+noopener
+Nop
+norwoodj
+notkaperner
+Npi
+npm
+numk
+Nvb
+nvidia
+oidc
+ojsonpath
+omitempty
+onboarded
+onsi
+openapi
+OSX
+outputdir
+overwriter
+packables
+Pallinder
+params
+patrickmn
+pdb
+percentunit
+permalink
+piechart
+pipefail
+Placeholders
+plugin
+Pluralizion
+png
+PODNAME
+podspec
+pointradius
+Poppins
+prateekgogia
+prealloc
+preemptible
+printf
+protobuf
+provisionable
+provisioners
+ptr
+pwd
+pygments
+qfdeof
+qps
+QZZQ
+randomdata
+rbac
+readyz
+regex
+relref
+reqs
+requeue
+resourcesemantics
+retriable
+Retryer
+retval
+rgba
+scalability
+sdk
+searchdirectory
+searchpath
+serializer
+serviceaccount
+sharedmain
+Shortcode
+should've
+sigs
+sitemap
+SPJ
+Sprintf
+src
+ssm
+SSMAPI
+ssmiface
+stacktrace
+startinformers
+stderr
+stdin
+stdout
+strconv
+sts
+stylecheck
+subdir
+subneta
+subnetb
+subnetc
+subreconciler
+subresource
+substr
+sudo
+svg
+sys
+tabern
+templating
+TEMPOUT
+terraform
+testclient
+testenv
+testzone
+Tgc
+timepicker
+timezone
+TLS
+todo
+toolchain
+tooltip
+topdown
+tparallel
+tsbuckets
+ttl
+uber
+uberwriter
+uid
+uint
+Uncomment
+unconstrain
+underutilized
+Unescape
+uninstall
+uninstalling
+unparam
+unschedulable
+updatecopy
+url
+userdata
+userguide
+username
+usr
+utf
+utilruntime
+utils
+Utuw
+UVj
+validatingwebhookconfigurations
+vals
+vcpu
+Vec
+versioned
+versioning
+virtualization
+virtualized
+vmimport
+vpc
+VRHVd
+walkthrough
+webhook
+website
+westzones
+wiki
+wikipedia
+wildcards
+WJRUF
+workflow
+workqueue
+writerow
+www
+xargs
+XAu
+xaxis
+xlarge
+xml
+xvda
+xyproto
+yaml
+yaxes
+yaxis
+YBuckets
+yml
+Ymt
+youtu
+youtube
+YXIu
+zapr
+ZGVv
+ZWJk
diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt
new file mode 100644
index 000000000000..16baa7384b48
--- /dev/null
+++ b/.github/actions/spelling/patterns.txt
@@ -0,0 +1,30 @@
+# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
+
+# GitHub SHAs
+\bapi.github\.com/repos/[^/]+/[^/]+/[^/]+/[0-9a-f]+\b
+(?:\[[0-9a-f]+\]\(https:/|)/(?:www\.|)github\.com/[^/]+/[^/]+(?:/[^/]+/[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
+\bgithub\.com/[^/]+/[^/]+[@#][0-9a-f]+\b
+# githubusercontent
+/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
+# gist github
+/gist\.github\.com/[^/]+/[0-9a-f]+
+# git.io
+\bgit\.io/[0-9a-zA-Z]+
+# GitHub JSON
+"node_id": "[-a-zA-Z=;:/0-9+]*"
+# Contributor
+\[[^\]]+]\(https://github\.com/[^/]+\)
+# GHSA
+GHSA(?:-[0-9a-z]{4}){3}
+
+# sha256
+sha256:[0-9a-f]+
+
+# v#
+[Vv]\d+(?:\b|(?=[a-zA-Z_]))
+
+# Python stringprefix / binaryprefix
+\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'
+
+# ignore long runs of a single character:
+\b([A-Za-z])\g{-1}{3,}\b
diff --git a/.github/actions/spelling/reject.txt b/.github/actions/spelling/reject.txt
new file mode 100644
index 000000000000..a5ba6f6390ef
--- /dev/null
+++ b/.github/actions/spelling/reject.txt
@@ -0,0 +1,7 @@
+^attache$
+benefitting
+occurence
+Sorce
+^[Ss]pae
+^untill
+^wether
diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml
new file mode 100644
index 000000000000..c6844bc52972
--- /dev/null
+++ b/.github/workflows/spelling.yml
@@ -0,0 +1,67 @@
+name: Spell checking
+on:
+ push:
+ branches: ["**"]
+ tags-ignore: ["**"]
+ pull_request_target:
+
+jobs:
+ spelling:
+ name: Spell checking
+ permissions:
+ contents: read
+ pull-requests: read
+ outputs:
+ internal_state_directory: ${{ steps.spelling.outputs.internal_state_directory }}
+ runs-on: ubuntu-latest
+ if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'"
+ concurrency:
+ group: spelling-${{ github.event.pull_request.number || github.ref }}
+ # note: If you use only_check_changed_files, you do not want cancel-in-progress
+ cancel-in-progress: true
+ steps:
+ - name: checkout
+ uses: actions/checkout@v2
+ - name: checkout-merge
+ if: "contains(github.event_name, 'pull_request')"
+ uses: check-spelling/checkout-merge@v0.0.0
+ - name: check-spelling
+ if: env.MERGE_FAILED != '1'
+ id: spelling
+ uses: check-spelling/check-spelling@v0.0.20-alpha4
+ with:
+ suppress_push_for_open_pull_request: 1
+ post_comment: 0
+ - name: store-comment
+ if: failure() && steps.spelling.outputs.internal_state_directory
+ uses: actions/upload-artifact@v2
+ with:
+ retention-days: 1
+ name: "check-spelling-comment-${{ github.run_id }}"
+ path: |
+ ${{ steps.spelling.outputs.internal_state_directory }}
+
+ comment:
+ name: Comment
+ runs-on: ubuntu-latest
+ needs: spelling
+ permissions:
+ contents: write
+ pull-requests: write
+ if: always() && needs.spelling.result == 'failure' && needs.spelling.outputs.internal_state_directory
+ steps:
+ - name: checkout
+ uses: actions/checkout@v2
+ - name: set up
+ run: |
+ mkdir /tmp/data
+ - name: retrieve-comment
+ uses: actions/download-artifact@v2
+ with:
+ name: "check-spelling-comment-${{ github.run_id }}"
+ path: /tmp/data
+ - name: comment
+ uses: check-spelling/check-spelling@v0.0.20-alpha4
+ with:
+ custom_task: comment
+ internal_state_directory: /tmp/data