본문 바로가기

Technical/Cloud, Virtualization, Containers

[Kubernetes] 1.7.x~1.9.x, kubeadm 으로 L3 네트워크 기반 Cluster 구성(with Calico CNI)-3/4







4개의 시리즈 중 세 번 째로, 이번에는 2017/08 최종 버전인 Kubernetes 1.7.4 의 kubeadm 을 통한 클러스터 구축을 서로 다른 네트워크가 L3로 연결된 환경에서 구현하는 과정과 방법에 대해 알아 보고, 기본적 테스트와 검증을 진행하는 내용으로 마무리 하고자 한다.

* 1.8.x 버전 릴리즈 시 변경 사항 추가(2017.10.16. ... #1.8.x, 붉은 글씨로 표시). 

 : https://github.com/kubernetes/kubernetes/issues/53333 참고)

* 1.9.x 버전 릴리즈 시 변경 사항 추가(2017.12.26. ... #1.9.x, 붉은 글씨로 표시).



각 노드에 해당하는 서버의 준비


  • Master: CentOS 7.3(1611), CPU 2, Memory 1.2GB, IP 10.255.10.170
  • Minion 1: CentOS 7.3(1611), CPU 2, Memory 1.2GB, IP 10.255.10.171
  • Minion 2: CentOS 7.3(1611), CPU 2, Memory 1.2GB, IP 10.255.20.170
  • Minion 3: CentOS 7.3(1611), CPU 2, Memory 1.2GB, IP 10.255.20.171



각 노드 기본 설정


* 전체 서버 개별 설정


# hostnamectl set-hostname kubemaster


# hostnamectl set-hostname kubenode1


# hostnamectl set-hostname kubenode2


# hostnamectl set-hostname kubenode3



* 전체 서버 공통 설정


# vi /etc/hosts

...

10.255.10.170 kubemaster

10.255.10.171 kubenode1

10.255.20.170 kubenode2

10.255.20.171 kubenode3

* Optional: kubeadm 을 통한 node join 시 Warning 발생 . 작업 환경 내에 직접 관리하는 DNS 가 없을 경우, 편의를 위해 사용하는 방식임


# yum makecache fast

# yum install -y epel-release

# yum provides docker

Loaded plugins: fastestmirror

Loading mirror speeds from cached hostfile

 * base: ftp.nara.wide.ad.jp

 * epel: ftp.kddilabs.jp

 * extras: ftp.iij.ad.jp

 * updates: ftp.nara.wide.ad.jp

2:docker-1.12.6-32.git88a4867.el7.centos.x86_64 : Automates deployment of

                                                : containerized applications

Repo        : extras ...

# yum install -y docker-1.12.6-32.git88a4867.el7.centos.x86_64 chrony

# systemctl stop firewalld && systemctl disable firewalld

# systemctl enable docker && systemctl start docker 

* yum provides docker 를 실행하여 리스팅 되는 docker 릴리즈 버전을 선택하여 설치한다


# vi /etc/yum.repos.d/kubernetes.repo

[kubernetes]

name=Kubernetes

baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64

enabled=1

gpgcheck=1

repo_gpgcheck=1

gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg

        https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg



K8s Master 설정


[root@kubemaster ~]# vi /etc/sysctl.conf 

...

net.bridge.bridge-nf-call-iptables=1

net.bridge.bridge-nf-call-ip6tables=1

net.netfilter.nf_conntrack_max = 786432

[root@kubemaster ~]# sysctl -p

* #1.9.x에서는  반드시 수행해야 함


[root@kubemaster ~]# vi /etc/chrony.conf

...

server time.bora.net iburst

allow 10.255.0.0/16

local stratum 10

...

[root@kubemaster ~]# systemctl enable chronyd && systemctl restart chronyd

[root@kubemaster ~]# chronyc tracking

[root@kubemaster ~]# chronyc sources -v


[root@kubemaster ~]# yum update -y 

[root@kubemaster ~]# yum install -y kubelet kubeadm kubectl kubernetes-cni nmap bind-utils net-tools chrony wget fping jq git bash-completion

[root@kubemaster ~]# systemctl enable kubelet && systemctl start kubelet


[root@kubemaster ~]# source /etc/profile.d/bash_completion.sh

[root@kubemaster ~]# source <(kubectl completion bash)    

[root@kubemaster ~]# echo "source /etc/profile.d/bash_completion.sh" | tee -a ~/.bashrc

[root@kubemaster ~]# echo "source <(kubectl completion bash)" | tee -a ~/.bashrc

* kubectl 명령 옵션의 자동 완성 기능 설정(option 사항임). .bashrc 또는 .bash_profile에 추가하여 사용


[root@kubemaster ~]# setenforce 0

* Permissive 로 임시 전환(부팅 후 enforcing 으로 자동 전환됨)

* 갑작스러운 리부팅 이후에 apiserver, etcd 등이 정상 기동되지 않는 경우가 자주 발생한다면, /etc/selinux/config 에서 permissive 로 설정하여 사용하는 경우도 고려해 볼 수 있음


[root@kubemaster ~]# vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

...

Environment="KUBELET_DNS_ARGS=--cluster-dns=10.128.0.10 --cluster-domain=cluster.local"

...

[root@kubemaster ~]# systemctl daemon-reload

[root@kubemaster ~]# systemctl restart kubelet

* #1.8.x, 1.9.x: ExecStart= 위의 라인에 Environment="KUBELET_EXTRA_ARGS=--fail-swap-on=false --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice" 추가 필요

* systemctl status kubelet 실행시 status=1/FAILURE 로 나타나지만 무시해도 됨(kubeadm 이 정상 실행 되면 정상화)


* Cluster IP 범위(=service-cidr) 를 Default 값인 10.96.0.0/12 와 다른 값으로 바꾸려면, DNS IP도 그에 맞게 수정해 두어야 한다

* 해당 변경은 모든 Minion 노드에서도 각각 수행해 주어야 함(1.8.x 버전에서는 kubeadm init 옵션에서 이 부분을 동적으로 반영하도록 수정될 수 있음)


[root@kubemaster ~]# kubeadm init --skip-preflight-checks --pod-network-cidr 172.31.0.0/16 --service-cidr 10.128.0.0/12 --service-dns-domain "cluster.local" --apiserver-advertise-address 10.255.10.170 --token-ttl 0

[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.

[init] Using Kubernetes version: v1.7.4

[init] Using Authorization modes: [Node RBAC]

[preflight] Skipping pre-flight checks

[kubeadm] WARNING: starting in 1.8, tokens expire after 24 hours by default (if you require a non-expiring token use --token-ttl 0)

[certificates] Generated CA certificate and key.

[certificates] Generated API server certificate and key.

[certificates] API Server serving cert is signed for DNS names [kubemaster kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.128.0.1 10.255.10.170]

[certificates] Generated API server kubelet client certificate and key.

[certificates] Generated service account token signing key and public key.

[certificates] Generated front-proxy CA certificate and key.

[certificates] Generated front-proxy client certificate and key.

[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"

[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"

[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"

[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"

[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"

[apiclient] Created API client, waiting for the control plane to become ready

[apiclient] All control plane components are healthy after 99.501670 seconds

[token] Using token: 826c89.818bf5757e8aa2cc

[apiconfig] Created RBAC rules

[addons] Applied essential addon: kube-proxy

[addons] Applied essential addon: kube-dns


Your Kubernetes master has initialized successfully!


To start using your cluster, you need to run (as a regular user):


  mkdir -p $HOME/.kube

  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

  sudo chown $(id -u):$(id -g) $HOME/.kube/config


You should now deploy a pod network to the cluster.

Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:

  http://kubernetes.io/docs/admin/addons/


You can now join any number of machines by running the following on each node

as root:


  kubeadm join --token 826c89.818bf5757e8aa2cc 10.255.10.170:6443

* #1.9.x: --skip-preflight-checks 옵션 삭제, --ignore-preflight-errors=all 옵션 추가

* 1.6.x 이후 버전부터는 설치시 생성되는 토큰(bootstrap token)은 24시간 이후에 자동 삭제 되며, 이후에 노드 추가 등의 작업을 위해서 'kubeadm token create' 으로 새로운 토큰을 생성해 주어야 한다. '--token-ttl 0' 옵션은 토큰이 만료되지 않도록 설정함

* 즉시 완료되지는 않으며, /var/log/message 에 connection refused .. 메시지가 다량 관찰 되며, 수 분~수 십분 가량 걸릴 수 있음

* 완료된 후에도 journal log 또는 /var/log/messages log에는 network plugin is not read: cni config uninitialized 오류는 계속 나옴(정상 상태)



K8s Master 노드 kubectl 실행환경 설정 & 확인


[root@kubemaster ~]# mkdir -p $HOME/.kube

[root@kubemaster ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

[root@kubemaster ~]# chown $(id -u):$(id -g) $HOME/.kube/config

[root@kubemaster ~]# export KUBECONFIG=$HOME/.kube/config

[root@kubemaster ~]# echo "export KUBECONFIG=$HOME/.kube/config" | tee -a ~/.bashrc


[root@kubemaster ~]# kubectl get componentstatus

NAME                 STATUS    MESSAGE              ERROR

controller-manager   Healthy   ok                   

scheduler            Healthy   ok                   

etcd-0               Healthy   {"health": "true"}


K8s Minion(worker) 노드 전체 설정


* 나중에 새로운 Minion을 추가할 때마다 위의 전체 노드 공통 설정과 함께 이 과정을 거치면 된다


[root@kubenode1 ~]# vi /etc/sysctl.conf 

...

net.bridge.bridge-nf-call-iptables=1

net.bridge.bridge-nf-call-ip6tables=1

net.netfilter.nf_conntrack_max = 786432

[root@kubenode1 ~]# sysctl -p


[root@kubenode1 ~]# vi /etc/chrony.conf

...

server 10.255.10.170 iburst

local stratum 10

...

[root@kubenode1 ~]# systemctl enable chronyd && systemctl restart chronyd

[root@kubenode1 ~]# chronyc tracking

[root@kubenode1 ~]# chronyc sources -v


[root@kubenode1 ~]#  yum update -y  

[root@kubenode1 ~]#  yum install -y kubelet kubeadm kubernetes-cni net-tools



K8s Minion 노드 설정 후 각각 추가


[root@kubenode1 ~]# systemctl enable kubelet && systemctl start kubelet

[root@kubenode1 ~]# setenforce 0
[root@kubenode1 ~]# vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

...

Environment="KUBELET_DNS_ARGS=--cluster-dns=10.128.0.10 --cluster-domain=cluster.local"

...

[root@kubenode1 ~]# systemctl daemon-reload

[root@kubenode1 ~]# systemctl restart kubelet

* #1.8.x, 1.9.x: ExecStart= 위의 라인에 Environment="KUBELET_EXTRA_ARGS=--fail-swap-on=false --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice" 추가 필요

* systemctl status kubelet 실행시 status=1/FAILURE 로 나타나지만 무시해도 됨(kubeadm 이 정상 실행 되면 정상화)


[root@kubenode1 ~]# kubeadm join --token 102952.1a7dd4d8d9f4cc5 10.255.10.170:6443

* #1.9.x: --ignore-preflight-errors=all --discovery-token-unsafe-skip-ca-verification 옵션 추가

* Token 값은 새로운 노드를 추가할 때 재사용 가능하며, 분실시 또는 expire 시 에는 Master에서 'kubeadm token list' 로 알아낼 수 있다


K8s Master, Minion 노드 & Pod 실행 상태 확인


[root@kubemaster ~]# kubectl get nodes

NAME         STATUS     AGE       VERSION

kubemaster   NotReady   3m        v1.7.4

kubenode1    NotReady   9s        v1.7.4

kubenode2    NotReady   5s        v1.7.4

kubenode3    NotReady   1s        v1.7.4


[root@kubemaster ~]# kubectl get pods --all-namespaces

NAMESPACE     NAME                                 READY     STATUS    RESTARTS   AGE

kube-system   etcd-kubemaster                      1/1       Running   0          4m

kube-system   kube-apiserver-kubemaster            1/1       Running   0          3m

kube-system   kube-controller-manager-kubemaster   1/1       Running   0          4m

kube-system   kube-dns-2425271678-08gjk            0/3       Pending   0          4m

kube-system   kube-proxy-5hgsc                     1/1       Running   0          4m

kube-system   kube-proxy-68r71                     1/1       Running   0          1m

kube-system   kube-proxy-h262f                     1/1       Running   0          1m

kube-system   kube-proxy-s4n74                     1/1       Running   0          1m

kube-system   kube-scheduler-kubemaster            1/1       Running   0          4m

* kube-dns 이외의 모든 Pod 는 Running 상태이어야 하며, kube-dns 는 Network fabric solution 을 설치하기 전까지는 Pending 으로 나올 수 있음

(kubeadm은 network provider-agnostic함)



K8s Master, Calico CNI(Container Network Interface) plugin 설치 & 네트워크 활성화


[root@kubemaster ~]# git clone https://github.com/DragOnMe/kubernetes-1.7.3-with-calico-and-test-sample.git k8s-setup-test

[root@kubemaster ~]# cd k8s-setup-test/kube-cni-calico

* calico-2.4.1.yaml, calico-2.6.1.yaml 중 선택

* L3 네트워크와 무관한 Flat network 를 사용하고 싶을 경우 Calico 외에도 Weave, Flannel 등의 다른 CNI plugin 을 설치해도 되며, 여기를 참조하여 다양한 CNI들 중 하나를 취사선택하여 설치할 수도 있다

* [참고1] Weave 의 경우 kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')" 로 간단히 한번에 설치 가능하며(Kubernetes v1.4 버전 이후의 경우에만 해당), 이후의 calico 설치 과정은 skip해도 된다

* [참고2] Weave는 컨테이너간 multicast 통신이 가능하며, Calico와 비슷하게 Network Policy 기능까지 제공한다. 나중을 위해 yaml 파일로 저장해서 사용하거나 일부를 수정하여 사용하려면 curl -fsSLo weave-daemonset.yaml "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')" 로 다운로드 받은 후 사용하면 된다(참고: https://www.weave.works/docs/net/latest/kubernetes/kube-addon/)



아래 설치 내용은 L3 네트워크를 지원하는 Calico CNI 를 Kubernetes 1.7.x~1.8.x 에 설치할 경우에만 해당되므로 위에서 weave CNI를 설치하였거나  또는 Kubernetes 1.9.x 버전일 경우 내용상 설정과정이 달라질 수 있다(나중에 추가로 다룰 예정).


* Calico 2.6.1 설치 시작


[root@kubemaster kube-cni-calico]# vi calico-2.6.1.yaml 

...

17     etcd_endpoints: "http://10.128.232.136:6666"

...

113   clusterIP: 10.128.232.136

...

180             # Configure the IP Pool from which Pod IPs will be chosen.

181             - name: CALICO_IPV4POOL_CIDR

182               value: "172.31.0.0/16"

...

* calico_etcd 주소: 10.96.232.136 (default) 에서 10.128.232.136 으로 변경(Cluster IP cidr 범위 내에 있어야 함)

* CALICO_IPV4POOL_CIDR: 172.31.0.0/16(kubeadm init 시의 pod-network-cidr 값과 동일해야 함)

  CALICO_IPV4POOL_CIDR 범위 내의 IP가 Minion 노드의 tunl0 에 할당 되며, Pod에도 동적으로 할당 됨


[root@kubemaster ~]# cd ~

[root@kubemaster ~]# kubectl apply -f k8s-setup-test/kube-cni-calico/calico.yaml

configmap "calico-config" created

daemonset "calico-etcd" created

service "calico-etcd" created

daemonset "calico-node" created

deployment "calico-policy-controller" created

clusterrolebinding "calico-cni-plugin" created

clusterrole "calico-cni-plugin" created

serviceaccount "calico-cni-plugin" created

clusterrolebinding "calico-policy-controller" created

clusterrole "calico-policy-controller" created

serviceaccount "calico-policy-controller" created


[root@kubemaster ~]# kubectl get pods -n kube-system -o wide

NAME                                       READY     STATUS              RESTARTS   AGE       IP              NODE

calico-etcd-695ln                          0/1       ImagePullBackOff    0          5m        10.255.10.170   kubemaster

calico-node-278k3                          0/2       ContainerCreating   0          5m        10.255.20.171   kubenode3

calico-node-4l1f4                          0/2       ContainerCreating   0          5m        10.255.10.170   kubemaster

calico-node-cr5cr                          0/2       ErrImagePull        0          5m        10.255.20.170   kubenode2

calico-node-dr73h                          0/2       ContainerCreating   0          5m        10.255.10.171   kubenode1

calico-policy-controller-336633499-drd9n   0/1       Pending             0          5m        <none>          <none>

etcd-kubemaster                            1/1       Running             0          14m       10.255.10.170   kubemaster

kube-apiserver-kubemaster                  1/1       Running             0          13m       10.255.10.170   kubemaster

kube-controller-manager-kubemaster         1/1       Running             0          14m       10.255.10.170   kubemaster

kube-dns-2425271678-08gjk                  0/3       Pending             0          14m       <none>          <none>

kube-proxy-5hgsc                           1/1       Running             0          14m       10.255.10.170   kubemaster

kube-proxy-68r71                           1/1       Running             0          11m       10.255.10.171   kubenode1

kube-proxy-h262f                           1/1       Running             0          11m       10.255.20.170   kubenode2

kube-proxy-s4n74                           1/1       Running             0          10m       10.255.20.171   kubenode3

kube-scheduler-kubemaster                  1/1       Running             0          14m       10.255.10.170   kubemaster


* Calico 2.6.1 설치 끝


[root@kubemaster ~]# kubectl get nodes

NAME         STATUS     AGE       VERSION

kubemaster   NotReady   29m       v1.7.4

kubenode1    Ready      26m       v1.7.4

kubenode2    NotReady   25m       v1.7.4

kubenode3    Ready      25m       v1.7.4

* Calico Network Pod가 정상 기동되기 전까지는 모든 노드는 NotReady 상태로 보일 수도 있다. 위의 과정을 보면 Calico Pod 가 Ready로 올라옴에 따라

노드가 하나씩 Ready 상태로 바뀌고 있는 것을 알 수 있다(Calico node Pod 의 경우 전체 Minion에 걸쳐 완료되려면 수 십분 정도 걸릴 수도 있다)


...

Aug 24 02:06:43 localhost kubelet: E0824 02:06:43.126000    3032 pod_workers.go:182] Error syncing pod 0c9bb31d-8825-11e7-b7d7-08002729d0c4 ("calico-etcd-695ln_kube-system(0c9bb31d-8825-11e7-b7d7-08002729d0c4)"), skipping: failed to "StartContainer" for "calico-etcd" with ImagePullBackOff: "Back-off pulling image \"quay.io/coreos/etcd:v3.1.10\""

Aug 24 02:06:43 localhost kubelet: W0824 02:06:43.531722    3032 cni.go:189] Unable to update cni config: No networks found in /etc/cni/net.d

Aug 24 02:06:43 localhost kubelet: E0824 02:06:43.531821    3032 kubelet.go:2136] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

Aug 24 02:06:48 localhost kubelet: W0824 02:06:48.533281    3032 cni.go:189] Unable to update cni config: No networks found in /etc/cni/net.d

Aug 24 02:06:48 localhost kubelet: E0824 02:06:48.533882    3032 kubelet.go:2136] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

...

* Example /var/log/messages


[root@kubemaster ~]# kubectl get pods -n kube-system -o wide

NAME                                       READY     STATUS    RESTARTS   AGE       IP              NODE

calico-etcd-695ln                          1/1       Running   0          45m       10.255.10.170   kubemaster

calico-node-278k3                          2/2       Running   7          45m       10.255.20.171   kubenode3

calico-node-4l1f4                          2/2       Running   5          45m       10.255.10.170   kubemaster

calico-node-cr5cr                          2/2       Running   8          45m       10.255.20.170   kubenode2

calico-node-dr73h                          2/2       Running   6          45m       10.255.10.171   kubenode1

calico-policy-controller-336633499-drd9n   1/1       Running   9          45m       10.255.20.171   kubenode3

etcd-kubemaster                            1/1       Running   0          30m       10.255.10.170   kubemaster

kube-apiserver-kubemaster                  1/1       Running   0          30m       10.255.10.170   kubemaster

kube-controller-manager-kubemaster         1/1       Running   0          30m       10.255.10.170   kubemaster

kube-dns-2425271678-08gjk                  3/3       Running   4          54m       172.31.45.192   kubenode3

kube-proxy-5hgsc                           1/1       Running   0          54m       10.255.10.170   kubemaster

kube-proxy-68r71                           1/1       Running   0          50m       10.255.10.171   kubenode1

kube-proxy-h262f                           1/1       Running   0          50m       10.255.20.170   kubenode2

kube-proxy-s4n74                           1/1       Running   0          50m       10.255.20.171   kubenode3

kube-scheduler-kubemaster                  1/1       Running   0          30m       10.255.10.170   kubemaster

* 시간이 지남에 따라 점차로 Pod들이 자리를 잡으며, 후반으로 가면 kube-dns가 Running 상태로 바뀌고 Pod Network의 IP를 할당 받음을 볼 수 있다


[root@kubemaster ~]# kubectl get nodes

NAME         STATUS    AGE       VERSION

kubemaster   Ready     55m       v1.7.4

kubenode1    Ready     51m       v1.7.4

kubenode2    Ready     51m       v1.7.4

kubenode3    Ready     51m       v1.7.4

* 모든 노드가 Ready 상태로 바뀌면 설치가 완료되어 Cluster 의 사용이 가능한 상태가 된 것이다



Cluster 정상 상태 및 DNS 동작 확인을 위한 Pod 생성


[root@kubemaster ~]# mkdir k8s-test && cd k8s-test

[root@kubemasterk8s-test]# vi busybox-for-dnstest.yaml

apiVersion: v1
kind: Pod
metadata:
  name: busybox-for-dnstest
  namespace: default
spec:
  containers:
  - image: busybox
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox-container
  restartPolicy: Always


[root@kubemasterk8s-test]# vi test-hostnames-deploy.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hostnames
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: hostnames
    spec:
      containers:
      - name: hostnames
        image: gcr.io/google_containers/serve_hostname
        ports:
        - containerPort: 9376
          protocol: TCP


[root@kubemasterk8s-test]# vi test-hostnames-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: hostnames
spec:
  selector:
    app: hostnames
  ports:
  - name: default
    protocol: TCP
    port: 80
    targetPort: 9376


[root@kubemaster k8s-test]# kubectl create -f busybox-for-dnstest.yaml

pod "busybox-for-dnstest" created

[root@kubemaster k8s-test]# kubectl create -f test-hostnames-deploy.yaml 

deployment "hostnames" created

[root@kubemaster k8s-test]# kubectl create -f test-hostnames-svc.yaml 

service "hostnames" created



Cluster DNS 정상 작동 상태 확인


* Kubernetes 클러스터의 정상적인 서비스를 위해서 가장 중요한 요소 중 하나인 DNS 기능을 확인해 봄으로써, 전체 클러스터의 기본적 동작을 점검할 수 있다.


[root@kubemaster k8s-test]# kubectl exec -it busybox-for-dnstest -- sh

/ # nslookup yahoo.com

Server:    10.128.0.10

Address 1: 10.128.0.10 kube-dns.kube-system.svc.cluster.local


Name:      yahoo.com

Address 1: 2001:4998:58:c02::a9 ir1.fp.vip.bf1.yahoo.com

Address 2: 2001:4998:c:a06::2:4008 ir1.fp.vip.gq1.yahoo.com

Address 3: 2001:4998:44:204::a7 ir1.fp.vip.ne1.yahoo.com

Address 4: 206.190.36.45 ir1.fp.vip.gq1.yahoo.com

Address 5: 98.138.253.109 ir1.fp.vip.ne1.yahoo.com

Address 6: 98.139.180.149 ir1.fp.vip.bf1.yahoo.com

/ # nslookup kubernetes

Server:    10.128.0.10

Address 1: 10.128.0.10 kube-dns.kube-system.svc.cluster.local


Name:      kubernetes

Address 1: 10.128.0.1 kubernetes.default.svc.cluster.local

/ # nslookup hostnames

Server:    10.128.0.10

Address 1: 10.128.0.10 kube-dns.kube-system.svc.cluster.local


Name:      hostnames

Address 1: 10.128.89.48 hostnames.default.svc.cluster.local


/ # wget -O- http://hostnames

Connecting to hostnames (10.98.89.48:80)

hostnames-2923313648-rtlgg

-                    100% |*******************************|    27   0:00:00 ETA

/ # wget -O- http://hostnames

Connecting to hostnames (10.98.89.48:80)

hostnames-2923313648-f8s4x

-                    100% |*******************************|    27   0:00:00 ETA

/ # wget -O- http://hostnames

Connecting to hostnames (10.98.89.48:80)

hostnames-2923313648-rtlgg

-                    100% |*******************************|    27   0:00:00 ETA

/ # wget -O- http://hostnames

Connecting to hostnames (10.98.89.48:80)

hostnames-2923313648-j5tp0

-                    100% |*******************************|    27   0:00:00 ETA

/ # wget -O- http://hostnames

Connecting to hostnames (10.98.89.48:80)

hostnames-2923313648-rtlgg

-                    100% |*******************************|    27   0:00:00 ETA

/ # wget -O- http://hostnames

Connecting to hostnames (10.98.89.48:80)

hostnames-2923313648-f8s4x

-                    100% |*******************************|    27   0:00:00 ETA

* DNS의 Round-Robin 에 의해, wget 실행시 마다 다른 Pod에 번갈아서 접속됨을 확인할 수 있다



Cluster Network 정상 작동 확인(Master 노드 - ping - Cluster IP)


* Kubernetes 클러스터 내의 가상네트워크(ClusterIP) 의 정상 동작 여부 확인

[root@kubemaster k8s-test]# kubectl get pods -o wide

NAME                         READY     STATUS    RESTARTS   AGE       IP               NODE

busybox-for-dnstest          1/1       Running   0          4m        172.31.35.72     kubenode2

hostnames-2923313648-3104j   1/1       Running   0          4m        172.31.35.73     kubenode2

hostnames-2923313648-h4n8j   1/1       Running   0          4m        172.31.45.199    kubenode3

hostnames-2923313648-r89h4   1/1       Running   0          4m        172.31.205.197   kubenode1


[root@kubemaster k8s-test] kubectl get po -o json | jq .items[].status.podIP -r | fping

172.31.35.72 is alive

172.31.35.73 is alive

172.31.45.199 is alive

172.31.205.197 is alive

* 현재 리스트업 되는 모든 pod 들에 대해 ping 실행



Addon 설치 - Dashboard with Heapster, InfluxDB/Grafana


#1.8.x, #1.9.x 버전에서 Dashboard(v1.8.x 기반)의 간편한 설치를 위해 다음 링크를 통해 진행함(추가: 2017/12/28)

https://github.com/DragOnMe/k8s-1.8-dashboard-heapster-mod



* Heapster, influxdb & grafana 설치

[root@kubemaster ~]# cd ~/k8s-setup-test/heapster

[root@kubemaster heapster]# kubectl create -f deploy/kube-config/influxdb/

[root@kubemaster heapster]# kubectl create -f deploy/kube-config/rbac/heapster-rbac.yaml

* k8s-setup-test/heapster 의 내용은 https://github.com/kubernetes/heapster 의 내용과 동일함

* 따라서 k8s 새로운 버전에 대한 heapster 는 https://github.com/kubernetes/heapster 를 clone 하여 사용을 권장함


* kubernetes-dashboard 설치

[root@kubemaster ~]# cd ~/k8s-setup-test/kubernetes-dashboard/

[root@kubemaster kubernetes-dashboard]# kubectl apply -f kubernetes-dashboard.yaml

* k8s-setup-test/kubernetes-dashboard/kubernetes-dashboard.yaml 내용은   https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml 의 내용과 동일함


* Dashboard 접속 URL 확인

[root@kubemaster ~]# kubectl -n kube-system expose deployment kubernetes-dashboard --name kubernetes-dashboard-nodeport --type=NodePort

[root@kubemaster ~]# kubectl get svc -nkube-system

NAME                            CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE

calico-etcd                     10.128.232.136    <none>        6666/TCP         20h

heapster                        10.108.175.104   <none>        80/TCP           15h

kube-dns                        10.128.0.10       <none>        53/UDP,53/TCP    21h

kubernetes-dashboard            10.103.62.100    <none>        80/TCP           1h

kubernetes-dashboard-nodeport   10.102.218.165   <nodes>       9090:30707/TCP   1h

monitoring-grafana              10.102.181.221   <none>        80/TCP           15h

monitoring-influxdb             10.99.75.72      <none>        8086/TCP         15h

* http://10.255.10.170:30707/ 로 dashboard 접속





클러스터 유지보수, 해체 등 운영 방법


  • 불가피한 사정으로 Cluster 를 셧다운 시는 Minion - Master 순으로 수행
  • 재기동 시는 Master-Minion 순으로 수행


* Minion 노드 유지보수(At master node)

[root@kubemaster ~]# kubectl get nodes

NAME         STATUS    AGE       VERSION

kubemaster   Ready     6d        v1.7.4

kubenode1    Ready     6d        v1.7.4

kubenode2    Ready     6d        v1.7.4

kubenode3    Ready     6d        v1.7.4

[root@kubemaster ~]#  kubectl drain hostname --force --ignore-daemonsets

node "hostname" cordoned

WARNING: Ignoring DaemonSet-managed pods: calico-node-f6an0, kube-proxy-jv53g

* 해당 노드는 cordoned 상태가 되며, 내부의 Pod는 유지되나, Pod의 추가 deploy 대상에서 제외됨


* 점검 후 복귀

[root@kubemaster ~]# kubectl uncordon node hostname


* 삭제 후 재투입(drain 후)

[root@kubemaster ~]# kubectl delete node hostname

[root@kubemaster ~]# kubeadm join --token xxxxxxxxxxxxxx 10.255.10.170:6443

* Minion 노드 재설치 및 신규 투입 과정과 동일함



* Cluster 해체시

[root@kubemaster ~]# kubectl drain hostname1 --delete-local-data --force --ignore-daemonsets

[root@kubemaster ~]# kubectl delete node hostname1

[root@kubemaster ~]# kubectl drain hostname2 --delete-local-data --force --ignore-daemonsets

[root@kubemaster ~]# kubectl delete node hostname2

...

[root@kubemaster ~]# kubeadm reset

[root@kubemaster ~]# systemctl daemon-reload

[root@kubemaster ~]# systemctl restart docker

[root@kubemaster ~]# systemctl restart kubelet

...

* At master node


[root@kubenode1 ~]# kubeadm reset

[root@kubenode1 ~]# systemctl daemon-reload

[root@kubenode1 ~]# systemctl restart docker

[root@kubenode1 ~]# systemctl restart kubelet

* Minion nodes



- Barracuda -


[관련 글 목록]

[Technical/Cloud, 가상화, PaaS] - [Kubernetes] CentOS 7.3 으로 Kubernetes Cluster 구성(with Flannel)-1/4

[Technical/Cloud, 가상화, PaaS] - [Kubernetes] CentOS 7.3 으로 Kubernetes Cluster 구성(노드 추가하기)-2/4

[Technical/Cloud, 가상화, PaaS] - [Kubernetes] 1.7.3/1.7.4, kubeadm 으로 L3 네트워크 기반 Cluster 구성(with Calico CNI)-3/4

[Technical/Cloud, 가상화, PaaS] - [Kubernetes] Hyper-converged GlusterFs integration with Heketi -4/4

[Technical/Cloud, 가상화, PaaS] - [GlusterFS & Kubernetes] External Gluster PV with Heketi CLI/Rest API