티스토리 뷰

들어가는 말

  • 안녕하세요 OSCKOREA의 Tommy.choi 입니다. 오늘은 쿠버네티스를 맛보기 정도 소개하고자 합니다. 

대상

  • 도커와 쿠버네티스를 이론적으로만 알고 있으며, 실제로 도커에 쿠버네티스에 Node에 Pod 까지 직접 올려테스트 해봄으로써 간적접으로 필드 경험을 돕기 위함입니다.
  • k8s 처음 접하시는분들께.... 짧은 시간이지만 한번 같이 고민해보고 어떻게 생겼는지 같이 경험해보길 기원합니다. 

 

1탄!! 쿠버네티스 구성준비/Master & Node

2탄!! 쿠버네티스와 컨테이너를 쉽게 이해하기

3탄!! Kubernetes 구성도 알아보자!

4탄!! NFS 설정입니다.

5탄!! helm install 방법

6탄 !! 도커 컴포즈 VS 쿠버네티스 컴포즈

7탄!! 쿠버네티스에 pod 올리자! pod? 뭐에요?

8탄!! K8S 대시보드 설치

9탄!! 쿠버네티스 오토스케일링(kubernetes autoscaling)

10탄!! K8S Namespace 생성방법

11탄!! 쿠버네티스 용어 정리

12탄!! 도커 깔끔히 삭제하기

# 부록!! 쿠버네티스 장애 처리5탄부록!! 쿠버네티스 장애 처리

#기타 참고하기  

마이크로 쿠버네티스 설치 해보기

쿠버네티스(컨테이너) 환경 구축의 어려운점~!

쿠버네티스(튜토리얼 실습)

쿠버네티스 초기설치및  볼트 디비 올리기[샘플]

헬름챠트로 올리기[샘플]11) 쿠버네티스 가상스토리지(Ceph) 설치

 

 


 

쿠버네티스 바로가기

쿠버네티스 kubadm 바로가기

 

github : 바로가기


 

사족

  1. 본 소개글은 쿠버네티스에 관련된 내용 입니다. 쿠버네티스를 다들 어렵다고 합니다. 이유가 뭘까요?
  2. 쿠버네티스는 도커기반으로 만들어 진놈입니다. 결국 가시적으로 눈에 보이지 않기 때문입니다. 네트웍 설정부터 너무 유기적으로 동작하기 때문입니다. 설정 하나하나가 컴포넌트 이기 때문입니다. 
  3. 도커를 잘 알면.. 쿠버네티스는 문제가 되질 않는데 도커가 문제군요!!
  4. 도커 설정 변경을 몰라서 5시간씩 헤맬수 있습니다. 짧은시간에 많은 정보를 얻어가시길 바랍니다.
  5. 미리 시행착오을 겪어 봤고 해결할수 있도록 돕겠습니다. 
  6. 감사합니다. 

지금껏 셋팅해보아도 인플런 만큼 잘된곳은 못본듯 합니다. 출처 밝히고 그대로 시행해본내용을 토대로 아래와 같이 작성 하겠습니다. https://kubetm.github.io/practice/appendix/installation_case2/ 인플런 강사님께 감사드립니다. 

만약 문제가 되면 바로 삭제 하도록 하겠습니다. 

 


1-1-1) Virtualbox 다운로드 및 설치

[윈도우10 버전으로 진행] 아래 경로에서 [Windows hosts] 클릭 하여 다운로드 후 설치 (별다른 변경없이 Next만 함)
>https://www.virtualbox.org/wiki/Downloads

 

1-1-2) CentOS Download

아래 경로로 들어가서 원하는 경로에서 Minimal 버전의 파일 다운로드
>http://isoredirect.centos.org/centos/7/isos/x86_64/

1-1-3) 원격접속 툴 MobaXterm 설치

꼭 MobaXterm이 아닌 각자 편한 원격접속 툴을 사용하셔도 되세요.
아래 예제는 MobaXterm를 설치하고 필요한 Host 등록 예제입니다.
>https://mobaxterm.mobatek.net/


2-1) Setting VM

2-1-1) VM 스펙 설정

메모리 및 디스크는 각자 상황에 맞게 참고해서 VM 설정

1. [VM 생성 1단계] 머신 > 새로 만들기 클릭
2. [VM 생성 1단계] 이름 : k8s-master, 종류: Linux, 버전: Other Linux(64-bit)
3. [VM 생성 2단계] 메모리 : 4096 MB
4. [VM 생성 3단계] 하드디스크 : 지금 새 가상 하드 디스크 만들기 (VDI:VirtualBox 디크스 이미지
   , 동적할당, 150GB)
5. [VM 생성 후 시스템 설정] 프로세서 개수 : CPU 2개
6. [VM 생성 후 저장소 설정] 컨트롤러:IDE 하위에 있는 광학드라이브 클릭 > CentOS 이미지 선택 후
   확인
7. [VM 생성 후 네트워크 설정] VM 선택 후 설정 버튼 클릭 > 네트워크 > 어댑터 1 탭 > 다음에 연결됨
    [어댑터에 브리지] 선택    - IP를 할당 받을 수 없는 경우  [NAT 네트워크] 
8. 시작

 

  • VM 환경  설치 및 동작 검증하였습니다.


2-2) Install CentOS

2-2-1) CentOS 설치

4번 단계에서 8.8.8.8는 Google DNS입니다. 원하는 DNS 쓰셔도 되요.

 

1. Test this media & install CentOS 7
2. Language : 한국어 
3. Disk 설정 [시스템 > 설치 대상]
   - [기타 저장소 옵션 > 파티션 설정] 파티션을 설정합니다. [체크] 후 [완료]
   - 새로운 CentOS 설치 > 여기를 클릭하여 자동으로 생성합니다. [클릭]
   - /home [클릭] 후 용량 5.12 GiB로 변경 [설정 업데이트 클릭]
   - / [클릭] 후 140 GiB 변경 후 [설정 업데이트 클릭]
   - [완료], [변경 사항 적용]
4. 네트워크 설정 [시스템 > 네트워크 및 호스트명 설정]
   - 호스트 이름: k8s-master [적용]
   - 이더넷 [켬], [설정], [IPv4 설정] 탭
   - 방식: 수동으로 선택, 
   - [Add] -> 주소: 192.168.0.30, 넷마스크 : 255.255.255.0, 게이트웨이: 192.168.0.1, 
     DNS 서버 : 8.8.8.8 [저장][완료]
5. 설치시작
6. [설정 > 사용자 설정] ROOT 암호 설정 
7. 설치 완료 후 [재부팅]​


3-1) Pre-Setting

3-1-1) SELinux 설정

Ubuntu나 Debian등 다른 OS를 설치하시는 분들께서는 아래 경로에서 명령어 참고 바래요
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
https://kubernetes.io/docs/setup/production-environment/container-runtimes/#docker
쿠버네티스가 Pod Network에 필요한 호스트 파일 시스템에 액세스가 가능하도록 하기 위해서 필요한 설정이예요
아래 설정으로 SELinux을 permissive로 변경해야하고

 

 

setenforce 0

리부팅시 다시 원복되기 때문에 아래 명령을 통해서 영구적으로 변경 해야되요

sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

 

아래 명령어를 실행해서 Current mode:permissive 내용 확인

set satus

 

3-1-2) 방화벽 해제

firewalld 비활성화

systemctl stop firewalld && systemctl disable firewalld

NetworkManager 비활성화

systemctl stop NetworkManager && systemctl disable NetworkManager

 

3-1-3) Swap 비활성화

Swap 사용에 관련해서는 많은 의견이 있어요.
>https://github.com/kubernetes/kubernetes/issues/53533
위 내용을 참고하셔서 swap 사용시의 고려해야할 점을 확인하시고 일단 여기선 사용하지 않도록 설정할께요.

 

swapoff -a && sed -i '/ swap / s/^/#/' /etc/fstab

3-1-4) Iptables 커널 옵션 활성화

RHEL이나 CentOS7 사용시 iptables가 무시되서 트래픽이 잘못 라우팅되는 문제가 발생한다고 하여 아래 설정이 추가

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

3-1-5) 쿠버네티스 YUM Repository 설정

YUM에 대해서 좀더 상세한 내용이 궁금한 분께서는 아래 싸이트가 잘 정리되어 있는거 같아 링크 첨부했어요.
>https://www.lesstif.com/display/1STB/yum

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=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
EOF

3-1-6) Centos Update

yum update

3-1-7) Hosts 등록

계획된 master와 node의 호스트 이름과 IP를 모두 등록해주세요. 안하시면 추후 kubeadm init시 Host이름으로 IP를 찾을 수 없다고 에러가 나요.

cat << EOF >> /etc/hosts
192.168.75.114  k8s-master
192.168.75.121  k8s-node1
192.168.75.153   k8s-node2
192.168.75.57   k8s-node3
EOF

3-2) Install

3-2-1) Docker 설치

도커 설치 전에 필요한 패키지 설치

yum install -y yum-utils device-mapper-persistent-data lvm2

도커 설치를 위한 저장소 를 설정

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

 

도커 패키지 설치

yum update && yum install docker-ce-18.06.2.ce
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

mkdir -p /etc/systemd/system/docker.service.d

3-2-2) Kubernetes 설치

yum install -y --disableexcludes=kubernetes kubeadm-1.18.8-0.x86_64 kubectl-1.18.8-0.x86_64 kubelet-1.18.8-0.x86_64


4-1) Clone VM

4-1-1) 시스템 Shutdown

여기까지 만든 이미지를 복사해 놓기 위해서 Master를 잠시 Shutdown 시켜요.

shutdown now

4-1-2) VM 복사

VirtualBox UI를 통해 Master 선택 후 마우스 우클릭을 해서 [복제] 버튼 클릭

1. 이름 : k8s-node1, MAC 주소정책 : 모든 네트워크 어댑터의 새 MAC 주소 생성
2. 복제방식 : 완전한 복제

node2도 반복

 

 

4-2) Config Node

4-2-1) Network 변경하기

VirtualBox UI에서 k8s-node1을 시작 시키면 뜨는 Console 창을 통해 아래 명령어 입력
Host의 Ip Address를 변경하기 위해 아래 명령어로 설정을 열고

vi /etc/sysconfig/network-scripts/ifcfg-eth0

IPADDR= 부분을 해당 Node의 IP (192.168.0.31)로 변경해주세요

...
DEVICE="etho0"
ONBOOT="yes"
IPADDR="192.168.0.31"
...

그리고 아래 명령어로 네트워크 재시작

systemctl restart network

4-2-2) Host Name 변경

해당 Node의 Host 이름을 변경해주세요

 

hostnamectl set-hostname k8s-node1

이와 같은 방식으로 k8s-node2(192.168.0.32) 도 설정합니다.

 

 


5-1) Master

5-1-1) 도커 및 쿠버네티스 실행

도커 실행

systemctl daemon-reload
systemctl enable --now docker

아래 명령어를 입력하면 image를 다운받는 내용이 나오면서 중간에 Hello for Docker! 가 보이면 설치 확인되면 설치가 잘 된거예요.

docker run hello-world

쿠버네티스 실행

systemctl enable --now kubelet

실행 화면

[root@k8s-master ~]# systemctl daemon-reload
[root@k8s-master ~]#
[root@k8s-master ~]# systemctl enable --now docker
[root@k8s-master ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

[root@k8s-master ~]# systemctl enable --now kubelet
[root@k8s-master ~]# kubeadm init --pod-network-cidr=10.96.0.0/12
I0411 11:57:07.602972    2901 version.go:252] remote version is much newer: v1.21.0; falling back to: stable-1.18
W0411 11:57:08.174479    2901 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
[init] Using Kubernetes version: v1.18.17
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.35.248]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [k8s-master localhost] and IPs [192.168.35.248 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [k8s-master localhost] and IPs [192.168.35.248 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
W0411 11:57:49.337109    2901 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[control-plane] Creating static Pod manifest for "kube-scheduler"
W0411 11:57:49.338474    2901 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 24.005201 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.18" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node k8s-master as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node k8s-master as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: msz6rk.37t654ytf9oxox8o
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

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.35.248:6443 --token msz6rk.37t654ytf9oxox8o \
    --discovery-token-ca-cert-hash sha256:adf3bb451c1097f0aca6230f72518a0965561e6aaca4029a5c410162a9584a18
[root@k8s-master ~]#

 

5-1-2) 쿠버네티스 초기화 명령 실행

kubeadm init 명령관련 해서 상세 내용이 궁금하신 분은 아래 싸이트 참고하세요. >https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/
pod-network-cidr 를 설정하면 Pod의 IP가 자동으로 생성될때 해당 network으로 생성되요


service-cidr 를 설정하면 Service의 IP가 자동으로 생성될때 해당 대역으로 생성되요 Default: 10.96.0.0/12


kubeadm init --pod-network-cidr=10.96.0.0/12

실행 후 [Your Kubernetes master has initialized successfully!] 문구를 확인하고 아래 내용 복사해서 별도로 저장해 둡니다.

kubeadm join 192.168.0.30:6443 –token ki4szr.t3wondaclij6d1a3
–discovery-token-ca-cert-hash sha256:2370f0451342c6e4bd0d38f6c2511bda5c50374c85e9c09da28e12dd666d5987

 

 

5-1-3) 환경변수 설정

root 계정을 이용해서 kubectl을 실행하기 위한 환경 변수를 설정

 

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

5-1-4) Kubectl 자동완성 기능 설치

kubectl 사용시 [tab] 버튼을 이용해서 다음에 올 명령어 리스트를 조회 할 수 있어요.
명령 실행 후 바로 적용이 안되기 때문에 접속을 끊고 다시 연결 후에 사용 가능합니다.

yum install bash-completion -y
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

 


5-2) Node

5-2-1) 도커 및 쿠버네티스 실행

도커 실행

 

systemctl daemon-reload
systemctl enable --now docker

쿠버네티스 실행

systemctl enable --now kubelet

 

5-2-2) Node 연결

Master Init 후 복사 했었던 내용 붙여넣기

 

kubeadm join 192.168.75.114:6443 --token jzptrq.zn6tkpeahf9p8xx7 \
    --discovery-token-ca-cert-hash sha256:24cdb731e7deddd9ba3e42dfde383f9d05c7aa7dac29100a11e27f639ee1308b

5-2-3) Node 연결 확인

Master 서버에 접속해서 아래 명령 입력 후 추가된 Node가 보이는지 확인 (Status는 NotReady)

 

kubectl get nodes

아래 상태 보시면 Notready => Ready 로 시간이 조금 걸립니다. (참고로 tailf /var/log/messages 터미널창 하나 더 띄워서 상태 확인하시길 바랍니다.

 


6-1) Networking

6-1-1) Calico 설치 vs Weave network 설치해보기

(개인적으로 calico 보단 Weave Test 해보니 더 잘됐습니다.)

또한 

Kubernetes Cluster Networking에는 많은 Plugin들이 있는데 그중 Calico 설치에 대한 내용 입니다.
>https://docs.projectcalico.org/v3.9/getting-started/kubernetes/
Calico는 기본 192.168.0.0/16 대역으로 설치가 되는데, 그럼 실제 VM이 사용하고 있는 대역대와 겹치기 때문에 수정을 해서 설치해야 할 경우

 

1) calico network 
curl -O https://docs.projectcalico.org/v3.9/manifests/calico.yaml
sed s/192.168.0.0\\/16/10.96.0.0\\/12/g -i calico.yaml
kubectl apply -f calico.yaml

2) weave network 
pod network를 생성
export kubever=$(kubectl version | base64 | tr -d '\n')
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$kubever"

 

calico와 coredns 관련 Pod의 Status가 Running인지 확인

kubectl get pods --all-namespaces

6-2) Dashboard

6-2-1) Dashboard 설치

해당 설정은 교육목적으로 권한 설정을 모두 해제하는 방법이기 때문에 프로젝트에서 사용하실때는 이점 유의바래요
>https://github.com/kubernetes/dashboard

 

kubectl apply -f https://kubetm.github.io/documents/appendix/kubetm-dashboard-v1.10.1.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recomme  

 

 

6-2-2) 백그라운드로 Proxy 띄우기

--address에 자신의 Host IP 입력

nohup kubectl proxy --port=8001 --address=192.168.75.114 --accept-hosts='^*$' >/dev/null 2>&1 &
  • 만약 Master 노드가 Restart 됐을 경우 이 부분은 다시 실행해 줘야 합니다.

6-2-3) 접속 URL

http://192.168.75.114:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/.

6-2-4) 언어 설정변경

Chrome 설정 > 언어 > 언어(한국어) > 원하는 언어를 위로 추가

 

마무리... 

자 기본적인 셋팅이 마무리 되었네요 

 


7-1-1)  기타내용(트러블슈팅)

1) 도커최신판 에러 정리 
vi /usr/lib/systemd/system/docker.service 
--exec-opt native.cgroupdriver=systemd
 
 
2) x509 발생시처리
export KUBECONFIG=/etc/kubernetes/admin.conf
 

3) docker 및 kubelet 재시작
systemctl enable kubelet && systemctl restart kubelet 
systemctl enable docker && systemctl start docker


4)클러스터 정보 확인
kubectl cluster-info

5) 시작 
kubeadm init --pod-network-cidr=10.96.0.0/12

6) 네트웍 시작
export kubever=$(kubectl version | base64 | tr -d '\n')
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$kubever"

 

7-1-2)  기본명령어 익히기

참고 URL 바로가기


#k8s-node1 워크노트에 key=worker 라는 label 추가해보기
kubectl label nodes k8s-node1 key=worker
k8s-node1  Ready  <none> 22m v1.18.6   .,key=worker,kubernetes.io/ #<-key=worker 추가확인

#k8s-node1 워크노트에 label 삭제해보기
kubectl label nodes k8s-node1 key-

#kubectl get nodes --show-labels # 조회해보기

# dev라는 dev namespace 생성해보기
kubectl create namespace dev                  # dev 라는 네임스페이스 생성

#dev namespace pod 생성해보기
kubectl apply -f  hello-node.yaml --namespace=dev
-->NAMESPACE NAME         READY   STATUS     RESTARTS   AGE
   dev       hello-node   1/1     Running    0          5m28s

#dev namespace 있는 hello-node pod 삭제해보기 
kubect delete pod,service hello-node --namespace=dev

# 기본 출력을 위한 Get 커맨드
kubectl create namespace dev                  # dev 라는 네임스페이스 생성
kubectl get services                          # 네임스페이스 목록 조회
kubectl get pods --all-namespaces             # 모든 네임스페이스파드의 목록 조회
kubectl get pods -o wide                      # 네임스페이스 내 모든 파드의 상세 목록 조회
kubectl get deployment my-dep                 # 특정 디플로이먼트의 목록 조회
kubectl get pods                              # 네임스페이스 내 모든 파드의 목록 조회
kubectl get pod my-pod -o yaml                # 파드의 YAML 조회

# 상세 출력을 위한 Describe 커맨드
kubectl describe nodes my-node
kubectl describe pods my-pod

# Name으로 정렬된 서비스의 목록 조회
kubectl get services --sort-by=.metadata.name

# 재시작 횟수로 정렬된 파드의 목록 조회
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

# PersistentVolumes을 용량별로 정렬해서 조회
kubectl get pv --sort-by=.spec.capacity.storage

# app=cassandra 레이블을 가진 모든 파드의 레이블 버전 조회
kubectl get pods --selector=app=cassandra -o \
  jsonpath='{.items[*].metadata.labels.version}'

# 모든 워커 노드 조회 (셀렉터를 사용하여 'node-role.kubernetes.io/master'
# 으로 명명된 라벨의 결과를 제외)
kubectl get node --selector='!node-role.kubernetes.io/master'

# 네임스페이스의 모든 실행 중인 파드를 조회
kubectl get pods --field-selector=status.phase=Running

# 모든 노드의 외부IP를 조회
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'

# 특정 RC에 속해있는 파드 이름의 목록 조회
# "jq" 커맨드는 jsonpath를 사용하는 매우 복잡한 변환에 유용하다. https://stedolan.github.io/jq/ 에서 확인할 수 있다.
sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})

# 모든 파드(또는 레이블을 지원하는 다른 쿠버네티스 오브젝트)의 레이블 조회
kubectl get pods --show-labels

# 어떤 노드가 준비됐는지 확인
JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
 && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"

# 파드에 의해 현재 사용되고 있는 모든 시크릿 목록 조회
kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq

# 모든 파드의 초기화 컨테이너(initContainer)의 컨테이너ID 목록 조회
# 초기화 컨테이너(initContainer)를 제거하지 않고 정지된 모든 컨테이너를 정리할 때 유용하다.
kubectl get pods --all-namespaces -o jsonpath='{range .items[*].status.initContainerStatuses[*]}{.containerID}{"\n"}{end}' | cut -d/ -f3

# 타임스탬프로 정렬된 이벤트 목록 조회
kubectl get events --sort-by=.metadata.creationTimestamp

# 매니페스트가 적용된 경우 클러스터의 현재 상태와 클러스터의 상태를 비교한다.
kubectl diff -f ./my-manifest.yaml


7-1-3) 리소스 삭제해보기

kubectl delete -f ./pod.json                                              # pod.json에 지정된 유형 및 이름을 사용하여 파드 삭제
kubectl delete pod,service baz foo                                        # "baz", "foo"와 동일한 이름을 가진 파드와 서비스 삭제
kubectl delete pods,services -l name=myLabel                              # name=myLabel 라벨을 가진 파드와 서비스 삭제
kubectl delete pods,services -l name=myLabel --include-uninitialized      # 초기화되지 않은 것을 포함하여, name=myLabel 라벨을 가진 파드와 서비스 삭제
kubectl -n my-ns delete pod,svc --all                                      # 초기화되지 않은 것을 포함하여, my-ns 네임스페이스 내 모든 파드와 서비스 삭제
# awk pattern1 또는 pattern2에 매칭되는 모든 파드 삭제
kubectl get pods  -n mynamespace --no-headers=true | awk '/pattern1|pattern2/{print $1}' | xargs  kubectl delete -n mynamespace pod

7-1-4) 자주 사용하는 명령어 

1) pod 생성
kubectl에는 create와 appy가 있는데, create -f 로 하면 이후에 apply를 통해 다시 반영할 수 없다. 
그러나 처음부터 apply -f 로 하면 계속 apply할 수 있다는 차이점이 있다.

2) kubectl create -f nginx-deployment.yaml
pod 상태를 조회한다.

3) kubectl get pods
NAME                                READY     STATUS    RESTARTS   AGE
nginx-deployment-7fc9b7bd96-7nmtx   0/1       Pending   0          6m
nginx-deployment-7fc9b7bd96-9q6w2   0/1       Pending   0          6m

4) pod 삭제
$ kubectl delete -f nginx-deployment.yaml
deployment.extensions "nginx-deployment" deleted
pod 상태를 조회한다.

5) 조회
$ kubectl get pods
No resources found.

7-1-5) log 확인해보기

kubectl logs my-pod                                 # 파드 로그(stdout) 덤프
kubectl logs -l name=myLabel                        # name이 myLabel인 파드 로그 덤프 (stdout)
kubectl logs my-pod --previous                      # 컨테이너의 이전 인스턴스 생성에 대한 파드 로그(stdout) 덤프
kubectl logs my-pod -c my-container                 # 파드 로그(stdout, 멀티-컨테이너 경우) 덤프
kubectl logs -l name=myLabel -c my-container        # name이 myLabel인 파드 로그 덤프 (stdout)
kubectl logs my-pod -c my-container --previous      # 컨테이너의 이전 인스턴스 생성에 대한 파드 로그(stdout, 멀티-컨테이너 경우) 덤프
kubectl logs -f my-pod                              # 실시간 스트림 파드 로그(stdout)
kubectl logs -f my-pod -c my-container              # 실시간 스트림 파드 로그(stdout, 멀티-컨테이너 경우)
kubectl logs -f -l name=myLabel --all-containers    # name이 myLabel인 모든 파드의 로그 스트리밍 (stdout)
kubectl run -i --tty busybox --image=busybox -- sh  # 대화형 셸로 파드를 실행
kubectl run nginx --image=nginx -n
mynamespace                                         # 특정 네임스페이스에서 nginx 파드 실행
kubectl run nginx --image=nginx                     # nginx 파드를 실행하고 해당 스펙을 pod.yaml 파일에 기록
--dry-run=client -o yaml > pod.yaml

kubectl attach my-pod -i                            # 실행중인 컨테이너에 연결
kubectl port-forward my-pod 5000:6000               # 로컬 머신의 5000번 포트를 리스닝하고, my-pod의 6000번 포트로 전달
kubectl exec my-pod -- ls /                         # 기존 파드에서 명령 실행(한 개 컨테이너 경우)
kubectl exec my-pod -c my-container -- ls /         # 기존 파드에서 명령 실행(멀티-컨테이너 경우)
kubectl top pod POD_NAME --containers               # 특정 파드와 해당 컨테이너에 대한 메트릭 표시

7-1-6)  cluster 상태 확인 

kubectl cordon my-node                                                # my-node를 스케줄링할 수 없도록 표기
kubectl drain my-node                                                 # 유지 보수를 위해서 my-node를 준비 상태로 비움
kubectl uncordon my-node                                              # my-node를 스케줄링할 수 있도록 표기
kubectl top node my-node                                              # 주어진 노드에 대한 메트릭 표시
kubectl cluster-info                                                  # 마스터 및 서비스의 주소 표시
kubectl cluster-info dump                                             # 현재 클러스터 상태를 stdout으로 덤프
kubectl cluster-info dump --output-directory=/path/to/cluster-state   # 현재 클러스터 상태를 /path/to/cluster-state으로 덤프

# key와 effect가 있는 테인트(taint)가 이미 존재하면, 그 값이 지정된 대로 대체된다.
kubectl taint nodes foo dedicated=special-user:NoSchedule

리소스 타입 확인 하기
#kubectl api-resources
kubectl api-resources --namespaced=true      # 네임스페이스를 가지는 모든 리소스
kubectl api-resources --namespaced=false     # 네임스페이스를 가지지 않는 모든 리소스
kubectl api-resources -o name                # 모든 리소스의 단순한 (리소스 이름 만) 출력
kubectl api-resources -o wide                # 모든 리소스의 확장된 ("wide"로 알려진) 출력
kubectl api-resources --verbs=list,get       # "list"와 "get"의 요청 동사를 지원하는 모든 리소스 출력
kubectl api-resources --api-group=extensions # "extensions" API 그룹의 모든 리소스

7-1-7)  image 확인해보기

 

# 클러스터에서 실행 중인 모든 이미지
kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image'

 # "k8s.gcr.io/coredns:1.6.2" 를 제외한 모든 이미지
kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="k8s.gcr.io/coredns:1.6.2")].image'

# 이름에 관계없이 메타데이터 아래의 모든 필드
kubectl get pods -A -o=custom-columns='DATA:metadata.*'

7-1-8)  Kubectl 출력 로그 상세 레벨(verbosity)과 디버깅 확인

--v=0	일반적으로 클러스터 운영자(operator)에게 항상 보여지게 하기에는 유용함.
--v=1	자세한 정보를 원하지 않는 경우, 적절한 기본 로그 수준.
--v=2	 시스템에서 권장되는 기본 로그 수준이다.	
--v=3	변경 사항에 대한 확장 정보.	
--v=4	디버그 수준 상세화.	
--v=6	요청한 리소스를 표시.	
--v=7	HTTP 요청 헤더를 표시.	
--v=8	HTTP 요청 내용을 표시.	
--v=9	내용을 잘라 내지 않고 HTTP 요청 내용을 표시.

 

7-1-9) deployment 및 replicas 테스트 [1.14.2  vs 1.12.1 ]

디플로이먼트 생성
다음은 디플로이먼트의 예시이다. 예시는 3개의 nginx 파드를 불러오기 위한 레플리카셋을 생성한다.
kubectl apply nginx-deployment.yaml -f namespace=dev 

vi nginx-deployment.yaml 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.12.1
        ports:
        - containerPort: 80

도커 깔끔히 삭제하기

1탄!! 쿠버네티스 구성준비!

2탄!! 쿠버네티스 설치 준비[마스터노드]

3탄!! 쿠버네티스 WORKER NODE 환경 구성

4탄 NFS 설정입니다.

5탄!! helm install 방법

6탄 !! 도커 컴포즈 VS 쿠버네티스 컴포즈

7탄!! 쿠버네티스에 pod 올리자! pod? 뭐에요?

부록!! 쿠버네티스 장애 처리5탄

댓글