[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] Hyper-converged GlusterFs integration with Heketi -4/4
[Technical/Cloud, 가상화, PaaS] - [GlusterFS & Kubernetes] External Gluster PV with Heketi CLI/Rest API