<p>We currently have 2 Kubernetes clusters:</p>

<ul>
<li><p>One setup with Kops running on AWS</p></li>
<li><p>One setup with Kubeadm running on our own hardware</p></li>
</ul>

<p>We want to combine them to only have a single cluster to manage. </p>

<p>The master could end up being on AWS or on our servers, both are fine.</p>

<p>We can't find a way to add nodes configured with one cluster to the other. </p>

<ul>
<li><p><code>kubeadm</code> is not made available on nodes setup with Kops, so we can't do eg <code>kubeadm token create --print-join-command</code></p></li>
<li><p>Kops doesn't seem to have utilities to let us add arbitrary nodes, see <a href="https://stackoverflow.com/questions/50248179/how-to-add-an-node-to-my-kops-cluster-node-in-here-is-my-external-instance">how to add an node to my kops cluster? (node in here is my external instance)</a></p></li>
</ul>

<p>This issue raises the same question but was left unanswered: <a href="https://github.com/kubernetes/kops/issues/5024" rel="nofollow noreferrer">https://github.com/kubernetes/kops/issues/5024</a></p>

<p>You can join the nodes manually, but this is really not a recommend way of doing things.</p>

<p>If you're using kubeadm, you probably already have all the relevant components installed on the workers to have them join in a valid way. What I'd say the process to follow is:</p>

<p>run <code>kubeadm reset</code> on the on-prem in question</p>

<p>login to the kops node, and examine the kubelet configuration:</p>

<p><code>systemctl cat kubelet</code></p>

<p>In here, you'll see the kubelet config is specified at <code>/etc/sysconfig/kubelet</code>. You'll need to copy that file and ensure the on-prem node has it in its systemd startup config</p>

<p>Copy the relevent config over to the on-prem node. You'll need to remove any references to the AWS cloud provider stuff, as well as make sure the hostname is valid. Here's an example config I copied from a kops node, and modified:</p>

<pre><code>DAEMON_ARGS="--allow-privileged=true --cgroup-root=/ --cluster-dns=100.64.0.10 --cluster-domain=cluster.local --enable-debugging-handlers=true - --feature-gates=ExperimentalCriticalPodAnnotation=true --hostname-override=&lt;my_dns_name&gt; --kubeconfig=/var/lib/kubelet/kubeconfig --network-plugin=cni --node-labels=kops.k8s.io/instancegroup=onpremnodes,kubernetes.io/role=node,node-role.kubernetes.io/node= --non-masquerade-cidr=100.64.0.0/10 --pod-infra-container-image=gcr.io/google_containers/pause-amd64:3.0 --pod-manifest-path=/etc/kubernetes/manifests --register-schedulable=true --v=2 --cni-bin-dir=/opt/cni/bin/ --cni-conf-dir=/etc/cni/net.d/"
HOME="/root"
</code></pre>

<p>Also, examine the kubelet kubeconfig configuration (it should be at <code>/var/lib/kubelet/kubeconfig</code>). This is the config which tells the kubelet which API server to register with. Ensure that exists on the on-prem node</p>

<p>This should get your node joining the API. You may have to go through some debugging as you go through this process.</p>

<p>I really don't recommend doing this though, for the following reasons:</p>

<ul>
<li>Unless you use node-labels in a sane way, you're going to have issues provisioning cloud elements. The kubelet will interact with the AWS API regularly, so if you try use service of type LoadBalancer or any cloud volumes, you'll need to pin the workloads to specific nodes. You'll need to make heavy uses of <a href="https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/" rel="nofollow noreferrer">taints and tolerations.</a></li>
<li>Kubernetes workers aren't designed to connect over a WAN. You're probably going to see issue at some point with network latency etc</li>
<li>If you do choose to go down this route, you'll need to ensure you have TLS configured in both directions for the API &lt;-> kubelet communication, or a VPN.</li>
</ul>
