5

When trying to access a k3s Kubernetes cluster that's running on another machine, I get the following error message:

E0204 19:13:27.185678    8066 proxy_server.go:147]
Error while proxying request:
  tls: failed to verify certificate:
    x509: certificate is valid for kubernetes, kubernetes.default,
    kubernetes.default.svc, kubernetes.default.svc.cluster.local,
    localhost, node1, not node1.lan

node1 is the hostname of the machine serving as the master node in the k3s cluster. However, hosts on my LAN are suffixed with .lan, so node1 is available at node1.lan.

I believe I am receiving the error above because the certificate generated by k3s doesn't include node1.lan. I would like to modify/replace the certificate with one that also includes node1.lan.

I have already tried the instructions documented on the k8s site. However, as I am using k3s not k8s, some details differ.

I'm quite a k8s amateur, so any guidance would be appreciated.

James
  • 153

3 Answers3

4

I also struggled for quite some time with this exact issue, however I think I found the correct way to fix this in k3s.

The naive solution

For a long time i just ran all kubectl commands with --insecure-skip-tls-verify which worked fine, but became annoying after some time (and is insecure).

The correct way

What finally solved my issue with accessing my k3s cluster from another domain/machine was running the k3s server command with the --tls-san <domain name> flag as documented here https://docs.k3s.io/cli/server.

To make this permanent, the domain can either be added to the k3s config file or to the k3s systemd/openrc service depending on what your system is using.

I'm using Alpine Linux and openrc, this means I had to first stop the k3s service with rc-service k3s stop then alter the service file in /etc/init.d/k3s and change command_args="server" to command_args="server --tls-san <domain> before starting the service again with rc-service k3s start.

I yoloed this when I set it up, and did not consider accidentally deleting or breaking services on the node etc. Draining the node or otherwise gracefully shutting down containers is probably ideal before stopping the service.

This is how my k3s openrc service file ended up looking:

#!/sbin/openrc-run

depend() { after network-online want cgroups }

start_pre() { rm -f /tmp/k3s.* }

supervisor=supervise-daemon name=k3s command="/usr/local/bin/k3s"

This is the line i changed

command_args="server --tls-san <domain>
>>/var/log/k3s.log 2>&1"

output_log=/var/log/k3s.log error_log=/var/log/k3s.log

pidfile="/var/run/k3s.pid" respawn_delay=5 respawn_max=0

set -o allexport if [ -f /etc/environment ]; then . /etc/environment; fi if [ -f /etc/rancher/k3s/k3s.env ]; then . /etc/rancher/k3s/k3s.env; fi set +o allexport

Where <domain> is the domain that kubectl complains about when running any kubectl command against the cluster.

The better solution is probably to alter the k3s config file under with default path /etc/rancher/k3s/config.yaml. Example from the documentation:

write-kubeconfig-mode: "0644"
tls-san:
  - "foo.local"
node-label:
  - "foo=bar"
  - "something=amazing"
cluster-init: true

If you are using a system with systemd the default path to the k3s service should be /etc/systemd/system and there should be a line with ExecStart=k3s server under [service] (not validated this). To start and stop the service sudo systemctl stop k3s and sudo systemctl start k3s

Hope this helps!

2

The error message indicates that the certificate presented by the k3s cluster is not valid for the domain name node1.lan. This is likely because the certificate was generated for a different domain name, such as kubernetes.default.svc. Because the subject name in the Kubernetes cluster certificate that you wish to monitor differs from the endpoint that you have set in the Kubernetes target configuration.

Put the IP into the kube config it works just fine, follow this blog by Micro focus for more details.

Workaround:1

Rotate certificates with custom CA helps to add a domain to K3s certificates

As per this doc by K3s

  • To rotate custom CA certificates, use the k3s certificate rotate-ca subcommand. Updated files must be staged into a temporary directory, loaded into the datastore and k3s must be restarted on all nodes to use the updated certificates.
  • By doing this, all cluster certificates including server certificates with the new domains will be generated.
  • For complete certificate management across the cluster, use custom CA rotation.

Workaround:2

To add domain to k3s certificate follow below steps:

  • Create a new certificate that includes additional domains
  • Create a certificate signing request (CSR) and edit the CSR to include the domain name.
  • Submit that k3s Certificate Authority to get it signed with the help of CSR
  • Restart the k3s service on all nodes to access the k3s Kubernetes cluster without getting the error message

Refer to Setting up your own K3S home cluster BY BAS BREMER for more information.

0

Here is my solution to the problem:

  1. Run kubectl edit secrets -n kube-system k3s-serving, and create an entry under metadata.annotations: listener.cattle.io/cn-x.x.x.x: x.x.x.x, which means adding the IP address or domain name x.x.x.x to the TLS SAN.
  2. Run k3s certificate rotate to regenerate the TLS certificate.
  3. Run systemctl restart k3s to restart k3s.

That should do it.

jiegec
  • 1