Kubeadm
사전 작업
- 최소 필요 조건
- 2 CPU
- 2 GB memory
- 모든 노드에 대한 고유한 호스트 이름, MAC 주소, prodcut_uuid
ip link
sudo cat /sys/class/dmi/id/product_uuid
kubeadm-installation.yaml
---
- hosts: all
become: yes
vars:
version: 1.19.15-00
tasks:
- name: Install requirements
apt:
name: "{{ item }}"
state: latest
update_cache: yes
loop: ["apt-transport-https", "ca-certificates", "curl"]
- name: Add kubernetes GPG apt key
apt_key:
url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
keyring: /usr/share/keyrings/kubernetes-archive-keyring.gpg
- name: Add kubernetes repository
apt_repository:
repo: deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg]
https://apt.kubernetes.io/ kubernetes-xenial main
filename: kubernetes
- name: Install kubeadm kubectl kubelet version={{ version }}
apt:
name: "{{ item }}={{ version }}"
update_cache: yes
force: yes
loop: ["kubelet", "kubeadm", "kubectl"]
- name: Disable swap
command: swapoff -a
when: ansible_swaptotal_mb > 0
- name: Remove swapfile from /etc/fstab
replace:
path: /etc/fstab
regexp: '^([^#].*?\sswap\s+sw\s+.*)$'
replace: '# \1'
- name: Add br_netfilter to modules-load.d
lineinfile:
path: /etc/modules-load.d/k8s.conf
line: br_netfilter
mode: 0644
create: yes
- name: modprobe br_netfilter
modprobe:
name: br_netfilter
- name: Add netbridge config ip6
lineinfile:
path: /etc/sysctl.d/k8s.conf
line: "net.bridge.bridge-nf-call-ip6tables = 1"
mode: 0644
create: yes
- name: Add netbridge config ip4
lineinfile:
path: /etc/sysctl.d/k8s.conf
line: "net.bridge.bridge-nf-call-iptables = 1"
mode: 0644
create: yes
- name: Update sysctl
shell: sysctl --system
- name: Add kubectl completion to /home/{{ ansible_user }}/.bashrc
lineinfile:
path: /home/{{ ansible_user }}/.bashrc
line: |
source <(kubectl completion bash)
alias k=kubectl
complete -o default -F __start_kubectl k
mode: 0644
# AWS
- name: Set hostname to aws private dns name
shell: hostnamectl set-hostname $(curl http://169.254.169.254/latest/meta-data/local-hostname)
Control plane node
프로토콜 | 방향 | 포트 범위 | 목적 | 사용자 |
---|---|---|---|---|
TCP | 인바운드 | 6443* | Kubernetes API 서버 | 모두 |
TCP | 인바운드 | 2379-2380 | etcd 서버 클라이언트 API | kube-apiserver, etcd |
TCP | 인바운드 | 10250 | kubelet API | 자체, 컨트롤 플레인 |
TCP | 인바운드 | 10251 | kube-scheduler | 자체 |
TCP | 인바운드 | 10252 | kube-controller-manager | 자체 |
kubeadm-master.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
clusterName: kubernetes
kubernetesVersion: <version> # v1.19.15
networking:
dnsDomain: cluster.local
podSubnet: 192.168.0.0/16 # pod network에 할당되는 IP 주소 범위
serviceSubnet: 10.96.0.0/12 # 10.96.0.0 ~ 10.111.255.255
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
Remote에서 kubectl
명령어를 사용하고 싶은 경우 아래 내용을 추가합니다.
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
apiServer:
certSANs:
- <private-ip>
- <public-ip>
클라우드 서비스를 사용하는 경우 cloud-provider
사용을 위해 아래 내용을 추가합니다.
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
apiServer:
extraArgs:
cloud-provider: external
controllerManager:
extraArgs:
cloud-provider: external
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
cloud-provider: external
warning
Highly Available topology 구성을 위해서는 controlPlaneEndpoint
를 로드밸런서로 설정해야합니다. 추가 옵션이 있을 수 있습니다. 테스트 후 업데이트 하겠습니다.(TODO)
sudo kubeadm init --config kubeadm-master.yaml
mkdir -p $HOME/.kube \
&& sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config \
&& sudo chown $(id -u):$(id -g) $HOME/.kube/config
info
cloud에서 self managed kubernetes를 운영하는 경우 cloud-provider를 설치합니다.
CNI
kubectl get pods -n kube-system
coredns
가 Pending
상태인 것을 확인할 수 있습니다.
CNI 글을 읽어보시기 바랍니다.
token
kubeadm token list
kubeadm token create --print-join-command --ttl 10m
hash
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt \
| openssl rsa -pubin -outform der 2>/dev/null \
| openssl dgst -sha256 -hex | sed 's/^.* //'
Control plane node 추가
warning
Highly Available topology 구성을 위해서는 apiServerEndpoint
를 로드밸런서로 설정해서 진행해야합니다.
기존 마스터 노드에서 아래 명령어를 통해 2시간 동안 유효한 certificateKey
를 생성할 수 있습니다.
kubeadm init phase upload-certs --upload-certs
kubeadm-master.yaml
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: JoinConfiguration
discovery:
bootstrapToken:
apiServerEndpoint: <load balencer>:6443
token: <token>
caCertHashes:
- <hash>
controlPlane:
localAPIEndpoint:
advertiseAddress: <master ip>
certificateKey: <certificate key>
클라우드 서비스를 사용하는 경우 cloud-provider
사용을 위해 아래 내용을 추가합니다.
nodeRegistration:
kubeletExtraArgs:
cloud-provider: external
sudo kubeadm join --config kubeadm-master.yaml
Worker node
프로토콜 | 방향 | 포트 범위 | 목적 | 사용자 |
---|---|---|---|---|
TCP | 인바운드 | 10250 | kubelet API | 자체, 컨트롤 플레인 |
TCP | 인바운드 | 30000-32767 | NodePort | 서비스† 모두 |
kubeadm-worker.yaml
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: JoinConfiguration
discovery:
bootstrapToken:
apiServerEndpoint: <master endpoint>:6443
token: <token>
caCertHashes:
- <hash>
클라우드 서비스를 사용하는 경우 cloud-provider
사용을 위해 아래 내용을 추가합니다.
nodeRegistration:
kubeletExtraArgs:
cloud-provider: external
sudo kubeadm join --config kubeadm-worker.yaml
apiServer에 SAN 추가
SAN(Subject Alternative Name)
kubectl get configmap -n kube-system kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' > kubeadm-conf.yaml
apiServer:
certSANs:
- <private-ip>
- <public-ip>
위 내용을 추가한 후 /etc/kubernetes/pki/apiserver.*
을 삭제하고 아래 명령어를 실행하면 됩니다.
sudo kubeadm init phase certs apiserver --config kubeadm-conf.yaml
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text
reset
sudo kubeadm reset -f
sudo rm -r /etc/kubernetes/manifests $HOME/.kube/config
Reference
- https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
- https://kubernetes.io/docs/reference/setup-tools/kubeadm/
- https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver/
- https://kubernetes.io/docs/reference/config-api/kubeadm-config.v1beta3/
- https://blog.scottlowe.org/2021/10/12/using-the-external-aws-cloud-provider-for-kubernetes/