Cloudnet K8s Deploy 1주차 스터디를 진행하며 정리한 글입니다.
이번 포스팅에서는 Kubernetes의 내부 동작을 보다 깊이 이해하기 위해, 자동화된 설치 도구를 벗어나 Kubernetes the Hard Way 방식으로 클러스터를 구성해 봅니다.
- CA, TLS 인증서, kubeconfig를 직접 구성하며 Kubernetes 구성 요소 간 mTLS 통신 구조 이해
- 주요 컴포넌트를 systemd 서비스로 기동하여 실제 운영 환경과 유사한 구조 확인
- kind Kubernetes와의 비교를 통해 설정 방식과 동작 차이 분석
- macOS / Windows(WSL2)에서 동일하게 실습 가능한 Vagrant 기반 환경 제공
- 스크립트 자동화 대신 단계별 명령 실행과 설정 파일 설명 중심으로 실습 진행
이번 포스팅에서 구성할 클러스터는 아래와 같습니다.

| Name | Description | CPU | RAM | NIC1 | NIC2 | Hostname |
| jumpbox | Administration host | 2 | 1536 MB | 10.0.2.15 | 192.168.10.10 | jumpbox |
| server | Kubernetes server | 2 | 2GB | 10.0.2.15 | 192.168.10.100 | server.kubernetes.local server |
| node-0 | Kubernetes worker | 2 | 2GB | 10.0.2.15 | 192.168.10.101 | node-0.kubernetes.local node-0 |
| node-1 | Kubernetes worker | 2 | 2GB | 10.0.2.15 | 192.168.10.102 | node-1.kubernetes.local node-1 |
실습을 진행한 자료는 아래 Github 내용을 바탕으로 진행하였습니다.
https://github.com/kelseyhightower/kubernetes-the-hard-way
GitHub - kelseyhightower/kubernetes-the-hard-way: Bootstrap Kubernetes the hard way. No scripts.
Bootstrap Kubernetes the hard way. No scripts. Contribute to kelseyhightower/kubernetes-the-hard-way development by creating an account on GitHub.
github.com
기본 환경 설정 (Kind, Jumpbox 세팅)
kind와 krew 플러그인 도구를 설치합니다.
> kind create cluster --name myk8s --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
- role: worker
EOF
> kind get nodes --name myk8s 13:40:04
myk8s-control-plane
myk8s-worker
> kubens default
VirtualBox와 Vagrant를 설치하고, 실습용 가상머신을 배포합니다.
# Vagrantfile , init_cfg.sh 파일 다운로드
> curl -O https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/k8s-hardway/Vagrantfile
> curl -O https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/k8s-hardway/init_cfg.sh
# 실습용 가상 머신 배포
> vagrant up
# 실습용 OS 이미지 자동 다운로드 확인
> vagrant box list 5m 30s 13:36:01
bento/debian-12 (virtualbox, 202510.26.0, (arm64))
bento/ubuntu-24.04 (virtualbox, 202502.21.0, (arm64))
bento/ubuntu-24.04 (virtualbox, 202508.03.0, (arm64))
# 배포된 가상머신 확인
> vagrant status 13:37:31
Current machine states:
jumpbox running (virtualbox)
server running (virtualbox)
node-0 running (virtualbox)
node-1 running (virtualbox)
This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.
> vagrant ssh jumpbox 13:41:19
Linux jumpbox 6.1.0-40-arm64 #1 SMP Debian 6.1.153-1 (2025-09-20) aarch64
This system is built by the Bento project by Chef Software
More information can be found at https://github.com/chef/bento
Use of this system is acceptance of the OS vendor EULA and License Agreements.
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@jumpbox:~#
Jumpbox에 필요한 파일들을 설치합니다.
| 설치 항목 | 버전 |
| k8s 관련 (kube-apiserver, kubelet 등) | 1.32.2 |
| etcd | 3.6.0 |
| containerd | 2.1.0 |
| runc | 1.3.0 |
## vagrant 계정 로그인 시 'sudo su -' 실행으로 root 계정 전환됨
> cat /home/vagrant/.bashrc | tail -n 1
sudo su -
> apt-get update && apt install tree git jq yq unzip vim sshpass -y
> pwd
> git clone --depth 1 https://github.com/kelseyhightower/kubernetes-the-hard-way.git
> cd kubernetes-the-hard-way
> tree
.
├── ca.conf
├── configs
│ ├── 10-bridge.conf
│ ├── 99-loopback.conf
│ ├── containerd-config.toml
│ ├── encryption-config.yaml
│ ├── kube-apiserver-to-kubelet.yaml
│ ├── kubelet-config.yaml
│ ├── kube-proxy-config.yaml
│ └── kube-scheduler.yaml
├── CONTRIBUTING.md
├── COPYRIGHT.md
├── docs
│ ├── 01-prerequisites.md
│ ├── 02-jumpbox.md
│ ├── 03-compute-resources.md
│ ├── 04-certificate-authority.md
│ ├── 05-kubernetes-configuration-files.md
│ ├── 06-data-encryption-keys.md
│ ├── 07-bootstrapping-etcd.md
│ ├── 08-bootstrapping-kubernetes-controllers.md
│ ├── 09-bootstrapping-kubernetes-workers.md
│ ├── 10-configuring-kubectl.md
│ ├── 11-pod-network-routes.md
│ ├── 12-smoke-test.md
│ └── 13-cleanup.md
├── downloads-amd64.txt
├── downloads-arm64.txt
├── LICENSE
├── README.md
└── units
├── containerd.service
├── etcd.service
├── kube-apiserver.service
├── kube-controller-manager.service
├── kubelet.service
├── kube-proxy.service
└── kube-scheduler.service
# CPU 아키텍처 확인
> dpkg --print-architecture
arm64
# CPU 아키텍처 별 다운로드 목록 정보 다름
> cat downloads-$(dpkg --print-architecture).txt
# wget 으로 다운로드 실행
> wget -q --show-progress \
--https-only \
--timestamping \
-P downloads \
-i downloads-$(dpkg --print-architecture).txt
Computing Resource 프로비저닝
SSH 접속 환경 설정을 구성합니다.
# Machine Database (서버 속성 저장 파일) : IPV4_ADDRESS FQDN HOSTNAME POD_SUBNET
## 참고) server(controlplane)는 kubelet 동작하지 않아서, 파드 네트워크 대역 설정 필요 없음
> cat <<EOF > machines.txt
192.168.10.100 server.kubernetes.local server
192.168.10.101 node-0.kubernetes.local node-0 10.200.0.0/24
192.168.10.102 node-1.kubernetes.local node-1 10.200.1.0/24
EOF
> while read IP FQDN HOST SUBNET; do
echo "${IP} ${FQDN} ${HOST} ${SUBNET}"
done < machines.txt
192.168.10.100 server.kubernetes.local server
192.168.10.101 node-0.kubernetes.local node-0 10.200.0.0/24
192.168.10.102 node-1.kubernetes.local node-1 10.200.1.0/24
# Configuring SSH Access 설정
# sshd config 설정 파일 확인 : 이미 암호 기반 인증 접속 설정 되어 있음
> grep "^[^#]" /etc/ssh/sshd_config
Include /etc/ssh/sshd_config.d/*.conf
KbdInteractiveAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
UseDNS no
GSSAPIAuthentication no
PasswordAuthentication yes
PermitRootLogin yes
# Generate a new SSH key
> ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa
Generating public/private rsa key pair.
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:fcS3G/41qQLQ94d8DyJFtucYtWin1EOMgBj5pU5lTV8 root@jumpbox
The key's randomart image is:
+---[RSA 3072]----+
| .+ ..+.o E|
| o . +.=.+. |
| ..= oo*o. |
| .+o oB.*. |
| oS o++B+. |
| ....+=o=.|
| .. .=+o|
| . ..+|
| .. .|
+----[SHA256]-----+
> ls -l /root/.ssh
total 8
-rw------- 1 root root 2602 Jan 10 13:51 id_rsa
-rw-r--r-- 1 root root 566 Jan 10 13:51 id_rsa.pub
# Copy the SSH public key to each machine
> while read IP FQDN HOST SUBNET; do
sshpass -p 'qwe123' ssh-copy-id -o StrictHostKeyChecking=no root@${IP}
done < machines.txt
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -o 'StrictHostKeyChecking=no' 'root@192.168.10.100'"
and check to make sure that only the key(s) you wanted were added.
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -o 'StrictHostKeyChecking=no' 'root@192.168.10.101'"
and check to make sure that only the key(s) you wanted were added.
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -o 'StrictHostKeyChecking=no' 'root@192.168.10.102'"
and check to make sure that only the key(s) you wanted were added.
> while read IP FQDN HOST SUBNET; do
ssh -n root@${IP} cat /root/.ssh/authorized_keys
done < machines.txt
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDzGyBAxcCEBJtrtNhudPuHchrV7a5t7GRWNq4r7ew/KztHsScspWB3tJIeDd4+TQgb5qexNUmwslBqoxYW6Lp8zoGiFJrVoj9GFO1O4iZimnHCIqzhufmkYp/FQuDnEsQi7tPQAjYPTojZfhvgpW4Z09+gPWpyl40P9KVOvGETtocLAdJACcL+I6uq+2JFKG6GnDHbER7zhXYngJKAizj/2t/Dx6l6SC/RfR8Z8jLUBgEguy8RAPQI8k20qYP4ONl77J8/3aQ7XJQptFODfQRmve1KRf8o509AjoDyktOG7LyAFxxlN8RVEDW5gN857WIzjOdnzirAIkt3+6ExrNIyb/XF4JIHWu36HfuAPUusEzIsP6V6+NxbrwQbZvi4wNgCl5OzQFVjtiDlCoa1DzG6rn4onQzW/OgxWoLENe7M4+5w1zS6hGZ/7OW33sO/DeFZOwl6mrdhoXiVBi10+M4sB/CI55a7aQ5J6VcPogxZq6slcoAFrXdiasyJaAPGXjc=
root@jumpbox
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDzGyBAxcCEBJtrtNhudPuHchrV7a5t7GRWNq4r7ew/KztHsScspWB3tJIeDd4+TQgb5qexNUmwslBqoxYW6Lp8zoGiFJrVoj9GFO1O4iZimnHCIqzhufmkYp/FQuDnEsQi7tPQAjYPTojZfhvgpW4Z09+gPWpyl40P9KVOvGETtocLAdJACcL+I6uq+2JFKG6GnDHbER7zhXYngJKAizj/2t/Dx6l6SC/RfR8Z8jLUBgEguy8RAPQI8k20qYP4ONl77J8/3aQ7XJQptFODfQRmve1KRf8o509AjoDyktOG7LyAFxxlN8RVEDW5gN857WIzjOdnzirAIkt3+6ExrNIyb/XF4JIHWu36HfuAPUusEzIsP6V6+NxbrwQbZvi4wNgCl5OzQFVjtiDlCoa1DzG6rn4onQzW/OgxWoLENe7M4+5w1zS6hGZ/7OW33sO/DeFZOwl6mrdhoXiVBi10+M4sB/CI55a7aQ5J6VcPogxZq6slcoAFrXdiasyJaAPGXjc=
root@jumpbox
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDzGyBAxcCEBJtrtNhudPuHchrV7a5t7GRWNq4r7ew/KztHsScspWB3tJIeDd4+TQgb5qexNUmwslBqoxYW6Lp8zoGiFJrVoj9GFO1O4iZimnHCIqzhufmkYp/FQuDnEsQi7tPQAjYPTojZfhvgpW4Z09+gPWpyl40P9KVOvGETtocLAdJACcL+I6uq+2JFKG6GnDHbER7zhXYngJKAizj/2t/Dx6l6SC/RfR8Z8jLUBgEguy8RAPQI8k20qYP4ONl77J8/3aQ7XJQptFODfQRmve1KRf8o509AjoDyktOG7LyAFxxlN8RVEDW5gN857WIzjOdnzirAIkt3+6ExrNIyb/XF4JIHWu36HfuAPUusEzIsP6V6+NxbrwQbZvi4wNgCl5OzQFVjtiDlCoa1DzG6rn4onQzW/OgxWoLENe7M4+5w1zS6hGZ/7OW33sO/DeFZOwl6mrdhoXiVBi10+M4sB/CI55a7aQ5J6VcPogxZq6slcoAFrXdiasyJaAPGXjc=
root@jumpbox
# 아래는 IP 기반으로 접속 확인
> while read IP FQDN HOST SUBNET; do
ssh -n root@${IP} hostname
done < machines.txt
server
node-0
node-1
> while read IP FQDN HOST SUBNET; do
ssh -n root@${IP} cat /etc/hosts
done < machines.txt
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.10.10 jumpbox
192.168.10.100 server.kubernetes.local server
192.168.10.101 node-0.kubernetes.local node-0
192.168.10.102 node-1.kubernetes.local node-1
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.10.10 jumpbox
192.168.10.100 server.kubernetes.local server
192.168.10.101 node-0.kubernetes.local node-0
192.168.10.102 node-1.kubernetes.local node-1
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.10.10 jumpbox
192.168.10.100 server.kubernetes.local server
192.168.10.101 node-0.kubernetes.local node-0
192.168.10.102 node-1.kubernetes.local node-1
# Hostnames 설정
> while read IP FQDN HOST SUBNET; do
ssh -n root@${IP} cat /etc/hosts
done < machines.txt
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.10.10 jumpbox
192.168.10.100 server.kubernetes.local server
192.168.10.101 node-0.kubernetes.local node-0
192.168.10.102 node-1.kubernetes.local node-1
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.10.10 jumpbox
192.168.10.100 server.kubernetes.local server
192.168.10.101 node-0.kubernetes.local node-0
192.168.10.102 node-1.kubernetes.local node-1
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.10.10 jumpbox
192.168.10.100 server.kubernetes.local server
192.168.10.101 node-0.kubernetes.local node-0
192.168.10.102 node-1.kubernetes.local node-1
> while read IP FQDN HOST SUBNET; do
ssh -n root@${IP} hostname --fqdn
done < machines.txt
server.kubernetes.local
node-0.kubernetes.local
node-1.kubernetes.local
> cat /etc/hosts
while read IP FQDN HOST SUBNET; do
sshpass -p 'qwe123' ssh -n -o StrictHostKeyChecking=no root@${HOST} hostname
done < machines.txt
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.10.10 jumpbox
192.168.10.100 server.kubernetes.local server
192.168.10.101 node-0.kubernetes.local node-0
192.168.10.102 node-1.kubernetes.local node-1
Warning: Permanently added 'server' (ED25519) to the list of known hosts.
server
Warning: Permanently added 'node-0' (ED25519) to the list of known hosts.
node-0
Warning: Permanently added 'node-1' (ED25519) to the list of known hosts.
node-1
> while read IP FQDN HOST SUBNET; do
sshpass -p 'qwe123' ssh -n root@${HOST} uname -o -m -n
done < machines.txt
server aarch64 GNU/Linux
node-0 aarch64 GNU/Linux
node-1 aarch64 GNU/Linux
CA 생성 및 TLS 인증서 발급
Kubernetes 클러스터를 구성하는 각 구성 요소가 mTLS 통신을 하기 위해 어떤 인증서(키·CSR·CRT)를 가지고, 어떤 정체성(CN/O)과 용도로 사용되는지를 정리한 표입니다.
| 항목 | 개인키 | CSR | 인증서 | 참고 정보 | X509v3 Extended Key Usage |
| Root CA | ca.key | X | ca.crt | ||
| admin | admin.key | admin.csr | admin.crt | CN = admin, O = system:masters | TLS Web Client Authentication |
| node-0 | node-0.key | node-0.csr | node-0.crt | CN = system:node:node-0, O = system:nodes | TLS Web Server / Client Authentication |
| node-1 | node-1.key | node-1.csr | node-1.crt | CN = system:node:node-1, O = system:nodes | TLS Web Server / Client Authentication |
| kube-proxy | kube-proxy.key | kube-proxy.csr | kube-proxy.crt | CN = system:kube-proxy, O = system:node-proxier | TLS Web Server / Client Authentication |
| kube-scheduler | kube-scheduler.key | kube-scheduler | kube-scheduler.crt | CN = system:kube-scheduler, O = system:kube-scheduler | TLS Web Server / Client Authentication |
| kube-controller-manager | kube-controller-manager.key | kube-controller-manager.csr | kube-controller-manager.crt | CN = system:kube-controller-manager, O = system:kube-controller-manager | TLS Web Server / Client Authentication |
| kube-api-server | kube-api-server.key | kube-api-server.csr | kube-api-server.crt | CN = kubernetes, SAN: IP(127.0.0.1, 10.32.0.1), DNS(kubernetes,..) | TLS Web Server / Client Authentication |
| service-accounts | service-accounts.key | service-accounts.csr | service-accounts.crt | CN = service-accounts | TLS Web Client Authentication |
구성한 네트워크 대역은 다음과 같습니다.
| 항목 | 네트워크 대역 or IP |
| clusterCIDR | 10.200.0.0/16 |
| → node-0 PodCIDR | 10.200.0.0/24 |
| → node-1 PodCIDR | 10.200.1.0/24 |
| ServiceCIDR | 10.32.0.0/24 |
| →api clusterIP | 10.32.0.1 |
참고를 위해 kind k8s에서 인증서 관련 파일을 확인해보겠습니다.
> docker exec -it myk8s-control-plane sh -c 'apt update && apt install tree yq jq -y'
> docker exec -i myk8s-control-plane kubeadm certs check-expiration 5s 06:59:25
[check-expiration] Reading configuration from the "kubeadm-config" ConfigMap in namespace "kube-system"...
[check-expiration] Use 'kubeadm init phase upload-config --config your-config.yaml' to re-upload it.
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf Jan 10, 2027 04:03 UTC 364d ca no
apiserver Jan 10, 2027 04:03 UTC 364d ca no
apiserver-etcd-client Jan 10, 2027 04:03 UTC 364d etcd-ca no
apiserver-kubelet-client Jan 10, 2027 04:03 UTC 364d ca no
controller-manager.conf Jan 10, 2027 04:03 UTC 364d ca no
etcd-healthcheck-client Jan 10, 2027 04:03 UTC 364d etcd-ca no
etcd-peer Jan 10, 2027 04:03 UTC 364d etcd-ca no
etcd-server Jan 10, 2027 04:03 UTC 364d etcd-ca no
front-proxy-client Jan 10, 2027 04:03 UTC 364d front-proxy-ca no
scheduler.conf Jan 10, 2027 04:03 UTC 364d ca no
super-admin.conf Jan 10, 2027 04:03 UTC 364d ca no
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca Jan 08, 2036 04:03 UTC 9y no
etcd-ca Jan 08, 2036 04:03 UTC 9y no
front-proxy-ca Jan 08, 2036 04:03 UTC 9y no
> docker exec -it myk8s-control-plane tree /etc/kubernetes 06:59:49
/etc/kubernetes
|-- admin.conf
|-- controller-manager.conf
|-- kubelet.conf
|-- manifests
| |-- etcd.yaml
| |-- kube-apiserver.yaml
| |-- kube-controller-manager.yaml
| `-- kube-scheduler.yaml
|-- pki
| |-- apiserver-etcd-client.crt
| |-- apiserver-etcd-client.key
| |-- apiserver-kubelet-client.crt
| |-- apiserver-kubelet-client.key
| |-- apiserver.crt
| |-- apiserver.key
| |-- ca.crt
| |-- ca.key
| |-- etcd
| | |-- ca.crt
| | |-- ca.key
| | |-- healthcheck-client.crt
| | |-- healthcheck-client.key
| | |-- peer.crt
| | |-- peer.key
| | |-- server.crt
| | `-- server.key
| |-- front-proxy-ca.crt
| |-- front-proxy-ca.key
| |-- front-proxy-client.crt
| |-- front-proxy-client.key
| |-- sa.key
| `-- sa.pub
|-- scheduler.conf
`-- super-admin.conf
4 directories, 31 files
CA 설정파일, certificate, private key를 생성하겠습니다.
우선 certificate authority를 생성하겠습니다.
CN(Common Name)은 X.509 인증서의 식별자 이름 필드로 인증서 주체(또는 발급자)를 사람이 알아보기 쉽게 부르는 이름입니다.
Issuer는 이 인증서를 발급한 CA의 DN, Subject는 이 인증서의 소유자 DN입니다.
따라서, 현재 이 인증서는 self-signed CA으로, Issuer와 Subject가 CN=CA입니다.
root@jumpbox:~/kubernetes-the-hard-way# openssl genrsa -out ca.key 4096
root@jumpbox:~/kubernetes-the-hard-way# ls -l ca.key
-rw------- 1 root root 3272 Jan 11 07:04 ca.key
root@jumpbox:~/kubernetes-the-hard-way# cat ca.key
-----BEGIN PRIVATE KEY-----
MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQCe03U+G0LIGAZd
GlXG5uInPOFL35RAls8fXKDFjeT1R4F+BZX8mVDR9kxuijGKzZzkAY+4nNiahOcW
Z/eoSBRw5CwVRtIUiRFJA0CgjZ1O8wMgQrnH77GTqrtieJcZdAPu3AAY3uCi2THr
cUfQ6UEygoAY0+rQx2oXQRmsqq7JMJllI6sOxyTqj7amUjl542HlzQSIAQ2Vi1b1
BbLOsLxUr1xcYcJJePOFOw0kAXqQWjlpMx+YXsLEAtOMlCKwnhUljD4a5N0pqDQz
igr8y3Ykt6kgjGLG348wkXmArGNS3lPZrzN+7osFP08rtN3a6C4sYU7y60Fo4Tw4
Jhzp/SCWpG12sYgDO68Do4p9FfSA8JzGjrtBM/Iu0JkQR5nKha+ERJBQudzcfk+x
b3TbCi0Tj8n8bbTvx3pdODhXn+lLxPjj0KbZ7C5bKjoyxBjZhWYYfDSovwuCAIP0
xOq8DWFg+zyPjrqpFZuwyDnWEWVaTrKg7kT8fnBQecFP4u5Wi2L2lDj+FnzuHoyw
KU7IL6UTcUjZj9ICmN9YoX224iHF9yvC6emu74v51X3HrLOf0j+oHxm9orLWcofo
Q3AOc7uJ7sX7nWChpmrQRZ74fHmDYSm7R8/688674rTKYsGJdpNsAoJIyijhlmil
AHQAxSSiyzofVzpEXnCXpmViTLD5kQIDAQABAoICACOJnQowf1jWR1Y9tkOzFZdC
AAdCF6H8HIwf5blObpSTU14nUdAbXgIc4i05rqwoJZq+3rGoJq8sXaidysRUnH5G
D7cTCZ6erMdxetxx02j+5wwo4fjioRExeowl/2kqlFa10y+9bvYBMzJDPpZ4GqZ6
nL7xa/EbLZnWbzA7YLCTtz7yJCxCUvhI/81nSIUFY7pPjVwBIFD9xI8+nyuwT/OC
6V+iYB6geZyuAdq0mgACsCXh0of9bAb/uuYRn1F1jbXBE4RhATt473U4xgyaWe0N
S0KFJvTowNlVM6Ke7/py1MA4e4VDSsf5ynU1Gw8INIypmUixawlUnGzT2lRg1xGD
o6Jjec5usxBLEDoW81NB/IHicn0RxLMnlGwhI4fn2qvOEmIs9j7QkvISNSxUX5+I
/6hE8EQq7SYQcj1BgnkT2vuyEGoBLAnV3PbWfwC89P4+a4ZtsV/7sK66hgTl4c9P
y5B5/oPt6pxYF2T2XeDkP6Szj77hnDCFovfcClqrOPDB9s4HRUTpszdMSykTpjoG
z+9z7JWSTHd/IAaF7wK/3HGfUIfHEh6EV7+jokxdYG3ixswTcqkaplN8tqtJdPKw
Q4wSmBkNfckpTtoWyi47a5GaENg/wDGgGKyyWLPOIQdXxHUTcAIUcY0eUl9cWNCa
hNR7ZqFWyxC6jCN6cSOBAoIBAQDPTqwANmqVlJ93B+OGVKKaJ4ao+nJHSFXR3fN/
nSC8i2gphIlcQS42GsHz4OAYwR+Q1nAX1f5hUmOwdj2TRQsgKBfYSrb4vjjjVK6v
xbPGLC5gn+TJA9J8kt8JelFa4GoOvOBJ/GBhrQwK3gRtaeLtj92io2ab90XbrvXZ
bvVfGc+9zPEzgS3I0WdQDTvWome4avOpP30ULQqVay2XkLl2slO/q7cs0mRhHEV4
H+gp4mswbmUwiW1IFThYCDvOuE4ir3A+WZKyOhTJjF2nsnHGiaMB0RhUa3cC6O1N
DgJDBHlX1EVxINF3z1DnduPTVpv3qL/jq9yn+GGfynCYQvQNAoIBAQDEIZ6TN91+
Rfu9VI+ozwkfBDIW1nbc/Y8KDQd0nWVK14LiPDyxZdhXQm+97jouzcmq45rHr5QM
nCfwo45SeitOA8f4tQewbz5Q1V9td3kOUHva4wf0f0bSAEQLPiYOJPn35pxRMNfH
XuRg1lqMVHGdvVoS/ZR24TEh2fjZjhEMqMAir14QUN8313qTqVziK6Hbm7qJxDcM
RcGf18edtVlV5D/kyucCGSeRUjdJodLB+nCw22i/RvCLhdp2nFXsp67Jmt45Gz7m
YlX3ZM5oU1dWTKELJ8QGutAcphI+P6QhvKlUlO3Xee4+YOC9PWXezsc43hCJ2Qqa
ddhavH9YuyaVAoIBAQCBH0taxooUqQG6Lhu1a7nrsnrZfUT4yUFK+qfT8JaXWW2D
jp3P7HlQEdKEiKiMQp3apPYkopFTJPIa00r/E54eZVqUydS1kiX00qYLrWSQJqys
WmsyGUNdfE2XpaxOokDs9Q/uhVey/wnlKuwvCijiNx2hU41xz86fSpau28HRfk46
tg/2OJu/3U4wOk3vHjDkWRlzbawGiRdygdNf+DDMkb5AQEBTlqgXJHjQnW8Jx5Fk
FR7J4I9EupLhoh8+XuWsDQIok7ofcLXJ47fh3++l7cyuMQKqclUqZtKHkBYwj/TU
k8686+gMbADEavT0iZmT5HPA5ycFKFwGHx2KeQlxAoIBAQChZrlElXik7ZqY1/nR
BW+QIrfFq3/tpIwNzWMRSGWPDYMcAk4//nvmcznZpy4iTh9jjiJVqdu/9NG5ah85
KGhyrxHlTbSiMSmrA6ygPO1WJk2Gd8aYIhV5w9Y7Gk3e3fcHVrPU7MjlvOVb+4pQ
aT2GfcieUCfZHMB+Bw6OmibVsBlNcduKucK4BY9N7NYPGbD9NE5yCRLz+oO4sq4G
zrJRyJ/7/C3WwDSblnkBEzaJgzsxj53Hqu1RJDn/2e+r7OId7mBpxk4g8VOlX0Os
/siksDLnJzZeA2Y37UKeD2lWihcfD+AarrCsjLTlhp1KmgfAeJ5Lklzzd38wTGbP
8lNxAoIBAQCNikVjxJ7XChzch3b6rIcDM3cfL7Et7XDKXMJa/Q9HQy1Lm2tgFVJA
YmHaFpNiq9CVRmyZ6pxpXMEDjClifdpi1utl8LHanDvJRHtKxi0d5oogl4E2wnD7
uVxZu7pX7KjsQSan0YV9Z4/DoW0gKBljoVOxOsUMwrevCN9jJjelo2vyP3bT6F0V
jtxleALdKGcvFL0sSRk3BFQzS6SOgl/7V5CpWvxq7axgArvCabfAG9MAvLMuuXMQ
sRRJ87cgboc7i6nutfldMhWeXM1kFJgvnOwTu8mBEHLOGTkUKewkAgT2EdafIkCK
nCdtHCf+g7W4SvE216mOC6MjpU+IP/+S
-----END PRIVATE KEY-----
root@jumpbox:~/kubernetes-the-hard-way#
root@jumpbox:~/kubernetes-the-hard-way# openssl rsa -in ca.key -text -noout # 개인키 구조 확인
Private-Key: (4096 bit, 2 primes)
modulus:
00:9e:d3:75:3e:1b:42:c8:18:06:5d:1a:55:c6:e6:
e2:27:3c:e1:4b:df:94:40:96:cf:1f:5c:a0:c5:8d:
e4:f5:47:81:7e:05:95:fc:99:50:d1:f6:4c:6e:8a:
31:8a:cd:9c:e4:01:8f:b8:9c:d8:9a:84:e7:16:67:
f7:a8:48:14:70:e4:2c:15:46:d2:14:89:11:49:03:
40:a0:8d:9d:4e:f3:03:20:42:b9:c7:ef:b1:93:aa:
bb:62:78:97:19:74:03:ee:dc:00:18:de:e0:a2:d9:
31:eb:71:47:d0:e9:41:32:82:80:18:d3:ea:d0:c7:
6a:17:41:19:ac:aa:ae:c9:30:99:65:23:ab:0e:c7:
24:ea:8f:b6:a6:52:39:79:e3:61:e5:cd:04:88:01:
0d:95:8b:56:f5:05:b2:ce:b0:bc:54:af:5c:5c:61:
c2:49:78:f3:85:3b:0d:24:01:7a:90:5a:39:69:33:
1f:98:5e:c2:c4:02:d3:8c:94:22:b0:9e:15:25:8c:
3e:1a:e4:dd:29:a8:34:33:8a:0a:fc:cb:76:24:b7:
a9:20:8c:62:c6:df:8f:30:91:79:80:ac:63:52:de:
53:d9:af:33:7e:ee:8b:05:3f:4f:2b:b4:dd:da:e8:
2e:2c:61:4e:f2:eb:41:68:e1:3c:38:26:1c:e9:fd:
20:96:a4:6d:76:b1:88:03:3b:af:03:a3:8a:7d:15:
f4:80:f0:9c:c6:8e:bb:41:33:f2:2e:d0:99:10:47:
99:ca:85:af:84:44:90:50:b9:dc:dc:7e:4f:b1:6f:
74:db:0a:2d:13:8f:c9:fc:6d:b4:ef:c7:7a:5d:38:
38:57:9f:e9:4b:c4:f8:e3:d0:a6:d9:ec:2e:5b:2a:
3a:32:c4:18:d9:85:66:18:7c:34:a8:bf:0b:82:00:
83:f4:c4:ea:bc:0d:61:60:fb:3c:8f:8e:ba:a9:15:
9b:b0:c8:39:d6:11:65:5a:4e:b2:a0:ee:44:fc:7e:
70:50:79:c1:4f:e2:ee:56:8b:62:f6:94:38:fe:16:
7c:ee:1e:8c:b0:29:4e:c8:2f:a5:13:71:48:d9:8f:
d2:02:98:df:58:a1:7d:b6:e2:21:c5:f7:2b:c2:e9:
e9:ae:ef:8b:f9:d5:7d:c7:ac:b3:9f:d2:3f:a8:1f:
19:bd:a2:b2:d6:72:87:e8:43:70:0e:73:bb:89:ee:
c5:fb:9d:60:a1:a6:6a:d0:45:9e:f8:7c:79:83:61:
29:bb:47:cf:fa:f3:ce:bb:e2:b4:ca:62:c1:89:76:
93:6c:02:82:48:ca:28:e1:96:68:a5:00:74:00:c5:
24:a2:cb:3a:1f:57:3a:44:5e:70:97:a6:65:62:4c:
b0:f9:91
publicExponent: 65537 (0x10001)
privateExponent:
23:89:9d:0a:30:7f:58:d6:47:56:3d:b6:43:b3:15:
97:42:00:07:42:17:a1:fc:1c:8c:1f:e5:b9:4e:6e:
94:93:53:5e:27:51:d0:1b:5e:02:1c:e2:2d:39:ae:
ac:28:25:9a:be:de:b1:a8:26:af:2c:5d:a8:9d:ca:
c4:54:9c:7e:46:0f:b7:13:09:9e:9e:ac:c7:71:7a:
dc:71:d3:68:fe:e7:0c:28:e1:f8:e2:a1:11:31:7a:
8c:25:ff:69:2a:94:56:b5:d3:2f:bd:6e:f6:01:33:
32:43:3e:96:78:1a:a6:7a:9c:be:f1:6b:f1:1b:2d:
99:d6:6f:30:3b:60:b0:93:b7:3e:f2:24:2c:42:52:
f8:48:ff:cd:67:48:85:05:63:ba:4f:8d:5c:01:20:
50:fd:c4:8f:3e:9f:2b:b0:4f:f3:82:e9:5f:a2:60:
1e:a0:79:9c:ae:01:da:b4:9a:00:02:b0:25:e1:d2:
87:fd:6c:06:ff:ba:e6:11:9f:51:75:8d:b5:c1:13:
84:61:01:3b:78:ef:75:38:c6:0c:9a:59:ed:0d:4b:
42:85:26:f4:e8:c0:d9:55:33:a2:9e:ef:fa:72:d4:
c0:38:7b:85:43:4a:c7:f9:ca:75:35:1b:0f:08:34:
8c:a9:99:48:b1:6b:09:54:9c:6c:d3:da:54:60:d7:
11:83:a3:a2:63:79:ce:6e:b3:10:4b:10:3a:16:f3:
53:41:fc:81:e2:72:7d:11:c4:b3:27:94:6c:21:23:
87:e7:da:ab:ce:12:62:2c:f6:3e:d0:92:f2:12:35:
2c:54:5f:9f:88:ff:a8:44:f0:44:2a:ed:26:10:72:
3d:41:82:79:13:da:fb:b2:10:6a:01:2c:09:d5:dc:
f6:d6:7f:00:bc:f4:fe:3e:6b:86:6d:b1:5f:fb:b0:
ae:ba:86:04:e5:e1:cf:4f:cb:90:79:fe:83:ed:ea:
9c:58:17:64:f6:5d:e0:e4:3f:a4:b3:8f:be:e1:9c:
30:85:a2:f7:dc:0a:5a:ab:38:f0:c1:f6:ce:07:45:
44:e9:b3:37:4c:4b:29:13:a6:3a:06:cf:ef:73:ec:
95:92:4c:77:7f:20:06:85:ef:02:bf:dc:71:9f:50:
87:c7:12:1e:84:57:bf:a3:a2:4c:5d:60:6d:e2:c6:
cc:13:72:a9:1a:a6:53:7c:b6:ab:49:74:f2:b0:43:
8c:12:98:19:0d:7d:c9:29:4e:da:16:ca:2e:3b:6b:
91:9a:10:d8:3f:c0:31:a0:18:ac:b2:58:b3:ce:21:
07:57:c4:75:13:70:02:14:71:8d:1e:52:5f:5c:58:
d0:9a:84:d4:7b:66:a1:56:cb:10:ba:8c:23:7a:71:
23:81
prime1:
00:cf:4e:ac:00:36:6a:95:94:9f:77:07:e3:86:54:
a2:9a:27:86:a8:fa:72:47:48:55:d1:dd:f3:7f:9d:
20:bc:8b:68:29:84:89:5c:41:2e:36:1a:c1:f3:e0:
e0:18:c1:1f:90:d6:70:17:d5:fe:61:52:63:b0:76:
3d:93:45:0b:20:28:17:d8:4a:b6:f8:be:38:e3:54:
ae:af:c5:b3:c6:2c:2e:60:9f:e4:c9:03:d2:7c:92:
df:09:7a:51:5a:e0:6a:0e:bc:e0:49:fc:60:61:ad:
0c:0a:de:04:6d:69:e2:ed:8f:dd:a2:a3:66:9b:f7:
45:db:ae:f5:d9:6e:f5:5f:19:cf:bd:cc:f1:33:81:
2d:c8:d1:67:50:0d:3b:d6:a2:67:b8:6a:f3:a9:3f:
7d:14:2d:0a:95:6b:2d:97:90:b9:76:b2:53:bf:ab:
b7:2c:d2:64:61:1c:45:78:1f:e8:29:e2:6b:30:6e:
65:30:89:6d:48:15:38:58:08:3b:ce:b8:4e:22:af:
70:3e:59:92:b2:3a:14:c9:8c:5d:a7:b2:71:c6:89:
a3:01:d1:18:54:6b:77:02:e8:ed:4d:0e:02:43:04:
79:57:d4:45:71:20:d1:77:cf:50:e7:76:e3:d3:56:
9b:f7:a8:bf:e3:ab:dc:a7:f8:61:9f:ca:70:98:42:
f4:0d
prime2:
00:c4:21:9e:93:37:dd:7e:45:fb:bd:54:8f:a8:cf:
09:1f:04:32:16:d6:76:dc:fd:8f:0a:0d:07:74:9d:
65:4a:d7:82:e2:3c:3c:b1:65:d8:57:42:6f:bd:ee:
3a:2e:cd:c9:aa:e3:9a:c7:af:94:0c:9c:27:f0:a3:
8e:52:7a:2b:4e:03:c7:f8:b5:07:b0:6f:3e:50:d5:
5f:6d:77:79:0e:50:7b:da:e3:07:f4:7f:46:d2:00:
44:0b:3e:26:0e:24:f9:f7:e6:9c:51:30:d7:c7:5e:
e4:60:d6:5a:8c:54:71:9d:bd:5a:12:fd:94:76:e1:
31:21:d9:f8:d9:8e:11:0c:a8:c0:22:af:5e:10:50:
df:37:d7:7a:93:a9:5c:e2:2b:a1:db:9b:ba:89:c4:
37:0c:45:c1:9f:d7:c7:9d:b5:59:55:e4:3f:e4:ca:
e7:02:19:27:91:52:37:49:a1:d2:c1:fa:70:b0:db:
68:bf:46:f0:8b:85:da:76:9c:55:ec:a7:ae:c9:9a:
de:39:1b:3e:e6:62:55:f7:64:ce:68:53:57:56:4c:
a1:0b:27:c4:06:ba:d0:1c:a6:12:3e:3f:a4:21:bc:
a9:54:94:ed:d7:79:ee:3e:60:e0:bd:3d:65:de:ce:
c7:38:de:10:89:d9:0a:9a:75:d8:5a:bc:7f:58:bb:
26:95
exponent1:
00:81:1f:4b:5a:c6:8a:14:a9:01:ba:2e:1b:b5:6b:
b9:eb:b2:7a:d9:7d:44:f8:c9:41:4a:fa:a7:d3:f0:
96:97:59:6d:83:8e:9d:cf:ec:79:50:11:d2:84:88:
a8:8c:42:9d:da:a4:f6:24:a2:91:53:24:f2:1a:d3:
4a:ff:13:9e:1e:65:5a:94:c9:d4:b5:92:25:f4:d2:
a6:0b:ad:64:90:26:ac:ac:5a:6b:32:19:43:5d:7c:
4d:97:a5:ac:4e:a2:40:ec:f5:0f:ee:85:57:b2:ff:
09:e5:2a:ec:2f:0a:28:e2:37:1d:a1:53:8d:71:cf:
ce:9f:4a:96:ae:db:c1:d1:7e:4e:3a:b6:0f:f6:38:
9b:bf:dd:4e:30:3a:4d:ef:1e:30:e4:59:19:73:6d:
ac:06:89:17:72:81:d3:5f:f8:30:cc:91:be:40:40:
40:53:96:a8:17:24:78:d0:9d:6f:09:c7:91:64:15:
1e:c9:e0:8f:44:ba:92:e1:a2:1f:3e:5e:e5:ac:0d:
02:28:93:ba:1f:70:b5:c9:e3:b7:e1:df:ef:a5:ed:
cc:ae:31:02:aa:72:55:2a:66:d2:87:90:16:30:8f:
f4:d4:93:ce:bc:eb:e8:0c:6c:00:c4:6a:f4:f4:89:
99:93:e4:73:c0:e7:27:05:28:5c:06:1f:1d:8a:79:
09:71
exponent2:
00:a1:66:b9:44:95:78:a4:ed:9a:98:d7:f9:d1:05:
6f:90:22:b7:c5:ab:7f:ed:a4:8c:0d:cd:63:11:48:
65:8f:0d:83:1c:02:4e:3f:fe:7b:e6:73:39:d9:a7:
2e:22:4e:1f:63:8e:22:55:a9:db:bf:f4:d1:b9:6a:
1f:39:28:68:72:af:11:e5:4d:b4:a2:31:29:ab:03:
ac:a0:3c:ed:56:26:4d:86:77:c6:98:22:15:79:c3:
d6:3b:1a:4d:de:dd:f7:07:56:b3:d4:ec:c8:e5:bc:
e5:5b:fb:8a:50:69:3d:86:7d:c8:9e:50:27:d9:1c:
c0:7e:07:0e:8e:9a:26:d5:b0:19:4d:71:db:8a:b9:
c2:b8:05:8f:4d:ec:d6:0f:19:b0:fd:34:4e:72:09:
12:f3:fa:83:b8:b2:ae:06:ce:b2:51:c8:9f:fb:fc:
2d:d6:c0:34:9b:96:79:01:13:36:89:83:3b:31:8f:
9d:c7:aa:ed:51:24:39:ff:d9:ef:ab:ec:e2:1d:ee:
60:69:c6:4e:20:f1:53:a5:5f:43:ac:fe:c8:a4:b0:
32:e7:27:36:5e:03:66:37:ed:42:9e:0f:69:56:8a:
17:1f:0f:e0:1a:ae:b0:ac:8c:b4:e5:86:9d:4a:9a:
07:c0:78:9e:4b:92:5c:f3:77:7f:30:4c:66:cf:f2:
53:71
coefficient:
00:8d:8a:45:63:c4:9e:d7:0a:1c:dc:87:76:fa:ac:
87:03:33:77:1f:2f:b1:2d:ed:70:ca:5c:c2:5a:fd:
0f:47:43:2d:4b:9b:6b:60:15:52:40:62:61:da:16:
93:62:ab:d0:95:46:6c:99:ea:9c:69:5c:c1:03:8c:
29:62:7d:da:62:d6:eb:65:f0:b1:da:9c:3b:c9:44:
7b:4a:c6:2d:1d:e6:8a:20:97:81:36:c2:70:fb:b9:
5c:59:bb:ba:57:ec:a8:ec:41:26:a7:d1:85:7d:67:
8f:c3:a1:6d:20:28:19:63:a1:53:b1:3a:c5:0c:c2:
b7:af:08:df:63:26:37:a5:a3:6b:f2:3f:76:d3:e8:
5d:15:8e:dc:65:78:02:dd:28:67:2f:14:bd:2c:49:
19:37:04:54:33:4b:a4:8e:82:5f:fb:57:90:a9:5a:
fc:6a:ed:ac:60:02:bb:c2:69:b7:c0:1b:d3:00:bc:
b3:2e:b9:73:10:b1:14:49:f3:b7:20:6e:87:3b:8b:
a9:ee:b5:f9:5d:32:15:9e:5c:cd:64:14:98:2f:9c:
ec:13:bb:c9:81:10:72:ce:19:39:14:29:ec:24:02:
04:f6:11:d6:9f:22:40:8a:9c:27:6d:1c:27:fe:83:
b5:b8:4a:f1:36:d7:a9:8e:0b:a3:23:a5:4f:88:3f:
ff:92
# Root CA 인증서 생성 : ca.crt
## -x509 : CSR을 만들지 않고 바로 인증서(X.509) 생성, 즉, Self-Signed Certificate
## -noenc : 개인키를 암호화하지 않음, 즉, CA 키(ca.key)에 패스프레이즈 없음
## -config ca.conf : 인증서 세부 정보는 설정 파일에서 읽음 , [req] 섹션 사용됨 - DN 정보 → [req_distinguished_name] , CA 확장 → [ca_x509_extensions]
root@jumpbox:~/kubernetes-the-hard-way# openssl req -x509 -new -sha512 -noenc \
-key ca.key -days 3653 \
-config ca.conf \
-out ca.crt
root@jumpbox:~/kubernetes-the-hard-way# ls -l ca.crt
-rw-r--r-- 1 root root 1899 Jan 11 07:05 ca.crt
# ca.conf 내용 확인
root@jumpbox:~/kubernetes-the-hard-way# cat ca.conf
[req]
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = ca_x509_extensions
[ca_x509_extensions]
basicConstraints = CA:TRUE # 이 인증서는 CA 역할 가능
keyUsage = cRLSign, keyCertSign # cRLSign: 인증서 폐기 목록(CRL) 서명 가능, keyCertSign: 다른 인증서를 서명할 수 있음
[req_distinguished_name]
C = US
ST = Washington
L = Seattle
CN = CA
[admin]
distinguished_name = admin_distinguished_name
prompt = no
req_extensions = default_req_extensions
[admin_distinguished_name]
CN = admin
O = system:masters
# Service Accounts
#
# The Kubernetes Controller Manager leverages a key pair to generate
# and sign service account tokens as described in the
# [managing service accounts](https://kubernetes.io/docs/admin/service-accounts-admin/)
# documentation.
[service-accounts]
distinguished_name = service-accounts_distinguished_name
prompt = no
req_extensions = default_req_extensions
[service-accounts_distinguished_name]
CN = service-accounts
# Worker Nodes
#
# Kubernetes uses a [special-purpose authorization mode](https://kubernetes.io/docs/admin/authorization/node/)
# called Node Authorizer, that specifically authorizes API requests made
# by [Kubelets](https://kubernetes.io/docs/concepts/overview/components/#kubelet).
# In order to be authorized by the Node Authorizer, Kubelets must use a credential
# that identifies them as being in the `system:nodes` group, with a username
# of `system:node:<nodeName>`.
[node-0]
distinguished_name = node-0_distinguished_name
prompt = no
req_extensions = node-0_req_extensions
[node-0_req_extensions]
basicConstraints = CA:FALSE
extendedKeyUsage = clientAuth, serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
nsCertType = client
nsComment = "Node-0 Certificate"
subjectAltName = DNS:node-0, IP:127.0.0.1
subjectKeyIdentifier = hash
[node-0_distinguished_name]
CN = system:node:node-0
O = system:nodes
C = US
ST = Washington
L = Seattle
[node-1]
distinguished_name = node-1_distinguished_name
prompt = no
req_extensions = node-1_req_extensions
[node-1_req_extensions]
basicConstraints = CA:FALSE
extendedKeyUsage = clientAuth, serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
nsCertType = client
nsComment = "Node-1 Certificate"
subjectAltName = DNS:node-1, IP:127.0.0.1
subjectKeyIdentifier = hash
[node-1_distinguished_name]
CN = system:node:node-1
O = system:nodes
C = US
ST = Washington
L = Seattle
# Kube Proxy Section
[kube-proxy]
distinguished_name = kube-proxy_distinguished_name
prompt = no
req_extensions = kube-proxy_req_extensions
[kube-proxy_req_extensions]
basicConstraints = CA:FALSE
extendedKeyUsage = clientAuth, serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
nsCertType = client
nsComment = "Kube Proxy Certificate"
subjectAltName = DNS:kube-proxy, IP:127.0.0.1
subjectKeyIdentifier = hash
[kube-proxy_distinguished_name]
CN = system:kube-proxy
O = system:node-proxier
C = US
ST = Washington
L = Seattle
# Controller Manager
[kube-controller-manager]
distinguished_name = kube-controller-manager_distinguished_name
prompt = no
req_extensions = kube-controller-manager_req_extensions
[kube-controller-manager_req_extensions]
basicConstraints = CA:FALSE
extendedKeyUsage = clientAuth, serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
nsCertType = client
nsComment = "Kube Controller Manager Certificate"
subjectAltName = DNS:kube-controller-manager, IP:127.0.0.1
subjectKeyIdentifier = hash
[kube-controller-manager_distinguished_name]
CN = system:kube-controller-manager
O = system:kube-controller-manager
C = US
ST = Washington
L = Seattle
# Scheduler
[kube-scheduler]
distinguished_name = kube-scheduler_distinguished_name
prompt = no
req_extensions = kube-scheduler_req_extensions
[kube-scheduler_req_extensions]
basicConstraints = CA:FALSE
extendedKeyUsage = clientAuth, serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
nsCertType = client
nsComment = "Kube Scheduler Certificate"
subjectAltName = DNS:kube-scheduler, IP:127.0.0.1
subjectKeyIdentifier = hash
[kube-scheduler_distinguished_name]
CN = system:kube-scheduler
O = system:system:kube-scheduler
C = US
ST = Washington
L = Seattle
# API Server
#
# The Kubernetes API server is automatically assigned the `kubernetes`
# internal dns name, which will be linked to the first IP address (`10.32.0.1`)
# from the address range (`10.32.0.0/24`) reserved for internal cluster
# services.
[kube-api-server]
distinguished_name = kube-api-server_distinguished_name
prompt = no
req_extensions = kube-api-server_req_extensions
[kube-api-server_req_extensions]
basicConstraints = CA:FALSE
extendedKeyUsage = clientAuth, serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
nsCertType = client, server
nsComment = "Kube API Server Certificate"
subjectAltName = @kube-api-server_alt_names
subjectKeyIdentifier = hash
[kube-api-server_alt_names]
IP.0 = 127.0.0.1
IP.1 = 10.32.0.1
DNS.0 = kubernetes
DNS.1 = kubernetes.default
DNS.2 = kubernetes.default.svc
DNS.3 = kubernetes.default.svc.cluster
DNS.4 = kubernetes.svc.cluster.local
DNS.5 = server.kubernetes.local
DNS.6 = api-server.kubernetes.local
[kube-api-server_distinguished_name]
CN = kubernetes
C = US
ST = Washington
L = Seattle
[default_req_extensions]
basicConstraints = CA:FALSE
extendedKeyUsage = clientAuth
keyUsage = critical, digitalSignature, keyEncipherment
nsCertType = client
nsComment = "Admin Client Certificate"
subjectKeyIdentifier = hash
root@jumpbox:~/kubernetes-the-hard-way# cat ca.crt
-----BEGIN CERTIFICATE-----
MIIFTDCCAzSgAwIBAgIUcSMTtyKoWqyd+YXYFjUVawNiOjkwDQYJKoZIhvcNAQEN
BQAwQTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcM
B1NlYXR0bGUxCzAJBgNVBAMMAkNBMB4XDTI2MDExMDIyMDU1NloXDTM2MDExMTIy
MDU1NlowQTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNV
BAcMB1NlYXR0bGUxCzAJBgNVBAMMAkNBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEAntN1PhtCyBgGXRpVxubiJzzhS9+UQJbPH1ygxY3k9UeBfgWV/JlQ
0fZMbooxis2c5AGPuJzYmoTnFmf3qEgUcOQsFUbSFIkRSQNAoI2dTvMDIEK5x++x
k6q7YniXGXQD7twAGN7gotkx63FH0OlBMoKAGNPq0MdqF0EZrKquyTCZZSOrDsck
6o+2plI5eeNh5c0EiAENlYtW9QWyzrC8VK9cXGHCSXjzhTsNJAF6kFo5aTMfmF7C
xALTjJQisJ4VJYw+GuTdKag0M4oK/Mt2JLepIIxixt+PMJF5gKxjUt5T2a8zfu6L
BT9PK7Td2uguLGFO8utBaOE8OCYc6f0glqRtdrGIAzuvA6OKfRX0gPCcxo67QTPy
LtCZEEeZyoWvhESQULnc3H5PsW902wotE4/J/G2078d6XTg4V5/pS8T449Cm2ewu
Wyo6MsQY2YVmGHw0qL8LggCD9MTqvA1hYPs8j466qRWbsMg51hFlWk6yoO5E/H5w
UHnBT+LuVoti9pQ4/hZ87h6MsClOyC+lE3FI2Y/SApjfWKF9tuIhxfcrwunpru+L
+dV9x6yzn9I/qB8ZvaKy1nKH6ENwDnO7ie7F+51goaZq0EWe+Hx5g2Epu0fP+vPO
u+K0ymLBiXaTbAKCSMoo4ZZopQB0AMUkoss6H1c6RF5wl6ZlYkyw+ZECAwEAAaM8
MDowDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFJ7NNroia0On
2yMpl1Mb0XLfbWHSMA0GCSqGSIb3DQEBDQUAA4ICAQBwpr8+8niGE9UjAKQG2ANk
xzHnMPQNyN85zEqrB0Zx3kiHBtE/FhzQtxh/Idfz3E3tSI8nTMm4lH62rvPvc54F
19K1gWWzhxLkZC+tK20JUUSyuRdKEeO6SHptQYp8FdMeaYYLI/cHuArdS6L9zMia
BL4YXGpm1q3yXyTkwugHRSpYqyBzP8LksDJ57Oa2a+7CLZau5fw3JJODRDsuy9tT
XFKe3OeVA/H6g/AC0S9JkRCNuJ88q8n4KHCE4rK06uA+VIThymwZttylNHCAEF6w
kjmn45JwHKvRcf2m5ad9U5cVwJynBbvvW6/e1qNTh2ftopE/QUkhz3RO/5iLCpHB
MR6VenjcNEa86Nz2Q5V8Tf/8RXzNZ6GSPAAxlPCS43dZJLeVTscvm0TFVsFndBKq
iNYvcPlrXztv+0MRq9zdUjPKX6o/9/dA9y1doFBPQ1aqEhgPdVBrjzrMn7WiEgkg
eaxVVZbz/msqaAujFgEGZgey8AVPB7YcJJ+yuqRWlLnbtzyv1KzXguK+Xb6Ak4Et
yOjlqhH6SJ6oI8072WpqzyghDpoH9kyTjH//1HEK5VNuu1mF10ekwNUBOpBDDuyy
3CKm1RhdPyXF8mILp9OE80koq5K6tFwNS/hDERtQWt/s1CvtqKkSqdYRUIs+0sqt
YTBe2HubYTjmiGN38NfyNA==
-----END CERTIFICATE-----
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in ca.crt -text -noout # 인증서 전체 내용 확인
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
71:23:13:b7:22:a8:5a:ac:9d:f9:85:d8:16:35:15:6b:03:62:3a:39
Signature Algorithm: sha512WithRSAEncryption
Issuer: C = US, ST = Washington, L = Seattle, CN = CA # kind는 kubernetes임
Validity
Not Before: Jan 10 22:05:56 2026 GMT
Not After : Jan 11 22:05:56 2036 GMT
Subject: C = US, ST = Washington, L = Seattle, CN = CA # kind는 kubernetes임
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:9e:d3:75:3e:1b:42:c8:18:06:5d:1a:55:c6:e6:
e2:27:3c:e1:4b:df:94:40:96:cf:1f:5c:a0:c5:8d:
e4:f5:47:81:7e:05:95:fc:99:50:d1:f6:4c:6e:8a:
31:8a:cd:9c:e4:01:8f:b8:9c:d8:9a:84:e7:16:67:
f7:a8:48:14:70:e4:2c:15:46:d2:14:89:11:49:03:
40:a0:8d:9d:4e:f3:03:20:42:b9:c7:ef:b1:93:aa:
bb:62:78:97:19:74:03:ee:dc:00:18:de:e0:a2:d9:
31:eb:71:47:d0:e9:41:32:82:80:18:d3:ea:d0:c7:
6a:17:41:19:ac:aa:ae:c9:30:99:65:23:ab:0e:c7:
24:ea:8f:b6:a6:52:39:79:e3:61:e5:cd:04:88:01:
0d:95:8b:56:f5:05:b2:ce:b0:bc:54:af:5c:5c:61:
c2:49:78:f3:85:3b:0d:24:01:7a:90:5a:39:69:33:
1f:98:5e:c2:c4:02:d3:8c:94:22:b0:9e:15:25:8c:
3e:1a:e4:dd:29:a8:34:33:8a:0a:fc:cb:76:24:b7:
a9:20:8c:62:c6:df:8f:30:91:79:80:ac:63:52:de:
53:d9:af:33:7e:ee:8b:05:3f:4f:2b:b4:dd:da:e8:
2e:2c:61:4e:f2:eb:41:68:e1:3c:38:26:1c:e9:fd:
20:96:a4:6d:76:b1:88:03:3b:af:03:a3:8a:7d:15:
f4:80:f0:9c:c6:8e:bb:41:33:f2:2e:d0:99:10:47:
99:ca:85:af:84:44:90:50:b9:dc:dc:7e:4f:b1:6f:
74:db:0a:2d:13:8f:c9:fc:6d:b4:ef:c7:7a:5d:38:
38:57:9f:e9:4b:c4:f8:e3:d0:a6:d9:ec:2e:5b:2a:
3a:32:c4:18:d9:85:66:18:7c:34:a8:bf:0b:82:00:
83:f4:c4:ea:bc:0d:61:60:fb:3c:8f:8e:ba:a9:15:
9b:b0:c8:39:d6:11:65:5a:4e:b2:a0:ee:44:fc:7e:
70:50:79:c1:4f:e2:ee:56:8b:62:f6:94:38:fe:16:
7c:ee:1e:8c:b0:29:4e:c8:2f:a5:13:71:48:d9:8f:
d2:02:98:df:58:a1:7d:b6:e2:21:c5:f7:2b:c2:e9:
e9:ae:ef:8b:f9:d5:7d:c7:ac:b3:9f:d2:3f:a8:1f:
19:bd:a2:b2:d6:72:87:e8:43:70:0e:73:bb:89:ee:
c5:fb:9d:60:a1:a6:6a:d0:45:9e:f8:7c:79:83:61:
29:bb:47:cf:fa:f3:ce:bb:e2:b4:ca:62:c1:89:76:
93:6c:02:82:48:ca:28:e1:96:68:a5:00:74:00:c5:
24:a2:cb:3a:1f:57:3a:44:5e:70:97:a6:65:62:4c:
b0:f9:91
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
X509v3 Key Usage:
Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
9E:CD:36:BA:22:6B:43:A7:DB:23:29:97:53:1B:D1:72:DF:6D:61:D2
Signature Algorithm: sha512WithRSAEncryption
Signature Value:
70:a6:bf:3e:f2:78:86:13:d5:23:00:a4:06:d8:03:64:c7:31:
e7:30:f4:0d:c8:df:39:cc:4a:ab:07:46:71:de:48:87:06:d1:
3f:16:1c:d0:b7:18:7f:21:d7:f3:dc:4d:ed:48:8f:27:4c:c9:
b8:94:7e:b6:ae:f3:ef:73:9e:05:d7:d2:b5:81:65:b3:87:12:
e4:64:2f:ad:2b:6d:09:51:44:b2:b9:17:4a:11:e3:ba:48:7a:
6d:41:8a:7c:15:d3:1e:69:86:0b:23:f7:07:b8:0a:dd:4b:a2:
fd:cc:c8:9a:04:be:18:5c:6a:66:d6:ad:f2:5f:24:e4:c2:e8:
07:45:2a:58:ab:20:73:3f:c2:e4:b0:32:79:ec:e6:b6:6b:ee:
c2:2d:96:ae:e5:fc:37:24:93:83:44:3b:2e:cb:db:53:5c:52:
9e:dc:e7:95:03:f1:fa:83:f0:02:d1:2f:49:91:10:8d:b8:9f:
3c:ab:c9:f8:28:70:84:e2:b2:b4:ea:e0:3e:54:84:e1:ca:6c:
19:b6:dc:a5:34:70:80:10:5e:b0:92:39:a7:e3:92:70:1c:ab:
d1:71:fd:a6:e5:a7:7d:53:97:15:c0:9c:a7:05:bb:ef:5b:af:
de:d6:a3:53:87:67:ed:a2:91:3f:41:49:21:cf:74:4e:ff:98:
8b:0a:91:c1:31:1e:95:7a:78:dc:34:46:bc:e8:dc:f6:43:95:
7c:4d:ff:fc:45:7c:cd:67:a1:92:3c:00:31:94:f0:92:e3:77:
59:24:b7:95:4e:c7:2f:9b:44:c5:56:c1:67:74:12:aa:88:d6:
2f:70:f9:6b:5f:3b:6f:fb:43:11:ab:dc:dd:52:33:ca:5f:aa:
3f:f7:f7:40:f7:2d:5d:a0:50:4f:43:56:aa:12:18:0f:75:50:
6b:8f:3a:cc:9f:b5:a2:12:09:20:79:ac:55:55:96:f3:fe:6b:
2a:68:0b:a3:16:01:06:66:07:b2:f0:05:4f:07:b6:1c:24:9f:
b2:ba:a4:56:94:b9:db:b7:3c:af:d4:ac:d7:82:e2:be:5d:be:
80:93:81:2d:c8:e8:e5:aa:11:fa:48:9e:a8:23:cd:3b:d9:6a:
6a:cf:28:21:0e:9a:07:f6:4c:93:8c:7f:ff:d4:71:0a:e5:53:
6e:bb:59:85:d7:47:a4:c0:d5:01:3a:90:43:0e:ec:b2:dc:22:
a6:d5:18:5d:3f:25:c5:f2:62:0b:a7:d3:84:f3:49:28:ab:92:
ba:b4:5c:0d:4b:f8:43:11:1b:50:5a:df:ec:d4:2b:ed:a8:a9:
12:a9:d6:11:50:8b:3e:d2:ca:ad:61:30:5e:d8:7b:9b:61:38:
e6:88:63:77:f0:d7:f2:34
Client, Server admin 인증서 생성하겠습니다.
root@jumpbox:~/kubernetes-the-hard-way# openssl genrsa -out admin.key 4096
root@jumpbox:~/kubernetes-the-hard-way# ls -l admin.key
-rw------- 1 root root 3272 Jan 11 07:19 admin.key
root@jumpbox:~/kubernetes-the-hard-way# cat ca.conf
[req]
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = ca_x509_extensions
[ca_x509_extensions]
basicConstraints = CA:TRUE
keyUsage = cRLSign, keyCertSign
[req_distinguished_name]
C = US
ST = Washington
L = Seattle
CN = CA
[admin] # ca.conf 에 admin 섹션 확인
distinguished_name = admin_distinguished_name
prompt = no
req_extensions = default_req_extensions
[admin_distinguished_name]
CN = admin
O = system:masters
...
# csr 파일 생성 : admin.key 개인키를 사용해 'CN=admin, O=system:masters'인 Kubernetes 관리자용 클라이언트 인증서 요청(admin.csr) 생성
root@jumpbox:~/kubernetes-the-hard-way# openssl req -new -key admin.key -sha256 \
-config ca.conf -section admin \
-out admin.csr
root@jumpbox:~/kubernetes-the-hard-way#
root@jumpbox:~/kubernetes-the-hard-way# ls -l admin.csr
-rw-r--r-- 1 root root 1830 Jan 11 07:20 admin.csr
root@jumpbox:~/kubernetes-the-hard-way# openssl req -in admin.csr -text -noout # CSR 전체 내용 확인
Certificate Request:
Data:
Version: 1 (0x0)
Subject: CN = admin, O = system:masters
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:b7:77:93:30:ae:01:ce:08:55:60:66:4e:35:a4:
c2:97:cc:10:22:d6:76:7c:02:20:3d:16:c7:11:a5:
ce:fa:44:5b:9c:7e:92:39:fa:50:2b:a1:82:ff:e2:
14:6f:80:74:7e:e1:58:14:fe:3f:06:c4:2c:1d:81:
7c:05:24:12:5f:ed:2d:84:b3:5b:11:7b:b6:ae:00:
5d:10:8c:a2:76:8c:37:a1:a3:67:34:75:cb:d3:66:
f5:64:86:0c:bc:7b:34:40:ef:e5:07:02:86:30:7e:
9b:47:67:97:2d:23:62:95:9d:75:55:b4:d0:33:1a:
34:85:da:e9:34:e7:cf:1e:89:2b:a0:c8:25:05:7a:
13:5d:94:6d:a1:c7:a3:4d:dd:f8:46:1f:8e:03:4c:
97:b3:41:83:9b:bb:08:59:f7:03:25:b6:07:9d:ea:
ed:0c:26:f4:22:ba:35:00:64:34:f9:9a:f9:ed:26:
e4:35:3c:f9:79:5f:37:69:59:ed:8b:db:7e:f7:42:
0c:15:ff:bb:1a:3e:f9:dd:b1:79:56:d1:96:b9:98:
ee:a0:76:52:49:8d:a9:73:26:c1:97:6b:fe:7a:eb:
39:24:3e:97:f7:e8:c2:85:4c:e3:99:8c:98:f5:76:
4f:8d:b1:b2:3e:45:5c:7a:db:c9:47:bd:95:3f:57:
09:ad:98:4d:3c:62:f1:82:d3:79:f0:99:f6:95:47:
58:c1:e3:e5:e1:f8:2a:a7:d9:f2:27:ae:d9:09:00:
6e:bb:96:50:b2:f4:ab:ac:84:db:27:f0:6d:01:8b:
26:fc:58:f7:8a:70:bc:e3:0e:c3:49:1e:b2:a2:67:
8e:c9:9b:1d:8a:43:90:0a:33:ed:d7:f9:70:f5:0a:
61:02:d9:99:49:1d:88:3c:c8:1b:e5:4c:75:28:99:
12:9e:6c:83:45:0b:f7:47:ac:ed:4d:31:df:f2:6d:
9e:99:26:0a:37:cd:31:3f:d3:b6:80:e4:c9:02:be:
d1:21:21:dd:48:0a:03:a8:39:40:14:1d:e7:5b:e2:
5b:0e:6b:9c:11:e1:58:da:28:bf:6f:ae:8d:d9:65:
0c:d3:e7:ef:00:6e:ee:7c:83:1c:be:e3:10:4b:c3:
77:e0:06:2e:54:f7:8a:8d:5c:bc:e9:8f:dc:d4:fb:
92:5d:f5:e5:f9:0c:ff:1a:a9:27:bf:28:ae:fd:f9:
e8:25:5b:02:11:cf:df:59:f0:ad:f8:d8:1a:cb:ed:
9b:00:45:b7:2e:76:63:b3:7b:e2:0f:44:75:a7:e6:
a8:eb:53:24:9e:95:a0:56:1b:71:0c:f6:10:a1:b0:
e9:c0:bd:c5:d8:3d:9b:d5:04:81:23:ba:7b:e3:88:
84:2c:b5
Exponent: 65537 (0x10001)
Attributes:
Requested Extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
Netscape Cert Type:
SSL Client
Netscape Comment:
Admin Client Certificate
X509v3 Subject Key Identifier:
4C:56:38:B9:6E:E5:81:0A:70:F1:C9:02:CB:48:5C:8D:CE:B4:65:18
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
65:29:3a:20:5b:28:a2:86:5f:54:aa:0c:e5:57:11:9c:9c:87:
b0:97:35:1b:f9:a0:f2:3d:c5:6f:e6:b3:73:fc:42:f7:b4:22:
84:54:58:67:f9:7c:aa:18:e5:d7:2e:06:61:be:e7:53:8c:3c:
87:49:09:ed:05:f5:b1:03:0a:cd:a8:52:df:a1:f4:92:db:ec:
c0:f0:b8:ba:2b:10:b5:6b:eb:6a:e5:ec:08:f3:cf:3a:4d:0a:
07:42:d2:a1:b3:3a:18:7d:d8:ae:07:04:c0:e2:fd:78:b8:31:
0d:7a:d8:c1:aa:c2:d9:61:cd:ee:2e:6a:e8:bd:83:67:74:28:
c7:1d:ca:c6:39:cd:cf:8c:3d:d6:57:63:0e:32:ea:0f:58:f5:
43:db:76:95:b2:34:7f:ef:6a:1e:cb:af:22:14:c0:35:59:dc:
02:30:69:7f:55:4c:82:ff:b5:e0:ec:eb:2b:2a:9a:b7:9e:c8:
7f:8e:14:a6:09:82:7c:fa:82:2e:28:57:2e:5d:ec:8e:63:e8:
a3:69:0a:42:3f:31:e7:5e:7b:fb:09:d5:64:69:30:04:ff:b6:
67:e0:49:64:a0:2d:c7:c9:18:98:12:9d:3e:ba:c3:d5:41:00:
a1:89:28:94:0f:90:9e:b6:23:cd:62:c7:b6:dd:cc:f7:da:32:
84:9d:d2:a5:37:9b:7e:a5:c2:45:65:1e:97:ab:a0:4d:3f:2c:
ff:00:43:cf:20:c9:37:a6:a3:cf:4f:a8:47:5a:f4:f2:be:10:
20:19:e6:ee:c7:e1:c4:d2:f2:c1:da:84:f7:23:5d:bb:e5:a3:
0e:ae:19:d0:4a:1b:7d:76:ff:89:5d:02:b4:26:4f:72:ba:37:
aa:02:9d:1c:0e:5b:9a:a3:ff:ba:a2:4f:2f:bb:8e:a7:fa:5a:
8d:78:e1:8e:61:55:f0:48:d3:b8:64:64:db:50:98:e0:3d:66:
d1:fc:2b:19:f8:8d:da:36:5e:cb:0c:ae:f4:ec:e5:10:62:3e:
1c:c0:8a:e6:d1:0e:b0:dd:74:80:da:8f:77:76:76:d3:0b:95:
0f:c4:19:60:7a:e5:49:72:6a:63:0c:9e:8d:46:03:47:d4:36:
16:36:a7:7a:ee:26:d9:6e:8d:d3:fb:79:40:7b:ff:2c:bb:35:
be:35:1f:da:47:cb:e3:4d:dd:d7:f4:35:e5:2a:29:f3:32:7e:
8c:2c:ce:89:6a:ad:0e:a7:a0:8e:77:06:75:eb:0d:10:9a:96:
5d:10:98:3e:e7:8e:bb:92:dc:6e:2f:ad:14:79:82:ec:bf:14:
4e:42:08:6a:34:29:f0:a9:5a:e6:58:86:9d:ea:34:92:50:aa:
c8:4a:33:39:89:02:fd:2e
# ca에 csr 요청을 통한 crt 파일 생성
## -req : CSR를 입력으로 받아 인증서를 생성, self-signed 아님, CA가 서명하는 방식
## -days 3653 : 인증서 유효기간 3653일 (약 10년)
## -copy_extensions copyall : CSR에 포함된 모든 X.509 extensions를 인증서로 복사
## -CAcreateserial : CA 시리얼 번호 파일 자동 생성, 다음 인증서 발급 시 재사용, 기본 생성 파일(ca.srl)
openssl x509 -req -days 3653 -in admin.csr \
-copy_extensions copyall \
-sha256 -CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out admin.crt
Certificate request self-signature ok
subject=CN = admin, O = system:masters
root@jumpbox:~/kubernetes-the-hard-way# ls -l admin.crt
-rw-r--r-- 1 root root 2021 Jan 11 07:25 admin.crt
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in admin.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2b:03:f7:ba:63:e9:26:c8:a5:c1:9f:dd:8b:d8:df:4c:aa:56:f5:6f
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Washington, L = Seattle, CN = CA
Validity
Not Before: Jan 10 22:25:09 2026 GMT
Not After : Jan 11 22:25:09 2036 GMT
Subject: CN = admin, O = system:masters # admin
Client, Server 인증서 나머지 전부에 대하여 생성하겠습니다.
# ca.conf 수정
root@jumpbox:~/kubernetes-the-hard-way# cat ca.conf | grep system:kube-scheduler
CN = system:kube-scheduler
O = system:system:kube-scheduler
root@jumpbox:~/kubernetes-the-hard-way# sed -i 's/system:system:kube-scheduler/system:kube-scheduler/' ca.conf
root@jumpbox:~/kubernetes-the-hard-way# cat ca.conf | grep system:kube-scheduler
CN = system:kube-scheduler
O = system:kube-scheduler
# 변수 지정
root@jumpbox:~/kubernetes-the-hard-way# certs=(
"node-0" "node-1"
"kube-proxy" "kube-scheduler"
"kube-controller-manager"
"kube-api-server"
"service-accounts"
)
# 확인
root@jumpbox:~/kubernetes-the-hard-way# echo ${certs[*]}
node-0 node-1 kube-proxy kube-scheduler kube-controller-manager kube-api-server service-accounts
# 개인키 생성, csr 생성, 인증서 생성
root@jumpbox:~/kubernetes-the-hard-way# for i in ${certs[*]}; do
openssl genrsa -out "${i}.key" 4096
openssl req -new -key "${i}.key" -sha256 \
-config "ca.conf" -section ${i} \
-out "${i}.csr"
openssl x509 -req -days 3653 -in "${i}.csr" \
-copy_extensions copyall \
-sha256 -CA "ca.crt" \
-CAkey "ca.key" \
-CAcreateserial \
-out "${i}.crt"
done
Certificate request self-signature ok
subject=CN = system:node:node-0, O = system:nodes, C = US, ST = Washington, L = Seattle
Certificate request self-signature ok
subject=CN = system:node:node-1, O = system:nodes, C = US, ST = Washington, L = Seattle
Certificate request self-signature ok
subject=CN = system:kube-proxy, O = system:node-proxier, C = US, ST = Washington, L = Seattle
Certificate request self-signature ok
subject=CN = system:kube-scheduler, O = system:kube-scheduler, C = US, ST = Washington, L = Seattle
Certificate request self-signature ok
subject=CN = system:kube-controller-manager, O = system:kube-controller-manager, C = US, ST = Washington, L = Seattle
Certificate request self-signature ok
subject=CN = kubernetes, C = US, ST = Washington, L = Seattle
Certificate request self-signature ok
subject=CN = service-accounts
root@jumpbox:~/kubernetes-the-hard-way# ls -1 *.crt *.key *.csr
admin.crt
admin.csr
admin.key
ca.crt
ca.key
kube-api-server.crt
kube-api-server.csr
kube-api-server.key
kube-controller-manager.crt
kube-controller-manager.csr
kube-controller-manager.key
kube-proxy.crt
kube-proxy.csr
kube-proxy.key
kube-scheduler.crt
kube-scheduler.csr
kube-scheduler.key
node-0.crt
node-0.csr
node-0.key
node-1.crt
node-1.csr
node-1.key
service-accounts.crt
service-accounts.csr
service-accounts.key
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in node-0.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2b:03:f7:ba:63:e9:26:c8:a5:c1:9f:dd:8b:d8:df:4c:aa:56:f5:70
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Washington, L = Seattle, CN = CA
Validity
Not Before: Jan 10 22:28:48 2026 GMT
Not After : Jan 11 22:28:48 2036 GMT
Subject: CN = system:node:node-0, O = system:nodes, C = US, ST = Washington, L = Seattle
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:d3:fe:f2:c0:df:bb:08:76:6d:ef:1b:c5:25:e0:
16:66:be:d1:36:b0:2e:6b:9a:c5:d7:79:f9:36:da:
2b:cb:95:91:94:1b:75:92:f5:87:26:0b:a8:8c:e5:
a0:07:e6:c3:01:71:61:c1:f1:40:43:57:1d:63:bb:
51:c6:fd:81:ab:e0:83:40:b0:29:78:6f:22:30:63:
17:21:6e:41:31:37:39:b9:af:5f:8c:0c:ad:87:d8:
81:95:c6:d4:be:6e:f9:da:1b:1c:c8:a3:0f:72:3c:
77:2a:7a:1b:2b:71:40:85:a3:e4:fb:5e:d5:81:14:
a0:15:99:ce:6a:c4:1f:50:3a:4f:a9:10:17:bb:dc:
e9:e2:ba:03:48:e9:19:ec:8b:94:1d:d6:93:1b:57:
46:ee:25:39:d3:9b:3b:4a:1b:8c:71:ff:21:ff:60:
78:4f:b2:0a:10:cf:da:73:a9:4b:dc:f1:50:2d:c5:
82:0b:44:34:cb:40:87:dc:07:3b:88:1f:ce:c3:85:
c5:12:b7:f3:13:4d:77:e0:7d:60:a9:5b:ac:81:3c:
3f:79:63:b0:88:27:a9:92:e2:c2:bd:86:0e:e8:f2:
ed:bb:bf:2f:ed:14:f0:50:cf:bb:a3:8d:8e:8e:e5:
be:45:72:ad:83:78:1e:da:4d:4e:9f:d9:4f:6d:5b:
2b:25:8d:80:67:5b:bd:a5:13:b8:d3:1a:35:61:9c:
8b:c6:e7:b5:45:6e:d2:5e:82:b5:19:ee:6a:92:14:
b7:ef:04:66:8a:b3:94:0a:44:bf:d2:40:c3:62:7d:
15:f3:50:4b:9f:76:41:6c:87:15:5c:ac:74:26:cc:
c6:51:29:c0:e1:35:52:d1:8c:45:c1:93:17:e2:45:
88:8d:9f:23:4e:19:9d:4e:df:40:59:3a:f0:e7:12:
57:fe:da:72:f8:a7:1b:4e:be:45:75:5f:32:94:69:
11:02:4f:a9:6a:53:b9:23:62:88:42:b6:16:ec:f9:
64:31:ea:8d:6d:f1:f1:d1:da:ec:9f:b9:a9:da:a6:
27:39:e8:4e:e4:0f:62:11:e2:44:0c:aa:7c:44:19:
85:8f:29:35:b8:63:6d:df:85:9d:19:86:c3:49:6f:
ad:57:f6:03:3f:8f:c7:56:3b:24:a1:9b:c6:85:6d:
70:98:7b:46:2a:06:93:bc:88:0f:33:c4:3d:de:0c:
79:e2:c3:0f:68:57:2c:07:bc:b4:e4:04:f5:f8:0b:
ce:5e:b7:80:f5:bc:44:df:aa:eb:38:34:c4:a3:e1:
34:b3:24:21:42:f4:10:c8:13:a8:32:66:0f:c6:84:
bb:6b:ff:58:fa:b9:3d:16:c5:9c:f0:be:2d:9e:7b:
4d:b0:f9
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
Netscape Cert Type:
SSL Client
Netscape Comment:
Node-0 Certificate
X509v3 Subject Alternative Name:
DNS:node-0, IP Address:127.0.0.1 # DNS:node-0
X509v3 Subject Key Identifier:
F0:75:8C:46:52:57:57:BF:C3:36:4E:CB:92:2B:4D:F1:32:D7:69:E0
X509v3 Authority Key Identifier:
9E:CD:36:BA:22:6B:43:A7:DB:23:29:97:53:1B:D1:72:DF:6D:61:D2
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
16:15:df:57:75:b0:6d:6e:8d:35:52:d6:43:07:61:cd:f3:00:
60:d2:6a:1d:81:da:55:98:24:88:ce:c2:59:42:0b:b1:83:a7:
de:71:41:df:02:b4:53:9e:3b:6c:bd:de:85:97:c1:d7:71:8a:
33:aa:49:88:67:a6:74:4a:d8:80:68:cb:2e:a1:ae:52:ac:74:
44:02:41:0c:79:15:6f:d7:48:56:9e:d8:41:0f:b3:f2:31:dc:
b6:6b:f1:09:e7:af:df:75:6a:fd:be:d5:dd:69:20:8e:66:5f:
88:f3:13:c3:49:e5:c8:ca:59:ce:83:1c:df:20:38:4f:e3:13:
93:d4:3d:c7:fb:63:85:d6:5d:14:90:4c:c9:45:42:e3:54:e6:
e6:b7:c1:ec:b9:a1:68:eb:d5:1b:28:cc:bc:cc:07:94:fa:a2:
49:c0:14:19:55:b2:42:2b:04:c3:47:39:74:70:67:ac:8b:24:
1e:0a:e4:86:3a:1d:56:18:f3:96:e2:f4:d6:20:34:be:dd:79:
2f:b6:d6:4a:ed:c5:09:a3:42:9b:f3:c4:bd:99:ed:5a:05:27:
ce:2b:b6:48:de:49:39:5d:23:c3:3a:f5:28:1d:37:16:6f:93:
9b:15:4e:78:27:63:e1:de:1b:1e:36:66:d6:3f:e9:32:f0:41:
4c:c2:cd:65:06:70:40:a6:0a:55:5f:47:77:3a:eb:03:35:6f:
5a:06:75:c1:8f:81:f8:fd:2b:58:dd:d9:2d:d6:12:e1:f2:ae:
14:3e:7b:af:96:25:7d:68:29:d1:4b:bb:56:03:26:d9:a4:4d:
ae:bd:ac:93:ff:e3:7b:4f:17:d8:b8:d2:3f:a4:a4:da:73:4d:
1d:a1:b0:1d:b7:68:56:f2:d5:b9:6b:52:b3:cc:09:f5:55:16:
52:b7:a3:aa:36:54:13:72:7f:01:53:ca:79:e5:5e:84:87:40:
7e:c4:d7:c3:8b:20:32:e4:67:3f:4d:cd:33:d0:92:03:31:49:
c7:e2:2e:15:e7:16:a3:fa:dc:f8:cf:61:44:c8:ed:eb:ad:cc:
50:1a:0e:72:19:30:cb:22:86:6a:bd:24:24:18:b5:27:54:b1:
c4:96:cd:f3:d4:ba:9b:ec:7d:34:80:76:9e:24:10:b4:56:fa:
9f:4a:81:60:f2:57:ad:d2:45:ce:65:aa:c8:95:24:6f:e4:6b:
3f:9f:fc:d6:cb:34:54:09:2a:8c:17:6c:c8:4d:0f:ba:b4:d4:
c5:ff:e5:14:2c:fb:50:34:c4:f6:87:12:44:ea:e7:b9:e3:84:
d8:06:1b:b8:a7:a6:26:bd:c3:bf:7e:e0:0c:72:9e:38:42:8f:
ec:ea:c3:43:ce:b3:26:69
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in node-1.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2b:03:f7:ba:63:e9:26:c8:a5:c1:9f:dd:8b:d8:df:4c:aa:56:f5:71
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Washington, L = Seattle, CN = CA
Validity
Not Before: Jan 10 22:28:50 2026 GMT
Not After : Jan 11 22:28:50 2036 GMT
Subject: CN = system:node:node-1, O = system:nodes, C = US, ST = Washington, L = Seattle
...
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
Netscape Cert Type:
SSL Client
Netscape Comment:
Node-1 Certificate
X509v3 Subject Alternative Name:
DNS:node-1, IP Address:127.0.0.1
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in kube-proxy.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2b:03:f7:ba:63:e9:26:c8:a5:c1:9f:dd:8b:d8:df:4c:aa:56:f5:72
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Washington, L = Seattle, CN = CA
Validity
Not Before: Jan 10 22:28:52 2026 GMT
Not After : Jan 11 22:28:52 2036 GMT
Subject: CN = system:kube-proxy, O = system:node-proxier, C = US, ST = Washington, L = Seattle
...
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
Netscape Cert Type:
SSL Client
Netscape Comment:
Kube Proxy Certificate
X509v3 Subject Alternative Name:
DNS:kube-proxy, IP Address:127.0.0.1
X509v3 Subject Key Identifier:
BE:7D:4E:DC:92:C0:AA:B9:6C:41:1E:D5:2F:A2:C6:26:79:F5:63:52
X509v3 Authority Key Identifier:
9E:CD:36:BA:22:6B:43:A7:DB:23:29:97:53:1B:D1:72:DF:6D:61:D2
# 아래 컴포넌트에 대해서도 모두 CN = system:컴포넌트, X509v3 Subject Alternative Name:DNS:컴포넌트 동일
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in kube-scheduler.crt -text -noout
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in kube-controller-manager.crt -text -noout
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in kube-api-server.crt -text -noout
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in service-accounts.crt -text -noout
각 VM에게 Client, Server 인증서를 나누어줍니다.
root@jumpbox:~/kubernetes-the-hard-way# for host in node-0 node-1; do
ssh root@${host} mkdir /var/lib/kubelet/
scp ca.crt root@${host}:/var/lib/kubelet/
scp ${host}.crt \
root@${host}:/var/lib/kubelet/kubelet.crt
scp ${host}.key \
root@${host}:/var/lib/kubelet/kubelet.key
done
ca.crt 100% 1899 2.5MB/s 00:00
node-0.crt 100% 2147 3.4MB/s 00:00
node-0.key 100% 3272 4.2MB/s 00:00
ca.crt 100% 1899 2.9MB/s 00:00
node-1.crt 100% 2147 3.2MB/s 00:00
node-1.key 100% 3272 5.1MB/s 00:00
root@jumpbox:~/kubernetes-the-hard-way# ssh node-0 ls -l /var/lib/kubelet
total 12
-rw-r--r-- 1 root root 1899 Jan 11 07:35 ca.crt
-rw-r--r-- 1 root root 2147 Jan 11 07:35 kubelet.crt
-rw------- 1 root root 3272 Jan 11 07:35 kubelet.key
root@jumpbox:~/kubernetes-the-hard-way# ssh node-1 ls -l /var/lib/kubelet
total 12
-rw-r--r-- 1 root root 1899 Jan 11 07:35 ca.crt
-rw-r--r-- 1 root root 2147 Jan 11 07:35 kubelet.crt
-rw------- 1 root root 3272 Jan 11 07:35 kubelet.key
root@jumpbox:~/kubernetes-the-hard-way# scp \
ca.key ca.crt \
kube-api-server.key kube-api-server.crt \
service-accounts.key service-accounts.crt \
root@server:~/
ca.key 100% 3272 2.8MB/s 00:00
ca.crt 100% 1899 2.0MB/s 00:00
kube-api-server.key 100% 3268 3.3MB/s 00:00
kube-api-server.crt 100% 2354 1.7MB/s 00:00
service-accounts.key 100% 3272 3.3MB/s 00:00
service-accounts.crt 100% 2004 1.9MB/s 00:00
root@jumpbox:~/kubernetes-the-hard-way# ssh server ls -l /root
total 24
-rw-r--r-- 1 root root 1899 Jan 11 07:36 ca.crt
-rw------- 1 root root 3272 Jan 11 07:36 ca.key
-rw-r--r-- 1 root root 2354 Jan 11 07:36 kube-api-server.crt
-rw------- 1 root root 3268 Jan 11 07:36 kube-api-server.key
-rw-r--r-- 1 root root 2004 Jan 11 07:36 service-accounts.crt
-rw------- 1 root root 3272 Jan 11 07:36 service-accounts.key
인증을 위한 Kubernetes 설정 파일 생성
API Server와 통신을 위한 Client 인증 설정 파일을 작성하겠습니다.
우선, kubelet 전용 kubeconfig 파일을 생성하겠습니다.
각 kubelet이 API Server에 ‘자기 자신’으로 인증·인가받을 수 있도록 kubeconfig(클라이언트 인증 설정 파일)를 만들어주는 단계입니다.
kubelet은 API Server에 클라이언트로 요청을 보낼때, 이 요청들은 익명 요청이 아니라 인증된 요청이어야합니다.
kubelet 인증서의 Subject CN이 반드시 system:node:<node-name> 형태여야 합니다.
따라서, node-0, node-1의 kubeconfig 파일을 생성하겠습니다.
root@jumpbox:~/kubernetes-the-hard-way# kubectl describe pod -n kube-system kube-apiserver-myk8s-control-plane
...
Command:
kube-apiserver
--authorization-mode=Node,RBAC
...
# config set-cluster
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.crt \
--embed-certs=true \
--server=https://server.kubernetes.local:6443 \
--kubeconfig=node-0.kubeconfig && ls -l node-0.kubeconfig && cat node-0.kubeconfig
Cluster "kubernetes-the-hard-way" set.
-rw------- 1 root root 2758 Jan 11 07:47 node-0.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZURENDQXpTZ0F3SUJBZ0lVY1NNVHR5S29XcXlkK1lYWUZqVVZhd05pT2prd0RRWUpLb1pJaHZjTkFRRU4KQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2xkaGMyaHBibWQwYjI0eEVEQU9CZ05WQkFjTQpCMU5sWVhSMGJHVXhDekFKQmdOVkJBTU1Ba05CTUI0WERUSTJNREV4TURJeU1EVTFObG9YRFRNMk1ERXhNVEl5Ck1EVTFObG93UVRFTE1Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBZ01DbGRoYzJocGJtZDBiMjR4RURBT0JnTlYKQkFjTUIxTmxZWFIwYkdVeEN6QUpCZ05WQkFNTUFrTkJNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QQpNSUlDQ2dLQ0FnRUFudE4xUGh0Q3lCZ0dYUnBWeHViaUp6emhTOStVUUpiUEgxeWd4WTNrOVVlQmZnV1YvSmxRCjBmWk1ib294aXMyYzVBR1B1SnpZbW9UbkZtZjNxRWdVY09Rc0ZVYlNGSWtSU1FOQW9JMmRUdk1ESUVLNXgrK3gKazZxN1luaVhHWFFEN3R3QUdON2dvdGt4NjNGSDBPbEJNb0tBR05QcTBNZHFGMEVacktxdXlUQ1paU09yRHNjawo2bysycGxJNWVlTmg1YzBFaUFFTmxZdFc5UVd5enJDOFZLOWNYR0hDU1hqemhUc05KQUY2a0ZvNWFUTWZtRjdDCnhBTFRqSlFpc0o0VkpZdytHdVRkS2FnME00b0svTXQySkxlcElJeGl4dCtQTUpGNWdLeGpVdDVUMmE4emZ1NkwKQlQ5UEs3VGQydWd1TEdGTzh1dEJhT0U4T0NZYzZmMGdscVJ0ZHJHSUF6dXZBNk9LZlJYMGdQQ2N4bzY3UVRQeQpMdENaRUVlWnlvV3ZoRVNRVUxuYzNINVBzVzkwMndvdEU0L0ovRzIwNzhkNlhUZzRWNS9wUzhUNDQ5Q20yZXd1Cld5bzZNc1FZMllWbUdIdzBxTDhMZ2dDRDlNVHF2QTFoWVBzOGo0NjZxUldic01nNTFoRmxXazZ5b081RS9INXcKVUhuQlQrTHVWb3RpOXBRNC9oWjg3aDZNc0NsT3lDK2xFM0ZJMlkvU0FwamZXS0Y5dHVJaHhmY3J3dW5wcnUrTAorZFY5eDZ5em45SS9xQjhadmFLeTFuS0g2RU53RG5PN2llN0YrNTFnb2FacTBFV2UrSHg1ZzJFcHUwZlArdlBPCnUrSzB5bUxCaVhhVGJBS0NTTW9vNFpab3BRQjBBTVVrb3NzNkgxYzZSRjV3bDZabFlreXcrWkVDQXdFQUFhTTgKTURvd0RBWURWUjBUQkFVd0F3RUIvekFMQmdOVkhROEVCQU1DQVFZd0hRWURWUjBPQkJZRUZKN05Ocm9pYTBPbgoyeU1wbDFNYjBYTGZiV0hTTUEwR0NTcUdTSWIzRFFFQkRRVUFBNElDQVFCd3ByOCs4bmlHRTlVakFLUUcyQU5rCnh6SG5NUFFOeU44NXpFcXJCMFp4M2tpSEJ0RS9GaHpRdHhoL0lkZnozRTN0U0k4blRNbTRsSDYycnZQdmM1NEYKMTlLMWdXV3poeExrWkMrdEsyMEpVVVN5dVJkS0VlTzZTSHB0UVlwOEZkTWVhWVlMSS9jSHVBcmRTNkw5ek1pYQpCTDRZWEdwbTFxM3lYeVRrd3VnSFJTcFlxeUJ6UDhMa3NESjU3T2EyYSs3Q0xaYXU1ZnczSkpPRFJEc3V5OXRUClhGS2UzT2VWQS9INmcvQUMwUzlKa1JDTnVKODhxOG40S0hDRTRySzA2dUErVklUaHltd1p0dHlsTkhDQUVGNncKa2ptbjQ1SndIS3ZSY2YybTVhZDlVNWNWd0p5bkJidnZXNi9lMXFOVGgyZnRvcEUvUVVraHozUk8vNWlMQ3BIQgpNUjZWZW5qY05FYTg2TnoyUTVWOFRmLzhSWHpOWjZHU1BBQXhsUENTNDNkWkpMZVZUc2N2bTBURlZzRm5kQktxCmlOWXZjUGxyWHp0diswTVJxOXpkVWpQS1g2by85L2RBOXkxZG9GQlBRMWFxRWhnUGRWQnJqenJNbjdXaUVna2cKZWF4VlZaYnovbXNxYUF1akZnRUdaZ2V5OEFWUEI3WWNKSit5dXFSV2xMbmJ0enl2MUt6WGd1SytYYjZBazRFdAp5T2pscWhINlNKNm9JODA3MldwcXp5Z2hEcG9IOWt5VGpILy8xSEVLNVZOdXUxbUYxMGVrd05VQk9wQkREdXl5CjNDS20xUmhkUHlYRjhtSUxwOU9FODBrb3E1SzZ0RndOUy9oREVSdFFXdC9zMUN2dHFLa1NxZFlSVUlzKzBzcXQKWVRCZTJIdWJZVGptaUdOMzhOZnlOQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
server: https://server.kubernetes.local:6443
name: kubernetes-the-hard-way
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.crt \
--embed-certs=true \
--server=https://server.kubernetes.local:6443 \
--kubeconfig=node-1.kubeconfig && ls -l node-1.kubeconfig && cat node-1.kubeconfig
# config set-credentials
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-credentials system:node:node-0 \
--client-certificate=node-0.crt \
--client-key=node-0.key \
--embed-certs=true \
--kubeconfig=node-0.kubeconfig && cat node-0.kubeconfig
User "system:node:node-0" set.
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZURENDQXpTZ0F3SUJBZ0lVY1NNVHR5S29XcXlkK1lYWUZqVVZhd05pT2prd0RRWUpLb1pJaHZjTkFRRU4KQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2xkaGMyaHBibWQwYjI0eEVEQU9CZ05WQkFjTQpCMU5sWVhSMGJHVXhDekFKQmdOVkJBTU1Ba05CTUI0WERUSTJNREV4TURJeU1EVTFObG9YRFRNMk1ERXhNVEl5Ck1EVTFObG93UVRFTE1Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBZ01DbGRoYzJocGJtZDBiMjR4RURBT0JnTlYKQkFjTUIxTmxZWFIwYkdVeEN6QUpCZ05WQkFNTUFrTkJNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QQpNSUlDQ2dLQ0FnRUFudE4xUGh0Q3lCZ0dYUnBWeHViaUp6emhTOStVUUpiUEgxeWd4WTNrOVVlQmZnV1YvSmxRCjBmWk1ib294aXMyYzVBR1B1SnpZbW9UbkZtZjNxRWdVY09Rc0ZVYlNGSWtSU1FOQW9JMmRUdk1ESUVLNXgrK3gKazZxN1luaVhHWFFEN3R3QUdON2dvdGt4NjNGSDBPbEJNb0tBR05QcTBNZHFGMEVacktxdXlUQ1paU09yRHNjawo2bysycGxJNWVlTmg1YzBFaUFFTmxZdFc5UVd5enJDOFZLOWNYR0hDU1hqemhUc05KQUY2a0ZvNWFUTWZtRjdDCnhBTFRqSlFpc0o0VkpZdytHdVRkS2FnME00b0svTXQySkxlcElJeGl4dCtQTUpGNWdLeGpVdDVUMmE4emZ1NkwKQlQ5UEs3VGQydWd1TEdGTzh1dEJhT0U4T0NZYzZmMGdscVJ0ZHJHSUF6dXZBNk9LZlJYMGdQQ2N4bzY3UVRQeQpMdENaRUVlWnlvV3ZoRVNRVUxuYzNINVBzVzkwMndvdEU0L0ovRzIwNzhkNlhUZzRWNS9wUzhUNDQ5Q20yZXd1Cld5bzZNc1FZMllWbUdIdzBxTDhMZ2dDRDlNVHF2QTFoWVBzOGo0NjZxUldic01nNTFoRmxXazZ5b081RS9INXcKVUhuQlQrTHVWb3RpOXBRNC9oWjg3aDZNc0NsT3lDK2xFM0ZJMlkvU0FwamZXS0Y5dHVJaHhmY3J3dW5wcnUrTAorZFY5eDZ5em45SS9xQjhadmFLeTFuS0g2RU53RG5PN2llN0YrNTFnb2FacTBFV2UrSHg1ZzJFcHUwZlArdlBPCnUrSzB5bUxCaVhhVGJBS0NTTW9vNFpab3BRQjBBTVVrb3NzNkgxYzZSRjV3bDZabFlreXcrWkVDQXdFQUFhTTgKTURvd0RBWURWUjBUQkFVd0F3RUIvekFMQmdOVkhROEVCQU1DQVFZd0hRWURWUjBPQkJZRUZKN05Ocm9pYTBPbgoyeU1wbDFNYjBYTGZiV0hTTUEwR0NTcUdTSWIzRFFFQkRRVUFBNElDQVFCd3ByOCs4bmlHRTlVakFLUUcyQU5rCnh6SG5NUFFOeU44NXpFcXJCMFp4M2tpSEJ0RS9GaHpRdHhoL0lkZnozRTN0U0k4blRNbTRsSDYycnZQdmM1NEYKMTlLMWdXV3poeExrWkMrdEsyMEpVVVN5dVJkS0VlTzZTSHB0UVlwOEZkTWVhWVlMSS9jSHVBcmRTNkw5ek1pYQpCTDRZWEdwbTFxM3lYeVRrd3VnSFJTcFlxeUJ6UDhMa3NESjU3T2EyYSs3Q0xaYXU1ZnczSkpPRFJEc3V5OXRUClhGS2UzT2VWQS9INmcvQUMwUzlKa1JDTnVKODhxOG40S0hDRTRySzA2dUErVklUaHltd1p0dHlsTkhDQUVGNncKa2ptbjQ1SndIS3ZSY2YybTVhZDlVNWNWd0p5bkJidnZXNi9lMXFOVGgyZnRvcEUvUVVraHozUk8vNWlMQ3BIQgpNUjZWZW5qY05FYTg2TnoyUTVWOFRmLzhSWHpOWjZHU1BBQXhsUENTNDNkWkpMZVZUc2N2bTBURlZzRm5kQktxCmlOWXZjUGxyWHp0diswTVJxOXpkVWpQS1g2by85L2RBOXkxZG9GQlBRMWFxRWhnUGRWQnJqenJNbjdXaUVna2cKZWF4VlZaYnovbXNxYUF1akZnRUdaZ2V5OEFWUEI3WWNKSit5dXFSV2xMbmJ0enl2MUt6WGd1SytYYjZBazRFdAp5T2pscWhINlNKNm9JODA3MldwcXp5Z2hEcG9IOWt5VGpILy8xSEVLNVZOdXUxbUYxMGVrd05VQk9wQkREdXl5CjNDS20xUmhkUHlYRjhtSUxwOU9FODBrb3E1SzZ0RndOUy9oREVSdFFXdC9zMUN2dHFLa1NxZFlSVUlzKzBzcXQKWVRCZTJIdWJZVGptaUdOMzhOZnlOQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
server: https://server.kubernetes.local:6443
name: kubernetes-the-hard-way
contexts: null
current-context: ""
kind: Config
preferences: {}
users:
- name: system:node:node-0
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdCRENDQSt5Z0F3SUJBZ0lVS3dQM3VtUHBKc2lsd1ovZGk5amZUS3BXOVhBd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2xkaGMyaHBibWQwYjI0eEVEQU9CZ05WQkFjTQpCMU5sWVhSMGJHVXhDekFKQmdOVkJBTU1Ba05CTUI0WERUSTJNREV4TURJeU1qZzBPRm9YRFRNMk1ERXhNVEl5Ck1qZzBPRm93YURFYk1Ca0dBMVVFQXd3U2MzbHpkR1Z0T201dlpHVTZibTlrWlMwd01SVXdFd1lEVlFRS0RBeHoKZVhOMFpXMDZibTlrWlhNeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBYWVhOb2FXNW5kRzl1TVJBdwpEZ1lEVlFRSERBZFRaV0YwZEd4bE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBCjAvN3l3Tis3Q0hadDd4dkZKZUFXWnI3Uk5yQXVhNXJGMTNuNU50b3J5NVdSbEJ0MWt2V0hKZ3Vvak9XZ0IrYkQKQVhGaHdmRkFRMWNkWTd0Unh2MkJxK0NEUUxBcGVHOGlNR01YSVc1Qk1UYzV1YTlmakF5dGg5aUJsY2JVdm03NQoyaHNjeUtNUGNqeDNLbm9iSzNGQWhhUGsrMTdWZ1JTZ0Zabk9hc1FmVURwUHFSQVh1OXpwNHJvRFNPa1o3SXVVCkhkYVRHMWRHN2lVNTA1czdTaHVNY2Y4aC8yQjRUN0lLRU0vYWM2bEwzUEZRTGNXQ0MwUTB5MENIM0FjN2lCL08KdzRYRkVyZnpFMDEzNEgxZ3FWdXNnVHcvZVdPd2lDZXBrdUxDdllZTzZQTHR1Nzh2N1JUd1VNKzdvNDJPanVXKwpSWEt0ZzNnZTJrMU9uOWxQYlZzckpZMkFaMXU5cFJPNDB4bzFZWnlMeHVlMVJXN1NYb0sxR2U1cWtoUzM3d1JtCmlyT1VDa1MvMGtERFluMFY4MUJMbjNaQmJJY1ZYS3gwSnN6R1VTbkE0VFZTMFl4RndaTVg0a1dJalo4alRobWQKVHQ5QVdUcnc1eEpYL3RweStLY2JUcjVGZFY4eWxHa1JBaytwYWxPNUkyS0lRcllXN1Bsa01lcU5iZkh4MGRycwpuN21wMnFZbk9laE81QTlpRWVKRURLcDhSQm1GanlrMXVHTnQzNFdkR1liRFNXK3RWL1lEUDQvSFZqc2tvWnZHCmhXMXdtSHRHS2dhVHZJZ1BNOFE5M2d4NTRzTVBhRmNzQjd5MDVBVDErQXZPWHJlQTlieEUzNnJyT0RURW8rRTAKc3lRaFF2UVF5Qk9vTW1ZUHhvUzdhLzlZK3JrOUZzV2M4TDR0bm50TnNQa0NBd0VBQWFPQnpEQ0J5VEFKQmdOVgpIUk1FQWpBQU1CMEdBMVVkSlFRV01CUUdDQ3NHQVFVRkJ3TUNCZ2dyQmdFRkJRY0RBVEFPQmdOVkhROEJBZjhFCkJBTUNCYUF3RVFZSllJWklBWWI0UWdFQkJBUURBZ2VBTUNFR0NXQ0dTQUdHK0VJQkRRUVVGaEpPYjJSbExUQWcKUTJWeWRHbG1hV05oZEdVd0Z3WURWUjBSQkJBd0RvSUdibTlrWlMwd2h3Ui9BQUFCTUIwR0ExVWREZ1FXQkJUdwpkWXhHVWxkWHY4TTJUc3VTSzAzeE10ZHA0REFmQmdOVkhTTUVHREFXZ0JTZXpUYTZJbXREcDlzaktaZFRHOUZ5CjMyMWgwakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBRmhYZlYzV3diVzZOTlZMV1F3ZGh6Zk1BWU5KcUhZSGEKVlpna2lNN0NXVUlMc1lPbjNuRkIzd0swVTU0N2JMM2VoWmZCMTNHS002cEppR2VtZEVyWWdHakxMcUd1VXF4MApSQUpCREhrVmI5ZElWcDdZUVErejhqSGN0bXZ4Q2VldjMzVnEvYjdWM1drZ2ptWmZpUE1UdzBubHlNcFp6b01jCjN5QTRUK01UazlROXgvdGpoZFpkRkpCTXlVVkM0MVRtNXJmQjdMbWhhT3ZWR3lqTXZNd0hsUHFpU2NBVUdWV3kKUWlzRXcwYzVkSEJucklza0hncmtoam9kVmhqemx1TDAxaUEwdnQxNUw3YldTdTNGQ2FOQ20vUEV2Wm50V2dVbgp6aXUyU041Sk9WMGp3enIxS0IwM0ZtK1RteFZPZUNkajRkNGJIalptMWovcE12QkJUTUxOWlFad1FLWUtWVjlICmR6cnJBelZ2V2daMXdZK0IrUDByV04zWkxkWVM0Zkt1RkQ1N3I1WWxmV2dwMFV1N1ZnTW0yYVJOcnIyc2svL2oKZTA4WDJMalNQNlNrMm5OTkhhR3dIYmRvVnZMVnVXdFNzOHdKOVZVV1VyZWpxalpVRTNKL0FWUEtlZVZlaElkQQpmc1RYdzRzZ011Um5QMDNOTTlDU0F6Rkp4K0l1RmVjV28vcmMrTTloUk1qdDY2M01VQm9PY2hrd3l5S0dhcjBrCkpCaTFKMVN4eEpiTjg5UzZtK3g5TklCMm5pUVF0RmI2bjBxQllQSlhyZEpGem1XcXlKVWtiK1JyUDUvODFzczAKVkFrcWpCZHN5RTBQdXJUVXhmL2xGQ3o3VURURTlvY1NST3JudWVPRTJBWWJ1S2VtSnIzRHYzN2dESEtlT0VLUAo3T3JEUTg2ekptaz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRRFQvdkxBMzdzSWRtM3YKRzhVbDRCWm12dEUyc0M1cm1zWFhlZmsyMml2TGxaR1VHM1dTOVljbUM2aU01YUFINXNNQmNXSEI4VUJEVngxagp1MUhHL1lHcjRJTkFzQ2w0YnlJd1l4Y2hia0V4TnptNXIxK01ESzJIMklHVnh0Uytidm5hR3h6SW93OXlQSGNxCmVoc3JjVUNGbytUN1h0V0JGS0FWbWM1cXhCOVFPaytwRUJlNzNPbml1Z05JNlJuc2k1UWQxcE1iVjBidUpUblQKbXp0S0c0eHgveUgvWUhoUHNnb1F6OXB6cVV2YzhWQXR4WUlMUkRUTFFJZmNCenVJSDg3RGhjVVN0L01UVFhmZwpmV0NwVzZ5QlBEOTVZN0NJSjZtUzRzSzloZzdvOHUyN3Z5L3RGUEJRejd1ampZNk81YjVGY3EyRGVCN2FUVTZmCjJVOXRXeXNsallCblc3MmxFN2pUR2pWaG5Jdkc1N1ZGYnRKZWdyVVo3bXFTRkxmdkJHYUtzNVFLUkwvU1FNTmkKZlJYelVFdWZka0ZzaHhWY3JIUW16TVpSS2NEaE5WTFJqRVhCa3hmaVJZaU5ueU5PR1oxTzMwQlpPdkRuRWxmKwoybkw0cHh0T3ZrVjFYektVYVJFQ1Q2bHFVN2tqWW9oQ3RoYnMrV1F4Nm8xdDhmSFIydXlmdWFuYXBpYzU2RTdrCkQySVI0a1FNcW54RUdZV1BLVFc0WTIzZmhaMFpoc05KYjYxWDlnTS9qOGRXT3lTaG04YUZiWENZZTBZcUJwTzgKaUE4enhEM2VESG5pd3c5b1Z5d0h2TFRrQlBYNEM4NWV0NEQxdkVUZnF1czROTVNqNFRTekpDRkM5QkRJRTZneQpaZy9HaEx0ci8xajZ1VDBXeFp6d3ZpMmVlMDJ3K1FJREFRQUJBb0lDQURBTlh1cjNDNGI4aVNpa3E4aE5CZWJlCkk3LzRxVno4cFJHVmRUYkl0eHFiV1hjdnpqTzBjYURmRGFKNlBnN3NjSkU0S1FkejdyUVUzL1dHTlNBY3dESzgKWGlQZ2lsWGhJdWZDM2pCV3RISTZhVnc4Y3pUa2ZzVUcvMEI2NUNnU01aSU5pVFcxT0VBVmtwRlBRaTlUcVdOaApaZnJRWVNhMERTRTRUc0NHbWU1dWVUWUNEczhuWU9CaWQzSWtYQnJ3L0c3Uy8xODRKankrdFYvUWxOelVaNzVECkxXcWNiRWpzT3puYVUxTGFNZmJ2djlQUUxBenZ0ZVBJU2NORzVHaVRoU051ZytBZFQveTFGNUlMK1VnS0hvemcKb2lhYXdSM3JsNVZTenY5MGpwYWcwZUEza3Q1elc1R0Z0S3Q2MzdCbVJQMnE0OGVrQjZKRjJhZUQ4MnYvT1VVTQoyR1JadDYrdXhHeWkxblRWSTA2YjZQVDFPQU5zSGZ4OUtvcTBybEdUQnY5TnFYcUtrczBldWRBUmFPUTB3UmFUCityaXA2MFhpalNFRkg2RzFlQXE3UnkvdUtTc0UzbnEwdGs3d2lWbFYwemlleVk2cjFUZnFXZjgvKzBxYndyZDIKalpVemp6UHUwSmJCZGRTeHJVUUpwcTcvSlliMjNKb0dnUVJPaTFQMUhKbjBqUVZXUkdPRUMzK2JKTitvamYzTQorSnhKUndidFNaYUphbnpMckpKbTF2MUFQMENqeENiM2N1b2lnc2JwL2RzOWF4YnFLaTduaVpvZjUwZUJSei9qCmQ3ZkJ1Sm9yQ09sbEpmM2p5ZHpXWTVqY1BSNjYyemczc2IyWUlnc2dacDJTaytCVTM0bXVCc0hsUUx6elFxRXgKc1RlQmNsd3BrQlNaODVoSzRkWjlBb0lCQVFEOUJRbGJjMUNPOFZLaFI0KzdtalJPTTMyMVNxdVlneEkveWFBWgpNUThIWEFaV1Uya084QnZ2bjZDdHI5SHlXQ005U1ZlQWEyNzdzQ1dSTkkxRGVoR0ZPekpJTUFOcDEzaGgva3lICkN3NzY4NTY0MHBtVlh3d1lSejBIN2FuUXJudHpaQ2YwV0lwWE5pd01CNnZvNkh3a1Z5M25LdDRTTWVRY2Y2bVoKYU1saHBrdlM1c3NkU25zUmRPUWZiZGhmdHF4ZXp6dlQ4WmcxNnFTeHM3b3IraytUVjlBbmZqL21HMnV3RHdLWApQb2Q5R3JUdTlJaXBuOFBvZ1Qza01xTzNCUUdJVml4V200cHc3T3dLOUhsYzNpcGR6eUV1YVcyREM0OGRyNm4zCk9lMDZ0ODJGRGZRZHZra0hUN3g2eU9aalBiRXBMNjNSYkpjVktRVFBpb1lFK1JmakFvSUJBUURXZmpVUi9QOWwKVTZjb0VhZEkrbmdvK3pVOU1WQ1VZazZnK3J1U3cvWml2ZTFBY1RUdXlZZmRQMGc1eDlDbkRLeXVhSlpEc0JXSgpiQUNCS2N6RjNYcHBoZ1BJRXA3WkFVYy9KdHZlWUNWYVlqczQ2cnZIbitNNHd2U3gvZ1JKSDhFZnZwVG1Bc1V3CktMMGFVRWVSWnFnTjZMREJRNnVRWFppR3hyd1pRdFZhTVlzVVpXSDAwTzFja0d0Mk5jUWdlOXh0YVZwV3BwY2MKWGxSYWRSK0JXaXFvSTJLdllwK1ZpU3VEQ3FnN0gwWlBVeGY1RHgvcEVYd3l0WDRkUjdaSVdvaEVoV2R2b25NLwp3VEhTSUZHc0ZBQlhVdEUrbkRHNjhJQzh3ejdNR2dEbW1adW5KbXZUN2RnMEQ0ZmtwZnQ2NHlQRHFiZ2VrUnE0CmtNUnFiL28rZmhKekFvSUJBQ1daZVFHQkNtaWpqZjd2am5sM2VleGhGSDQ3WVhLaGo3V3c5Ynlvb0s0Y1M4aksKVG1OczVRbmY4OVc3dWZ4RWdzQVp4UW9OYlFtejdIRSttUHQ5Q1Z0K0o0TzR0dGtrcnZ3SStVQmNNVmF6bTFPbAo0RExsVS92TG9sTXFTMEQ2bk5mUisyb0JPbFdwZERRNWM1K0I1T2pWbDdteGtoeXNFMVQwMTdRM2NTMjBzN0hjCm9EUnpIQVRGRlIxaWluUDJ4bmkwWFJTcTQwNm4xdCtkY0w0V1RYcjg0cTdyd1AwbCtBUEt4enpJaXdQWlV5ZnIKYU4ra0lVM00zdkNwWWREUnlwK0RCc1c4Q1grc2hZcy9OMFhJc2cwTXVjYVczakpLSm5ObjVsOFoyWm9QTkZoZwpjWFYyRUk0b21ENjYyaG5IVWl0bnJYSGdyRGIxeUlRNjlwMklrcmNDZ2dFQUdRT3c5cjhWbmVDS252Nm9EcmUvCktiQmFQaCt4TVF6aDlKNHBIKzJnbjFWZEJPWHU4V1lwWlNFTE1FbmdTSXNPM0d3d0VnYklERFcvUFZEOW81bTMKdS9TNEhpNGx2bE1LMXcrV0ZySUp5U2VwbG5LeG9ZOUE5WTZ1OE04Wit0a3NNYUtOUk9IUDAxVDg4TU9xQlFmKwowMWh1dkt0Q3A5eHlmRTFUQkhNcDVKSGdrV2xkYWlxdmM5c1gzVHBaL0J2VjBpQzJPMkxFUHJlMWlMTWVFSHpPCmVydGR0K3g5aGZmd1RpRUJDNXdUSEE4cHZZOEkvcXBlWEorVDdLQS9YdUxILzQyN1NXYWRvRExNdDUrelJxa3kKZlB5WWtIK3d3UWRwVEJwTkNZcUN6bUhkcURtdjI1QmlaWGZtTmtFeE9keWhnQ0ViNnR5clRCajkveGUrREdteApod0tDQVFFQWlxa2lHTUtBZms2cG5lelNiZUdjVis3bjNyQlB1TXJoTHVyRkNtMllpL1BSOTE1YXlLdWtYdnpVCnNleld5eFY1cUJIblZYdnNpblRYT212THBnVEovdWdzREdRQ3h2bVNaZXNqWkpNcE1VUnUvZmswS2pVK0RqZVgKeFVGZ3p5NVpiVjZlSXlwWmE4OUZqK2RYVnJqWTZsNXVnWjdhZHNJUnN5WkFMQnQwRjNaZ200REFBRWo5RWtMdgpZZjJlbUdwTGpOVE9FOTdlOXNMNC9LWEZ3UmdZbm5kc1hMdVNPQ29DWnBDTG56VENWMTdYeTR5MHlTZ3ZaTUxUCjIxaTI3WVAvNlc0WDUvNmFGVVhIOUFhaHJOMzB2MnpMVmRLeXJHQUk4amtJeHJDWW05UjBLOWR1RGdtYXNRRWYKaC9ka2dDM0x3WHB2djUyTG1rbUtZL09nTUh3OW13PT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-credentials system:node:node-1 \
--client-certificate=node-1.crt \
--client-key=node-1.key \
--embed-certs=true \
--kubeconfig=node-1.kubeconfig && cat node-1.kubeconfig
# set-context : default 추가
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:node:node-0 \
--kubeconfig=node-0.kubeconfig && cat node-0.kubeconfig
Context "default" created.
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZURENDQXpTZ0F3SUJBZ0lVY1NNVHR5S29XcXlkK1lYWUZqVVZhd05pT2prd0RRWUpLb1pJaHZjTkFRRU4KQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2xkaGMyaHBibWQwYjI0eEVEQU9CZ05WQkFjTQpCMU5sWVhSMGJHVXhDekFKQmdOVkJBTU1Ba05CTUI0WERUSTJNREV4TURJeU1EVTFObG9YRFRNMk1ERXhNVEl5Ck1EVTFObG93UVRFTE1Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBZ01DbGRoYzJocGJtZDBiMjR4RURBT0JnTlYKQkFjTUIxTmxZWFIwYkdVeEN6QUpCZ05WQkFNTUFrTkJNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QQpNSUlDQ2dLQ0FnRUFudE4xUGh0Q3lCZ0dYUnBWeHViaUp6emhTOStVUUpiUEgxeWd4WTNrOVVlQmZnV1YvSmxRCjBmWk1ib294aXMyYzVBR1B1SnpZbW9UbkZtZjNxRWdVY09Rc0ZVYlNGSWtSU1FOQW9JMmRUdk1ESUVLNXgrK3gKazZxN1luaVhHWFFEN3R3QUdON2dvdGt4NjNGSDBPbEJNb0tBR05QcTBNZHFGMEVacktxdXlUQ1paU09yRHNjawo2bysycGxJNWVlTmg1YzBFaUFFTmxZdFc5UVd5enJDOFZLOWNYR0hDU1hqemhUc05KQUY2a0ZvNWFUTWZtRjdDCnhBTFRqSlFpc0o0VkpZdytHdVRkS2FnME00b0svTXQySkxlcElJeGl4dCtQTUpGNWdLeGpVdDVUMmE4emZ1NkwKQlQ5UEs3VGQydWd1TEdGTzh1dEJhT0U4T0NZYzZmMGdscVJ0ZHJHSUF6dXZBNk9LZlJYMGdQQ2N4bzY3UVRQeQpMdENaRUVlWnlvV3ZoRVNRVUxuYzNINVBzVzkwMndvdEU0L0ovRzIwNzhkNlhUZzRWNS9wUzhUNDQ5Q20yZXd1Cld5bzZNc1FZMllWbUdIdzBxTDhMZ2dDRDlNVHF2QTFoWVBzOGo0NjZxUldic01nNTFoRmxXazZ5b081RS9INXcKVUhuQlQrTHVWb3RpOXBRNC9oWjg3aDZNc0NsT3lDK2xFM0ZJMlkvU0FwamZXS0Y5dHVJaHhmY3J3dW5wcnUrTAorZFY5eDZ5em45SS9xQjhadmFLeTFuS0g2RU53RG5PN2llN0YrNTFnb2FacTBFV2UrSHg1ZzJFcHUwZlArdlBPCnUrSzB5bUxCaVhhVGJBS0NTTW9vNFpab3BRQjBBTVVrb3NzNkgxYzZSRjV3bDZabFlreXcrWkVDQXdFQUFhTTgKTURvd0RBWURWUjBUQkFVd0F3RUIvekFMQmdOVkhROEVCQU1DQVFZd0hRWURWUjBPQkJZRUZKN05Ocm9pYTBPbgoyeU1wbDFNYjBYTGZiV0hTTUEwR0NTcUdTSWIzRFFFQkRRVUFBNElDQVFCd3ByOCs4bmlHRTlVakFLUUcyQU5rCnh6SG5NUFFOeU44NXpFcXJCMFp4M2tpSEJ0RS9GaHpRdHhoL0lkZnozRTN0U0k4blRNbTRsSDYycnZQdmM1NEYKMTlLMWdXV3poeExrWkMrdEsyMEpVVVN5dVJkS0VlTzZTSHB0UVlwOEZkTWVhWVlMSS9jSHVBcmRTNkw5ek1pYQpCTDRZWEdwbTFxM3lYeVRrd3VnSFJTcFlxeUJ6UDhMa3NESjU3T2EyYSs3Q0xaYXU1ZnczSkpPRFJEc3V5OXRUClhGS2UzT2VWQS9INmcvQUMwUzlKa1JDTnVKODhxOG40S0hDRTRySzA2dUErVklUaHltd1p0dHlsTkhDQUVGNncKa2ptbjQ1SndIS3ZSY2YybTVhZDlVNWNWd0p5bkJidnZXNi9lMXFOVGgyZnRvcEUvUVVraHozUk8vNWlMQ3BIQgpNUjZWZW5qY05FYTg2TnoyUTVWOFRmLzhSWHpOWjZHU1BBQXhsUENTNDNkWkpMZVZUc2N2bTBURlZzRm5kQktxCmlOWXZjUGxyWHp0diswTVJxOXpkVWpQS1g2by85L2RBOXkxZG9GQlBRMWFxRWhnUGRWQnJqenJNbjdXaUVna2cKZWF4VlZaYnovbXNxYUF1akZnRUdaZ2V5OEFWUEI3WWNKSit5dXFSV2xMbmJ0enl2MUt6WGd1SytYYjZBazRFdAp5T2pscWhINlNKNm9JODA3MldwcXp5Z2hEcG9IOWt5VGpILy8xSEVLNVZOdXUxbUYxMGVrd05VQk9wQkREdXl5CjNDS20xUmhkUHlYRjhtSUxwOU9FODBrb3E1SzZ0RndOUy9oREVSdFFXdC9zMUN2dHFLa1NxZFlSVUlzKzBzcXQKWVRCZTJIdWJZVGptaUdOMzhOZnlOQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
server: https://server.kubernetes.local:6443
name: kubernetes-the-hard-way
contexts:
- context:
cluster: kubernetes-the-hard-way
user: system:node:node-0
name: default
current-context: ""
kind: Config
preferences: {}
users:
- name: system:node:node-0
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdCRENDQSt5Z0F3SUJBZ0lVS3dQM3VtUHBKc2lsd1ovZGk5amZUS3BXOVhBd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2xkaGMyaHBibWQwYjI0eEVEQU9CZ05WQkFjTQpCMU5sWVhSMGJHVXhDekFKQmdOVkJBTU1Ba05CTUI0WERUSTJNREV4TURJeU1qZzBPRm9YRFRNMk1ERXhNVEl5Ck1qZzBPRm93YURFYk1Ca0dBMVVFQXd3U2MzbHpkR1Z0T201dlpHVTZibTlrWlMwd01SVXdFd1lEVlFRS0RBeHoKZVhOMFpXMDZibTlrWlhNeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBYWVhOb2FXNW5kRzl1TVJBdwpEZ1lEVlFRSERBZFRaV0YwZEd4bE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBCjAvN3l3Tis3Q0hadDd4dkZKZUFXWnI3Uk5yQXVhNXJGMTNuNU50b3J5NVdSbEJ0MWt2V0hKZ3Vvak9XZ0IrYkQKQVhGaHdmRkFRMWNkWTd0Unh2MkJxK0NEUUxBcGVHOGlNR01YSVc1Qk1UYzV1YTlmakF5dGg5aUJsY2JVdm03NQoyaHNjeUtNUGNqeDNLbm9iSzNGQWhhUGsrMTdWZ1JTZ0Zabk9hc1FmVURwUHFSQVh1OXpwNHJvRFNPa1o3SXVVCkhkYVRHMWRHN2lVNTA1czdTaHVNY2Y4aC8yQjRUN0lLRU0vYWM2bEwzUEZRTGNXQ0MwUTB5MENIM0FjN2lCL08KdzRYRkVyZnpFMDEzNEgxZ3FWdXNnVHcvZVdPd2lDZXBrdUxDdllZTzZQTHR1Nzh2N1JUd1VNKzdvNDJPanVXKwpSWEt0ZzNnZTJrMU9uOWxQYlZzckpZMkFaMXU5cFJPNDB4bzFZWnlMeHVlMVJXN1NYb0sxR2U1cWtoUzM3d1JtCmlyT1VDa1MvMGtERFluMFY4MUJMbjNaQmJJY1ZYS3gwSnN6R1VTbkE0VFZTMFl4RndaTVg0a1dJalo4alRobWQKVHQ5QVdUcnc1eEpYL3RweStLY2JUcjVGZFY4eWxHa1JBaytwYWxPNUkyS0lRcllXN1Bsa01lcU5iZkh4MGRycwpuN21wMnFZbk9laE81QTlpRWVKRURLcDhSQm1GanlrMXVHTnQzNFdkR1liRFNXK3RWL1lEUDQvSFZqc2tvWnZHCmhXMXdtSHRHS2dhVHZJZ1BNOFE5M2d4NTRzTVBhRmNzQjd5MDVBVDErQXZPWHJlQTlieEUzNnJyT0RURW8rRTAKc3lRaFF2UVF5Qk9vTW1ZUHhvUzdhLzlZK3JrOUZzV2M4TDR0bm50TnNQa0NBd0VBQWFPQnpEQ0J5VEFKQmdOVgpIUk1FQWpBQU1CMEdBMVVkSlFRV01CUUdDQ3NHQVFVRkJ3TUNCZ2dyQmdFRkJRY0RBVEFPQmdOVkhROEJBZjhFCkJBTUNCYUF3RVFZSllJWklBWWI0UWdFQkJBUURBZ2VBTUNFR0NXQ0dTQUdHK0VJQkRRUVVGaEpPYjJSbExUQWcKUTJWeWRHbG1hV05oZEdVd0Z3WURWUjBSQkJBd0RvSUdibTlrWlMwd2h3Ui9BQUFCTUIwR0ExVWREZ1FXQkJUdwpkWXhHVWxkWHY4TTJUc3VTSzAzeE10ZHA0REFmQmdOVkhTTUVHREFXZ0JTZXpUYTZJbXREcDlzaktaZFRHOUZ5CjMyMWgwakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBRmhYZlYzV3diVzZOTlZMV1F3ZGh6Zk1BWU5KcUhZSGEKVlpna2lNN0NXVUlMc1lPbjNuRkIzd0swVTU0N2JMM2VoWmZCMTNHS002cEppR2VtZEVyWWdHakxMcUd1VXF4MApSQUpCREhrVmI5ZElWcDdZUVErejhqSGN0bXZ4Q2VldjMzVnEvYjdWM1drZ2ptWmZpUE1UdzBubHlNcFp6b01jCjN5QTRUK01UazlROXgvdGpoZFpkRkpCTXlVVkM0MVRtNXJmQjdMbWhhT3ZWR3lqTXZNd0hsUHFpU2NBVUdWV3kKUWlzRXcwYzVkSEJucklza0hncmtoam9kVmhqemx1TDAxaUEwdnQxNUw3YldTdTNGQ2FOQ20vUEV2Wm50V2dVbgp6aXUyU041Sk9WMGp3enIxS0IwM0ZtK1RteFZPZUNkajRkNGJIalptMWovcE12QkJUTUxOWlFad1FLWUtWVjlICmR6cnJBelZ2V2daMXdZK0IrUDByV04zWkxkWVM0Zkt1RkQ1N3I1WWxmV2dwMFV1N1ZnTW0yYVJOcnIyc2svL2oKZTA4WDJMalNQNlNrMm5OTkhhR3dIYmRvVnZMVnVXdFNzOHdKOVZVV1VyZWpxalpVRTNKL0FWUEtlZVZlaElkQQpmc1RYdzRzZ011Um5QMDNOTTlDU0F6Rkp4K0l1RmVjV28vcmMrTTloUk1qdDY2M01VQm9PY2hrd3l5S0dhcjBrCkpCaTFKMVN4eEpiTjg5UzZtK3g5TklCMm5pUVF0RmI2bjBxQllQSlhyZEpGem1XcXlKVWtiK1JyUDUvODFzczAKVkFrcWpCZHN5RTBQdXJUVXhmL2xGQ3o3VURURTlvY1NST3JudWVPRTJBWWJ1S2VtSnIzRHYzN2dESEtlT0VLUAo3T3JEUTg2ekptaz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRRFQvdkxBMzdzSWRtM3YKRzhVbDRCWm12dEUyc0M1cm1zWFhlZmsyMml2TGxaR1VHM1dTOVljbUM2aU01YUFINXNNQmNXSEI4VUJEVngxagp1MUhHL1lHcjRJTkFzQ2w0YnlJd1l4Y2hia0V4TnptNXIxK01ESzJIMklHVnh0Uytidm5hR3h6SW93OXlQSGNxCmVoc3JjVUNGbytUN1h0V0JGS0FWbWM1cXhCOVFPaytwRUJlNzNPbml1Z05JNlJuc2k1UWQxcE1iVjBidUpUblQKbXp0S0c0eHgveUgvWUhoUHNnb1F6OXB6cVV2YzhWQXR4WUlMUkRUTFFJZmNCenVJSDg3RGhjVVN0L01UVFhmZwpmV0NwVzZ5QlBEOTVZN0NJSjZtUzRzSzloZzdvOHUyN3Z5L3RGUEJRejd1ampZNk81YjVGY3EyRGVCN2FUVTZmCjJVOXRXeXNsallCblc3MmxFN2pUR2pWaG5Jdkc1N1ZGYnRKZWdyVVo3bXFTRkxmdkJHYUtzNVFLUkwvU1FNTmkKZlJYelVFdWZka0ZzaHhWY3JIUW16TVpSS2NEaE5WTFJqRVhCa3hmaVJZaU5ueU5PR1oxTzMwQlpPdkRuRWxmKwoybkw0cHh0T3ZrVjFYektVYVJFQ1Q2bHFVN2tqWW9oQ3RoYnMrV1F4Nm8xdDhmSFIydXlmdWFuYXBpYzU2RTdrCkQySVI0a1FNcW54RUdZV1BLVFc0WTIzZmhaMFpoc05KYjYxWDlnTS9qOGRXT3lTaG04YUZiWENZZTBZcUJwTzgKaUE4enhEM2VESG5pd3c5b1Z5d0h2TFRrQlBYNEM4NWV0NEQxdkVUZnF1czROTVNqNFRTekpDRkM5QkRJRTZneQpaZy9HaEx0ci8xajZ1VDBXeFp6d3ZpMmVlMDJ3K1FJREFRQUJBb0lDQURBTlh1cjNDNGI4aVNpa3E4aE5CZWJlCkk3LzRxVno4cFJHVmRUYkl0eHFiV1hjdnpqTzBjYURmRGFKNlBnN3NjSkU0S1FkejdyUVUzL1dHTlNBY3dESzgKWGlQZ2lsWGhJdWZDM2pCV3RISTZhVnc4Y3pUa2ZzVUcvMEI2NUNnU01aSU5pVFcxT0VBVmtwRlBRaTlUcVdOaApaZnJRWVNhMERTRTRUc0NHbWU1dWVUWUNEczhuWU9CaWQzSWtYQnJ3L0c3Uy8xODRKankrdFYvUWxOelVaNzVECkxXcWNiRWpzT3puYVUxTGFNZmJ2djlQUUxBenZ0ZVBJU2NORzVHaVRoU051ZytBZFQveTFGNUlMK1VnS0hvemcKb2lhYXdSM3JsNVZTenY5MGpwYWcwZUEza3Q1elc1R0Z0S3Q2MzdCbVJQMnE0OGVrQjZKRjJhZUQ4MnYvT1VVTQoyR1JadDYrdXhHeWkxblRWSTA2YjZQVDFPQU5zSGZ4OUtvcTBybEdUQnY5TnFYcUtrczBldWRBUmFPUTB3UmFUCityaXA2MFhpalNFRkg2RzFlQXE3UnkvdUtTc0UzbnEwdGs3d2lWbFYwemlleVk2cjFUZnFXZjgvKzBxYndyZDIKalpVemp6UHUwSmJCZGRTeHJVUUpwcTcvSlliMjNKb0dnUVJPaTFQMUhKbjBqUVZXUkdPRUMzK2JKTitvamYzTQorSnhKUndidFNaYUphbnpMckpKbTF2MUFQMENqeENiM2N1b2lnc2JwL2RzOWF4YnFLaTduaVpvZjUwZUJSei9qCmQ3ZkJ1Sm9yQ09sbEpmM2p5ZHpXWTVqY1BSNjYyemczc2IyWUlnc2dacDJTaytCVTM0bXVCc0hsUUx6elFxRXgKc1RlQmNsd3BrQlNaODVoSzRkWjlBb0lCQVFEOUJRbGJjMUNPOFZLaFI0KzdtalJPTTMyMVNxdVlneEkveWFBWgpNUThIWEFaV1Uya084QnZ2bjZDdHI5SHlXQ005U1ZlQWEyNzdzQ1dSTkkxRGVoR0ZPekpJTUFOcDEzaGgva3lICkN3NzY4NTY0MHBtVlh3d1lSejBIN2FuUXJudHpaQ2YwV0lwWE5pd01CNnZvNkh3a1Z5M25LdDRTTWVRY2Y2bVoKYU1saHBrdlM1c3NkU25zUmRPUWZiZGhmdHF4ZXp6dlQ4WmcxNnFTeHM3b3IraytUVjlBbmZqL21HMnV3RHdLWApQb2Q5R3JUdTlJaXBuOFBvZ1Qza01xTzNCUUdJVml4V200cHc3T3dLOUhsYzNpcGR6eUV1YVcyREM0OGRyNm4zCk9lMDZ0ODJGRGZRZHZra0hUN3g2eU9aalBiRXBMNjNSYkpjVktRVFBpb1lFK1JmakFvSUJBUURXZmpVUi9QOWwKVTZjb0VhZEkrbmdvK3pVOU1WQ1VZazZnK3J1U3cvWml2ZTFBY1RUdXlZZmRQMGc1eDlDbkRLeXVhSlpEc0JXSgpiQUNCS2N6RjNYcHBoZ1BJRXA3WkFVYy9KdHZlWUNWYVlqczQ2cnZIbitNNHd2U3gvZ1JKSDhFZnZwVG1Bc1V3CktMMGFVRWVSWnFnTjZMREJRNnVRWFppR3hyd1pRdFZhTVlzVVpXSDAwTzFja0d0Mk5jUWdlOXh0YVZwV3BwY2MKWGxSYWRSK0JXaXFvSTJLdllwK1ZpU3VEQ3FnN0gwWlBVeGY1RHgvcEVYd3l0WDRkUjdaSVdvaEVoV2R2b25NLwp3VEhTSUZHc0ZBQlhVdEUrbkRHNjhJQzh3ejdNR2dEbW1adW5KbXZUN2RnMEQ0ZmtwZnQ2NHlQRHFiZ2VrUnE0CmtNUnFiL28rZmhKekFvSUJBQ1daZVFHQkNtaWpqZjd2am5sM2VleGhGSDQ3WVhLaGo3V3c5Ynlvb0s0Y1M4aksKVG1OczVRbmY4OVc3dWZ4RWdzQVp4UW9OYlFtejdIRSttUHQ5Q1Z0K0o0TzR0dGtrcnZ3SStVQmNNVmF6bTFPbAo0RExsVS92TG9sTXFTMEQ2bk5mUisyb0JPbFdwZERRNWM1K0I1T2pWbDdteGtoeXNFMVQwMTdRM2NTMjBzN0hjCm9EUnpIQVRGRlIxaWluUDJ4bmkwWFJTcTQwNm4xdCtkY0w0V1RYcjg0cTdyd1AwbCtBUEt4enpJaXdQWlV5ZnIKYU4ra0lVM00zdkNwWWREUnlwK0RCc1c4Q1grc2hZcy9OMFhJc2cwTXVjYVczakpLSm5ObjVsOFoyWm9QTkZoZwpjWFYyRUk0b21ENjYyaG5IVWl0bnJYSGdyRGIxeUlRNjlwMklrcmNDZ2dFQUdRT3c5cjhWbmVDS252Nm9EcmUvCktiQmFQaCt4TVF6aDlKNHBIKzJnbjFWZEJPWHU4V1lwWlNFTE1FbmdTSXNPM0d3d0VnYklERFcvUFZEOW81bTMKdS9TNEhpNGx2bE1LMXcrV0ZySUp5U2VwbG5LeG9ZOUE5WTZ1OE04Wit0a3NNYUtOUk9IUDAxVDg4TU9xQlFmKwowMWh1dkt0Q3A5eHlmRTFUQkhNcDVKSGdrV2xkYWlxdmM5c1gzVHBaL0J2VjBpQzJPMkxFUHJlMWlMTWVFSHpPCmVydGR0K3g5aGZmd1RpRUJDNXdUSEE4cHZZOEkvcXBlWEorVDdLQS9YdUxILzQyN1NXYWRvRExNdDUrelJxa3kKZlB5WWtIK3d3UWRwVEJwTkNZcUN6bUhkcURtdjI1QmlaWGZtTmtFeE9keWhnQ0ViNnR5clRCajkveGUrREdteApod0tDQVFFQWlxa2lHTUtBZms2cG5lelNiZUdjVis3bjNyQlB1TXJoTHVyRkNtMllpL1BSOTE1YXlLdWtYdnpVCnNleld5eFY1cUJIblZYdnNpblRYT212THBnVEovdWdzREdRQ3h2bVNaZXNqWkpNcE1VUnUvZmswS2pVK0RqZVgKeFVGZ3p5NVpiVjZlSXlwWmE4OUZqK2RYVnJqWTZsNXVnWjdhZHNJUnN5WkFMQnQwRjNaZ200REFBRWo5RWtMdgpZZjJlbUdwTGpOVE9FOTdlOXNMNC9LWEZ3UmdZbm5kc1hMdVNPQ29DWnBDTG56VENWMTdYeTR5MHlTZ3ZaTUxUCjIxaTI3WVAvNlc0WDUvNmFGVVhIOUFhaHJOMzB2MnpMVmRLeXJHQUk4amtJeHJDWW05UjBLOWR1RGdtYXNRRWYKaC9ka2dDM0x3WHB2djUyTG1rbUtZL09nTUh3OW13PT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:node:node-1 \
--kubeconfig=node-1.kubeconfig && cat node-1.kubeconfig
# use-context : current-context 에 default 추가
root@jumpbox:~/kubernetes-the-hard-way# kubectl config use-context default \
--kubeconfig=node-0.kubeconfig
Switched to context "default".
root@jumpbox:~/kubernetes-the-hard-way# kubectl config use-context default \
--kubeconfig=node-1.kubeconfig
Switched to context "default".
root@jumpbox:~/kubernetes-the-hard-way# ls -l *.kubeconfig
-rw------- 1 root root 10161 Jan 11 07:49 node-0.kubeconfig
-rw------- 1 root root 10161 Jan 11 07:49 node-1.kubeconfig
동일한 방식으로 kube-proxy, kube-controller-manager, kube-scheduler, admin kubeconfig 파일 생성 후 나누겠습니다.
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.crt \
--embed-certs=true \
--server=https://server.kubernetes.local:6443 \
--kubeconfig=kube-proxy.kubeconfig
Cluster "kubernetes-the-hard-way" set.
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-credentials system:kube-proxy \
--client-certificate=kube-proxy.crt \
--client-key=kube-proxy.key \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
User "system:kube-proxy" set.
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
Context "default" created.
root@jumpbox:~/kubernetes-the-hard-way# kubectl config use-context default \
--kubeconfig=kube-proxy.kubeconfig
Switched to context "default".
root@jumpbox:~/kubernetes-the-hard-way# cat kube-proxy.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZURENDQXpTZ0F3SUJBZ0lVY1NNVHR5S29XcXlkK1lYWUZqVVZhd05pT2prd0RRWUpLb1pJaHZjTkFRRU4KQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2xkaGMyaHBibWQwYjI0eEVEQU9CZ05WQkFjTQpCMU5sWVhSMGJHVXhDekFKQmdOVkJBTU1Ba05CTUI0WERUSTJNREV4TURJeU1EVTFObG9YRFRNMk1ERXhNVEl5Ck1EVTFObG93UVRFTE1Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBZ01DbGRoYzJocGJtZDBiMjR4RURBT0JnTlYKQkFjTUIxTmxZWFIwYkdVeEN6QUpCZ05WQkFNTUFrTkJNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QQpNSUlDQ2dLQ0FnRUFudE4xUGh0Q3lCZ0dYUnBWeHViaUp6emhTOStVUUpiUEgxeWd4WTNrOVVlQmZnV1YvSmxRCjBmWk1ib294aXMyYzVBR1B1SnpZbW9UbkZtZjNxRWdVY09Rc0ZVYlNGSWtSU1FOQW9JMmRUdk1ESUVLNXgrK3gKazZxN1luaVhHWFFEN3R3QUdON2dvdGt4NjNGSDBPbEJNb0tBR05QcTBNZHFGMEVacktxdXlUQ1paU09yRHNjawo2bysycGxJNWVlTmg1YzBFaUFFTmxZdFc5UVd5enJDOFZLOWNYR0hDU1hqemhUc05KQUY2a0ZvNWFUTWZtRjdDCnhBTFRqSlFpc0o0VkpZdytHdVRkS2FnME00b0svTXQySkxlcElJeGl4dCtQTUpGNWdLeGpVdDVUMmE4emZ1NkwKQlQ5UEs3VGQydWd1TEdGTzh1dEJhT0U4T0NZYzZmMGdscVJ0ZHJHSUF6dXZBNk9LZlJYMGdQQ2N4bzY3UVRQeQpMdENaRUVlWnlvV3ZoRVNRVUxuYzNINVBzVzkwMndvdEU0L0ovRzIwNzhkNlhUZzRWNS9wUzhUNDQ5Q20yZXd1Cld5bzZNc1FZMllWbUdIdzBxTDhMZ2dDRDlNVHF2QTFoWVBzOGo0NjZxUldic01nNTFoRmxXazZ5b081RS9INXcKVUhuQlQrTHVWb3RpOXBRNC9oWjg3aDZNc0NsT3lDK2xFM0ZJMlkvU0FwamZXS0Y5dHVJaHhmY3J3dW5wcnUrTAorZFY5eDZ5em45SS9xQjhadmFLeTFuS0g2RU53RG5PN2llN0YrNTFnb2FacTBFV2UrSHg1ZzJFcHUwZlArdlBPCnUrSzB5bUxCaVhhVGJBS0NTTW9vNFpab3BRQjBBTVVrb3NzNkgxYzZSRjV3bDZabFlreXcrWkVDQXdFQUFhTTgKTURvd0RBWURWUjBUQkFVd0F3RUIvekFMQmdOVkhROEVCQU1DQVFZd0hRWURWUjBPQkJZRUZKN05Ocm9pYTBPbgoyeU1wbDFNYjBYTGZiV0hTTUEwR0NTcUdTSWIzRFFFQkRRVUFBNElDQVFCd3ByOCs4bmlHRTlVakFLUUcyQU5rCnh6SG5NUFFOeU44NXpFcXJCMFp4M2tpSEJ0RS9GaHpRdHhoL0lkZnozRTN0U0k4blRNbTRsSDYycnZQdmM1NEYKMTlLMWdXV3poeExrWkMrdEsyMEpVVVN5dVJkS0VlTzZTSHB0UVlwOEZkTWVhWVlMSS9jSHVBcmRTNkw5ek1pYQpCTDRZWEdwbTFxM3lYeVRrd3VnSFJTcFlxeUJ6UDhMa3NESjU3T2EyYSs3Q0xaYXU1ZnczSkpPRFJEc3V5OXRUClhGS2UzT2VWQS9INmcvQUMwUzlKa1JDTnVKODhxOG40S0hDRTRySzA2dUErVklUaHltd1p0dHlsTkhDQUVGNncKa2ptbjQ1SndIS3ZSY2YybTVhZDlVNWNWd0p5bkJidnZXNi9lMXFOVGgyZnRvcEUvUVVraHozUk8vNWlMQ3BIQgpNUjZWZW5qY05FYTg2TnoyUTVWOFRmLzhSWHpOWjZHU1BBQXhsUENTNDNkWkpMZVZUc2N2bTBURlZzRm5kQktxCmlOWXZjUGxyWHp0diswTVJxOXpkVWpQS1g2by85L2RBOXkxZG9GQlBRMWFxRWhnUGRWQnJqenJNbjdXaUVna2cKZWF4VlZaYnovbXNxYUF1akZnRUdaZ2V5OEFWUEI3WWNKSit5dXFSV2xMbmJ0enl2MUt6WGd1SytYYjZBazRFdAp5T2pscWhINlNKNm9JODA3MldwcXp5Z2hEcG9IOWt5VGpILy8xSEVLNVZOdXUxbUYxMGVrd05VQk9wQkREdXl5CjNDS20xUmhkUHlYRjhtSUxwOU9FODBrb3E1SzZ0RndOUy9oREVSdFFXdC9zMUN2dHFLa1NxZFlSVUlzKzBzcXQKWVRCZTJIdWJZVGptaUdOMzhOZnlOQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
server: https://server.kubernetes.local:6443
name: kubernetes-the-hard-way
contexts:
- context:
cluster: kubernetes-the-hard-way
user: system:kube-proxy
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: system:kube-proxy
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdFakNDQS9xZ0F3SUJBZ0lVS3dQM3VtUHBKc2lsd1ovZGk5amZUS3BXOVhJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2xkaGMyaHBibWQwYjI0eEVEQU9CZ05WQkFjTQpCMU5sWVhSMGJHVXhDekFKQmdOVkJBTU1Ba05CTUI0WERUSTJNREV4TURJeU1qZzFNbG9YRFRNMk1ERXhNVEl5Ck1qZzFNbG93YmpFYU1CZ0dBMVVFQXd3UmMzbHpkR1Z0T210MVltVXRjSEp2ZUhreEhEQWFCZ05WQkFvTUUzTjUKYzNSbGJUcHViMlJsTFhCeWIzaHBaWEl4Q3pBSkJnTlZCQVlUQWxWVE1STXdFUVlEVlFRSURBcFhZWE5vYVc1bgpkRzl1TVJBd0RnWURWUVFIREFkVFpXRjBkR3hsTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDCkNnS0NBZ0VBNEt1RGdrWVhrRzhaYVFhb2dmcnhCVFNOOXovZkhKdWxNalBBODRYL0ZHaTYzNFNMSEpSbUZybC8Kb2tzYXRjdGhBaWcwaXVlNW4wWHYwUzUxU2NhUlpHQk1NQ1dBOVVDRUdoOTRGVHZFemp4SkpnZHlLbjEreldHMAp0UFhIM2ROWFNHaWptYmpqWGI5Nmhndm0xMEN3WjZYMWVneksxTnRPUVRRVmR4emhUWUpkZjFYNU5VUERLZHo3CmdsZ1FvS2F2TW5LMmV0T2ZMTGpBamdncWsvaEZYbTloUXNCdDJDWHp6ZlF5Nkc1ZHR6OUJwSGxRT1liamJZNEEKU0grNUR4clk0MGd5dHM0TFdtNmU4bHZCditWUXhubTlJcUhFQ2Vvc3JkRENjWWx5bW9RNmpmY0JtN2dRYXFnUAptY0Q0T0ptVlVEdE1iZ2piTXBxOG4zZ1JrcXFLam9lQTN2d1BFYStvK0UvcHpYQy9udEZ5WEhzQjNsclNkOUNhClN6V2xmVkFyQWlSOVBQdHMwbjFqMCtzTFgxSytMYndQVUh0cjliRWVzV0RSbW9kODE0QXRsY3lPVVkvYlBqbHMKaEtENDF1Qk9ZcU0zVGJucHVQTjBkNDBtOEFJYXpGY0p6RFU4Vk5FLzU1ellIeHlXcEQ3dm5JclZHclVNYVA1NApPcUxKRE56Si9XQmhFcklrRFlEZ1lwSEFIL3RFcEZqc3pKM3BZZllBb2hBaDdIL0JYSHNGYmlPUmpZUnZTckw1CjJaQ3lUQkFpV1QrWEl3SE9aY2EySnhaNXRIejIzQ1EwWFYwaW9WRldldDIxZ0p4MWFKalFEN1RlbXVoT0RDTnEKQmQ0MDY5UjVqOEY2QW5oSjZvaDZIRFBtVGFtRHlOLzNtc2JaU0xUbk9McnUwQzFnS3EwQ0F3RUFBYU9CMURDQgowVEFKQmdOVkhSTUVBakFBTUIwR0ExVWRKUVFXTUJRR0NDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREFUQU9CZ05WCkhROEJBZjhFQkFNQ0JhQXdFUVlKWUlaSUFZYjRRZ0VCQkFRREFnZUFNQ1VHQ1dDR1NBR0crRUlCRFFRWUZoWkwKZFdKbElGQnliM2g1SUVObGNuUnBabWxqWVhSbE1Cc0dBMVVkRVFRVU1CS0NDbXQxWW1VdGNISnZlSG1IQkg4QQpBQUV3SFFZRFZSME9CQllFRkw1OVR0eVN3S3E1YkVFZTFTK2l4aVo1OVdOU01COEdBMVVkSXdRWU1CYUFGSjdOCk5yb2lhME9uMnlNcGwxTWIwWExmYldIU01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRQ05WRURkSlFsSlozNVYKVEM1UmJITExQTEk2SFJOeTVvUm9UUGFRazhPSWFWZTZULzR0Vk15bUNwZklVR1JxQVFqRkZDcVBua3R1QjBEKwpmd1RoL01xMDNYNDRwRTlwWmFEbVIzWk5qVVpkV045NjF2UnJSTTVaVzhzaDIrVk5CN2lpc2VHY3h1ZDN1TnEvCmlEdjV4d3BEQUZib1R5ZDE0VDFsT0NIbW45eFBTcDQ1aGtKWjhYT00yT1dJNTlINWZ0Y2lLNmdCd1Y4OWxMSHQKNGFyMmZ6VEdaR3hPOW04ZHRsbUxXaVg1S1U0VVlyVTN0OW5pUGV3a2g0VzhMM0FvVU1QSlZFa0F1VlNBZE81NgpBTHRibDdJbW5tZ3RRU1gvS0dheDVGdEl5TUhoMGZ0cFlCNFJGQnRBa0FXQ04zN04yNmJGWnB5TEdOVDE3MFArCkU2QTZoVjlWUVZDeXV1TzdSN3VUcFRDR1BmU1VxZGNJbVVDVUxlVUR5d3VnR1R4VTVwSFNiQ1VMTmdDU2FHcWcKeUtkV04vb3dicVY1Tkd6WWdtVnJ3RUV1WWtUYi9RS3h4SWF0UEEyRmFySlBSK2xBRFYyRXVid1V6ZzVJN21DUApjb040WXA1Y2N4ZzQ1bWNDOE5iN0J3OTJHREhYeUZoWGc4UWJuREVUWThwdmQzWWVhTXhCSHF6ZlM5S0lqa25aCkYzd29aQTcwWlVPQlkrMk1NcURRZzUxYnBaM0d6Zkk5L0IxVE92MHpTbXFLa2xpMmRDNHNzVGNyaTNTU3h0emQKY0VNMWlpdVBPaXN5YnVEMWhIeXpDYnVEU0MyZTdXMUU4UmttajRmQjhVVzF0NFYxdHJ3c3hINFd0UGdkMmJKWQpPcEkwR3FEeDU3TEduMFFXSms1OW9lRFFQU0ZEVEE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
client-key-data: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRd0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Mwd2dna3BBZ0VBQW9JQ0FRRGdxNE9DUmhlUWJ4bHAKQnFpQit2RUZOSTMzUDk4Y202VXlNOER6aGY4VWFMcmZoSXNjbEdZV3VYK2lTeHExeTJFQ0tEU0s1N21mUmUvUgpMblZKeHBGa1lFd3dKWUQxUUlRYUgzZ1ZPOFRPUEVrbUIzSXFmWDdOWWJTMDljZmQwMWRJYUtPWnVPTmR2M3FHCkMrYlhRTEJucGZWNkRNclUyMDVCTkJWM0hPRk5nbDEvVmZrMVE4TXAzUHVDV0JDZ3BxOHljclo2MDU4c3VNQ08KQ0NxVCtFVmViMkZDd0czWUpmUE45RExvYmwyM1AwR2tlVkE1aHVOdGpnQklmN2tQR3RqalNESzJ6Z3RhYnA3eQpXOEcvNVZER2ViMGlvY1FKNml5dDBNSnhpWEthaERxTjl3R2J1QkJxcUErWndQZzRtWlZRTzB4dUNOc3ltcnlmCmVCR1Nxb3FPaDREZS9BOFJyNmo0VCtuTmNMK2UwWEpjZXdIZVd0SjMwSnBMTmFWOVVDc0NKSDA4KzJ6U2ZXUFQKNnd0ZlVyNHR2QTlRZTJ2MXNSNnhZTkdhaDN6WGdDMlZ6STVSajlzK09XeUVvUGpXNEU1aW96ZE51ZW00ODNSMwpqU2J3QWhyTVZ3bk1OVHhVMFQvbm5OZ2ZISmFrUHUrY2l0VWF0UXhvL25nNm9za00zTW45WUdFU3NpUU5nT0JpCmtjQWYrMFNrV096TW5lbGg5Z0NpRUNIc2Y4RmNld1Z1STVHTmhHOUtzdm5aa0xKTUVDSlpQNWNqQWM1bHhyWW4KRm5tMGZQYmNKRFJkWFNLaFVWWjYzYldBbkhWb21OQVB0TjZhNkU0TUkyb0YzalRyMUhtUHdYb0NlRW5xaUhvYwpNK1pOcVlQSTMvZWF4dGxJdE9jNHV1N1FMV0FxclFJREFRQUJBb0lDQUFjNS9SVG5wRUpsRUhBc1lxY3JweXovCnI4RlFNS0QrOEtWWXZOQVljMGY0eG1vQ0hXZGg3cGEwaU1Kem4veFErbUhUWVQxR2p0WHNyZllRaEgxSEFjNDAKdXI2aHRqQXRUeEo0Q0tqR0wySmkxZ2QvSGRENEVHZ1N5SGs1bnFBbitCckFJdU1DNjIxTWgyaGdZYUJ5MkRtOQpRTlFZTFQ0RGY5VGhFLytzMGlKb0d4SEpkaWFjYzE2WldRMnNQM3lyWDk5RGlWTVNFNENnd0xEUTJtM0FBcHN6CkFmSGZ0cWpKTDdwa0xHOEZmY1l6SnExZnFaRHdJY2lZVkxJQVNiZU9xWU5HQXp1V0RROXZsM1U4TmxNeDBSTlIKUHlBcUMrQTF4QklqTU4zdUNkMm1leXV0MGtOci9Ec3lCSzV4WW9xUGhobjZqazdMd2lFeWtQYWdLaENKbzhNNgpieGZMbGdnSFhhdSsrbkNvRVF6Q3VKdVZLV2IvOS9OTE1HUmlEYW1PcERtc2xFa2tZSHBhaVBFZ0p2amlpQzJsCnFSMXBEZitJb1YwdWFRMWlWdGJPY3RpeVhYclMrRkFEWVFnaXY2V1BVNnVWRTk2M1hqWk9kWCt1V0RUdGtuZ2MKSmJLejVWeThxQUl0dWlNQWFiZjR4dkdMRG1XSVJQbm9FY2JRZVZUaktOcG8wWkw2Q2kySlpOR0w1cnFqaXBPZwo3ZzhhOVRvREk0aWZYakRXeGd6MmkyNTNJMStML3lzR1hzVklCUnF0Wnl5dDVYejQ1d1BXL3IwMm9hQ21KR0RqCmhDWW5KVVhFUzdBM3ZpQS9OVWdFa1E5eE13cTVibEN3eVlRRlU5VGdiZ3NDWjkybkJNamh2REZZOWtzeUlDRWIKQmV4NjkvWkYwTS9IZFNSS1JwOFJBb0lCQVFENnE0eEQvaXhQbEVuSURWZkhaWFFkb0dDY0dyd09yL2tWR0R6Qgo3a0diK2dTZm5xMTF2NEthNWYzUVluQ1ZEQWVmK3dPL2Viaksvb2UwK2dFc1lXZEk0b0h1YjFHUkVEUk1wdElNCk54bkRuS1BWSUVRL2JadTJla3MydUVuYzNnNTdYbjNFSjNzSWIwU04wSDFYWDZRVkhaLzRkTVcvR3kvZ2dTTlAKbE1TZnRKRXZERFR5dGhCWHVkVm5HQk9qbGwzUlBuQzhHRkdOR1IyNlFoeisrNy9Zb2dvb1hFYlBrelFPQjRMYwpValY1YlI0ck9wWmJLQWR5SnFEbTJQc1F6RjBuSzFxaElFQ3g5ekFodmNwcWljcFhjU0NuRG9WS25pdXdJdEZmCm5OYWNnMXQ4S0JGZmRzaG4vdVFOYjgyQjZXZWJ5WC8yeWc4TkZyNWY5YXc0ejd3SEFvSUJBUURsY25EL1FJeFAKVzdZNVl3L1UzVGxOcEljU1JsTXhpNEs1SGdwRTFXWHR5QWFtb3BvZzdSb1ZsVEhJRVQ4eUpyWW8zQkE4UXMzVApFbGRjWkFMWGI5S3JyVTUvbmlCOHRrWXltSlI5ZDJEdzAyVlZNenlUb2MwQlFGbUlldUd0ejdtbmVPMFlMWXhOClZ0bTlZZVYzNCtNekxueVNZalFYSjluSGlYRm5scnBWcFlGZERYdXJYM2VnWFJZUTRKTWNSUGJzaEJmQVFpRmUKQjV0TXllMEVqTThVKzFBOURLR2ZKL3kyTjF3eDVsR01TQ3B1NzkvcHIvNWp5c001K0VBQ0pNaldpSkNxR3dwegplZkprdXYzdFBjNmJsOFNFaGtIRGMySkNidkNnbmFUNWJjVjJDSlZzRkxsaGNaMkpIaEpSOG1XOXZYZDhkQjFECjIzVDZyZUNCRlY2ckFvSUJBUUN5cTc0aDVMUyswRXE2emsvbjczZVJlblFDTU1na2krZTEwbjNVR1Rnb3JrL0gKV25uM09OY21BNU1qaWxjRzFmbEZYY3p4R1JqUGtCYzR0dzVKRFBCcXNoQzgzQm0rbFZkQjM1Sk9aS1AzbXRubwpHc1NxbFR6dEYwUXZMN0p1UE5VRHVIbGFiRzIwdUdLYjFxVFF0M29rRnVha1dNOXVoVGxlQTQ0Z3RrQmtPWGRXCm1wUFBBRmlydnVqT1FBb1hpeUU1K1JDdjhZR0hXZ1NuYzJKcG1SWEltczgwcjNsRmtYNEVGZlIvaUJWWGhLQ0IKWFpRNFMxTHJXWDlNckJKZ2lkcElCZzNtVlMvbjZmSWp5cnpSclg5TlRuUmd2dWZoSk5hdENGUkdtMnNaU2tQVwpQbFVMdjRYZkluNTQyVjBaSVQzWmZBbTY1WkZPMmd3K0o4Vm5CU0xYQW9JQkFRQ3Y5amdhU1JKUnVlL2h5c3JWCllHTVYzRnVKOUV6UTdrRHVYczlaUXA3TTRGM1paVkgyZGw5T3RnQmJnbjZJbzQrSGZsMGxHY1puWE9XS2dWaDgKaDlGMHY1QTM1cmpiYTU0aUowbVpmdmZsT1BtNWdYV3ZjcUtabHhRU3lzcFFWY0gzWVpIU3ZQdWdSRDd3TWllYwo3alBMaUpjWVhCKytzbDBkM1pZTzcxVXZZYUg0RHVNTTVrWUR3ZCt1U2N3SUhndVFEeTEzMEQ5dXNUNjBnUmM0CktoU1Y3clgyVzcySEpVOTFIcmVodlJSRkZRTVYyUGhMYXlFWXZ1TkJqZFRvei9VR01lMWZ4eVVZc2lqbWYxRkYKbytUVEJtMDdoUXJpTFpicGc5TWVHa2Z1MGZSaE5Pd0MyMUhnSFJYSGxqeE9oQ3JxZkdjcUZwSnErOTZXY01wLwp0RGZKQW9JQkFIWUYxa01kL0I2cUdlVEsxaTlBK3dQQ3AzQXhWTWxjWTVSbVFsWTIvcXRyN3plYVNqTlorUisrCk96OGNBVWFHUkxOVzRiNVkzU3NTaDhVNEZUUGZDN3d3RXJDcnl2SEdMbzcxTlZwdEVRQkFza3BkQkw4VFBHQ2cKMWhSbG0zTWlsSmhGYmxNalp0QVVLWGdsajlaSklZcW9ZRTY2NWlIeHV2ZGdmT2RaU2RoMzhHL3ptODB5czRWZQpRWnNhRjJ5a2RmSjU4M1NWVWluNHViOXRhMll4cU9MTm1iNnhRMkJmWVB4b0luOXB0YTA2bFcxUTNuNDFUOElSCndya1A5QllYZXlVZlRXeTgxazFXdFRYUmV0VnZ1S3JaeDZFdy9oWTNwcjdvTzFnRFlzTVgzVDQ2bFRQS0Z0aVkKOWMzcHphc3JyT01Bd1dDTDFaakxCUHYra1JRT09JTT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
...
root@jumpbox:~/kubernetes-the-hard-way# ls -l *.kubeconfig
-rw------- 1 root root 9953 Jan 11 07:53 admin.kubeconfig
-rw------- 1 root root 10305 Jan 11 07:53 kube-controller-manager.kubeconfig
-rw------- 1 root root 10187 Jan 11 07:52 kube-proxy.kubeconfig
-rw------- 1 root root 10211 Jan 11 07:53 kube-scheduler.kubeconfig
-rw------- 1 root root 10161 Jan 11 07:49 node-0.kubeconfig
-rw------- 1 root root 10161 Jan 11 07:49 node-1.kubeconfig
# kubelet, kube-proxy kubeconfig 파일을 node-0, node-1에 복사
root@jumpbox:~/kubernetes-the-hard-way# for host in node-0 node-1; do
ssh root@${host} "mkdir -p /var/lib/{kube-proxy,kubelet}"
scp kube-proxy.kubeconfig \
root@${host}:/var/lib/kube-proxy/kubeconfig \
scp ${host}.kubeconfig \
root@${host}:/var/lib/kubelet/kubeconfig
done
kube-proxy.kubeconfig 100% 10KB 8.8MB/s 00:00
node-0.kubeconfig 100% 10KB 12.1MB/s 00:00
kube-proxy.kubeconfig 100% 10KB 12.0MB/s 00:00
node-1.kubeconfig 100% 10KB 10.5MB/s 00:00
root@jumpbox:~/kubernetes-the-hard-way# ssh node-0 ls -l /var/lib/*/kubeconfig
-rw------- 1 root root 10161 Jan 11 07:55 /var/lib/kubelet/kubeconfig
-rw------- 1 root root 10187 Jan 11 07:55 /var/lib/kube-proxy/kubeconfig
root@jumpbox:~/kubernetes-the-hard-way# ssh node-1 ls -l /var/lib/*/kubeconfig
-rw------- 1 root root 10161 Jan 11 07:55 /var/lib/kubelet/kubeconfig
-rw------- 1 root root 10187 Jan 11 07:55 /var/lib/kube-proxy/kubeconfig
# kube-controller-manager,kube-scheduler kubeconfig files을 서버로 복사
root@jumpbox:~/kubernetes-the-hard-way# scp admin.kubeconfig \
kube-controller-manager.kubeconfig \
kube-scheduler.kubeconfig \
root@server:~/
admin.kubeconfig 100% 9953 9.7MB/s 00:00
kube-controller-manager.kubeconfig 100% 10KB 12.8MB/s 00:00
kube-scheduler.kubeconfig 100% 10KB 14.4MB/s 00:00
root@jumpbox:~/kubernetes-the-hard-way# ssh server ls -l /root/*.kubeconfig
-rw------- 1 root root 9953 Jan 11 07:56 /root/admin.kubeconfig
-rw------- 1 root root 10305 Jan 11 07:56 /root/kube-controller-manager.kubeconfig
-rw------- 1 root root 10211 Jan 11 07:56 /root/kube-scheduler.kubeconfig
데이터 암호화를 위한 설정 및 키 생성
이 단계는 Kubernetes API Server가 Secret을 etcd에 저장할 때 평문이 아닌 암호화된 형태로 저장하도록 설정하는 과정입니다.
# 암호키 생성
root@jumpbox:~/kubernetes-the-hard-way# export ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
echo $ENCRYPTION_KEY
pR499HLO7RNc0VAgKmO9WqlfgE/rqBRsGskyllCp3Xo=
# Create the encryption-config.yaml encryption config file
# (참고) 실제 etcd 값에 기록되는 헤더 : k8s:enc:aescbc:v1:key1:<ciphertext>
root@jumpbox:~/kubernetes-the-hard-way# cat configs/encryption-config.yaml
kind: EncryptionConfiguration # kube-apiserver가 etcd에 저장할 리소스를 어떻게 암호화할지 정의
apiVersion: apiserver.config.k8s.io/v1 # --encryption-provider-config 플래그로 참조
resources:
- resources:
- secrets # 암호화 대상 Kubernetes 리소스 : 여기서는 Secret 리소스만 암호화
providers: # 지원 providers(위 부터 적용됨) : identity, aescbc, aesgcm, kms v2, secretbox
- aescbc: # etcd에 저장될 Secret을 AES-CBC 방식으로 암호화
keys:
- name: key1 # 키 식별자 (etcd 데이터에 기록됨)
secret: ${ENCRYPTION_KEY}
- identity: {} # 암호화하지 않음 (Plaintext), 주로 하위 호환성 / 점진적 암호화 목적
root@jumpbox:~/kubernetes-the-hard-way# cat configs/encryption-config.yaml
kind: EncryptionConfiguration
apiVersion: apiserver.config.k8s.io/v1
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: ${ENCRYPTION_KEY}
- identity: {}
root@jumpbox:~/kubernetes-the-hard-way#
root@jumpbox:~/kubernetes-the-hard-way#
root@jumpbox:~/kubernetes-the-hard-way# envsubst < configs/encryption-config.yaml > encryption-config.yaml
root@jumpbox:~/kubernetes-the-hard-way# cat encryption-config.yaml
kind: EncryptionConfiguration
apiVersion: apiserver.config.k8s.io/v1
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: pR499HLO7RNc0VAgKmO9WqlfgE/rqBRsGskyllCp3Xo=
- identity: {}
# encryption-config.yaml, encryption config file을 controller instance에 복사
root@jumpbox:~/kubernetes-the-hard-way# scp encryption-config.yaml root@server:~/
encryption-config.yaml 100% 271 343.0KB/s 00:00
root@jumpbox:~/kubernetes-the-hard-way# ssh server ls -l /root/encryption-config.yaml
-rw-r--r-- 1 root root 271 Jan 11 08:04 /root/encryption-config.yaml
etcd 클러스터 부트스트래핑
server 노드에 etcd 서비스 기동하겠습니다.
# Prerequisites
# hostname 변경 : controller -> server
# http 평문 통신!
# 각 etcd 멤버는 etcd 클러스터에서 모두 고유한 이름을 가져야합니다.
# etcd 이름을 현재의 compute instance에 맞추어 지정합니다.
root@jumpbox:~/kubernetes-the-hard-way# cat units/etcd.service | grep controller
--name controller \
--initial-cluster controller=http://127.0.0.1:2380 \
root@jumpbox:~/kubernetes-the-hard-way# ETCD_NAME=server
root@jumpbox:~/kubernetes-the-hard-way# cat > units/etcd.service <<EOF
[Unit]
Description=etcd
Documentation=https://github.com/etcd-io/etcd
[Service]
Type=notify
ExecStart=/usr/local/bin/etcd \\
--name ${ETCD_NAME} \\
--initial-advertise-peer-urls http://127.0.0.1:2380 \\
--listen-peer-urls http://127.0.0.1:2380 \\
--listen-client-urls http://127.0.0.1:2379 \\
--advertise-client-urls http://127.0.0.1:2379 \\
--initial-cluster-token etcd-cluster-0 \\
--initial-cluster ${ETCD_NAME}=http://127.0.0.1:2380 \\
--initial-cluster-state new \\
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
root@jumpbox:~/kubernetes-the-hard-way# cat units/etcd.service | grep server
--name server \
--initial-cluster server=http://127.0.0.1:2380 \
# etcd 바이너리 파일과 systemd 유닛 파일을 서버에 복사합니다.
root@jumpbox:~/kubernetes-the-hard-way# scp \
downloads/controller/etcd \
downloads/client/etcdctl \
units/etcd.service \
root@server:~/
etcd 100% 23MB 96.5MB/s 00:00
etcdctl 100% 15MB 135.0MB/s 00:00
etcd.service 100% 564 1.2MB/s 00:00
# 아래는 server 가상머신 접속 후 명령 실행
root@jumpbox:~/kubernetes-the-hard-way# ssh root@server
# Bootstrapping an etcd Cluster
# etcd 바이너리 파일 설치
root@server:~# pwd
/root
root@server:~# mv etcd etcdctl /usr/local/bin/
# etcd 서버 설정
root@server:~# mkdir -p /etc/etcd /var/lib/etcd
root@server:~# chmod 700 /var/lib/etcd
root@server:~# cp ca.crt kube-api-server.key kube-api-server.crt /etc/etcd/
# etcd.service, systemd 유닛 파일 생성
root@server:~# mv etcd.service /etc/systemd/system/
root@server:~# tree /etc/systemd/system/
/etc/systemd/system/
├── apt-daily.service -> /dev/null
├── apt-daily-upgrade.service -> /dev/null
├── dbus-org.freedesktop.timesync1.service -> /lib/systemd/system/systemd-timesyncd.service
├── etcd.service
├── getty.target.wants
│ └── getty@tty1.service -> /lib/systemd/system/getty@.service
├── multi-user.target.wants
│ ├── console-setup.service -> /lib/systemd/system/console-setup.service
│ ├── cron.service -> /lib/systemd/system/cron.service
│ ├── e2scrub_reap.service -> /lib/systemd/system/e2scrub_reap.service
│ ├── networking.service -> /lib/systemd/system/networking.service
│ ├── nfs-client.target -> /lib/systemd/system/nfs-client.target
│ ├── remote-fs.target -> /lib/systemd/system/remote-fs.target
│ ├── rpcbind.service -> /lib/systemd/system/rpcbind.service
│ ├── ssh.service -> /lib/systemd/system/ssh.service
│ ├── vboxadd.service -> /lib/systemd/system/vboxadd.service
│ └── vboxadd-service.service -> /lib/systemd/system/vboxadd-service.service
├── network-online.target.wants
│ └── networking.service -> /lib/systemd/system/networking.service
├── paths.target.wants
│ └── acpid.path -> /lib/systemd/system/acpid.path
├── remote-fs.target.wants
│ └── nfs-client.target -> /lib/systemd/system/nfs-client.target
├── sockets.target.wants
│ ├── acpid.socket -> /lib/systemd/system/acpid.socket
│ ├── dm-event.socket -> /lib/systemd/system/dm-event.socket
│ └── rpcbind.socket -> /lib/systemd/system/rpcbind.socket
├── sshd.service -> /lib/systemd/system/ssh.service
├── sysinit.target.wants
│ ├── blk-availability.service -> /lib/systemd/system/blk-availability.service
│ ├── keyboard-setup.service -> /lib/systemd/system/keyboard-setup.service
│ ├── lvm2-lvmpolld.socket -> /lib/systemd/system/lvm2-lvmpolld.socket
│ ├── lvm2-monitor.service -> /lib/systemd/system/lvm2-monitor.service
│ ├── systemd-pstore.service -> /lib/systemd/system/systemd-pstore.service
│ └── systemd-timesyncd.service -> /lib/systemd/system/systemd-timesyncd.service
└── timers.target.wants
├── dpkg-db-backup.timer -> /lib/systemd/system/dpkg-db-backup.timer
├── e2scrub_all.timer -> /lib/systemd/system/e2scrub_all.timer
├── fstrim.timer -> /lib/systemd/system/fstrim.timer
├── logrotate.timer -> /lib/systemd/system/logrotate.timer
└── man-db.timer -> /lib/systemd/system/man-db.timer
9 directories, 33 files
# etcd 서버 시작
root@server:~# systemctl daemon-reload
root@server:~# systemctl enable etcd
Created symlink /etc/systemd/system/multi-user.target.wants/etcd.service → /etc/systemd/system/etcd.service.
root@server:~# systemctl start etcd
root@server:~# systemctl status etcd --no-pager
● etcd.service - etcd
Loaded: loaded (/etc/systemd/system/etcd.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-01-11 08:19:06 KST; 2min 11s ago
Docs: https://github.com/etcd-io/etcd
Main PID: 2627 (etcd)
Tasks: 7 (limit: 2096)
Memory: 9.2M
CPU: 1.148s
CGroup: /system.slice/etcd.service
└─2627 /usr/local/bin/etcd --name server --initial-advertise-peer-urls http://127.0.0.1:2380 --listen-peer-urls http://127.0.0.1:2380 --listen-client-urls http://127.0.0.1:237…
Jan 11 08:19:06 server etcd[2627]: {"level":"info","ts":"2026-01-11T08:19:06.399737+0900","caller":"membership/cluster.go:647","msg":"set initial cluster version","cluster-i…version":"3.6"}
Jan 11 08:19:06 server etcd[2627]: {"level":"info","ts":"2026-01-11T08:19:06.399834+0900","caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.6"}
Jan 11 08:19:06 server etcd[2627]: {"level":"info","ts":"2026-01-11T08:19:06.399881+0900","caller":"etcdserver/server.go:2383","msg":"cluster version is updated","cluster-version":"3.6"}
Jan 11 08:19:06 server etcd[2627]: {"level":"info","ts":"2026-01-11T08:19:06.400006+0900","caller":"etcdmain/main.go:44","msg":"notifying init daemon"}
Jan 11 08:19:06 server etcd[2627]: {"level":"info","ts":"2026-01-11T08:19:06.400040+0900","caller":"version/monitor.go:116","msg":"cluster version differs from storage versi…rsion":"3.5.0"}
Jan 11 08:19:06 server etcd[2627]: {"level":"info","ts":"2026-01-11T08:19:06.400109+0900","caller":"schema/migration.go:65","msg":"updated storage version","new-storage-version":"3.6.0"}
Jan 11 08:19:06 server etcd[2627]: {"level":"info","ts":"2026-01-11T08:19:06.402219+0900","caller":"v3rpc/health.go:63","msg":"grpc service status changed","service":"","status":"SERVING"}
Jan 11 08:19:06 server etcd[2627]: {"level":"info","ts":"2026-01-11T08:19:06.404687+0900","caller":"etcdmain/main.go:50","msg":"successfully notified init daemon"}
Jan 11 08:19:06 server systemd[1]: Started etcd.service - etcd.
Jan 11 08:19:06 server etcd[2627]: {"level":"info","ts":"2026-01-11T08:19:06.407277+0900","caller":"embed/serve.go:220","msg":"serving client traffic insecurely; this is str…27.0.0.1:2379"}
Hint: Some lines were ellipsized, use -l to show in full.
root@server:~# ss -tnlp | grep etcd
LISTEN 0 4096 127.0.0.1:2379 0.0.0.0:* users:(("etcd",pid=2627,fd=6))
LISTEN 0 4096 127.0.0.1:2380 0.0.0.0:* users:(("etcd",pid=2627,fd=3))
root@server:~# etcdctl member list
6702b0a34e2cfd39, started, server, http://127.0.0.1:2380, http://127.0.0.1:2379, false
root@server:~# etcdctl member list -w table
+------------------+---------+--------+-----------------------+-----------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+--------+-----------------------+-----------------------+------------+
| 6702b0a34e2cfd39 | started | server | http://127.0.0.1:2380 | http://127.0.0.1:2379 | false |
+------------------+---------+--------+-----------------------+-----------------------+------------+
root@server:~# etcdctl endpoint status -w table
+----------------+------------------+------------+-----------------+---------+--------+-----------------------+-------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
| ENDPOINT | ID | VERSION | STORAGE VERSION | DB SIZE | IN USE | PERCENTAGE NOT IN USE | QUOTA | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | DOWNGRADE TARGET VERSION | DOWNGRADE ENABLED |
+----------------+------------------+------------+-----------------+---------+--------+-----------------------+-------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
| 127.0.0.1:2379 | 6702b0a34e2cfd39 | 3.6.0-rc.3 | 3.6.0 | 20 kB | 16 kB | 20% | 0 B | true | false | 2 | 4 | 4 | | | false |
+----------------+------------------+------------+-----------------+---------+--------+-----------------------+-------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
컨트롤 플레인 부트스트래핑
server 노드에 api server, scheduler, kube controller manager 서비스 기동하겠습니다.
# api -> kubelet 호출 시 Flow
kube-apiserver (client)
|
| (TLS client cert, CN=kubernetes)
↓
kubelet API Server 역할 (/stats, /log, /metrics)
|
↓
RBAC 평가:
User = kubernetes
→ ClusterRoleBinding system:kube-apiserver 매칭
→ ClusterRole system:kube-apiserver-to-kubelet 권한 부여
# kube-apiserver.service 수정 : service-cluster-ip-range 추가
# https://github.com/kelseyhightower/kubernetes-the-hard-way/issues/905
# service-cluster-ip 값은 ca.conf 에 설정한 [kube-api-server_alt_names] 항목의 Service IP 범위
root@jumpbox:~/kubernetes-the-hard-way# cat ca.conf | grep '\[kube-api-server_alt_names' -A2
[kube-api-server_alt_names]
IP.0 = 127.0.0.1
IP.1 = 10.32.0.1
root@jumpbox:~/kubernetes-the-hard-way# cat << EOF > units/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
--allow-privileged=true \\
--apiserver-count=1 \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/var/log/audit.log \\
--authorization-mode=Node,RBAC \\
--bind-address=0.0.0.0 \\
--client-ca-file=/var/lib/kubernetes/ca.crt \\
--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
--etcd-servers=http://127.0.0.1:2379 \\
--event-ttl=1h \\
--encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
--kubelet-certificate-authority=/var/lib/kubernetes/ca.crt \\
--kubelet-client-certificate=/var/lib/kubernetes/kube-api-server.crt \\
--kubelet-client-key=/var/lib/kubernetes/kube-api-server.key \\
--runtime-config='api/all=true' \\
--service-account-key-file=/var/lib/kubernetes/service-accounts.crt \\
--service-account-signing-key-file=/var/lib/kubernetes/service-accounts.key \\
--service-account-issuer=https://server.kubernetes.local:6443 \\
--service-cluster-ip-range=10.32.0.0/24 \\
--service-node-port-range=30000-32767 \\
--tls-cert-file=/var/lib/kubernetes/kube-api-server.crt \\
--tls-private-key-file=/var/lib/kubernetes/kube-api-server.key \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# kube-apiserver가 kubelet(Node)에 접근할 수 있도록 허용하는 '시스템 내부용 RBAC' 설정
root@jumpbox:~/kubernetes-the-hard-way# cat configs/kube-apiserver-to-kubelet.yaml ; echo
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true" # Kubernetes가 업그레이드 시 자동 관리
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-apiserver-to-kubelet
rules:
- apiGroups:
- ""
resources:
- nodes/proxy
- nodes/stats
- nodes/log
- nodes/spec
- nodes/metrics
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:kube-apiserver # 누가 이 권한을 쓰는가? → kube-apiserver 자신
namespace: ""
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-apiserver-to-kubelet
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: kubernetes # 사용자 kubernetes ,이 사용자는 kube-apiserver가 사용하는 클라이언트 인증서의 CN
# api-server : Subject CN 확인
root@jumpbox:~/kubernetes-the-hard-way# openssl x509 -in kube-api-server.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2b:03:f7:ba:63:e9:26:c8:a5:c1:9f:dd:8b:d8:df:4c:aa:56:f5:75
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Washington, L = Seattle, CN = CA
Validity
Not Before: Jan 10 22:28:57 2026 GMT
Not After : Jan 11 22:28:57 2036 GMT
Subject: CN = kubernetes, C = US, ST = Washington, L = Seattle
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:96:43:8b:18:ed:f0:ab:92:9b:3d:21:22:28:f7:
13:48:d0:5e:26:0e:f9:e8:09:ce:29:8b:e4:f5:2a:
7b:bd:33:37:8d:a7:a5:42:28:2c:c0:ee:35:db:11:
0a:84:da:d3:ef:c1:7f:fa:bb:66:81:bf:d9:8a:fb:
74:c7:ed:20:e6:81:f8:5c:2a:98:18:c7:10:61:6d:
e8:0d:44:6b:7a:2c:c4:ad:e0:21:b9:d2:dd:dc:53:
56:8c:1c:03:e6:40:bc:e1:7b:32:b5:7b:2b:e6:85:
4d:6b:e2:db:20:e6:7b:ac:18:bf:69:ae:ca:0e:1b:
45:14:0c:0a:5d:c1:c6:30:7c:5e:d4:87:45:4a:97:
54:16:7e:b6:99:16:36:98:30:cd:60:4b:cb:0d:9f:
95:30:c5:f6:7c:0e:9d:6f:e2:ea:b1:a1:3a:aa:c6:
0e:e8:35:75:55:e3:a1:ef:6b:fd:0f:2e:a1:1b:14:
d5:e6:e5:16:67:a0:65:3c:a7:9b:b6:34:44:f6:60:
27:64:39:0a:c2:ca:51:db:89:44:6a:6c:cc:47:ec:
73:72:05:9d:b2:82:76:4d:60:e3:3a:e8:cf:d4:61:
6b:aa:ab:6c:2d:85:13:36:fb:01:04:b7:57:7c:91:
5d:08:4f:61:5c:d3:a3:62:8f:1a:2f:51:24:a1:9a:
a9:5a:8d:0c:04:e2:e4:16:ad:46:af:99:45:32:a5:
aa:a7:b7:6a:37:9b:60:aa:76:24:5f:48:40:76:b1:
09:0f:b0:85:04:eb:d5:0d:2e:86:d2:4a:e5:10:e7:
36:28:e8:d8:41:ba:e5:5d:98:e2:72:97:cf:6d:89:
4b:59:1a:44:f9:72:1d:f8:e9:03:01:3b:ac:61:b6:
b0:95:c0:c2:7a:b4:e4:da:7a:54:be:a6:7c:1a:4f:
57:66:b3:26:67:0d:7b:f2:60:ce:99:c5:79:3b:86:
79:dd:50:67:c3:4a:85:fb:e4:47:61:c8:7f:07:c4:
98:1f:d0:f4:e5:53:c4:ad:d9:e9:ab:4c:14:6b:3c:
50:c9:5c:6b:d5:7c:cd:bd:c4:a2:2e:e5:57:61:3e:
7f:b5:a2:59:42:c8:46:64:31:82:a3:d4:46:55:35:
db:cc:4b:ce:54:47:83:d7:7e:56:ec:76:8c:7c:67:
00:02:9d:b4:d1:fc:e0:60:a3:c7:9b:6a:28:3e:cf:
0b:e4:50:f8:78:32:ac:75:8c:ba:8e:8d:8a:1a:62:
ed:1a:74:c6:71:1a:c1:4c:ec:f6:0a:c5:0d:ae:1a:
c9:d6:f7:6e:a0:9c:97:48:93:f6:2c:f8:77:6d:8c:
50:5a:fd:3d:38:80:c0:fe:81:55:c3:ce:27:e2:07:
fa:52:9f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
Netscape Cert Type:
SSL Client, SSL Server
Netscape Comment:
Kube API Server Certificate
X509v3 Subject Alternative Name:
IP Address:127.0.0.1, IP Address:10.32.0.1, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster, DNS:kubernetes.svc.cluster.local, DNS:server.kubernetes.local, DNS:api-server.kubernetes.local
X509v3 Subject Key Identifier:
CA:7C:90:05:B6:3F:7B:38:75:8B:AA:2C:09:B9:17:94:60:F2:2F:0F
X509v3 Authority Key Identifier:
9E:CD:36:BA:22:6B:43:A7:DB:23:29:97:53:1B:D1:72:DF:6D:61:D2
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
21:c5:6b:cd:66:86:8b:34:99:a3:ab:04:2a:ba:d4:3b:25:86:
11:ab:f5:97:57:55:4c:c2:b3:57:f2:5f:06:a7:07:b6:10:ef:
60:8f:eb:af:48:f5:f7:c0:80:fd:50:7d:98:b6:82:a3:6b:44:
05:4c:06:59:ec:6e:33:be:0f:58:de:bd:94:d1:54:b9:7d:53:
09:b3:ca:32:e8:c9:64:e3:f4:1a:ab:bd:94:3b:38:fd:10:49:
8f:fa:17:aa:25:06:b2:78:48:26:7a:1d:e0:1a:73:4f:61:63:
92:01:e9:37:84:9e:dd:e5:23:ba:7d:8d:9d:c0:83:75:16:95:
f4:29:95:aa:f2:27:d4:c1:3a:57:d9:65:66:1a:f2:dd:27:5e:
d0:6c:47:3e:a7:75:06:7c:96:aa:5e:39:3b:e1:d9:be:0b:a7:
3a:71:a9:0b:49:4a:d0:ca:41:a2:52:0c:d1:a6:62:20:45:d6:
b3:29:bc:b9:8c:04:d5:b9:41:af:7a:42:5f:2c:00:cf:80:a4:
54:a4:a0:e2:fa:52:8d:da:57:ac:76:af:1f:ee:3a:d2:0c:2a:
9a:bb:ea:a2:bf:10:30:ab:f3:20:b4:e6:cc:c9:81:2b:63:c5:
8d:90:6d:71:84:10:cb:b0:3b:e0:c5:36:61:0a:fe:8b:f5:c1:
ed:28:ca:e4:c5:8d:8e:9d:9b:86:d4:81:de:26:a0:fd:e4:d1:
a1:1c:48:e5:83:4e:d7:a8:bd:6f:d6:f7:19:56:a9:34:3e:ff:
a7:a8:4c:96:c9:b3:a6:eb:2c:ae:a2:b6:58:b3:0a:7d:0b:4d:
3f:31:a9:25:41:1c:cd:7c:e0:f2:7e:aa:47:a4:2a:6f:9b:30:
2a:6e:46:cd:50:05:04:69:89:17:66:cd:7b:4b:01:1a:12:50:
53:2b:e5:f9:34:49:a3:a3:e0:5a:61:11:34:aa:fa:2d:3b:f3:
22:b6:3c:32:4a:90:ab:3c:f9:01:2f:43:5a:78:80:93:5e:66:
4d:ad:7b:a2:09:34:17:3b:ce:0b:94:14:f8:5a:01:ab:98:a7:
ba:4c:0f:70:ff:3b:3c:01:0f:97:9a:6b:5b:76:9e:8b:b5:10:
49:3d:ae:6a:40:c8:16:80:af:c4:61:b3:28:f7:32:21:bf:7a:
36:6f:97:f2:ae:b2:06:6c:75:5e:99:47:f2:a6:6b:09:3b:e3:
b7:cd:29:3c:89:62:29:d7:83:78:13:4b:29:be:41:58:e9:8e:
a1:a5:07:c2:12:02:ea:85:5c:6d:13:8f:d5:49:a7:25:83:09:
ca:fc:04:81:0e:d6:5a:03:db:55:e1:0b:c2:de:13:ca:c1:ae:
36:e9:cc:a3:3e:80:ee:67
root@jumpbox:~/kubernetes-the-hard-way# cat units/kube-scheduler.service ; echo
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-scheduler \
--config=/etc/kubernetes/config/kube-scheduler.yaml \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
root@jumpbox:~/kubernetes-the-hard-way# cat configs/kube-scheduler.yaml ; echo
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
clientConnection:
kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
leaderElection:
leaderElect: true
root@jumpbox:~/kubernetes-the-hard-way# cat units/kube-controller-manager.service ; echo
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-controller-manager \
--bind-address=0.0.0.0 \
--cluster-cidr=10.200.0.0/16 \
--cluster-name=kubernetes \
--cluster-signing-cert-file=/var/lib/kubernetes/ca.crt \
--cluster-signing-key-file=/var/lib/kubernetes/ca.key \
--kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \
--root-ca-file=/var/lib/kubernetes/ca.crt \
--service-account-private-key-file=/var/lib/kubernetes/service-accounts.key \
--service-cluster-ip-range=10.32.0.0/24 \
--use-service-account-credentials=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
# jumpbox에 연결하고 쿠버네티스 바이너리 파일과 systemd 유닛 파일을 복사합니다.
root@jumpbox:~/kubernetes-the-hard-way# scp \
downloads/controller/kube-apiserver \
downloads/controller/kube-controller-manager \
downloads/controller/kube-scheduler \
downloads/client/kubectl \
units/kube-apiserver.service \
units/kube-controller-manager.service \
units/kube-scheduler.service \
configs/kube-scheduler.yaml \
configs/kube-apiserver-to-kubelet.yaml \
root@server:~/
kube-apiserver 100% 86MB 120.2MB/s 00:00
kube-controller-manager 100% 80MB 107.7MB/s 00:00
kube-scheduler 100% 61MB 84.2MB/s 00:00
kubectl 100% 53MB 61.5MB/s 00:00
kube-apiserver.service 100% 1442 1.4MB/s 00:00
kube-controller-manager.service 100% 735 1.0MB/s 00:00
kube-scheduler.service 100% 281 408.4KB/s 00:00
kube-scheduler.yaml 100% 191 288.9KB/s 00:00
kube-apiserver-to-kubelet.yaml 100% 727 1.0MB/s 00:00
# 확인
root@jumpbox:~/kubernetes-the-hard-way# ssh server ls -l /root
total 286964
-rw------- 1 root root 9953 Jan 11 07:56 admin.kubeconfig
-rw-r--r-- 1 root root 1899 Jan 11 07:36 ca.crt
-rw------- 1 root root 3272 Jan 11 07:36 ca.key
-rw-r--r-- 1 root root 271 Jan 11 08:04 encryption-config.yaml
-rwxr-xr-x 1 root root 90243224 Jan 11 08:28 kube-apiserver
-rw-r--r-- 1 root root 2354 Jan 11 07:36 kube-api-server.crt
-rw------- 1 root root 3268 Jan 11 07:36 kube-api-server.key
-rw-r--r-- 1 root root 1442 Jan 11 08:28 kube-apiserver.service
-rw-r--r-- 1 root root 727 Jan 11 08:28 kube-apiserver-to-kubelet.yaml
-rwxr-xr-x 1 root root 83427480 Jan 11 08:28 kube-controller-manager
-rw------- 1 root root 10305 Jan 11 07:56 kube-controller-manager.kubeconfig
-rw-r--r-- 1 root root 735 Jan 11 08:28 kube-controller-manager.service
-rwxr-xr-x 1 root root 55836824 Jan 11 08:28 kubectl
-rwxr-xr-x 1 root root 64225432 Jan 11 08:28 kube-scheduler
-rw------- 1 root root 10211 Jan 11 07:56 kube-scheduler.kubeconfig
-rw-r--r-- 1 root root 281 Jan 11 08:28 kube-scheduler.service
-rw-r--r-- 1 root root 191 Jan 11 08:28 kube-scheduler.yaml
-rw-r--r-- 1 root root 2004 Jan 11 07:36 service-accounts.crt
-rw------- 1 root root 3272 Jan 11 07:36 service-accounts.key
쿠버네티스 컨트롤 플레인 프로비저닝을 진행하겠습니다.
root@jumpbox:~/kubernetes-the-hard-way# ssh root@server
# 서버 접근
root@server:~# pwd
/root
root@server:~# mkdir -p /etc/kubernetes/config
# 쿠버네티스 바이너리 설치
root@server:~# mv kube-apiserver \
kube-controller-manager \
kube-scheduler kubectl \
/usr/local/bin/
root@server:~# ls -l /usr/local/bin/kube-*
-rwxr-xr-x 1 root root 90243224 Jan 11 08:28 /usr/local/bin/kube-apiserver
-rwxr-xr-x 1 root root 83427480 Jan 11 08:28 /usr/local/bin/kube-controller-manager
-rwxr-xr-x 1 root root 64225432 Jan 11 08:28 /usr/local/bin/kube-scheduler
# 쿠버네티스 api server 설정
root@server:~# mkdir -p /var/lib/kubernetes/
root@server:~# mv ca.crt ca.key \
kube-api-server.key kube-api-server.crt \
service-accounts.key service-accounts.crt \
encryption-config.yaml \
/var/lib/kubernetes/
root@server:~# ls -l /var/lib/kubernetes/
total 28
-rw-r--r-- 1 root root 1899 Jan 11 07:36 ca.crt
-rw------- 1 root root 3272 Jan 11 07:36 ca.key
-rw-r--r-- 1 root root 271 Jan 11 08:04 encryption-config.yaml
-rw-r--r-- 1 root root 2354 Jan 11 07:36 kube-api-server.crt
-rw------- 1 root root 3268 Jan 11 07:36 kube-api-server.key
-rw-r--r-- 1 root root 2004 Jan 11 07:36 service-accounts.crt
-rw------- 1 root root 3272 Jan 11 07:36 service-accounts.key
# kube-apiserver.service systemd 유닛 파일 생서
root@server:~# mv kube-apiserver.service \
/etc/systemd/system/kube-apiserver.service
root@server:~# tree /etc/systemd/system
/etc/systemd/system
├── apt-daily.service -> /dev/null
├── apt-daily-upgrade.service -> /dev/null
├── dbus-org.freedesktop.timesync1.service -> /lib/systemd/system/systemd-timesyncd.service
├── etcd.service
├── getty.target.wants
│ └── getty@tty1.service -> /lib/systemd/system/getty@.service
├── kube-apiserver.service
├── multi-user.target.wants
│ ├── console-setup.service -> /lib/systemd/system/console-setup.service
│ ├── cron.service -> /lib/systemd/system/cron.service
│ ├── e2scrub_reap.service -> /lib/systemd/system/e2scrub_reap.service
│ ├── etcd.service -> /etc/systemd/system/etcd.service
│ ├── networking.service -> /lib/systemd/system/networking.service
│ ├── nfs-client.target -> /lib/systemd/system/nfs-client.target
│ ├── remote-fs.target -> /lib/systemd/system/remote-fs.target
│ ├── rpcbind.service -> /lib/systemd/system/rpcbind.service
│ ├── ssh.service -> /lib/systemd/system/ssh.service
│ ├── vboxadd.service -> /lib/systemd/system/vboxadd.service
│ └── vboxadd-service.service -> /lib/systemd/system/vboxadd-service.service
├── network-online.target.wants
│ └── networking.service -> /lib/systemd/system/networking.service
├── paths.target.wants
│ └── acpid.path -> /lib/systemd/system/acpid.path
├── remote-fs.target.wants
│ └── nfs-client.target -> /lib/systemd/system/nfs-client.target
├── sockets.target.wants
│ ├── acpid.socket -> /lib/systemd/system/acpid.socket
│ ├── dm-event.socket -> /lib/systemd/system/dm-event.socket
│ └── rpcbind.socket -> /lib/systemd/system/rpcbind.socket
├── sshd.service -> /lib/systemd/system/ssh.service
├── sysinit.target.wants
│ ├── blk-availability.service -> /lib/systemd/system/blk-availability.service
│ ├── keyboard-setup.service -> /lib/systemd/system/keyboard-setup.service
│ ├── lvm2-lvmpolld.socket -> /lib/systemd/system/lvm2-lvmpolld.socket
│ ├── lvm2-monitor.service -> /lib/systemd/system/lvm2-monitor.service
│ ├── systemd-pstore.service -> /lib/systemd/system/systemd-pstore.service
│ └── systemd-timesyncd.service -> /lib/systemd/system/systemd-timesyncd.service
└── timers.target.wants
├── dpkg-db-backup.timer -> /lib/systemd/system/dpkg-db-backup.timer
├── e2scrub_all.timer -> /lib/systemd/system/e2scrub_all.timer
├── fstrim.timer -> /lib/systemd/system/fstrim.timer
├── logrotate.timer -> /lib/systemd/system/logrotate.timer
└── man-db.timer -> /lib/systemd/system/man-db.timer
9 directories, 35 files
# 쿠버네티스 컨트롤러 매니저 구성
root@server:~# mv kube-controller-manager.kubeconfig /var/lib/kubernetes/
root@server:~# mv kube-controller-manager.service /etc/systemd/system/
root@server:~# mv kube-scheduler.kubeconfig /var/lib/kubernetes/
root@server:~# mv kube-scheduler.yaml /etc/kubernetes/config/
root@server:~# mv kube-scheduler.service /etc/systemd/system/
# 컨트롤러 서비스 시작
root@server:~# systemctl daemon-reload
root@server:~# systemctl enable kube-apiserver kube-controller-manager kube-scheduler
Created symlink /etc/systemd/system/multi-user.target.wants/kube-apiserver.service → /etc/systemd/system/kube-apiserver.service.
Created symlink /etc/systemd/system/multi-user.target.wants/kube-controller-manager.service → /etc/systemd/system/kube-controller-manager.service.
Created symlink /etc/systemd/system/multi-user.target.wants/kube-scheduler.service → /etc/systemd/system/kube-scheduler.service.
root@server:~# systemctl start kube-apiserver kube-controller-manager kube-scheduler
root@server:~# ss -tlp | grep kube
LISTEN 0 4096 *:6443 *:* users:(("kube-apiserver",pid=2803,fd=3))
LISTEN 0 4096 *:10257 *:* users:(("kube-controller",pid=2804,fd=3))
LISTEN 0 4096 *:10259 *:* users:(("kube-scheduler",pid=2809,fd=3))
root@server:~# systemctl is-active kube-apiserver
active
root@server:~# systemctl status kube-apiserver --no-pager
● kube-apiserver.service - Kubernetes API Server
Loaded: loaded (/etc/systemd/system/kube-apiserver.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-01-11 08:38:14 KST; 1min 9s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 2803 (kube-apiserver)
Tasks: 9 (limit: 2096)
Memory: 210.2M
CPU: 3.860s
CGroup: /system.slice/kube-apiserver.service
└─2803 /usr/local/bin/kube-apiserver --allow-privileged=true --apiserver-count=1 --audit-log-maxage=30 --audit-log-maxbackup=3 --audit-log-maxsize=100 --audit-log-path=/var/log/…
Jan 11 08:38:17 server kube-apiserver[2803]: I0111 08:38:17.446400 2803 storage_rbac.go:321] created rolebinding.rbac.authorization.k8s.io/system:controller:cloud-provider in kube-system
Jan 11 08:38:17 server kube-apiserver[2803]: I0111 08:38:17.448425 2803 storage_rbac.go:321] created rolebinding.rbac.authorization.k8s.io/system:controller:token-cleaner in kube-system
Jan 11 08:38:17 server kube-apiserver[2803]: I0111 08:38:17.450674 2803 storage_rbac.go:321] created rolebinding.rbac.authorization.k8s.io/system:controller:bootstrap-signer in kube-public
Jan 11 08:38:17 server kube-apiserver[2803]: I0111 08:38:17.504016 2803 alloc.go:330] "allocated clusterIPs" service="default/kubernetes" clusterIPs={"IPv4":"10.32.0.1"}
Jan 11 08:38:17 server kube-apiserver[2803]: W0111 08:38:17.506560 2803 lease.go:265] Resetting endpoints for master service "kubernetes" to [10.0.2.15]
Jan 11 08:38:17 server kube-apiserver[2803]: I0111 08:38:17.507060 2803 controller.go:615] quota admission added evaluator for: endpoints
Jan 11 08:38:17 server kube-apiserver[2803]: I0111 08:38:17.510095 2803 controller.go:615] quota admission added evaluator for: endpointslices.discovery.k8s.io
Jan 11 08:38:20 server kube-apiserver[2803]: I0111 08:38:20.160901 2803 controller.go:615] quota admission added evaluator for: serviceaccounts
Jan 11 08:38:26 server kube-apiserver[2803]: I0111 08:38:26.306880 2803 apf_controller.go:493] "Update CurrentCL" plName="exempt" seatDemandHighWatermark=2 seatDemandAvg=0.020429668431191…
Jan 11 08:38:36 server kube-apiserver[2803]: I0111 08:38:36.307942 2803 apf_controller.go:493] "Update CurrentCL" plName="exempt" seatDemandHighWatermark=1 seatDemandAvg=0.000540973546383…
Hint: Some lines were ellipsized, use -l to show in full.
root@server:~# systemctl status kube-scheduler --no-pager
● kube-scheduler.service - Kubernetes Scheduler
Loaded: loaded (/etc/systemd/system/kube-scheduler.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-01-11 08:38:14 KST; 1min 32s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 2809 (kube-scheduler)
Tasks: 8 (limit: 2096)
Memory: 15.3M
CPU: 1.321s
CGroup: /system.slice/kube-scheduler.service
└─2809 /usr/local/bin/kube-scheduler --config=/etc/kubernetes/config/kube-scheduler.yaml --v=2
Jan 11 08:38:17 server kube-scheduler[2809]: I0111 08:38:17.795270 2809 reflector.go:376] Caches populated for *v1.ReplicationController from k8s.io/client-go/informers/factory.go:160
Jan 11 08:38:17 server kube-scheduler[2809]: I0111 08:38:17.816831 2809 reflector.go:376] Caches populated for *v1.CSIDriver from k8s.io/client-go/informers/factory.go:160
Jan 11 08:38:17 server kube-scheduler[2809]: I0111 08:38:17.889509 2809 reflector.go:376] Caches populated for *v1.StorageClass from k8s.io/client-go/informers/factory.go:160
Jan 11 08:38:17 server kube-scheduler[2809]: I0111 08:38:17.976799 2809 reflector.go:376] Caches populated for *v1.ReplicaSet from k8s.io/client-go/informers/factory.go:160
Jan 11 08:38:18 server kube-scheduler[2809]: I0111 08:38:18.053109 2809 reflector.go:376] Caches populated for *v1.Pod from k8s.io/client-go/informers/factory.go:160
Jan 11 08:38:18 server kube-scheduler[2809]: I0111 08:38:18.104208 2809 reflector.go:376] Caches populated for *v1.Namespace from k8s.io/client-go/informers/factory.go:160
Jan 11 08:38:18 server kube-scheduler[2809]: I0111 08:38:18.104322 2809 reflector.go:376] Caches populated for *v1.PersistentVolumeClaim from k8s.io/client-go/informers/factory.go:160
Jan 11 08:38:20 server kube-scheduler[2809]: I0111 08:38:20.518170 2809 reflector.go:376] Caches populated for *v1.PersistentVolume from k8s.io/client-go/informers/factory.go:160
Jan 11 08:38:20 server kube-scheduler[2809]: I0111 08:38:20.543776 2809 leaderelection.go:257] attempting to acquire leader lease kube-system/kube-scheduler...
Jan 11 08:38:20 server kube-scheduler[2809]: I0111 08:38:20.547972 2809 leaderelection.go:271] successfully acquired lease kube-system/kube-scheduler
root@server:~# systemctl status kube-controller-manager --no-pager
● kube-controller-manager.service - Kubernetes Controller Manager
Loaded: loaded (/etc/systemd/system/kube-controller-manager.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-01-11 08:38:14 KST; 1min 38s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 2804 (kube-controller)
Tasks: 5 (limit: 2096)
Memory: 40.2M
CPU: 2.314s
CGroup: /system.slice/kube-controller-manager.service
└─2804 /usr/local/bin/kube-controller-manager --bind-address=0.0.0.0 --cluster-cidr=10.200.0.0/16 --cluster-name=kubernetes --cluster-signing-cert-file=/var/lib/kubernetes/ca.cr…
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.351097 2804 shared_informer.go:320] Caches are synced for certificate-csrsigning-kubelet-client
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.351083 2804 shared_informer.go:320] Caches are synced for certificate-csrsigning-legacy-unknown
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.351111 2804 shared_informer.go:320] Caches are synced for disruption
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.352466 2804 shared_informer.go:320] Caches are synced for ReplicaSet
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.352467 2804 shared_informer.go:320] Caches are synced for endpoint_slice
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.352487 2804 endpointslice_controller.go:288] "Starting service queue worker threads" logger="endpointsli…oller" total=5
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.352505 2804 endpointslice_controller.go:292] "Starting topology queue worker threads" logger="endpointsl…oller" total=1
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.352540 2804 shared_informer.go:320] Caches are synced for stateful set
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.353634 2804 shared_informer.go:320] Caches are synced for legacy-service-account-token-cleaner
Jan 11 08:38:24 server kube-controller-manager[2804]: I0111 08:38:24.353714 2804 shared_informer.go:320] Caches are synced for PVC protection
Hint: Some lines were ellipsized, use -l to show in full.
root@server:~# kubectl cluster-info --kubeconfig admin.kubeconfig
Kubernetes control plane is running at https://127.0.0.1:6443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
# kubectl 동작확인
root@server:~# kubectl get node --kubeconfig admin.kubeconfig
No resources found
root@server:~# kubectl get pod -A --kubeconfig admin.kubeconfig
No resources found
root@server:~# kubectl get service,ep --kubeconfig admin.kubeconfig
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.32.0.1 <none> 443/TCP 2m58s
NAME ENDPOINTS AGE
endpoints/kubernetes 10.0.2.15:6443 2m58s
root@server:~# kubectl get clusterroles --kubeconfig admin.kubeconfig
NAME CREATED AT
admin 2026-01-10T23:38:17Z
cluster-admin 2026-01-10T23:38:17Z
edit 2026-01-10T23:38:17Z
system:aggregate-to-admin 2026-01-10T23:38:17Z
system:aggregate-to-edit 2026-01-10T23:38:17Z
system:aggregate-to-view 2026-01-10T23:38:17Z
system:auth-delegator 2026-01-10T23:38:17Z
system:basic-user 2026-01-10T23:38:17Z
...
API Server가 워커 노드의 Kubelet API를 안전하게 호출할 수 있도록 RBAC 기반 접근 제어를 설정합니다. 이를 통해 메트릭 수집, 로그 조회, 포드 명령 실행과 같은 운영 기능을 API Server를 통해 수행할 수 있습니다.
Kubelet은 Webhook 권한 부여 모드를 사용하며, 요청에 대한 인가 판단은 SubjectAccessReview API를 통해 중앙에서 처리됩니다.
root@server:~# cat kube-apiserver-to-kubelet.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-apiserver-to-kubelet
rules:
- apiGroups:
- ""
resources:
- nodes/proxy
- nodes/stats
- nodes/log
- nodes/spec
- nodes/metrics
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:kube-apiserver
namespace: ""
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-apiserver-to-kubelet
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: kubernetesroot@server:~#
root@server:~# kubectl apply -f kube-apiserver-to-kubelet.yaml --kubeconfig admin.kubeconfig
clusterrole.rbac.authorization.k8s.io/system:kube-apiserver-to-kubelet created
clusterrolebinding.rbac.authorization.k8s.io/system:kube-apiserver created
점프 서버에서 Kubernetes 컨트롤 플레인 정상 동작 확인하겠습니다.
root@jumpbox:~/kubernetes-the-hard-way# curl -s -k --cacert ca.crt https://server.kubernetes.local:6443/version | jq
{
"major": "1",
"minor": "32",
"gitVersion": "v1.32.3",
"gitCommit": "32cc146f75aad04beaaa245a7157eb35063a9f99",
"gitTreeState": "clean",
"buildDate": "2025-03-11T19:52:21Z",
"goVersion": "go1.23.6",
"compiler": "gc",
"platform": "linux/arm64"
}
워커 노드 부트스트래핑
node-0, node-1 노드에 runc, container networking plugins, containerd, kubelet, kube-proxy 설치하겠습니다.
root@jumpbox:~/kubernetes-the-hard-way# cat configs/10-bridge.conf | jq
{
"cniVersion": "1.0.0",
"name": "bridge",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"ranges": [
[
{
"subnet": "SUBNET"
}
]
],
"routes": [
{
"dst": "0.0.0.0/0"
}
]
}
}
root@jumpbox:~/kubernetes-the-hard-way# cat configs/kubelet-config.yaml | yq # clusterDomain , clusterDNS 없어도 smoke test 까지 잘됨 -> 실습에서 coredns 미사용
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: "0.0.0.0" # kubelet HTTPS 서버 바인딩 주소 : 모든 인터페이스에서 10250 포트 수신
authentication:
anonymous:
enabled: false # 익명 인증 비활성화
webhook:
enabled: true # 인증 요청을 kube-apiserver에 위임 : ServiceAccount 토큰, bootstrap 토큰 처리 가능
x509: # kubelet에 접근하는 클라이언트 인증서 검증용 CA
clientCAFile: "/var/lib/kubelet/ca.crt" # (상동) 대상 : kube-apiserver, metrics-server, kubectl (직접 접근 시)
authorization:
mode: Webhook # 인가 요청을 kube-apiserver에 위임 : Node Authorizer + RBAC 적용됨
cgroupDriver: systemd
containerRuntimeEndpoint: "unix:///var/run/containerd/containerd.sock" # CRI 엔드포인트
enableServer: true # kubelet API 서버 활성화 , false면 apiserver가 kubelet 접근 불가
failSwapOn: false
maxPods: 16 # 노드당 최대 파드 수 16개
memorySwap:
swapBehavior: NoSwap
port: 10250 # kubelet HTTPS API 포트 : 로그, exec, stats, metrics 접근에 사용
resolvConf: "/etc/resolv.conf" # 파드에 전달할 DNS 설정 파일
registerNode: true # kubelet이 API 서버에 Node 객체 자동 등록
runtimeRequestTimeout: "15m" # CRI 요청 최대 대기 시간 : 이미지 pull, container start 등
tlsCertFile: "/var/lib/kubelet/kubelet.crt" # TLS 서버 인증서 (kubelet 자신) : kubelet HTTPS 서버의 서버 인증서
tlsPrivateKeyFile: "/var/lib/kubelet/kubelet.key"
root@jumpbox:~/kubernetes-the-hard-way# for HOST in node-0 node-1; do
SUBNET=$(grep ${HOST} machines.txt | cut -d " " -f 4)
sed "s|SUBNET|$SUBNET|g" \
configs/10-bridge.conf > 10-bridge.conf
sed "s|SUBNET|$SUBNET|g" \
configs/kubelet-config.yaml > kubelet-config.yaml
scp 10-bridge.conf kubelet-config.yaml \
root@${HOST}:~/
done
10-bridge.conf 100% 265 413.0KB/s 00:00
kubelet-config.yaml 100% 610 1.1MB/s 00:00
10-bridge.conf 100% 265 418.8KB/s 00:00
kubelet-config.yaml 100% 610 1.1MB/s 00:00
root@jumpbox:~/kubernetes-the-hard-way# ssh node-0 ls -l /root
total 8
-rw-r--r-- 1 root root 265 Jan 11 08:46 10-bridge.conf
-rw-r--r-- 1 root root 610 Jan 11 08:46 kubelet-config.yaml
root@jumpbox:~/kubernetes-the-hard-way# ssh node-1 ls -l /root
total 8
-rw-r--r-- 1 root root 265 Jan 11 08:46 10-bridge.conf
-rw-r--r-- 1 root root 610 Jan 11 08:46 kubelet-config.yaml
# 파일 확인 및 node-0/1에 전달
root@jumpbox:~/kubernetes-the-hard-way# cat configs/99-loopback.conf ; echo
{
"cniVersion": "1.1.0",
"name": "lo",
"type": "loopback"
}
root@jumpbox:~/kubernetes-the-hard-way# cat configs/containerd-config.toml ; echo
version = 2
[plugins."io.containerd.grpc.v1.cri"]
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "overlayfs"
default_runtime_name = "runc"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
root@jumpbox:~/kubernetes-the-hard-way# cat configs/kube-proxy-config.yaml ; echo
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
kubeconfig: "/var/lib/kube-proxy/kubeconfig"
mode: "iptables"
clusterCIDR: "10.200.0.0/16"
root@jumpbox:~/kubernetes-the-hard-way# cat units/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
root@jumpbox:~/kubernetes-the-hard-way# cat units/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \
--config=/var/lib/kubelet/kubelet-config.yaml \
--kubeconfig=/var/lib/kubelet/kubeconfig \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
root@jumpbox:~/kubernetes-the-hard-way# cat units/kube-proxy.service
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-proxy \
--config=/var/lib/kube-proxy/kube-proxy-config.yaml
Restart=on-failure
RestartSec=5
[Install]
root@jumpbox:~/kubernetes-the-hard-way# for HOST in node-0 node-1; do
scp \
downloads/worker/* \
downloads/client/kubectl \
configs/99-loopback.conf \
configs/containerd-config.toml \
configs/kube-proxy-config.yaml \
units/containerd.service \
units/kubelet.service \
units/kube-proxy.service \
root@${HOST}:~/
done
containerd 100% 54MB 109.8MB/s 00:00
containerd-shim-runc-v2 100% 7808KB 115.1MB/s 00:00
containerd-stress 100% 21MB 134.4MB/s 00:00
crictl 100% 37MB 126.0MB/s 00:00
ctr 100% 22MB 128.0MB/s 00:00
kubelet 100% 72MB 114.6MB/s 00:00
kube-proxy 100% 62MB 107.7MB/s 00:00
runc 100% 11MB 116.3MB/s 00:00
kubectl 100% 53MB 99.3MB/s 00:00
99-loopback.conf 100% 65 144.9KB/s 00:00
containerd-config.toml 100% 470 1.1MB/s 00:00
kube-proxy-config.yaml 100% 184 431.0KB/s 00:00
containerd.service 100% 352 739.2KB/s 00:00
kubelet.service 100% 365 781.0KB/s 00:00
kube-proxy.service 100% 268 498.2KB/s 00:00
containerd 100% 54MB 123.9MB/s 00:00
containerd-shim-runc-v2 100% 7808KB 123.9MB/s 00:00
containerd-stress 100% 21MB 128.7MB/s 00:00
crictl 100% 37MB 129.9MB/s 00:00
ctr 100% 22MB 127.6MB/s 00:00
kubelet 100% 72MB 121.1MB/s 00:00
kube-proxy 100% 62MB 103.1MB/s 00:00
runc 100% 11MB 132.1MB/s 00:00
kubectl 100% 53MB 114.7MB/s 00:00
99-loopback.conf 100% 65 116.5KB/s 00:00
containerd-config.toml 100% 470 715.5KB/s 00:00
kube-proxy-config.yaml 100% 184 204.4KB/s 00:00
containerd.service 100% 352 716.2KB/s 00:00
kubelet.service 100% 365 684.7KB/s 00:00
kube-proxy.service 100% 268 366.2KB/s 00:00
root@jumpbox:~/kubernetes-the-hard-way# for HOST in node-0 node-1; do
scp \
downloads/cni-plugins/* \
root@${HOST}:~/cni-plugins/
done
bandwidth 100% 4492KB 52.1MB/s 00:00
bridge 100% 5065KB 107.0MB/s 00:00
dhcp 100% 12MB 102.8MB/s 00:00
dummy 100% 4623KB 108.5MB/s 00:00
firewall 100% 5088KB 144.1MB/s 00:00
host-device 100% 4611KB 119.7MB/s 00:00
host-local 100% 3886KB 113.2MB/s 00:00
ipvlan 100% 4628KB 114.8MB/s 00:00
LICENSE 100% 11KB 14.6MB/s 00:00
loopback 100% 4030KB 126.9MB/s 00:00
macvlan 100% 4764KB 110.9MB/s 00:00
portmap 100% 4513KB 88.0MB/s 00:00
ptp 100% 4877KB 113.8MB/s 00:00
README.md 100% 2343 3.3MB/s 00:00
sbr 100% 4216KB 113.4MB/s 00:00
static 100% 3498KB 110.7MB/s 00:00
tap 100% 4775KB 122.1MB/s 00:00
tuning 100% 4054KB 108.8MB/s 00:00
vlan 100% 4627KB 80.0MB/s 00:00
vrf 100% 4325KB 116.8MB/s 00:00
bandwidth 100% 4492KB 64.0MB/s 00:00
bridge 100% 5065KB 140.7MB/s 00:00
dhcp 100% 12MB 128.4MB/s 00:00
dummy 100% 4623KB 134.0MB/s 00:00
firewall 100% 5088KB 134.2MB/s 00:00
host-device 100% 4611KB 130.3MB/s 00:00
host-local 100% 3886KB 137.3MB/s 00:00
ipvlan 100% 4628KB 135.9MB/s 00:00
LICENSE 100% 11KB 18.1MB/s 00:00
loopback 100% 4030KB 113.2MB/s 00:00
macvlan 100% 4764KB 124.8MB/s 00:00
portmap 100% 4513KB 124.5MB/s 00:00
ptp 100% 4877KB 129.0MB/s 00:00
README.md 100% 2343 4.5MB/s 00:00
sbr 100% 4216KB 127.5MB/s 00:00
static 100% 3498KB 135.4MB/s 00:00
tap 100% 4775KB 134.7MB/s 00:00
tuning 100% 4054KB 137.7MB/s 00:00
vlan 100% 4627KB 140.3MB/s 00:00
vrf 100% 4325KB 136.6MB/s 00:00
root@jumpbox:~/kubernetes-the-hard-way# ssh node-0 ls -l /root
total 347860
-rw-r--r-- 1 root root 265 Jan 11 08:46 10-bridge.conf
-rw-r--r-- 1 root root 65 Jan 11 08:51 99-loopback.conf
drwxr-xr-x 2 root root 4096 Jan 11 08:51 cni-plugins
-rwxr-xr-x 1 root root 56836190 Jan 11 08:51 containerd
-rw-r--r-- 1 root root 470 Jan 11 08:51 containerd-config.toml
-rw-r--r-- 1 root root 352 Jan 11 08:51 containerd.service
-rwxr-xr-x 1 root root 7995576 Jan 11 08:51 containerd-shim-runc-v2
-rwxr-xr-x 1 root root 22020449 Jan 11 08:51 containerd-stress
-rwxr-xr-x 1 root root 38808389 Jan 11 08:51 crictl
-rwxr-xr-x 1 root root 22806881 Jan 11 08:51 ctr
-rwxr-xr-x 1 root root 55836824 Jan 11 08:51 kubectl
-rwxr-xr-x 1 root root 75235588 Jan 11 08:51 kubelet
-rw-r--r-- 1 root root 610 Jan 11 08:46 kubelet-config.yaml
-rw-r--r-- 1 root root 365 Jan 11 08:51 kubelet.service
-rwxr-xr-x 1 root root 65274008 Jan 11 08:51 kube-proxy
-rw-r--r-- 1 root root 184 Jan 11 08:51 kube-proxy-config.yaml
-rw-r--r-- 1 root root 268 Jan 11 08:51 kube-proxy.service
-rwxr-xr-x 1 root root 11305168 Jan 11 08:51 runc
root@jumpbox:~/kubernetes-the-hard-way# ssh node-1 ls -l /root
total 347860
-rw-r--r-- 1 root root 265 Jan 11 08:46 10-bridge.conf
-rw-r--r-- 1 root root 65 Jan 11 08:51 99-loopback.conf
drwxr-xr-x 2 root root 4096 Jan 11 08:51 cni-plugins
-rwxr-xr-x 1 root root 56836190 Jan 11 08:51 containerd
-rw-r--r-- 1 root root 470 Jan 11 08:51 containerd-config.toml
-rw-r--r-- 1 root root 352 Jan 11 08:51 containerd.service
-rwxr-xr-x 1 root root 7995576 Jan 11 08:51 containerd-shim-runc-v2
-rwxr-xr-x 1 root root 22020449 Jan 11 08:51 containerd-stress
-rwxr-xr-x 1 root root 38808389 Jan 11 08:51 crictl
-rwxr-xr-x 1 root root 22806881 Jan 11 08:51 ctr
-rwxr-xr-x 1 root root 55836824 Jan 11 08:51 kubectl
-rwxr-xr-x 1 root root 75235588 Jan 11 08:51 kubelet
-rw-r--r-- 1 root root 610 Jan 11 08:46 kubelet-config.yaml
-rw-r--r-- 1 root root 365 Jan 11 08:51 kubelet.service
-rwxr-xr-x 1 root root 65274008 Jan 11 08:51 kube-proxy
-rw-r--r-- 1 root root 184 Jan 11 08:51 kube-proxy-config.yaml
-rw-r--r-- 1 root root 268 Jan 11 08:51 kube-proxy.service
-rwxr-xr-x 1 root root 11305168 Jan 11 08:51 runc
root@jumpbox:~/kubernetes-the-hard-way# ssh node-0 ls -l /root/cni-plugins
total 88164
-rwxr-xr-x 1 root root 4600029 Jan 11 08:51 bandwidth
-rwxr-xr-x 1 root root 5186762 Jan 11 08:51 bridge
-rwxr-xr-x 1 root root 12321657 Jan 11 08:51 dhcp
-rwxr-xr-x 1 root root 4734102 Jan 11 08:51 dummy
-rwxr-xr-x 1 root root 5210586 Jan 11 08:51 firewall
-rwxr-xr-x 1 root root 4721690 Jan 11 08:51 host-device
-rwxr-xr-x 1 root root 3979580 Jan 11 08:51 host-local
-rwxr-xr-x 1 root root 4738895 Jan 11 08:51 ipvlan
-rwxr-xr-x 1 root root 11357 Jan 11 08:51 LICENSE
-rwxr-xr-x 1 root root 4127141 Jan 11 08:51 loopback
-rwxr-xr-x 1 root root 4878636 Jan 11 08:51 macvlan
-rwxr-xr-x 1 root root 4621227 Jan 11 08:51 portmap
-rwxr-xr-x 1 root root 4994381 Jan 11 08:51 ptp
-rwxr-xr-x 1 root root 2343 Jan 11 08:51 README.md
-rwxr-xr-x 1 root root 4317592 Jan 11 08:51 sbr
-rwxr-xr-x 1 root root 3582221 Jan 11 08:51 static
-rwxr-xr-x 1 root root 4889353 Jan 11 08:51 tap
-rwxr-xr-x 1 root root 4150810 Jan 11 08:51 tuning
-rwxr-xr-x 1 root root 4738028 Jan 11 08:51 vlan
-rwxr-xr-x 1 root root 4428332 Jan 11 08:51 vrf
root@jumpbox:~/kubernetes-the-hard-way# ssh node-1 ls -l /root/cni-plugins
total 88164
-rwxr-xr-x 1 root root 4600029 Jan 11 08:51 bandwidth
-rwxr-xr-x 1 root root 5186762 Jan 11 08:51 bridge
-rwxr-xr-x 1 root root 12321657 Jan 11 08:51 dhcp
-rwxr-xr-x 1 root root 4734102 Jan 11 08:51 dummy
-rwxr-xr-x 1 root root 5210586 Jan 11 08:51 firewall
-rwxr-xr-x 1 root root 4721690 Jan 11 08:51 host-device
-rwxr-xr-x 1 root root 3979580 Jan 11 08:51 host-local
-rwxr-xr-x 1 root root 4738895 Jan 11 08:51 ipvlan
-rwxr-xr-x 1 root root 11357 Jan 11 08:51 LICENSE
-rwxr-xr-x 1 root root 4127141 Jan 11 08:51 loopback
-rwxr-xr-x 1 root root 4878636 Jan 11 08:51 macvlan
-rwxr-xr-x 1 root root 4621227 Jan 11 08:51 portmap
-rwxr-xr-x 1 root root 4994381 Jan 11 08:51 ptp
-rwxr-xr-x 1 root root 2343 Jan 11 08:51 README.md
-rwxr-xr-x 1 root root 4317592 Jan 11 08:51 sbr
-rwxr-xr-x 1 root root 3582221 Jan 11 08:51 static
-rwxr-xr-x 1 root root 4889353 Jan 11 08:51 tap
-rwxr-xr-x 1 root root 4150810 Jan 11 08:51 tuning
-rwxr-xr-x 1 root root 4738028 Jan 11 08:51 vlan
-rwxr-xr-x 1 root root 4428332 Jan 11 08:51 vrf
워커노드 프로비저닝을 위해 node-0, node-1에 접속하여 실행하겠습니다.
# kubelet ↔ containerd 연결 Flow
kubelet
↓ CRI (gRPC)
unix:///var/run/containerd/containerd.sock
↓
containerd CRI plugin
↓
runc
↓
Linux namespaces / cgroups
# Node 0 접속 후 실행 (Node 1도 동일)
root@jumpbox:~/kubernetes-the-hard-way# ssh root@node-0
root@node-0:~# apt-get -y install socat conntrack ipset kmod psmisc bridge-utils
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
kmod is already the newest version (30+20221128-1).
The following additional packages will be installed:
iptables libip6tc2 libipset13 libnetfilter-conntrack3 libnfnetlink0
...
# Disable Swap : Verify if swap is disabled:
root@node-0:~# swapon --show
# Create the installation directories
root@node-0:~# mkdir -p \
/etc/cni/net.d \
/opt/cni/bin \
/var/lib/kubelet \
/var/lib/kube-proxy \
/var/lib/kubernetes \
/var/run/kubernetes
# Install the worker binaries:
root@node-0:~# mv crictl kube-proxy kubelet runc /usr/local/bin/
root@node-0:~# mv containerd containerd-shim-runc-v2 containerd-stress /bin/
root@node-0:~# mv cni-plugins/* /opt/cni/bin/
# Configure CNI Networking
# Create the bridge network configuration file:
root@node-0:~# mv 10-bridge.conf 99-loopback.conf /etc/cni/net.d/
root@node-0:~# cat /etc/cni/net.d/10-bridge.conf
{
"cniVersion": "1.0.0",
"name": "bridge",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "10.200.0.0/24"}]
],
"routes": [{"dst": "0.0.0.0/0"}]
}
}
# To ensure network traffic crossing the CNI bridge network is processed by iptables, load and configure the br-netfilter kernel module:
root@node-0:~# lsmod | grep netfilter
root@node-0:~# modprobe br-netfilter
root@node-0:~# echo "br-netfilter" >> /etc/modules-load.d/modules.conf
root@node-0:~# lsmod | grep netfilter
br_netfilter 32768 0
bridge 262144 1 br_netfilter
root@node-0:~# echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.d/kubernetes.conf
root@node-0:~# echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.d/kubernetes.conf
root@node-0:~# sysctl -p /etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# Configure containerd : Install the containerd configuration files:
root@node-0:~# mkdir -p /etc/containerd/
root@node-0:~# mv containerd-config.toml /etc/containerd/config.toml
root@node-0:~# mv containerd.service /etc/systemd/system/
root@node-0:~# cat /etc/containerd/config.toml ; echo
version = 2
[plugins."io.containerd.grpc.v1.cri"] # CRI 플러그인 활성화 : kubelet은 이 플러그인을 통해 containerd와 통신
[plugins."io.containerd.grpc.v1.cri".containerd] # containerd 기본 런타임 설정
snapshotter = "overlayfs" # 컨테이너 파일시스템 레이어 관리 방식 : Linux표준/성능최적
default_runtime_name = "runc" # 기본 OCI 런타임 : 파드가 별도 지정 없을 경우 runc 사용
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] # runc 런타임 상세 설정
runtime_type = "io.containerd.runc.v2" # containerd 최신 runc shim
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] # runc 옵션
SystemdCgroup = true # containerd가 cgroup을 systemd로 관리
[plugins."io.containerd.grpc.v1.cri".cni] # CNI 설정
bin_dir = "/opt/cni/bin" # CNI 플러그인 바이너리 위치
conf_dir = "/etc/cni/net.d" # CNI 네트워크 설정 파일 위치
# Configure the Kubelet : Create the kubelet-config.yaml configuration file:
root@node-0:~# mv kubelet-config.yaml /var/lib/kubelet/
root@node-0:~# mv kubelet.service /etc/systemd/system/
# Configure the Kubernetes Proxy
root@node-0:~# mv kube-proxy-config.yaml /var/lib/kube-proxy/
root@node-0:~# mv kube-proxy.service /etc/systemd/system/
# Start the Worker Services
root@node-0:~# systemctl daemon-reload
root@node-0:~# systemctl enable containerd kubelet kube-proxy
Created symlink /etc/systemd/system/multi-user.target.wants/containerd.service → /etc/systemd/system/containerd.service.
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service → /etc/systemd/system/kubelet.service.
Created symlink /etc/systemd/system/multi-user.target.wants/kube-proxy.service → /etc/systemd/system/kube-proxy.service.
root@node-0:~# systemctl start containerd kubelet kube-proxy
# 확인
root@node-0:~# systemctl status kubelet --no-pager
● kubelet.service - Kubernetes Kubelet
Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-01-11 08:59:02 KST; 4s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 2937 (kubelet)
Tasks: 11 (limit: 2096)
Memory: 24.5M
CPU: 277ms
CGroup: /system.slice/kubelet.service
└─2937 /usr/local/bin/kubelet --config=/var/lib/kubelet/kubelet-config.yaml --kubeconfig=/var/lib/kubelet/kubeconfig --v=2
Jan 11 08:59:02 node-0 kubelet[2937]: I0111 08:59:02.425947 2937 kubelet_node_status.go:687] "Recording event message for node" node="node-0" event="NodeHasNoDiskPressure"
Jan 11 08:59:02 node-0 kubelet[2937]: I0111 08:59:02.425955 2937 kubelet_node_status.go:687] "Recording event message for node" node="node-0" event="NodeHasSufficientPID"
Jan 11 08:59:02 node-0 kubelet[2937]: I0111 08:59:02.426436 2937 kubelet_node_status.go:75] "Attempting to register node" node="node-0"
Jan 11 08:59:02 node-0 kubelet[2937]: I0111 08:59:02.432949 2937 kubelet_node_status.go:78] "Successfully registered node" node="node-0"
Jan 11 08:59:02 node-0 kubelet[2937]: I0111 08:59:02.655470 2937 kubelet_node_status.go:687] "Recording event message for node" node="node-0" event="NodeReady"
Jan 11 08:59:02 node-0 kubelet[2937]: I0111 08:59:02.655542 2937 kubelet_node_status.go:501] "Fast updating node status as it just became ready"
Jan 11 08:59:03 node-0 kubelet[2937]: I0111 08:59:03.201514 2937 apiserver.go:52] "Watching apiserver"
Jan 11 08:59:03 node-0 kubelet[2937]: I0111 08:59:03.204673 2937 reflector.go:376] Caches populated for *v1.Pod from pkg/kubelet/config/apiserver.go:66
Jan 11 08:59:03 node-0 kubelet[2937]: I0111 08:59:03.204949 2937 kubelet.go:2468] "SyncLoop ADD" source="api" pods=[]
Jan 11 08:59:03 node-0 kubelet[2937]: I0111 08:59:03.213472 2937 desired_state_of_world_populator.go:157] "Finished populating initial desired state of world"
root@node-0:~# systemctl status containerd --no-pager
● containerd.service - containerd container runtime
Loaded: loaded (/etc/systemd/system/containerd.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-01-11 08:59:02 KST; 7s ago
Docs: https://containerd.io
Process: 2929 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 2936 (containerd)
Tasks: 8 (limit: 2096)
Memory: 17.8M
CPU: 128ms
CGroup: /system.slice/containerd.service
└─2936 /bin/containerd
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.179211032+09:00" level=info msg="Start event monitor"
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.179221574+09:00" level=info msg="Start cni network conf syncer for default"
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.179226490+09:00" level=info msg="Start streaming server"
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.179238532+09:00" level=info msg="Registered namespace \"k8s.io\" with NRI"
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.179244282+09:00" level=info msg="runtime interface starting up..."
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.179248324+09:00" level=info msg="starting plugins..."
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.179258740+09:00" level=info msg="Synchronizing NRI (plugin) with current runtime state"
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.179524407+09:00" level=info msg=serving... address=/run/containerd/containerd.sock.ttrpc
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.180191990+09:00" level=info msg=serving... address=/run/containerd/containerd.sock
Jan 11 08:59:02 node-0 containerd[2936]: time="2026-01-11T08:59:02.180276824+09:00" level=info msg="containerd successfully booted in 0.080985s"
root@node-0:~# systemctl status kube-proxy --no-pager
● kube-proxy.service - Kubernetes Kube Proxy
Loaded: loaded (/etc/systemd/system/kube-proxy.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-01-11 08:59:02 KST; 10s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 2930 (kube-proxy)
Tasks: 5 (limit: 2096)
Memory: 14.2M
CPU: 282ms
CGroup: /system.slice/kube-proxy.service
└─2930 /usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/kube-proxy-config.yaml
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.470716 2930 server.go:499] "Golang settings" GOGC="" GOMAXPROCS="" GOTRACEBACK=""
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.474823 2930 config.go:199] "Starting service config controller"
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.474988 2930 shared_informer.go:313] Waiting for caches to sync for service config
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.475123 2930 config.go:329] "Starting node config controller"
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.475178 2930 shared_informer.go:313] Waiting for caches to sync for node config
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.475453 2930 config.go:105] "Starting endpoint slice config controller"
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.475478 2930 shared_informer.go:313] Waiting for caches to sync for endpoint slice config
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.575744 2930 shared_informer.go:320] Caches are synced for node config
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.575765 2930 shared_informer.go:320] Caches are synced for endpoint slice config
Jan 11 08:59:03 node-0 kube-proxy[2930]: I0111 08:59:03.575802 2930 shared_informer.go:320] Caches are synced for service config
원격 접근을 위한 kubectl 설정
jumpbox 노드에서 kubectl을 admin 자격 증명으로 사용을 위한 설정을 구성합니다.
# You should be able to ping server.kubernetes.local based on the /etc/hosts DNS entry from a previous lab.
root@jumpbox:~/kubernetes-the-hard-way# curl -s --cacert ca.crt https://server.kubernetes.local:6443/version | jq
{
"major": "1",
"minor": "32",
"gitVersion": "v1.32.3",
"gitCommit": "32cc146f75aad04beaaa245a7157eb35063a9f99",
"gitTreeState": "clean",
"buildDate": "2025-03-11T19:52:21Z",
"goVersion": "go1.23.6",
"compiler": "gc",
"platform": "linux/arm64"
}
# Generate a kubeconfig file suitable for authenticating as the admin user:
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.crt \
--embed-certs=true \
--server=https://server.kubernetes.local:6443
Cluster "kubernetes-the-hard-way" set.
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-credentials admin \
--client-certificate=admin.crt \
--client-key=admin.key
User "admin" set.
root@jumpbox:~/kubernetes-the-hard-way# kubectl config set-context kubernetes-the-hard-way \
--cluster=kubernetes-the-hard-way \
--user=admin
Context "kubernetes-the-hard-way" created.
root@jumpbox:~/kubernetes-the-hard-way# kubectl config use-context kubernetes-the-hard-way
Switched to context "kubernetes-the-hard-way".
root@jumpbox:~/kubernetes-the-hard-way# kubectl version
Client Version: v1.32.3
Kustomize Version: v5.5.0
Server Version: v1.32.3
root@jumpbox:~/kubernetes-the-hard-way#
root@jumpbox:~/kubernetes-the-hard-way# kubectl get nodes -v=6
I0111 09:20:48.852866 3046 loader.go:402] Config loaded from file: /root/.kube/config
I0111 09:20:48.853973 3046 envvar.go:172] "Feature gate default state" feature="ClientsAllowCBOR" enabled=false
I0111 09:20:48.854086 3046 envvar.go:172] "Feature gate default state" feature="ClientsPreferCBOR" enabled=false
I0111 09:20:48.854173 3046 envvar.go:172] "Feature gate default state" feature="InformerResourceVersion" enabled=false
I0111 09:20:48.854255 3046 envvar.go:172] "Feature gate default state" feature="WatchListClient" enabled=false
I0111 09:20:48.854156 3046 cert_rotation.go:140] Starting client certificate rotation controller
I0111 09:20:48.878114 3046 round_trippers.go:560] GET https://server.kubernetes.local:6443/api?timeout=32s 200 OK in 23 milliseconds
I0111 09:20:48.880569 3046 round_trippers.go:560] GET https://server.kubernetes.local:6443/apis?timeout=32s 200 OK in 1 milliseconds
I0111 09:20:48.893465 3046 round_trippers.go:560] GET https://server.kubernetes.local:6443/api/v1/nodes?limit=500 200 OK in 2 milliseconds
NAME STATUS ROLES AGE VERSION
node-0 Ready <none> 21m v1.32.3
node-1 Ready <none> 2m15s v1.32.3
root@jumpbox:~/kubernetes-the-hard-way# cat /root/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZURENDQXpTZ0F3SUJBZ0lVY1NNVHR5S29XcXlkK1lYWUZqVVZhd05pT2prd0RRWUpLb1pJaHZjTkFRRU4KQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2xkaGMyaHBibWQwYjI0eEVEQU9CZ05WQkFjTQpCMU5sWVhSMGJHVXhDekFKQmdOVkJBTU1Ba05CTUI0WERUSTJNREV4TURJeU1EVTFObG9YRFRNMk1ERXhNVEl5Ck1EVTFObG93UVRFTE1Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBZ01DbGRoYzJocGJtZDBiMjR4RURBT0JnTlYKQkFjTUIxTmxZWFIwYkdVeEN6QUpCZ05WQkFNTUFrTkJNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QQpNSUlDQ2dLQ0FnRUFudE4xUGh0Q3lCZ0dYUnBWeHViaUp6emhTOStVUUpiUEgxeWd4WTNrOVVlQmZnV1YvSmxRCjBmWk1ib294aXMyYzVBR1B1SnpZbW9UbkZtZjNxRWdVY09Rc0ZVYlNGSWtSU1FOQW9JMmRUdk1ESUVLNXgrK3gKazZxN1luaVhHWFFEN3R3QUdON2dvdGt4NjNGSDBPbEJNb0tBR05QcTBNZHFGMEVacktxdXlUQ1paU09yRHNjawo2bysycGxJNWVlTmg1YzBFaUFFTmxZdFc5UVd5enJDOFZLOWNYR0hDU1hqemhUc05KQUY2a0ZvNWFUTWZtRjdDCnhBTFRqSlFpc0o0VkpZdytHdVRkS2FnME00b0svTXQySkxlcElJeGl4dCtQTUpGNWdLeGpVdDVUMmE4emZ1NkwKQlQ5UEs3VGQydWd1TEdGTzh1dEJhT0U4T0NZYzZmMGdscVJ0ZHJHSUF6dXZBNk9LZlJYMGdQQ2N4bzY3UVRQeQpMdENaRUVlWnlvV3ZoRVNRVUxuYzNINVBzVzkwMndvdEU0L0ovRzIwNzhkNlhUZzRWNS9wUzhUNDQ5Q20yZXd1Cld5bzZNc1FZMllWbUdIdzBxTDhMZ2dDRDlNVHF2QTFoWVBzOGo0NjZxUldic01nNTFoRmxXazZ5b081RS9INXcKVUhuQlQrTHVWb3RpOXBRNC9oWjg3aDZNc0NsT3lDK2xFM0ZJMlkvU0FwamZXS0Y5dHVJaHhmY3J3dW5wcnUrTAorZFY5eDZ5em45SS9xQjhadmFLeTFuS0g2RU53RG5PN2llN0YrNTFnb2FacTBFV2UrSHg1ZzJFcHUwZlArdlBPCnUrSzB5bUxCaVhhVGJBS0NTTW9vNFpab3BRQjBBTVVrb3NzNkgxYzZSRjV3bDZabFlreXcrWkVDQXdFQUFhTTgKTURvd0RBWURWUjBUQkFVd0F3RUIvekFMQmdOVkhROEVCQU1DQVFZd0hRWURWUjBPQkJZRUZKN05Ocm9pYTBPbgoyeU1wbDFNYjBYTGZiV0hTTUEwR0NTcUdTSWIzRFFFQkRRVUFBNElDQVFCd3ByOCs4bmlHRTlVakFLUUcyQU5rCnh6SG5NUFFOeU44NXpFcXJCMFp4M2tpSEJ0RS9GaHpRdHhoL0lkZnozRTN0U0k4blRNbTRsSDYycnZQdmM1NEYKMTlLMWdXV3poeExrWkMrdEsyMEpVVVN5dVJkS0VlTzZTSHB0UVlwOEZkTWVhWVlMSS9jSHVBcmRTNkw5ek1pYQpCTDRZWEdwbTFxM3lYeVRrd3VnSFJTcFlxeUJ6UDhMa3NESjU3T2EyYSs3Q0xaYXU1ZnczSkpPRFJEc3V5OXRUClhGS2UzT2VWQS9INmcvQUMwUzlKa1JDTnVKODhxOG40S0hDRTRySzA2dUErVklUaHltd1p0dHlsTkhDQUVGNncKa2ptbjQ1SndIS3ZSY2YybTVhZDlVNWNWd0p5bkJidnZXNi9lMXFOVGgyZnRvcEUvUVVraHozUk8vNWlMQ3BIQgpNUjZWZW5qY05FYTg2TnoyUTVWOFRmLzhSWHpOWjZHU1BBQXhsUENTNDNkWkpMZVZUc2N2bTBURlZzRm5kQktxCmlOWXZjUGxyWHp0diswTVJxOXpkVWpQS1g2by85L2RBOXkxZG9GQlBRMWFxRWhnUGRWQnJqenJNbjdXaUVna2cKZWF4VlZaYnovbXNxYUF1akZnRUdaZ2V5OEFWUEI3WWNKSit5dXFSV2xMbmJ0enl2MUt6WGd1SytYYjZBazRFdAp5T2pscWhINlNKNm9JODA3MldwcXp5Z2hEcG9IOWt5VGpILy8xSEVLNVZOdXUxbUYxMGVrd05VQk9wQkREdXl5CjNDS20xUmhkUHlYRjhtSUxwOU9FODBrb3E1SzZ0RndOUy9oREVSdFFXdC9zMUN2dHFLa1NxZFlSVUlzKzBzcXQKWVRCZTJIdWJZVGptaUdOMzhOZnlOQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
server: https://server.kubernetes.local:6443
name: kubernetes-the-hard-way
contexts:
- context:
cluster: kubernetes-the-hard-way
user: admin
name: kubernetes-the-hard-way
current-context: kubernetes-the-hard-way
kind: Config
preferences: {}
users:
- name: admin
user:
client-certificate: /root/kubernetes-the-hard-way/admin.crt
client-key: /root/kubernetes-the-hard-way/admin.key
Pod 네트워크 라우팅 구성
node-0, node-1에 PodCIDR과 통신을 위한 OS커널에 라우팅 설정을 구성합니다.
구성하려는 네트워크 대역은 다음과 같습니다.
| 항목 | 네트워크 대역 or IP |
| clusterCIDR | 10.200.0.0/16 |
| → node-0 PodCIDR | 10.200.0.0/24 |
| → node-1 PodCIDR | 10.200.1.0/24 |
| ServiceCIDR | 10.32.0.0/24 |
| → api clusterIP | 10.32.0.1 |
# Print the internal IP address and Pod CIDR range for each worker instance:
root@jumpbox:~/kubernetes-the-hard-way# SERVER_IP=$(grep server machines.txt | cut -d " " -f 1)
NODE_0_IP=$(grep node-0 machines.txt | cut -d " " -f 1)
NODE_0_SUBNET=$(grep node-0 machines.txt | cut -d " " -f 4)
NODE_1_IP=$(grep node-1 machines.txt | cut -d " " -f 1)
NODE_1_SUBNET=$(grep node-1 machines.txt | cut -d " " -f 4)
echo $SERVER_IP $NODE_0_IP $NODE_0_SUBNET $NODE_1_IP $NODE_1_SUBNET
192.168.10.100 192.168.10.101 10.200.0.0/24 192.168.10.102 10.200.1.0/24
root@jumpbox:~/kubernetes-the-hard-way# ssh server ip -c route
default via 10.0.2.2 dev eth0
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
192.168.10.0/24 dev eth1 proto kernel scope link src 192.168.10.100
root@jumpbox:~/kubernetes-the-hard-way# ssh root@server <<EOF
ip route add ${NODE_0_SUBNET} via ${NODE_0_IP}
ip route add ${NODE_1_SUBNET} via ${NODE_1_IP}
EOF
Pseudo-terminal will not be allocated because stdin is not a terminal.
Linux server 6.1.0-40-arm64 #1 SMP Debian 6.1.153-1 (2025-09-20) aarch64
This system is built by the Bento project by Chef Software
More information can be found at https://github.com/chef/bento
Use of this system is acceptance of the OS vendor EULA and License Agreements.
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@jumpbox:~/kubernetes-the-hard-way# ssh server ip -c route
default via 10.0.2.2 dev eth0
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
10.200.0.0/24 via 192.168.10.101 dev eth1
10.200.1.0/24 via 192.168.10.102 dev eth1
192.168.10.0/24 dev eth1 proto kernel scope link src 192.168.10.100
root@jumpbox:~/kubernetes-the-hard-way# ssh node-0 ip -c route
default via 10.0.2.2 dev eth0
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
192.168.10.0/24 dev eth1 proto kernel scope link src 192.168.10.101
root@jumpbox:~/kubernetes-the-hard-way# ssh root@node-0 <<EOF
ip route add ${NODE_1_SUBNET} via ${NODE_1_IP}
EOF
Pseudo-terminal will not be allocated because stdin is not a terminal.
Linux node-0 6.1.0-40-arm64 #1 SMP Debian 6.1.153-1 (2025-09-20) aarch64
This system is built by the Bento project by Chef Software
More information can be found at https://github.com/chef/bento
Use of this system is acceptance of the OS vendor EULA and License Agreements.
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@jumpbox:~/kubernetes-the-hard-way# ssh node-0 ip -c route
default via 10.0.2.2 dev eth0
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
10.200.1.0/24 via 192.168.10.102 dev eth1
192.168.10.0/24 dev eth1 proto kernel scope link src 192.168.10.101
root@jumpbox:~/kubernetes-the-hard-way# ssh node-1 ip -c route
default via 10.0.2.2 dev eth0
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
192.168.10.0/24 dev eth1 proto kernel scope link src 192.168.10.102
root@jumpbox:~/kubernetes-the-hard-way# ssh root@node-1 <<EOF
ip route add ${NODE_0_SUBNET} via ${NODE_0_IP}
EOF
Pseudo-terminal will not be allocated because stdin is not a terminal.
Linux node-1 6.1.0-40-arm64 #1 SMP Debian 6.1.153-1 (2025-09-20) aarch64
This system is built by the Bento project by Chef Software
More information can be found at https://github.com/chef/bento
Use of this system is acceptance of the OS vendor EULA and License Agreements.
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@jumpbox:~/kubernetes-the-hard-way# ssh node-1 ip -c route
default via 10.0.2.2 dev eth0
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
10.200.0.0/24 via 192.168.10.101 dev eth1
192.168.10.0/24 dev eth1 proto kernel scope link src 192.168.10.102
Smoke Test
최종 구성도는 포스팅 상단에 작성한 다음 그림과 같습니다.

kubernetes 동작 테스트를 진행하겠습니다.
root@jumpbox:~/kubernetes-the-hard-way# kubectl create secret generic kubernetes-the-hard-way --from-literal="mykey=mydata"
secret/kubernetes-the-hard-way created
root@jumpbox:~/kubernetes-the-hard-way# kubectl get secret kubernetes-the-hard-way
NAME TYPE DATA AGE
kubernetes-the-hard-way Opaque 1 5s
root@jumpbox:~/kubernetes-the-hard-way# kubectl get secret kubernetes-the-hard-way -o yaml
apiVersion: v1
data:
mykey: bXlkYXRh
kind: Secret
metadata:
creationTimestamp: "2026-01-11T00:33:42Z"
name: kubernetes-the-hard-way
namespace: default
resourceVersion: "4565"
uid: ce1640d0-b57d-4e66-9edd-168e2580710b
type: Opaque
root@jumpbox:~/kubernetes-the-hard-way# kubectl get secret kubernetes-the-hard-way -o jsonpath='{.data.mykey}' ; echo
bXlkYXRh
root@jumpbox:~/kubernetes-the-hard-way# kubectl get secret kubernetes-the-hard-way -o jsonpath='{.data.mykey}' | base64 -d ; echo
mydata
# Print a hexdump of the kubernetes-the-hard-way secret stored in etcd
## etcdctl get … : etcd 내부 key 직접 조회, kubernetes API 우회(매우 강력한 접근)
## Secret 리소스의 etcd 실제 저장 경로: /registry/<resource>/<namespace>/<name> -> /registry/secrets/default/kubernetes-the-hard-way
root@jumpbox:~/kubernetes-the-hard-way# ssh root@server \
'etcdctl get /registry/secrets/default/kubernetes-the-hard-way | hexdump -C'
00000000 2f 72 65 67 69 73 74 72 79 2f 73 65 63 72 65 74 |/registry/secret|
00000010 73 2f 64 65 66 61 75 6c 74 2f 6b 75 62 65 72 6e |s/default/kubern|
00000020 65 74 65 73 2d 74 68 65 2d 68 61 72 64 2d 77 61 |etes-the-hard-wa|
00000030 79 0a 6b 38 73 3a 65 6e 63 3a 61 65 73 63 62 63 |y.k8s:enc:aescbc|
00000040 3a 76 31 3a 6b 65 79 31 3a 8a 92 59 2e 76 12 be |:v1:key1:..Y.v..|
00000050 c6 bf 8a 5e 14 50 fe d4 a8 0a 8c 02 95 bd 38 06 |...^.P........8.|
00000060 53 5d 71 8d 33 db 1b 35 3c 57 b3 ca 81 ca 52 ab |S]q.3..5<W....R.|
00000070 d9 7b 5b c1 cf 1d 6a e9 26 be 67 b9 33 a6 ba 38 |.{[...j.&.g.3..8|
00000080 0a ad af d3 0e 1e d7 ad 59 54 4b 1e 93 28 12 80 |........YTK..(..|
00000090 67 55 44 dd 4a 00 9c c7 58 5a 10 6b 47 76 42 76 |gUD.J...XZ.kGvBv|
000000a0 64 5d da cc 11 7d f7 38 60 c7 d8 70 ac ea 75 49 |d]...}.8`..p..uI|
000000b0 fd d8 83 6a 5e bb 9f 8f 60 73 f5 9f 95 e6 05 00 |...j^...`s......|
000000c0 2e af a9 63 38 be a7 5a 7e e4 a2 23 52 fd 47 63 |...c8..Z~..#R.Gc|
000000d0 d1 12 41 3b 36 4d 7a ce d7 0c 25 02 d8 40 d5 a7 |..A;6Mz...%..@..|
000000e0 04 ee 55 b1 20 5f e6 02 b6 ec a8 ab 7c fa 51 81 |..U. _......|.Q.|
000000f0 c3 78 18 64 f8 1a e0 3d 44 d9 57 3b 80 4d d5 35 |.x.d...=D.W;.M.5|
00000100 df 2f 79 c4 5c 1e 40 a5 93 ba 5f 52 bd f6 c2 fd |./y.\.@..._R....|
00000110 03 c7 ff e0 59 68 c1 ec 6c 02 af 94 56 45 10 6d |....Yh..l...VE.m|
00000120 d1 ce 21 d3 42 f8 12 e8 2e 77 46 8a fd 4f 99 29 |..!.B....wF..O.)|
00000130 a8 ba 9c 26 fe 55 cd 12 f7 29 2e 7d 0b ee 12 c6 |...&.U...).}....|
00000140 ad a2 60 83 56 b6 af 14 a4 13 20 1c ef 4e 95 19 |..`.V..... ..N..|
00000150 c1 b6 dd fc 78 40 66 82 07 0a |....x@f...|
0000015a
... # Kubernetes Secret이 etcd에 AES-CBC 방식으로 정상 암호화되어 저장되고 있음을 증명하는 출력
# k8s:enc : Kubernetes 암호화 포맷
# aescbc : 암호화 알고리즘 (AES-CBC)
# v1 : encryption provider 버전
# key1 : 사용된 encryption key 이름
# 이후 데이터는 암호화된 데이터'스터디 > K8s Deploy' 카테고리의 다른 글
| [K8s Deploy] Kubespray offline 설치 (0) | 2026.02.15 |
|---|---|
| [K8s Deploy] Kubespary HA & Upgrade (0) | 2026.02.04 |
| [K8s] Kubespray 배포 분석 (0) | 2026.02.01 |
| [K8s Deploy] Kubeadm Deep Dive (0) | 2026.01.24 |
| [K8s Deploy] Ansible 기초 (1) | 2026.01.18 |