아래 그림과 같이 외부에 etcd 서버를 별도로 구성하고, kube-apiserver를 통해 etcd에 read/write하도록 구성한다.
서버 구성은 아래와 같음
172.30.1.144 km.dd.io
172.30.1.145 kw.dd.io
172.30.1.146 etcd1.dd.io
● etcd 노드에서 실행
1. 방화벽 해제
systemctl stop firewalld ; systemctl disable firewalld
2. selinux 비활성화
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
3. kubernetes yum repository 설정
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
EOF
4. kubeadm 설치
yum install -y --disableexcludes=kubernetes kubeadm
5. etcd 구성원이 실행될 호스트에 대 kubeadm 구성 파일을 생성한다.
etcd 서버 중 한 곳에서만 아래 명령을 실행한다.
# etcd server ip
export HOST0=172.30.1.146
# etcd server hostname
export NAME0="etcd.dd.io"
mkdir -p /tmp/${HOST0}/
HOSTS=(${HOST0})
NAMES=(${NAME0})
for i in "${!HOSTS[@]}"; do
HOST=${HOSTS[$i]}
NAME=${NAMES[$i]}
cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml
---
apiVersion: "kubeadm.k8s.io/v1beta3"
kind: InitConfiguration
nodeRegistration:
name: ${NAME}
localAPIEndpoint:
advertiseAddress: ${HOST}
---
apiVersion: "kubeadm.k8s.io/v1beta3"
kind: ClusterConfiguration
etcd:
local:
serverCertSANs:
- "${HOST}"
peerCertSANs:
- "${HOST}"
extraArgs:
initial-cluster: ${NAMES[0]}=https://${HOSTS[0]}:2380,${NAMES[1]}=https://${HOSTS[1]}:2380,${NAMES[2]}=https://${HOSTS[2]}:2380
initial-cluster-state: new
name: ${NAME}
listen-peer-urls: https://${HOST}:2380
listen-client-urls: https://${HOST}:2379
advertise-client-urls: https://${HOST}:2379
initial-advertise-peer-urls: https://${HOST}:2380
EOF
done
6. CA 생성
이미 CA 가 있다면 CA 의 crt, key 파일을 /etc/kubernetes/pki/etcd/ca.crt 와 /etc/kubernetes/pki/etcd/ca.key 에 복사한다.
CA 가 없다면 위 2번 명령을 실행한 서버에서 아래 명령어를 실행한다.
kubeadm init phase certs etcd-ca
7. etcd 멤버에 대한 인증서 생성
kubeadm init phase certs etcd-server --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
인증서가 정상적으로 생성되었다면 아래와 같은 파일 구조를 가지게 된다.
[root@etcd 172.30.1.146]# tree /etc/kubernetes/pki/
/etc/kubernetes/pki/
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
├── ca.crt
├── ca.key
├── healthcheck-client.crt
├── healthcheck-client.key
├── peer.crt
├── peer.key
├── server.crt
└── server.key
8. etcd 설치
yum install -y etcd
9. etcd systemd 등록
NODE_IP=$(hostname -I | tr -d ' ')
ETCD_NAME=$(hostname)
ETCD1_IP="172.30.1.146"
cat <<EOF >/usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd
[Service]
Type=exec
ExecStart=/usr/bin/etcd \\
--name ${ETCD_NAME} \\
--cert-file=/etc/kubernetes/pki/etcd/server.crt \\
--client-cert-auth \\
--data-dir=/var/lib/etcd \\
--key-file=/etc/kubernetes/pki/etcd/server.key \\
--peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt \\
--peer-client-cert-auth \\
--peer-key-file=/etc/kubernetes/pki/etcd/peer.key \\
--peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt \\
--trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt \\
--initial-advertise-peer-urls https://${NODE_IP}:2380 \\
--listen-peer-urls https://${NODE_IP}:2380 \\
--advertise-client-urls https://${NODE_IP}:2379 \\
--listen-client-urls https://${NODE_IP}:2379,https://127.0.0.1:2379 \\
--initial-cluster ${ETCD_NAME}=https://${ETCD1_IP}:2380 \\
--initial-cluster-state new
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
10. etcd 시작
systemctl daemon-reload
systemctl enable --now etcd
11. etcd 서비스 정상동작 확인
[root@etcd ~]# ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --endpoints=https://172.30.1.146:2379 member list
fda9dae6d9a9a637, started, etcd.dd.io, https://172.30.1.146:2380, https://172.30.1.146:2379
● linux 환경 설정
linux 환경을 설정한다. 아래 1~ 14는 k8s cluster를 구성하는 모든 서버에서 실행한다.
1. 방화벽 해제
systemctl stop firewalld ; systemctl disable firewalld
2. selinux 비활성화 및 확인
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
3. swap 메모리 비활성화
k8s는 메모리 스왑을 고려하지 않고 설계했다고 함. 비활성화 해준다.
swap을 off하고 /etc/fstab의 내용 중 swap 관련 설정을 주석처리해준다.
swapoff -a
sed -i '/ swap / s/^/#/' /etc/fstab
4. br_netfilter 설정
bridge netfilter을 설정한다. 이걸 세팅해야 pod끼리 통신이 가능해진다고 한다.
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
5. iptables가 브리지된 트래픽을 보도록 iptables 커널 옵션을 활성화한다.
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
6. 4와 5번 설정을 시스템에 적용한다.
sysctl --system
7. 쿠버네티스 yum repository를 설정한다.
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
EOF
8. Centos package를 업데이트 한다.
yum update -y
9. docker 설치 전 필요 패키지 설치
device-mapper-persistent-data : Device Mapper는 Linux에서 많은 고급 볼륨 관리 기술을 뒷받침하는
커널 기반 프레임워크
LVM(Logical Volume Manager) : 관리자가 파일 시스템과 사용 중인 물리 저장소 사이의 추상 레이어를 제공하여 메타 장치를 만들 수 있게 한다.
yum install -y yum-utils device-mapper-persistent-data lvm2
10. docker repository 설정
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
11. docker 설치
yum install -y docker-ce docker-ce-cli containerd.io
containerd 설정 변경 후 재시작
sed -i '/"cri"/ s/^/#/' /etc/containerd/config.toml
systemctl restart containerd
12. cgroup driver 변경
kubelet과 Docker는 cgroupfs를 사용하고 나머지 프로세스는 systemd를 사용하도록 노드가 설정된 경우, 시스템 리소스 부족 현상이 발생할 수 있으므로 리눅스 init 시스템이 사용하는 cgroups 드라이버와 docker, kubelet의 드라이버를 맞춰준다.
mkdir /etc/docker
cat << EOF > /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
13. docker 실행하고 cgroup 확인
systemctl daemon-reload
systemctl start docker
systemctl enable --now docker
[root@hdm2 yum.repos.d]# docker info | grep Cgroup
Cgroup Driver: systemd
Cgroup Version: 1
14. kubelet, kubeadm, kubectl 설치 및 실행
yum install -y --disableexcludes=kubernetes kubeadm kubectl kubelet
systemctl enable --now kubelet
● k8s master 설정
아래 내용은 k8s master node에서만 진행한다. external etcd를 사용하기 위한 설정을 추가한다.
1. Cluster Configuration 생성
kubeadm-config.yaml에 external etcd 정보를 작성
ETCD1_IP="172.30.1.146"
KMASTER_IP="172.30.1.144"
cat <<EOF > kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
networking:
podSubnet: "192.168.0.0/16"
etcd:
external:
endpoints:
- https://${ETCD1_IP}:2379
caFile: /etc/kubernetes/pki/etcd/ca.crt
certFile: /etc/kubernetes/pki/etcd/server.crt
keyFile: /etc/kubernetes/pki/etcd/server.key
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: ${KMASTER_IP}
EOF
2. etcd 인증서 복사
etcd 서버에 있는 인증서를 k8s master 서버로 복사한다.
kube-apiserver에서 etcd 서버에 접근해 read/write하기 위해 필요함.
mkdir -p /etc/kubernetes/pki/etcd/
scp 172.30.1.146:/etc/kubernetes/pki/etcd/* /etc/kubernetes/pki/etcd/
3. Initialize Kubernetes Cluster
kubeadm init --config kubeadm-config.yaml
아래와 같은 join key가 생성된다.
kubeadm join 172.30.1.144:6443 --token rmb0su.k5v7ul7byfvqb6kl \
--discovery-token-ca-cert-hash sha256:1048d739e7f6743ef537e73912e4528420e60e2d134aaba8a8a4340b3351e74f
4. kubectl을 실행하기 위한 설정파일을 복사한다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
5. Network Plugin(CNI) 설정
kubectl create -f https://projectcalico.docs.tigera.io/manifests/tigera-operator.yaml
kubectl create -f https://projectcalico.docs.tigera.io/manifests/custom-resources.yaml
● k8s worker 설정
위에서 생성한 join key를 입력해 k8s cluster에 join한다.
kubeadm join 172.30.1.144:6443 --token rmb0su.k5v7ul7byfvqb6kl \
--discovery-token-ca-cert-hash sha256:1048d739e7f6743ef537e73912e4528420e60e2d134aaba8a8a4340b3351e74f
kubectl을 실행하기 위한 설정파일 master node에서 복사해온다.
mkdir -p ~/.kube
scp 172.30.1.144:/root/.kube/config ~/.kube/
k8s worker가 join 되었다.
[root@kw ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
km.dd.io Ready control-plane 14m v1.25.1
kw.dd.io Ready <none> 8m55s v1.25.1
external etcd를 사용하는 kubernetes cluster 구성이 잘 되었는 지 확인
아래와 같이 kube-system namespace이 etcd pod이 구동중이지 않고 master node에서 ps -ef 할때 kube-apiserver가 etcd를 바라보고 있으면 정상 완료임.
[root@kw ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-565d847f94-4wtbl 1/1 Running 0 16m
coredns-565d847f94-mp7xx 1/1 Running 0 16m
kube-apiserver-km.dd.io 1/1 Running 0 16m
kube-controller-manager-km.dd.io 1/1 Running 0 16m
kube-proxy-5t2pf 1/1 Running 0 16m
kube-proxy-pzbn7 1/1 Running 0 11m
kube-scheduler-km.dd.io 1/1 Running 0 16m
k8s master node에서 아래 명령어로 확인해보면 kube-apiserver가 external etcd를 바라보고 있는 것을 확인할 수 있다.
[root@km ~]# ps -ef | grep etcd
root 59491 59345 6 19:51 ? 00:01:11 kube-apiserver --advertise-address=172.30.1.144 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/etcd/server.crt --etcd-keyfile=/etc/kubernetes/pki/etcd/server.key --etcd-servers=https://172.30.1.146:2379 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-issuer=https://kubernetes.default.svc.cluster.local --service-account-key-file=/etc/kubernetes/pki/sa.pub --service-account-signing-key-file=/etc/kubernetes/pki/sa.key --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
'kubenetes' 카테고리의 다른 글
kubeadm join 시 pending (0) | 2022.09.30 |
---|---|
external etcd backup & restore (0) | 2022.09.18 |
etcd backup, restore (0) | 2022.09.15 |
docker 이미지 수정하는 방법 (1) | 2022.04.05 |
k8s flask web 수정하기 (0) | 2022.04.04 |
댓글