kubernetes설치&클러스터링(OnPromise)

9 분 소요

k8s 구성 시나리오

역할 os host name ip
k8s master node ubuntu 18.04.3 LTS kmaster 192.168.219.175
k8s worker node ubuntu 18.04.3 LTS knod1 192.168.219.115
k8s worker node windows server 2019 knod2 192.168.219.172

k8s Master Node 구성하기 (ubuntu 18.04.3 LTS)

swap 비활성화

sudo su
swapoff -a
nano /etc/fstab

/swapfile로 시작하는 부분 주석처리

#/swapfile.....

docker 설치

sudo su

apt-get update

apt-get install -y docker.io

curl 설치

apt-get update && apt-get install -y apt-tranport-https curl

apt install curl

Kubernetes Repository 추가

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF

3가지 설치 하기 : kubeadm , kubelet , kubectl

kubernetes Repository를 추가 했으므로 필히 apt-get update 실행 후 설치하도록 한다.

apt-get update

apt-get install -y kubelet kubeadm kubectl

kubernetes configuration 갱신

nano /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

Environment 마지막 라인에 다음 내용 추가

Environment="cgroup-driver-systemd/cgroup-driver-cgroupfs"

master 초기화

#혹시 docker service가 죽어 있다면 살려준다.
systemctl enable docker.service

kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.219.175

성공적으로 완료되었다면 다음과 같은 결과가 나온다

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following 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:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.219.175:6443 --token mxeojd.1b2yjhduv8mm7war \
    --discovery-token-ca-cert-hash sha256:d2add8f96df812c87d47ab19cff0d3a6eaabc90164e3023870d9b77f23de713f

약간 위쪽에 일반사용자로 명령을 실행하라는 부분을 진행한다.

#su로 로그인 되어있다면 exit 한다.
exit


#지금부터의 작업은 su가 아닌 일반유저로 실행해야한다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

아래와 같은 에러가 발생했을때에도 위 명령을 실행 시켜주면 해결된다.

The connection to the server localhost:8080 was refused - did you specify the right host or port?

$HOME/.kube/conficp: '$HOME/.kube/config'를 덮어쓸까요? y

위에서 admin.conf 파일은 kubeadm init 명령어를 수행했을 때 생성된다. 즉, master 노드에서만 kubectl 명령어를 사용할 수 있으며, 다른 노드에서 kubectl 명령어를 사용하고 싶을 때는 master 노드에서 생성한 admin.conf 파일을 복사해오면 일반 노드에서도 kubectl 명령어를 사용할 수 있다.

마지막 부분의

kubeadm join 192.168.219.175:6443 --token mxeojd.1b2yjhduv8mm7war \
    --discovery-token-ca-cert-hash sha256:d2add8f96df812c87d47ab19cff0d3a6eaabc90164e3023870d9b77f23de713f

명령을 잘 기억해야 한다. 이 명령을 통해 node가 master에 join할 수 있기 때문이다.

만약 위 kubueadm join 명령어가 기억이 나지 않는다면 Master 노드에서 아래 명령어를 실행해서 재생성할 수 있다.

kubeadm token create --print-join-command
kubeadm join 192.168.219.175:6443 --token jhc7xv.q020wj7z8a5c691r     --discovery-token-ca-cert-hash sha256:22f0d9fec14dfadb4c3c8709aec29aed3f3ad6553e7195f9492b2168a4f991f0

master에서 join된 node 확인

kubectl get nodes

아직은 NotReady라고 나온다

NAME        STATUS     ROLES    AGE   VERSION
kmaster   NotReady   master   34m   v1.16.3

pod network add-on 설치

pod network add-on이 설치되어 있지 않은 상태에서는 CoreDNS가 아직 Running이 아니다.

kubectl get pods -n kube-system
NAME                                READY   STATUS    RESTARTS   AGE
coredns-5644d7b6d9-5v2jw            0/1     Pending   0          39m
coredns-5644d7b6d9-8bl6g            0/1     Pending   0          39m
etcd-k8smaster                      1/1     Running   0          38m
kube-apiserver-k8smaster            1/1     Running   0          38m
kube-controller-manager-k8smaster   1/1     Running   0          38m
kube-proxy-vrzr7                    1/1     Running   0          39m
kube-scheduler-k8smaster            1/1     Running   0          38m

우리는 리눅스 마스터에 윈도우 노드를 붙여볼 것이기 때문에 아래 URL에 나와있는 가이드 대로 network add-on을 Flannel로 선택하여 설치할 것이다.

쿠버네티스에서 윈도우노드추가 가이드

참고: network add-on 선택기준 : http://kubernetes.io/docs/admin/addons/

Flannel을 사용할 때에 iptables 체인으로 IPv4 트래픽을 브릿지할 수 있게 하기위해 다음 명령을 실행한다.

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

Flannel 다운받고 구성하는 명령어 실행

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

VXLAN 네트워킹 벡엔드를 가능하게 하기 위해 수정할 곳은 두 곳이다.

sudo nano kube-flannel.yml

kube-flannel.ymlnet-conf.json부분과 cni-conf.json부분이다.

net-conf.json

net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan",
        "VNI": 4096,
        "Port": 4789
      }
    }

참고: 리눅스의 플라넬과 윈도우의 플라넬이 상호운용하기 위해서 VNI는 반드시 4096이고, Port는 4789여야 한다. 다른 VNI는 곧 지원될 예정이다. VXLAN 문서에서 이 필드의 설명 부분을 보자.

*여기서 잠깐 !! 우리는 Cluster Network를 설계해야한다.

https://www.ipaddressguide.com/cidr 이곳에 들어가서 CIDR을 입력해보면 사용한 아이피 범위를 확인할 수 있다.

cni-conf.json

네트워크 이름을 vxlan0로 바꾼다.

cni-conf.json: |
    {
      "name": "vxlan0",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }

플라넬 구성을 적용하자.

kubectl apply -f kube-flannel.yml

그리고 플라넬 파드는 리눅스 기반이라 여기 나온 노드 셀렉터 패치를 플라넬 데몬셋 파드에 적용한다.

mkdir -p kube/yaml && cd kube/yaml

kubectl get ds/kube-proxy -o go-template='\n' --namespace=kube-system

wget https://raw.githubusercontent.com/Microsoft/SDN/master/Kubernetes/flannel/l2bridge/manifests/node-selector-patch.yml
kubectl patch ds/kube-proxy --patch "$(cat node-selector-patch.yml)" -n=kube-system

add-on 설치가 정상적으로 끝나면 kube-dns 의 상태가 Running으로 변경된다.

다음 명령어로 확인해보자. 이제 모든 것이 Running 이다.

kubectl get pods -o wide --all-namespaces
NAMESPACE     NAME                              READY   STATUS    RESTARTS   AGE   IP                NODE      NOMINATED NODE   READINESS GATES
kube-system   coredns-5644d7b6d9-hsjzv          1/1     Running   0          26m   10.244.0.2        kmaster   <none>           <none>
kube-system   coredns-5644d7b6d9-lkc8g          1/1     Running   0          26m   10.244.0.3        kmaster   <none>           <none>
kube-system   etcd-kmaster                      1/1     Running   0          25m   192.168.219.175   kmaster   <none>           <none>
kube-system   kube-apiserver-kmaster            1/1     Running   0          25m   192.168.219.175   kmaster   <none>           <none>
kube-system   kube-controller-manager-kmaster   1/1     Running   0          25m   192.168.219.175   kmaster   <none>           <none>
kube-system   kube-flannel-ds-amd64-wcjlr       1/1     Running   0          16m   192.168.219.175   kmaster   <none>           <none>
kube-system   kube-proxy-qkltc                  1/1     Running   0          26m   192.168.219.175   kmaster   <none>           <none>
kube-system   kube-scheduler-kmaster            1/1     Running   0          25m   192.168.219.175   kmaster   <none>           <none>

연결되어 있는 노드를 확인해보자. STATUS가 Ready 이다.

kubectl get nodes
NAME      STATUS   ROLES    AGE   VERSION
kmaster   Ready    master   14m   v1.16.3

좀 더 편한 관리를 위한 대쉬보드 생성

# 아래 구문을 실행시켜 대쉬보드를 생성한다.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta6/aio/deploy/recommended.yaml

#node 확인
kubectl get pods -o wide --all-namespaces

아래 결과에서 처럼 kubernetes-dashboard NAMESPACE가 새로 생겼다.

NAMESPACE              NAME                                         READY   STATUS              RESTARTS   AGE   IP                NODE      NOMINATED NODE   READINESS GATES
kube-system            coredns-5644d7b6d9-hsjzv                     1/1     Running             0          9h    10.244.0.2        kmaster   <none>           <none>
kube-system            coredns-5644d7b6d9-lkc8g                     1/1     Running             0          9h    10.244.0.3        kmaster   <none>           <none>
kube-system            etcd-kmaster                                 1/1     Running             0          9h    192.168.219.175   kmaster   <none>           <none>
kube-system            kube-apiserver-kmaster                       1/1     Running             0          9h    192.168.219.175   kmaster   <none>           <none>
kube-system            kube-controller-manager-kmaster              1/1     Running             0          9h    192.168.219.175   kmaster   <none>           <none>
kube-system            kube-flannel-ds-amd64-wcjlr                  1/1     Running             0          8h    192.168.219.175   kmaster   <none>           <none>
kube-system            kube-proxy-qkltc                             1/1     Running             0          9h    192.168.219.175   kmaster   <none>           <none>
kube-system            kube-scheduler-kmaster                       1/1     Running             0          9h    192.168.219.175   kmaster   <none>           <none>
kubernetes-dashboard   dashboard-metrics-scraper-76585494d8-mfdmf   0/1     ContainerCreating   0          10s   <none>            kmaster   <none>           <none>
kubernetes-dashboard   kubernetes-dashboard-b65488c4-7b9v7          0/1     ContainerCreating   0          10s   <none>            kmaster   <none>           <none>
# To enable proxy and continues with new terminal window
kubectl proxy

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/.

local에서 접속이 가능하다.

image-20191208122355769

# To create a service account for your dashboard
kubectl create serviceaccount dashboard -n default

# To add cluster binding rules for ur roles on dashboard
kubectl create clusterrolebinding dashboard-admin -n defualt \
  --clusterrole=cluster-admin \
  --serviceaccount=default:dashboard

#토큰값 생성
kubectl get secret $(kubectl get serviceaccount dashboard -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode

아래와 같은 토큰값이 생성된다.

image-20191208130752402

그대로 토큰값을 복사해 붙여넣고 Sign in을 누른다.

image-20191208131014859

Kubernetes Dashboard를 확인할 수 있다.

image-20191208131102071

k8s Worker Node 구성하기 (ubuntu 18.04.3 LTS)

k8s Slave 192.168.219.115 knod1 에서

초기에 마스터를 init 할때 생성되었던 join 구문인 아래 구문을 실행시켜본다.

 sudo kubeadm join 192.168.219.175:6443 --token jhc7xv.q020wj7z8a5c691r     --discovery-token-ca-cert-hash sha256:22f0d9fec14dfadb4c3c8709aec29aed3f3ad6553e7195f9492b2168a4f991f0

아래와 같이 클러스터에 조인되었다는 메시지가 나온다.

[preflight] Running pre-flight checks
        [WARNING Service-Docker]: docker service is not enabled, please run 'systemctl enable docker.service'
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.16" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Activating the kubelet service
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

마스터에서 노드를 살펴보면 우리가 생성한 knod1이 참여되어 있음을 확인할 수 있다.

kubectl get nodes

NAME      STATUS   ROLES    AGE   VERSION
kmaster   Ready    master   10h   v1.16.3
knod1     Ready    <none>   16m   v1.16.3

image-20191208135049508

k8s Master 구성하기 (windows server 2019)

k8s 클러스터에 가입가능한 Windows node 제약조건

Windows Server 버전 1809의 Kubernetes 1.14 릴리스를 사용 하면 사용자가 Windows의 Kubernetes에서 다음 기능을 활용할 수 있다.

자세한 사항은 여기에서 확인 가능하다.

아래표에 따르면 Windows Server 2016은 버전 1607 이라서 Windows의 Kubernetes 에서 기능을 사용할 수 없다.

image-20191208220100254

https://docs.microsoft.com/ko-kr/windows-server/get-started/windows-server-release-info

windows server 방화벽 해제

오버레이 트래픽을 위해서 인바운드(inbound) 방화벽의 UDP 포트 4789를 열어준다.

docker 설치 및 컨테이너 실행

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name Docker -ProviderName DockerMsftProvider
Restart-Computer -Force

docker pull mcr.microsoft.com/windows/nanoserver:1809
docker tag mcr.microsoft.com/windows/nanoserver:1809 microsoft/nanoserver:latest
docker run microsoft/nanoserver:latest

Windows 용 Kubernetes 준비 디렉터리

mkdir C:\k

Kubernetes 인증서 복사

Kubernetes 인증서 파일 ($HOME/.kube/config)을 마스터(kmaster)에서 새로운 C:\k 디렉터리에 복사한다.

kmaster의 /home/shw/.kube/config 파일을 knod2의 C:\k 하위로 복사

scp shw@kmaster:/home/shw/.kube/config C:\k

Kubernetes 바이너리 다운로드

Kubernetes를 실행 하려면 먼저 kubectl, kubeletkube-proxy 이진 파일을 다운로드 한다. 최신 릴리스파일의 링크에서이를 다운로드할 수 있다.

다운로드 후 압축을 푼 다음 C:\k 하위에 배치한다.

image-20191208204722183

kubectl 설치

Windows에서 클러스터를 제어 하기 위해 kubectl 명령을 사용할 수 있다. 먼저, kubectl 명령을 C:\k\ 디렉터리 외부에서 사용 가능하게 하기위해 환경 변수 PATH 를 수정해야한다.

$env:Path += ";C:\k"
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\k", [EnvironmentVariableTarget]::Machine)

그 다음에는 클러스터 인증서 가 유효한지 확인한다. 구성 파일을 kubectl 찾을 위치를 설정 하려면 매개 변수를 --kubeconfig 전달 하거나 KUBECONFIG 환경 변수를 수정 하면 된다. 우리는 자동으로 구성파일을 찾을 수 있게 하기 위해 환경변수에 등록한다.

$env:KUBECONFIG="C:\k\config"
[Environment]::SetEnvironmentVariable("KUBECONFIG", "C:\k\config", [EnvironmentVariableTarget]::User)

구성이 올바르게 검색 되었는지 확인 한다.

kubectl config view

결과가 다음과 같이 나온다

PS C:\Users\Administrator> kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.219.175:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

클러스터에 Window 노드 Join하기

다음 파워셀을 실행하여 start.ps1을 다운로드 받는다

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
wget https://raw.githubusercontent.com/Microsoft/SDN/master/Kubernetes/flannel/start.ps1 -o c:\k\start.ps1

image-20191208205540424

Could not find valid interface on windows 와 같은 에러가 발생한다면 다음 명령을 powershell 창에서 실행하여 CodePage를 변경해 준다.

#CodePage 확인하기
chcp

#65001로 CodePage 변경하기
chcp 65001

다음 명령을 실행하여 Join 한다.

#오버레이 네트워크를 이용하여 Join해야 정상동작한다.
cd c:\k
.\start.ps1 -ManagementIP 192.168.219.172 -NetworkMode overlay -InterfaceName Ethernet -Verbose

마지막으로 Window 노드가 정상적으로 Join 되어 있는지 확인해보면..

image-20191208212838080

정상적으로 클러스터에 Join되어 있음을 확인할 수 있다.

Windows 노드에서 서비스에 kubernetes 구성요소 등록하기

C:\k 에 nssm.exe 를 다운로드한다. 다운로드 경로 (https://nssm.cc/download)

서비스에 등록시켜주는 파워셀 스크립트를 다운로드 받는다.

wget https://github.com/microsoft/SDN/blob/master/Kubernetes/flannel/register-svc.ps1 -o c:\k
\register-svc.ps1

그리고 다음 스크립트를 실행해준다.

#구문
cd c:\k
.\register-svc.ps1 -NetworkMode <Network mode> -ManagementIP <Windows Node IP> -ClusterCIDR <Cluster subnet> -KubeDnsServiceIP <Kube-dns Service IP> -LogDir <Directory to place logs>

#실행명령어
cd c:\k
.\register-svc.ps1 -ManagementIP 192.168.219.172 -ClusterCIDR 10.244.0.0/16 -ServiceCIDR 10.96.0.0/12 -KubeDnsServiceIP 10.96.0.10 -LogDir c:\k\logs

만일 스크립트를 다운로드 받지 못하는 상황이라면 다음과 같이 수동으로 등록할 수도 있다.

flanneld.exe 등록

nssm install flanneld C:\flannel\flanneld.exe
nssm set flanneld AppParameters --kubeconfig-file=c:\k\config --iface=<ManagementIP> --ip-masq=1 --kube-subnet-mgr=1
nssm set flanneld AppEnvironmentExtra NODE_NAME=<hostname>
nssm set flanneld AppDirectory C:\flannel
nssm start flanneld

kubelet.exe 등록

nssm install kubelet C:\k\kubelet.exe
nssm set kubelet AppParameters --hostname-override=<hostname> --v=6 --pod-infra-container-image=kubeletwin/pause --resolv-conf="" --allow-privileged=true --enable-debugging-handlers --cluster-dns=<DNS-service-IP> --cluster-domain=cluster.local --kubeconfig=c:\k\config --hairpin-mode=promiscuous-bridge --image-pull-progress-deadline=20m --cgroups-per-qos=false  --log-dir=<log directory> --logtostderr=false --enforce-node-allocatable="" --network-plugin=cni --cni-bin-dir=c:\k\cni --cni-conf-dir=c:\k\cni\config
nssm set kubelet AppDirectory C:\k
nssm start kubelet

kube-proxy.exe 등록 (l2bridge / host-gw)

nssm install kube-proxy C:\k\kube-proxy.exe
nssm set kube-proxy AppDirectory c:\k
nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --hostname-override=<hostname>--kubeconfig=c:\k\config --enable-dsr=false --log-dir=<log directory> --logtostderr=false
nssm.exe set kube-proxy AppEnvironmentExtra KUBE_NETWORK=cbr0
nssm set kube-proxy DependOnService kubelet
nssm start kube-proxy

kube-proxy.exe 등록 (오버레이 / vxlan)

PS C:\k> nssm install kube-proxy C:\k\kube-proxy.exe
PS C:\k> nssm set kube-proxy AppDirectory c:\k
PS C:\k> nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --feature-gates="WinOverlay=true" --hostname-override=<hostname> --kubeconfig=c:\k\config --network-name=vxlan0 --source-vip=<source-vip> --enable-dsr=false --log-dir=<log directory> --logtostderr=false
nssm set kube-proxy DependOnService kubelet
nssm start kube-proxy

참고 URL

https://blog.aliencube.org/ko/2018/06/04/running-kubernetes-on-wsl/

https://linuxconfig.org/how-to-install-kubernetes-on-ubuntu-18-04-bionic-beaver-linux

https://kubernetes.io/ko/docs/setup/production-environment/windows/user-guide-windows-nodes/

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

https://www.youtube.com/watch?v=UWg3ORRRF60

http://iamartin-gh.herokuapp.com/kubernetes-install/

https://docs.microsoft.com/ko-kr/virtualization/windowscontainers/kubernetes/creating-a-linux-master

https://docs.microsoft.com/ko-kr/virtualization/windowscontainers/kubernetes/network-topologies

https://docs.microsoft.com/ko-kr/virtualization/windowscontainers/kubernetes/joining-windows-workers?tabs=ManagementIP

https://docs.ncloud.com/ko/nks/nks-1-2.html

https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/kube-windows-services?tabs=ManagementIP

https://blog.tekspace.io/setup-windows-node-with-kubernetes-1-14/

댓글남기기