본문 바로가기
kubenetes

k8s external etcd 구성

by kyeongseo.oh 2022. 9. 17.

아래 그림과 같이 외부에 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

댓글