K3s Port 6443 and API Server Architecture

The networking architecture of K3s revolves heavily around the communication between the Kubernetes API server and the various components that depend on it, most notably the K3s agents and the internal cluster services. At the center of this communication is port 6443, the default HTTPS listen port for the K3s server. This port serves as the primary gateway for the kubectl CLI, agent node registration, and internal cluster coordination. Because K3s is designed for edge computing, IoT, and resource-constrained environments, the management of this port and the underlying API server configuration is critical for ensuring cluster stability, especially when dealing with restrictive corporate network policies, firewalls, or rootless execution environments.

Understanding port 6443 requires a look at the K3s server's role as the management entity. When a K3s server is initialized, it launches the Kubernetes API server, which listens on this port to handle all REST API requests. This is the entry point for any administrative action, from deploying a pod to querying the status of a node. The reliance on this port extends beyond just external management; internal components and the K3s agents themselves use this endpoint to maintain their connection to the cluster control plane.

The Role of Port 6443 in Cluster Communication

Port 6443 is the default designated port for the HTTPS listener of the K3s server. In a standard deployment, this port is the primary interface for the Kubernetes API server.

  • Direct Fact: The default HTTPS listen port for K3s is 6443.
  • Impact Layer: Users must ensure this port is open and reachable from any node intending to join the cluster as an agent, as well as from any workstation running kubectl. Failure to maintain connectivity on this port results in a complete loss of control over the cluster.
  • Contextual Layer: This port is intrinsically linked to the --https-listen-port flag in the server CLI and the --server flag used by agents.

When an agent is joined to a cluster, the command typically looks like sudo k3s agent --server https://myserver:6443 --token ${NODE_TOKEN}. This demonstrates that the agent must be able to establish a secure TLS connection to the server on port 6443. If the server is hosted on a machine with a firewall, such as a system running firewalld, the port must be explicitly opened.

Firewall Configuration and Network Access

Because port 6443 is the primary communication channel, firewall misconfigurations are a leading cause of installation failure. K3s operates in various environments, from Raspberry Pi clusters to AWS a1.4xlarge servers, each with different networking defaults.

  • Direct Fact: It is recommended to disable firewalld entirely using systemctl disable firewalld --now.
  • Impact Layer: Removing the firewall removes a significant layer of complexity and prevents "connection refused" errors during the agent join process.
  • Contextual Layer: If the firewall must remain active, specific rules are required to allow the API server to function.

If a user chooses to keep firewalld enabled, the following rules are mandatory:

  • firewall-cmd --permanent --add-port=6443/tcp
  • firewall-cmd --permanent --zone=trusted --add-source=10.42.0.0/16
  • firewall-cmd --permanent --zone=trusted --add-source=10.43.0.0/16
  • firewall-cmd --reload

The addition of port 6443/tcp allows the API server to receive traffic. The addition of the 10.42.0.0/16 and 10.43.0.0/16 ranges to the trusted zone is essential for pod-to-pod and pod-to-service communication, ensuring that the internal networking of the cluster is not blocked by the host's security policies.

Customizing the HTTPS Listen Port

In certain enterprise environments, default ports like 6443 may be prohibited by security policies or VM restrictions. K3s provides the flexibility to change this port via the server CLI.

  • Direct Fact: The --https-listen-port flag allows the user to specify a port other than 6443.
  • Impact Layer: This allows K3s to be deployed in environments with strict port-filtering rules, preventing the need to request global firewall exceptions for non-standard ports.
  • Contextual Layer: Changing this port requires synchronization across all agents and administrative tools.

However, changing the port from 6443 to another value (e.g., 46443, 30000, or 36443) can lead to critical failures in internal system pods. In observed cases, specifying a port other than 6443 has caused metric pod failures. Specifically, the metrics-server and local-path-provisioner pods may fail with "connection refused" errors when attempting to reach the API server.

The failure logs for these pods typically indicate a failure to connect to the service IP (e.g., https://10.43.0.1:443). This suggests that while the server is listening on the new custom port, some internal components may still be attempting to communicate via the standard Kubernetes service discovery mechanisms or may be unable to resolve the new port mapping, leading to fatal errors and panics.

Rootless K3s and Port Mapping

Rootless K3s is an execution mode that allows K3s to run without root privileges, which significantly changes how networking and ports are handled.

  • Direct Fact: Rootless K3s runs with networking detached from the host.
  • Impact Layer: The host cannot directly access Services run in Rootless K3s without port forwards to the K3s network namespace.
  • Contextual Layer: To bridge this gap, Rootless K3s includes a controller that automatically binds specific ports to the host.

The Rootless K3s controller handles port binding with a specific offset:

  • Port 6443 and other service ports below 1024 are bound to the host with an offset of 10000.
  • A service on port 80 becomes 10080 on the host.
  • A service on port 8080 remains 8080 because it is above the 1024 threshold.
  • Currently, only LoadBalancer Services are automatically bound in this manner.

This means that in a rootless environment, the standard 6443 port is shifted, and users must be aware of this offset when attempting to reach the API server from the host machine.

Rootless K3s Requirements and Cgroups

Running K3s in rootless mode introduces strict requirements regarding the Linux kernel's control group (cgroup) configuration.

  • Direct Fact: Only pure Cgroup v2 is supported for rootless K3s; Cgroup v1 and Hybrid v1/v2 are not supported.
  • Impact Layer: If a node is in Hybrid mode, K3s may fail to start due to "missing" cgroups, as those groups are still bound to a v1 controller.
  • Contextual Layer: This requirement forces administrators to ensure cgroup v2 delegation is enabled.

To resolve these issues, users must enable cgroup v2 delegation, as detailed in the rootlesscontainer.rs documentation. Without this, the rootless server cannot manage the resources of the containers it spawns.

Docker Integration and Port Mapping

K3s can be run inside Docker containers for local development, which requires explicit port mapping to expose the API server.

  • Direct Fact: Using docker run, the port 6443 must be mapped from the container to the host.
  • Impact Layer: Without -p 6443:6443, the host cannot communicate with the K3s API server, rendering the cluster unreachable from the outside.
  • Contextual Layer: This mapping is essential for copying the k3s.yaml config file and using it with a local kubectl instance.

Example Docker execution command:

bash sudo docker run \ --privileged \ --name k3s-server-1 \ --hostname k3s-server-1 \ -p 6443:6443 \ -d rancher/k3s:v1.24.10-k3s1 \ server

Once the container is running, the administrative kubeconfig can be extracted using:

bash sudo docker cp k3s-server-1:/etc/rancher/k3s/k3s.yaml ~/.kube/config

It is important to note that Docker images for K3s do not allow the + sign in tags; therefore, a - must be used instead (e.g., v1.24.10-k3s1).

Server CLI Options for Networking and Identity

The K3s server CLI provides several flags to refine how the API server listens and advertises itself on the network, including the 6443 port.

  • Direct Fact: The --bind-address flag determines the address the server binds to, defaulting to 0.0.0.0.
  • Impact Layer: This allows administrators to restrict the API server to a specific network interface for security purposes.
  • Contextual Layer: This works in tandem with the --advertise-address and --advertise-port.

The following table details the key listener-related CLI options:

Flag Default Value Description
--https-listen-port 6443 The port the HTTPS server listens on.
--bind-address 0.0.0.0 The address the K3s server binds to.
--advertise-address node-external-ip The address the apiserver uses to advertise to cluster members.
--advertise-port listen-port The port the apiserver uses to advertise to cluster members.
--tls-san N/A Adds additional hostnames or IPs as Subject Alternative Names.

These flags are critical when the API server is behind a load balancer or in a complex network where the internal IP differs from the IP used by agents to connect.

Node Identity and Hostname Requirements

Beyond port 6443, the identity of the node is a prerequisite for a functional cluster.

  • Direct Fact: Two nodes cannot share the same hostname.
  • Impact Layer: Duplicate hostnames cause conflicts in the Kubernetes API, leading to node flapping or registration failure.
  • Contextual Layer: K3s provides mechanisms to handle automated provisioning where hostnames might be reused.

To resolve hostname conflicts, users can employ:

  • The --with-node-id option, which appends a random suffix to the hostname.
  • The --node-name flag or the $K3S_NODE_NAME environment variable to specify a unique name manually.

Architecture and OS Support

K3s is designed to be lightweight and cross-platform, ensuring that the API server and its networking can run on various architectures.

  • Direct Fact: K3s supports x86_64, armhf, and arm64/aarch64.
  • Impact Layer: This enables the deployment of the 6443 API server on devices as small as a Raspberry Pi or as large as an AWS a1.4xlarge server.
  • Contextual Layer: OS-specific requirements may apply, particularly for SELinux.

On systems where SELinux is enabled by default (e.g., CentOS), proper SELinux policies must be installed. The K3s installation script attempts to automate this by installing the SELinux RPM from the Rancher repository, provided it is not an air-gapped installation.

Summary of Cluster Initialization and Agent Join

The interaction with port 6443 is most evident during the initial cluster setup and the subsequent joining of agents.

  1. Start the Server:
    The server is started using sudo k3s server &. This process initializes the API server on port 6443 and writes the kubeconfig to /etc/rancher/k3s/k3s.yaml.

  2. Verify Node Status:
    The command sudo k3s kubectl get node is used to confirm the server is ready.

  3. Join Agents:
    Agents connect using the server's IP and port 6443:
    bash sudo k3s agent --server https://myserver:6443 --token ${NODE_TOKEN}
    The ${NODE_TOKEN} is retrieved from /var/lib/rancher/k3s/server/node-token on the server node.

Analysis of API Server Port Dependencies

The stability of a K3s cluster is fundamentally tied to the reachability of the API server. While the ability to change port 6443 via --https-listen-port suggests total flexibility, the evidence from system pod failures (such as the metrics-server) indicates a deep coupling between the default port and the internal service discovery logic.

When the API server port is changed, the internal cluster services that rely on the kubernetes service (often mapped to 10.43.0.1:443) may experience connectivity issues if the networking layer does not correctly map the internal service port to the new custom listen port. This highlights a critical trade-off: while the API server can be moved to satisfy external network requirements, doing so may introduce internal instability unless the corresponding service configurations are updated.

Furthermore, the rootless execution model shifts the paradigm of port 6443 from a direct host-bound port to a namespaced port. The 10000-offset mechanism is a pragmatic solution to the lack of root privileges, but it adds a layer of cognitive overhead for the administrator. The transition from standard K3s to Rootless K3s requires a shift in how one perceives the "API Server Port," as it is no longer a static 6443 but a dynamic mapping based on the user's permission level.

Sources

  1. K3s Advanced Documentation
  2. K3s GitHub Issue #8030
  3. K3s Official Website
  4. K3s Server CLI Documentation
  5. K3s Installation Requirements

Related Posts