해당 글은 개인으로 사용하는 미니 PC에 Kubernetes를 설치하고, 기본적인 설정을 다룬 내용을 간략하게 정리한 글입니다.
관련해서 왜 이렇게 설치를 했는지에 대해서는 지속적으로 추가 업데이트 할 예정입니다.
쿠버네티스는 기본적으로 SELinux Mode가 permissive로 설정되어 있어야 합니다.
( 관련 문서: installing-kubeadm-kubelet-and-kubectl )
따라서 아래의 명령어를 통해 SELinux 설정을 변경해줍니다.
# Set SELinux in permissive mode (effectively disabling it)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
그리고 kubelet은 스왑 메모리가 감지되면 정상적으로 동작하지 않습니다.
( 관련 문서: install-kubeadm )
따라서 아래 명령어를 통해 스왑 메모리 설정을 비활성화시켜 줍니다.
sudo swapoff -a
net.ipv4.ip_forward 옵션은 리눅스 커널이 IPv4 패킷을 다른 인터페이스로 라우팅할 지에 대한 여부를 설정하는 옵션입니다.
쿠버네티스는 기본적으로 CNI를 통해 Pod / Node간 통신을 처리하는 구조로 되어있기 때문에, 라우팅/포워딩을 할 수 있도록 1로 설정해줍니다.
sudo sysctl -w net.ipv4.ip_forward=1
만약 이 설정을 하지 않을 경우 컨트롤 플레인 초기화 시 아래와 같은 에러가 발생할 수 있습니다.
[ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forward contents are not set to 1
쿠버네티스는 기본적으로 사용되는 포트가 존재합니다.
이 중 Kubernetes API server 포트와 Kubelet API 포트는 필수적으로 사용되는 포트이기 때문에 OS 방화벽에서 해당 포트들을 허용처리 해주어야 합니다.
쿠버네티스에서 기본적으로 사용되는 포트와 MySQL, Redis 등을 사용할 때 마다 방화벽을 설정하는 것도 좋지만, 이번 글에서는 귀찮으므로 OS 방화벽 설정을 해제하는 방법으로 진행하고자 합니다.
systemctl stop firewalld
systemctl disable firewalld
만약 이러한 설정을 하지 않을 경우 컨트롤 플레인 초기화 시 아래와 같은 에러가 발생할 수 있습니다.
[WARNING Firewalld]: firewalld is active, please ensure ports [6443 10250] are open or your cluster may not function correctly
쿠버네티스는 기본적으로 Pod에서 컨테이너를 실행시키기 위해 container runtime을 사용합니다.
사용할 수 있는 Container Runtime 목록
- containerd
- CRI-O
- Docker Engine
- Mirantis Container Runtime
그리고 이 글에서는 containerd를 사용하는 방법으로 진행합니다.
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install containerd.io
mv /etc/containerd/config.toml /etc/containerd/config.toml.bak # 삭제하지 않고 bakup으로 보관
service containerd restart
만약 이러한 설정을 하지 않을 경우 컨트롤 플레인 초기화 시 아래와 같은 에러가 발생할 수 있습니다.
[preflight] WARNING: Couldn't create the interface used for talking to the container runtime: failed to create new CRI runtime service: validate service connection: validate CRI v1 runtime API for endpoint "unix:///var/run/containerd/containerd.sock": rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.34/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.34/rpm/repodata/repomd.xml.key
EOF
dnf install kubelet kubeadm kubectl

kubeadm init --apiserver-advertise-address={IP_ADDRESS}
아래와 같이 메세지가 응답되었다면 Kubernetes control-plane 초기 설정에 성공한 것입니다.
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join {IP Address:Port} --token {token값} --discovery-token-ca-cert-hash {hash값}
그러면 안내를 따라서 아래의 명령을 실행해줍니다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
쿠버네티스는 기본적으로 컨트롤 플레인과 워커 노드로 구성됩니다.
기본적으로 컨트롤 플레인 노드는 클러스터의 운영, 관리의 역할을 수행하기 때문에 Pod를 띄울 수 없으며, kubeadm init을 통해 컨트롤 플레인을 구성하고, kubeadm join을 통해 워커 노드를 추가하여 Pod를 띄우는 것이 일반적인 방법입니다.
하지만 지금처럼 쿠버네티스를 단일 서버로 구성하는 경우 컨트롤 플레인 노드에서 Pod를 실행할 수 있게끔 taint를 변경해주어야 합니다.
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

참고 문서: https://kubernetes.io/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy/
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
kubectl get pods --all-namespaces
[root@localhost tmp]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-b45f49df6-zq85q 1/1 Running 0 35m
kube-system calico-node-6qr5n 1/1 Running 0 35m
kube-system coredns-66bc5c9577-mdvrd 1/1 Running 0 42m
kube-system coredns-66bc5c9577-pvwdq 1/1 Running 0 42m
kube-system etcd-localhost.localdomain 1/1 Running 0 42m
kube-system kube-apiserver-localhost.localdomain 1/1 Running 0 42m
kube-system kube-controller-manager-localhost.localdomain 1/1 Running 0 42m
kube-system kube-proxy-lw4z6 1/1 Running 0 42m
kube-system kube-scheduler-localhost.localdomain 1/1 Running 0 42m
kubectl get services --all-namespaces
[root@localhost tmp]# kubectl get services --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 42m
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 42m
sudo dnf install helm
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/
helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kubernetes-dashboard
아래와 같이 나오면 성공입니다.
Release "kubernetes-dashboard" does not exist. Installing it now.
NAME: kubernetes-dashboard
LAST DEPLOYED: Sat Nov 29 00:13:33 2025
NAMESPACE: kubernetes-dashboard
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
*************************************************************************************************
*** PLEASE BE PATIENT: Kubernetes Dashboard may need a few minutes to get up and become ready ***
*************************************************************************************************
Congratulations! You have just installed Kubernetes Dashboard in your cluster.
To access Dashboard run:
kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard-kong-proxy 8443:443
NOTE: In case port-forward command does not work, make sure that kong service name is correct.
Check the services in Kubernetes Dashboard namespace using:
kubectl -n kubernetes-dashboard get svc
Dashboard will be available at:
https://localhost:8443
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kubernetes-dashboard
namespace: kubernetes-dashboard
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
ingressClassName: nginx
rules:
- host: {dashboard-host}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kubernetes-dashboard-kong-proxy
port:
number: 443

ingress에서 설정한 {dashboard-host} 도메인으로 접속을 했을 때 아래와 같이 나오면 성공입니다.
https://{dashboard-host}

Kubernetes Dashboard에 접속할 때 사용할 수 있는 인증 전략은 여러가지가 있습니다.
그 중 아주 기본적이고 간단하게 접속할 수 있는 Bearer token을 수동으로 발급받아 접속하는 방법으로 설명하려고 합니다.
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
kubectl -n kubernetes-dashboard create token admin-user
kubectl -n kubernetes-dashboard create token admin-user
{발급된 Bearer Token 어쩌구}
발급된 Bearer Token을 입력 후 접속을 했을 때 아래와 같이 나온다면 성공입니다.

아래처럼 서비스를 활성화 및 시작하여 OS가 재부팅될 때 자동으로 실행되게끔 처리합니다.
sudo systemctl enable containerd
sudo systemctl start containerd
sudo systemctl enable kubelet
sudo systemctl start kubelet