[Retry, k8s] 02. 워크로드 API - 파드(Pod)

Date:     Updated:

카테고리:

태그:

[Retry, k8s] 02. 워크로드 API - 파드(Pod)



🔔 파드(Pod)

쿠버네티스에서 배포할 수 있는 가장 작은 단위로 파드는 한 개 이상의 컨테이너와 스토리지, 네트워크 속성으로 구성되며, 같은 파드에 포함된 컨테이너끼리는 네트워크적으로 격리되어 있지 않고 IP 주소를 공유한다. (즉, 컨테이너가 두 개 들어 있는 파드를 생성한 경우, 두 컨테이너는 같은 IP 주소를 가진다 따라서 파드 내부의 컨테이너는 서로 localhost로 통신할 수 있다.)


📜 파드 생성

cat <<EOF > sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
    - name: nginx-container
      image: nginx:1.16
EOF
# 파드 생성
$ kubectl apply -f sample-pod.yaml
pod/sample-pod created

# 파드 목록 표시
$ kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
sample-pod   1/1     Running   0          14s

# 파드 상세 정보 표시
$ kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP          NODE         NOMINATED NODE   READINESS GATES
sample-pod   1/1     Running   0          30s   10.44.0.1   k8s-node01   <none>           <none>


📜 두 개의 컨테이너를 포함한 파드 생성

【두 개의 컨테이너를 가진 파드 예제】

cat <<EOF > sample-2pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-2pod
spec:
  containers:
    - name: nginx-container
      image: nginx:1.16
    - name: redis-container
      image: redis:3.2
EOF
# 두 개의 컨테이너를 포함한 파드 생성
$ kubectl apply -f sample-2pod.yaml
pod/sample-2pod created

# 두 개의 컨테이너를 포함한 파드 확인
$ kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
sample-2pod   2/2     Running   0          14s

【같은 포틀를 사용하는 두 개의 컨테이너를 가진 파드 예제】

cat<<EOF > sample-2pod-fail.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-2pod-fail
spec:
  containers:
    - name: nginx-container-112
      image: nginx:1.16
    - name: nginx-container-113
      image: nginx:1.17
EOF
# 포트 충돌이 있는 파드 생성
$ kubectl apply -f sample-2pod-fail.yaml
pod/sample-2pod-fail created

# 파드 상태가 에러임을 확인
$ kubectl get pods
NAME               READY   STATUS    RESTARTS   AGE
sample-2pod-fail   1/2     Error     0          14s

# 파드 로그 확인
$ kubectl logs sample-2pod-fail -c nginx-container-113
2023/03/14 10:01:49 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)


📜 컨테이너에 접근 & 명령어 실행

【컨테이너 접근】

# 컨테이너에서 /bin/bash 실행
$ kubectl exec -it sample-pod -- /bin/bash
root@sample-pod:/#

# 확인 작업에 필요한 패키지 설치
root@sample-pod:/# apt update && apt -y install iproute2 procps

# 컨테이너 내부에서 IP 주소 확인
root@sample-pod:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue state UP group default
    link/ether ee:8b:41:e9:e3:f2 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.44.0.1/12 brd 10.47.255.255 scope global eth0
       valid_lft forever preferred_lft forever

# 컨테이너 내부에서 바인드(listen)하는 포트 확인
root@sample-pod:/# root@sample-pod:/# ss -napt
State             Recv-Q          Send-Q             Local Address:Port             Peer Address:Port
LISTEN            0               511                0.0.0.0:80                     0.0.0.0:*             users:(("nginx",pid=1,fd=6))
TIME-WAIT         0               0                  10.44.0.1:45618                151.101.110.132:80
TIME-WAIT         0               0                  10.44.0.1:35726                151.101.66.132:80

# 컨테이너 내부에서 프로세스 확인
root@sample-pod:/# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.1  10628  5492 ?        Ss   09:52   0:00 nginx: master process nginx -g daemon off;
nginx          6  0.0  0.0  11132  2676 ?        S    09:52   0:00 nginx: worker process
root           7  0.0  0.1   3872  3276 pts/0    Ss   10:07   0:00 /bin/bash
root         462  0.0  0.0   7644  2756 pts/0    R+   10:11   0:00 ps aux

【컨테이너에서 명령 실행】

# 컨테이너에서 ls 명령 실행
$ kubectl exec -it sample-pod -- /bin/ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

# 다수의 컨테이너를 포함한 파드의 경우, 특정 컨테이너 지정
$ kubectl exec -it sample-2pod -c nginx-container -- /bin/ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

# 옵션을 포함한 명령어 실행
$ kubectl exec -it sample-pod -- /bin/ls --all --classify
./   .dockerenv*  boot/  etc/   lib/    media/  opt/   root/  sbin/  sys/  usr/
../  bin/         dev/   home/  lib64/  mnt/    proc/  run/   srv/   tmp/  var/

# 파이프 등 특정 문자열을 포함한 경우
$ kubectl exec -it sample-pod -- /bin/bash -c "ls -a --classify | grep lib"
lib/
lib64/


📜 호스트의 네트워크 구성을 사용한 파드 기동

hostNetwork를 사용한 파드는 쿠버네티스 노드의 IP 주소를 사용하는 관계로 포트번호 충돌을 방지하기 위해 기본적으로 사용되지는 않는다.

cat << EOF > sample-hostnetwork.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-hostnetwork
spec:
  hostNetwork: true
  containers:
    - name: nginx-container
      image: nginx:1.16
EOF
# 파드의 IP 주소 확인
$ kubectl get pod sample-hostnetwork -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP                NODE         NOMINATED NODE   READINESS GATES
sample-hostnetwork   1/1     Running   0          9s    192.168.219.101   k8s-node01   <none>           <none>

# 파드가 기동 중인 노드의 IP 주소 확인
$ kubectl get node -o wide
NAME           STATUS   ROLES           AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
k8s-master01   Ready    control-plane   25h   v1.26.2   192.168.219.10    <none>        Ubuntu 22.04.2 LTS   5.15.0-67-generic   docker://23.0.1
k8s-node01     Ready    <none>          25h   v1.26.2   192.168.219.101   <none>        Ubuntu 22.04.2 LTS   5.15.0-67-generic   docker://23.0.1
k8s-node02     Ready    <none>          25h   v1.26.2   192.168.219.102   <none>        Ubuntu 22.04.2 LTS   5.15.0-67-generic   docker://23.0.1

# 파드의 호스트명 확인
$ kubectl exec -it sample-hostnetwork -- hostname
k8s-node01

# 파드의 DNS 설정 확인
$ kubectl exec -it sample-hostnetwork -- cat /etc/resolv.conf
nameserver 168.126.63.1
nameserver 8.8.8.8


📜 파드 DNS 설정

【ClusterFirst(기본값)】 : 클러스터 내부 DNS에 질의하여 해석되지 않으면 업스트림에 질의함

cat <<EOF > sample-dnspolicy-clusterfirst.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-dnspolicy-clusterfirst
spec:
  dnsPolicy: ClusterFirst
  containers:
    - name: nginx-container
      image: nginx:1.16
EOF
# 컨테이너 내부의 DNS 설정 파일 /etc/resolv.conf를 표시
$ kubectl exec -it sample-dnspolicy-clusterfirst -- cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

# 클러스터 내부의 DNS Service에 할당된 IP 주소를 확인
root@k8s-master01:~/kube_test# kubectl get services -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   25h

【None】 : 파드 정의 내에서 정적으로 설정

cat <<EOF > sample-dnspolicy-none.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-dnspolicy-none
spec:
  dnsPolicy: None
  dnsConfig:
    nameservers:
    - 8.8.8.8
    - 8.8.4.4
    searches:
    - example.com
    options:
    - name: ndots
      value: "5"
  containers:
    - name: nginx-container
      image: nginx:1.16
EOF
# 컨테이너 내부의 DNS 설정 파일 /etc/resolv.conf를 표시
$ kubectl exec -it sample-dnspolicy-none -- cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
search example.com
options ndots:5

【Default】 : 파드가 기동하는 쿠버네티스 노드의 /etc/resolv.conf를 상속받는다.

cat <<EOF > sample-dnspolicy-default.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-dnspolicy-default
spec:
  dnsPolicy: Default
  containers:
    - name: nginx-container
      image: nginx:1.16
EOF
# 컨테이너 내부의 DNS 설정 파일 /etc/resolv.conf를 표시
$ kubectl exec -it sample-dnspolicy-default -- cat /etc/resolv.conf
nameserver 168.126.63.1
nameserver 8.8.8.8

【ClusterFirstWithHostNet】 : ClusterFirst의 동작과 같다(hostNetwork 사용 시 설정)

cat <<EOF > sample-dnspolicy-clusterfirstwithhostnet.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-dnspolicy-clusterfirstwithhostnet
spec:
  dnsPolicy: ClusterFirstWithHostNet
  hostNetwork: true
  containers:
    - name: nginx-container
      image: nginx:1.16
EOF
# 컨테이너 내부의 DNS 설정 파일 /etc/resolv.conf를 표시
$ kubectl exec -it sample-dnspolicy-clusterfirstwithhostnet -- cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5


📜 정적 호스트명 해석 설정(/etc/hosts)

cat <<EOF > sample-hostaliases.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-hostaliases
spec:
  containers:
    - name: nginx-container
      image: nginx:1.16
  hostAliases:
    - ip: 8.8.8.8
      hostnames:
        - google-dns
        - google-public-dns
EOF
$ kubectl exec -it sample-hostaliases -- cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.36.0.1       sample-hostaliases

# Entries added by HostAliases.
8.8.8.8 google-dns      google-public-dns


📜 작업 디렉터리 설정

cat <<EOF > sample-workingdir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-workingdir
spec:
  containers:
    - name: nginx-container
      image: nginx:1.16
      workingDir: /tmp
EOF
$ kubectl exec -it sample-pod -- pwd
/

$ kubectl exec -it sample-workingdir -- pwd
/tmp


KUBERNETES 카테고리 내 다른 글 보러가기

댓글 남기기