kubectl
kubectl apply
kubectl apply -f nginx.yamlkubectl apply 를 통해 이미 만들어진 Object 를 파악하며 부분적으로 설정이 수정된 경우 해당 부분만 적용하는 기능 역시 지원한다.
# Live object configuration
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion": "v1", ...}
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
status:
conditions:
- lastProbeTime: null
...kubectl apply 를 실행하면 쿠버네티스는 사용자가 작성한 YAML 파일과 K8s memory 에 저장된 Live object configuration 과 kubectl.kubernetes.io/last-applied-configuration 필드를 비교하여 변경된 사항만 부분적으로 확인하고 적용이 가능하다.
kubectl get -o=custom-columns
k get deployments.apps -n=admin2406 -o=json
k get deployments.apps -n=admin2406 -o=custom-columns=DEPLOYMENT:.metadata.name,CONTAINER_IMAGE:.spec.template.spec.containers[0].image,READY_REPLICAS:.status.readyReplicas,NAMESPACE:.metadata.namespace > /opt/admin2406_dataK8s Object 의 특정 정보를 취합해서 파일로 저장하고 싶을 때 custom-columns 옵션을 활용할 수 있다. json 옵션을 사용했을 때 출력되는 계층을 따라 특정 정보에 접근할 수 있다.
kubectl logs
kubectl logs -l app=log-lab --prefix--prefix 옵션으로 로그 앞에 어느 파드의 어느 컨테이너에서 생성된 로그인지 확인 가능
kubectl logs -l app=log-lab --prefix --since=10m--since 옵션으로 최근 시간 내에 생성된 로그만 확인 가능
kubectl logs -l app=log-lab --prefix --since=10m --tail=100--tail 옵션으로 최근 로그 갯수 제한 가능
Some useful grep
kubectl logs -l app=log-lab --prefix --since=10m --tail=100 | grep -iE 'error|warn'grep -E 로 여러 키워드를 매칭해서 필터링 가능, -i 옵션까지 추가하면 대소문자 구분하지 않고 확인
kubectl logs -l app=log-lab --prefix --since=10m --tail=100 | grep -F "connection refused"grep -F 로 문자열 검색
kubectl logs -l app=log-lab --prefix --since=10m --tail=100 | grep -w "ERROR"grep -w 로 단어 단위로 매칭
kubectl logs -l app=log-lab --prefix --since=10m --tail=100 | grep -C2 'error'grep -C2 (Context 의 C) 로 매칭된 로그 앞 뒤로 2줄을 추가로 보여줄 수 있다
kubectl logs -l app=log-lab --prefix --since=10m --tail=100 | grep -A2 'error'grep -A2 (After 의 A) 로 매칭된 로그 뒤 2줄을 추가로 보여줄 수 있다
kubectl logs -l app=log-lab --prefix --since=10m --tail=100 | grep -B2 'error'grep -B2 (Before 의 B) 로 매칭된 로그 전 2줄을 추가로 보여줄 수 있다
kubectl logs -l app=log-lab --prefix -f | grep -E 'ERROR|WARN'-f 로 실시간 로그 확인, grep 조합으로 원하는 로그만 추출 가능
kubectl alias 및 자동완성 설정
echo '[[ $commands[kubectl] ]] && source <(kubectl completion zsh)' >> ~/.zshrc
echo 'alias k=kubectl' >> ~/.zshrc
echo 'compdef __start_kubectl k' >> ~/.zshrc
source ~/.zshrcLogging and Monitoring
Monitoring Cluster Components
K8s 를 운영할 때 모니터링 할 수 있는 지표는 Node 개수, CPU, Memory, Network, Disk 등이 있다. 이런 지표들은 kubelet 의 내장 컴포넌트 중 하나인 cAdvisor 를 통해 제공된다. K8s 는 기본적으로 제공하는 모니터링 툴이 없기 때문에 Prometheus, ELK, Datadog, Dynatrace 등 3rd Party 솔루션을 통해 K8s Cluster 를 모니터링 할 수 있다.
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl top node
kubectl top podMetric Server Pod 를 Cluster 에 배포한 뒤 위 명령어들을 통해 지표를 확인할 수 있다.
Managing Application Logs
docker logs -f {container-name}Docker Container 로 Application 을 실행했을 때 위 명령어로 Application Log 를 확인할 수 있는 것 처럼,
kubectl logs -f {pod-name} {container-name}위 명령어로 Pod 내 특정 Container 의 Log 를 확인할 수 있다.
Application Failure
curl http://web-service-ip:node-portApplication 에 접속할 수 없는 경우 아래와 같은 사항들을 진단해볼 수 있다.
Check Service Status
kubectl describe service web-service먼저 위 명령어를 통해 Selector 와 Endpoints 부분을 확인하여 Service 가 Pod 을 잘 찾아냈는지 진단한 후 만약 이슈가 있다면 Pod 의 metadata.labels.name 과 spec.containers.ports.containerPort 를 확인해 고쳐주도록 하자.
Check Pod
kubectl get pod
kubectl describe pod web
kubectl logs web -f --previousPod 의 재시작 상태와 log 들을 확인하여 문제를 찾아보자.
Check Dependent Service & Pod
위까지 문제가 없다면 종속성 있는 Service 와 Pod 를 위와 같은 방법으로 진단해보자.
Control Plane Failure
kubectl get nodes
kubectl get pods
kubectl get pods -n kube-system먼저 K8s Cluster 의 Node 와 Pod 들의 상태를 확인한 후, Control Plane Pod 들이 정상적으로 작동하는지 확인한다.
service kube-apiserver status
service kube-controller-manager status
service kube-scheduler status
service kubelet status
service kube-proxy status만약 kubeadm 으로 구축하지 않아 service 형태로 실행중인 경우 위와 같은 명령어로 상태를 확인할 수 있다.
kubectl logs kube-apiserver-master -n kube-system
sudo journalctl -u kube-apiserver이후 각 Component 들의 Log 를 확인해보자.
/etc/kubernetes/manifests/kubeadm 을 사용해 Cluster 를 구축한 경우 위 경로에서 조치가 필요한 Component 를 수정해주자.
Worker Node Failure
kubectl get nodes
kubectl describe node worker-1위 명령어들로 Node 의 상태를 확인한 뒤,
top
df -hCPU 와 메모리 사용량을 확인하고,
service kubelet status
sudo journalctl -u kubeletkubelet 의 상태를 확인하고,
service kubelet startkubelet 을 재시작하거나,
cat /etc/kubernetes/kubelet.confkubelet 설정을 확인해보자.
openssl x509 -in /var/lib/kubelet/worker-1.crt -textCA 의 Issuer, Validity, Subject 등을 확인해보자.
Network Troubleshooting
Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "c117e7be807116764889d820a073a0054630776881ddb92dfc46c2cbd174ce4e": plugin type="weave-net" name="weave" failed (add): unable to allocate IP address: Post "http://127.0.0.1:6784/ip/c117e7be807116764889d820a073a0054630776881ddb92dfc46c2cbd174ce4e": dial tcp 127.0.0.1:6784: connect: connection refusedCNI Plugin 이 설치되어있지 않은 경우 위와 같은 에러를 확인할 수 있다.
curl -L https://github.com/weaveworks/weave/releases/download/latest_release/weave-daemonset-k8s-1.11.yaml | kubectl apply -f설치해주자.
K9s
K9s 는 터미널 환경에서 실행되는 TUI, Text-based User Interface 도구이다.
brew install k9s설치 후 k9s 를 입력하면 현재 kubectl 컨텍스트에 설정된 클러스터 상태를 확인할 수 있다.
핵심 기능
:pods,:deploy,:svc등의 명령어로 리소스 및 네임스페이스를 빠르게 이동할 수 있다.l: Pod 로그 확인s: 컨테이너 쉘 접속d: 리소스 describe
Node Rolling 소요시간 확인
kubectl get nodes -l eks.amazonaws.com/nodegroup=${NODE_GROUP_NAME} -o json | jq -r '
.items[]
| (.status.conditions[] | select(.type=="Ready" and .status=="True") | .lastTransitionTime) as $ready
| select($ready != null)
| (.metadata.creationTimestamp | fromdateiso8601) as $c
| ($ready | fromdateiso8601) as $r
| [
.metadata.name,
(.spec.providerID | split("/")[-1]),
.metadata.annotations["alpha.kubernetes.io/provided-node-ip"],
.metadata.labels["topology.kubernetes.io/zone"],
.metadata.creationTimestamp[0:19],
$ready[0:19],
"\($r - $c)s"
] | @tsv
' | sort -k5 | column -t -s $'\t'현재 노드 Create, Ready 시간 및 AZ 확인
aws autoscaling describe-scaling-activities \
--auto-scaling-group-name "$ASG" \
--region ap-east-1 | jq -r '
["INSTANCE","ACTION","AZ","START(UTC)","END(UTC)","DUR","STATUS","PROG"],
(.Activities
| sort_by(.StartTime) | .[]
| (if (.Description | test("Launching")) then "Launch"
elif (.Description | test("Terminating")) then "Terminate"
else "?" end) as $action
| ((.Description | capture("(?<i>i-[0-9a-f]+)").i) // "-") as $iid
| ((.Details? | if . then (. | fromjson | .["Availability Zone"]) else null end) // "-") as $az
| ((.StartTime[0:19] + "Z") | fromdateiso8601) as $s
| (if .EndTime then (.EndTime[0:19] + "Z") | fromdateiso8601 else null end) as $e
| [ $iid,
$action,
$az,
.StartTime[0:19],
(.EndTime[0:19] // "-"),
(if $e then "\($e - $s)s" else "running" end),
.StatusCode,
(.Progress | tostring)
]
) | @tsv
' | column -t -s $'\t'노드 Launch/Terminate 시간 trace
- Node Group Update Config 에서
max_unavailable=1(기본값) 일 경우, 새로운 노드가 하나씩 Launch 되고 기존 노드가 하나씩 Terminate 된다. - 즉, Launch 시간, Terminate 시간 차이가 기존 노드 drain duration 이 된다.
Pod Eviction Failure 429 발생 시 기본적으로 1분마다 eviction retry 를 실행한다.
- Node Group
force_update_version=True일 경우, 19번의 retry 실패 후 Node drain timeout 으로 노드가 강제종료된다. - 즉, 기존 노드 drain 은 3-5분 걸리는데 비해 약 20분 가량까지 노드 drain 이 지연되어 Rolling Update 시간이 늘어날 수 있다.