ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 09. 쿠버네티스 핵심 개념 (4)
    개발 스터디/데브옵스(DevOps)를 위한 쿠버네티스 마스터 2021. 8. 5. 07:28
    반응형

    이 문서는 인프런 강의 "데브옵스를 위한 쿠버네티스 마스터"을 듣고 작성되었습니다. 최대한 요약해서 강의 내용을 최소로 하는데 목표를 두고 있어서, 더 친절하고 정확한 내용을 원하신다면 강의를 구매하시는 것을 추천드립니다. => 강의 링크

    쿠버네티스 네트워크 (1) Pod - Container 통신

    일반적으로 컨테이너 간 통신을 위한 도커 네트워크 구조는 다음과 같다.

    출처: 인프런 강의 Devops를 위한 쿠버네티스 마스터 

    각 컨테이너는 veth라는 가상의 네트워크 인터페이스를 통해서 통신을 한다. 반면에, 쿠버네티스에서 컨테이너 간 통신 구조는 살짝 다르다.

    출처: 인프런 강의 Devops를 위한 쿠버네티스 마스터 

    하나의 veth 가상 네트워크 인터페이스에 여러 컨테이너가 연결되어 있다. 그리고 pause라는 녀석이 옆에 붙어서 이들 통신을 지원해준다. VM에 다음을 입력해보자.

    $ sudo docker ps | grep pause
    7cec7bbcfd41   k8s.gcr.io/pause:3.4.1   "/pause"                 3 minutes ago   Up 3 minutes             k8s_POD_weave-net-qr5v6_kube-system_52d850d7-c8e4-4b75-93c5-2dd97237b818_8
    55878c1c9fbe   k8s.gcr.io/pause:3.4.1   "/pause"                 3 minutes ago   Up 3 minutes             k8s_POD_kube-proxy-hvpz5_kube-system_676e7f6d-825c-43b6-92ea-a1b891092eb4_8
    e149257efdfe   k8s.gcr.io/pause:3.4.1   "/pause"                 3 minutes ago   Up 3 minutes             k8s_POD_kube-controller-manager-master_kube-system_683f32b0119799727621446455e8d131_8
    ee74476df7aa   k8s.gcr.io/pause:3.4.1   "/pause"                 3 minutes ago   Up 3 minutes             k8s_POD_kube-apiserver-master_kube-system_4497338b493c596567d3c3eb86085559_8
    5b7c5e79e66a   k8s.gcr.io/pause:3.4.1   "/pause"                 3 minutes ago   Up 3 minutes             k8s_POD_etcd-master_kube-system_d0eb798391c9389c9721c4631c28dc9a_8
    3ec62d452070   k8s.gcr.io/pause:3.4.1   "/pause"                 3 minutes ago   Up 3 minutes             k8s_POD_kube-scheduler-master_kube-system_35ae2ec46407146c0fe6281c2c3292ce_8

     

    수 많은 pause가 이미 떠 있는 것을 알 수 있다. 이 puase들은 kube-apiserver, kube-scheduler-master 등의 컴포넌트에 붙어서 네트워크 통신을 지원한다. 마스터 노드에 있는 pod들을 한 번 확인해보자.

    $ kubectl get pod --all-namespaces -o wide | grep master
    kube-system   etcd-master                      1/1     Running   8          25d   10.0.2.15   master   <none>           <none>
    kube-system   kube-apiserver-master            1/1     Running   8          25d   10.0.2.15   master   <none>           <none>
    kube-system   kube-controller-manager-master   1/1     Running   8          25d   10.0.2.15   master   <none>           <none>
    kube-system   kube-proxy-hvpz5                 1/1     Running   8          25d   10.0.2.15   master   <none>           <none>
    kube-system   kube-scheduler-master            1/1     Running   8          25d   10.0.2.15   master   <none>           <none>
    kube-system   weave-net-qr5v6                  2/2     Running   17         25d   10.0.2.15   master   <none>           <none>

     

    이 중 apiserver 관련만 추출해서 보자.

    $ sudo docker ps | grep "apiserver"
    58bc8ecf485a   106ff58d4308             "kube-apiserver --ad…"   9 minutes ago   Up 9 minutes                           k8s_kube-apiserver_kube-apiserver-master_kube-system_4497338b493c596567d3c3eb86085559_8
    ee74476df7aa   k8s.gcr.io/pause:3.4.1   "/pause"                 9 minutes ago   Up 9 minutes                           k8s_POD_kube-apiserver-master_kube-system_4497338b493c596567d3c3eb86085559_8

    이렇게 각 컴포넌트를 수행하는 pod과 옆에 붙어서 컨테이너 간 통신을 지원하는 pause pod이 같이 떠 있는 것을 확인할 수 있다.

    쿠버네티스 네트워크 (2) Pod - Pod 통신

    쿠버네티스에서 pod끼리의 통신은 CNI(Container Network Interface) 플러그인을 통해서 이루어진다. 다음은 우리가 함께 설치한 Weavenet의 구조이다.

    출처: 인프런 강의 Devops를 위한 쿠버네티스 마스터 

    이를 확인하기 위해서는 VM에서 다음을 입력한다.

    $ sudo netstat -antp | grep weave
    tcp        0      0 127.0.0.1:6784          0.0.0.0:*               LISTEN      4229/weaver         
    tcp        0      0 10.0.2.15:43560         10.96.0.1:443           ESTABLISHED 4159/weave-npc      
    tcp6       0      0 :::6781                 :::*                    LISTEN      4159/weave-npc      
    tcp6       0      0 :::6782                 :::*                    LISTEN      4229/weaver         
    tcp6       0      0 :::6783                 :::*                    LISTEN      4229/weaver         
    tcp6       0      0 10.0.2.15:6783          10.0.2.5:54483          ESTABLISHED 4229/weaver         
    tcp6       0      0 10.0.2.15:6783          10.0.2.4:37053          ESTABLISHED 4229/weaver

     

    위 명령어는 weavenet에 통하는 네트워크 입출력을 보여준다. 자세히 보면 master node(10.0.2.15)에서 slave node들(10.0.2.4, 10.0.2.5)로 통신하는 것을 확인할 수 있다. 여기서 weaver의 노드 ip/port 확인해보자.

    $ ps -eaf | grep 4229
    root        4229    4090  0 18:48 ?        00:00:01 /home/weave/weaver --port=6783 --datapath=datapath --name=5a:cd:9a:0c:b3:54 --http-addr=127.0.0.1:6784 --metrics-addr=0.0.0.0:6782 --docker-api= --no-dns --db-prefix=/weavedb/weave-net --ipalloc-range=10.32.0.0/12 --nickname=master --ipalloc-init consensus=2 --conn-limit=200 --expect-npc --no-masq-local 10.0.2.4 10.0.2.5
    gurumee    13287    4862  0 19:06 pts/0    00:00:00 grep --color=auto 4229

     

    역시 master -> slave 통신을 확인할 수 있다. 한 가지 더 알아둘 것은 이 CNI 플러그인 역시 pod으로 구성되어 동작한다는 것이다. 터미널에 다음을 입력한다.

    $ sudo docker ps | grep weave
    21216183cb68   7f92d556d4ff             "/usr/bin/launch.sh"     19 minutes ago   Up 19 minutes             k8s_weave-npc_weave-net-qr5v6_kube-system_52d850d7-c8e4-4b75-93c5-2dd97237b818_8
    978cef952fea   df29c0a4002c             "/home/weave/launch.…"   19 minutes ago   Up 19 minutes             k8s_weave_weave-net-qr5v6_kube-system_52d850d7-c8e4-4b75-93c5-2dd97237b818_9
    7cec7bbcfd41   k8s.gcr.io/pause:3.4.1   "/pause"                 19 minutes ago   Up 19 minutes             k8s_POD_weave-net-qr5v6_kube-system_52d850d7-c8e4-4b75-93c5-2dd97237b818_8

     

    여기서 weave-netdaemon-set이라는 리소스로 구성되어 있다. 자세한 설명을 보려면 다음을 입력해보자.

    $ kubectl get ds weave-net -n kube-system -o yaml
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      annotations:
        cloud.weave.works/launcher-info: |-
          {
            "original-request": {
              "url": "/k8s/v1.16/net.yaml?k8s-version=Q2xpZW50IFZlcnNpb246IHZlcnNpb24uSW5mb3tNYWpvcjoiMSIsIE1pbm9yOiIyMSIsIEdpdFZlcnNpb246InYxLjIxLjIiLCBHaXRDb21taXQ6IjA5MmZiZmJmNTM0MjdkZTY3Y2FjMWU5ZmE1NGFhYTA5YTI4MzcxZDciLCBHaXRUcmVlU3RhdGU6ImNsZWFuIiwgQnVpbGREYXRlOiIyMDIxLTA2LTE2VDEyOjU5OjExWiIsIEdvVmVyc2lvbjoiZ28xLjE2LjUiLCBDb21waWxlcjoiZ2MiLCBQbGF0Zm9ybToibGludXgvYW1kNjQifQpTZXJ2ZXIgVmVyc2lvbjogdmVyc2lvbi5JbmZve01ham9yOiIxIiwgTWlub3I6IjIxIiwgR2l0VmVyc2lvbjoidjEuMjEuMiIsIEdpdENvbW1pdDoiMDkyZmJmYmY1MzQyN2RlNjdjYWMxZTlmYTU0YWFhMDlhMjgzNzFkNyIsIEdpdFRyZWVTdGF0ZToiY2xlYW4iLCBCdWlsZERhdGU6IjIwMjEtMDYtMTZUMTI6NTM6MTRaIiwgR29WZXJzaW9uOiJnbzEuMTYuNSIsIENvbXBpbGVyOiJnYyIsIFBsYXRmb3JtOiJsaW51eC9hbWQ2NCJ9Cg==",
              "date": "Sat Jul 03 2021 09:55:33 GMT+0000 (UTC)"
            },
            "email-address": "support@weave.works"
          }
        deprecated.daemonset.template.generation: "1"
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"apps/v1","kind":"DaemonSet","metadata":{"annotations":{"cloud.weave.works/launcher-info":"{\n  \"original-request\": {\n    \"url\": \"/k8s/v1.16/net.yaml?k8s-version=Q2xpZW50IFZlcnNpb246IHZlcnNpb24uSW5mb3tNYWpvcjoiMSIsIE1pbm9yOiIyMSIsIEdpdFZlcnNpb246InYxLjIxLjIiLCBHaXRDb21taXQ6IjA5MmZiZmJmNTM0MjdkZTY3Y2FjMWU5ZmE1NGFhYTA5YTI4MzcxZDciLCBHaXRUcmVlU3RhdGU6ImNsZWFuIiwgQnVpbGREYXRlOiIyMDIxLTA2LTE2VDEyOjU5OjExWiIsIEdvVmVyc2lvbjoiZ28xLjE2LjUiLCBDb21waWxlcjoiZ2MiLCBQbGF0Zm9ybToibGludXgvYW1kNjQifQpTZXJ2ZXIgVmVyc2lvbjogdmVyc2lvbi5JbmZve01ham9yOiIxIiwgTWlub3I6IjIxIiwgR2l0VmVyc2lvbjoidjEuMjEuMiIsIEdpdENvbW1pdDoiMDkyZmJmYmY1MzQyN2RlNjdjYWMxZTlmYTU0YWFhMDlhMjgzNzFkNyIsIEdpdFRyZWVTdGF0ZToiY2xlYW4iLCBCdWlsZERhdGU6IjIwMjEtMDYtMTZUMTI6NTM6MTRaIiwgR29WZXJzaW9uOiJnbzEuMTYuNSIsIENvbXBpbGVyOiJnYyIsIFBsYXRmb3JtOiJsaW51eC9hbWQ2NCJ9Cg==\",\n    \"date\": \"Sat Jul 03 2021 09:55:33 GMT+0000 (UTC)\"\n  },\n  \"email-address\": \"support@weave.works\"\n}"},"labels":{"name":"weave-net"},"name":"weave-net","namespace":"kube-system"},"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"name":"weave-net"}},"template":{"metadata":{"labels":{"name":"weave-net"}},"spec":{"containers":[{"command":["/home/weave/launch.sh"],"env":[{"name":"HOSTNAME","valueFrom":{"fieldRef":{"apiVersion":"v1","fieldPath":"spec.nodeName"}}},{"name":"INIT_CONTAINER","value":"true"}],"image":"docker.io/weaveworks/weave-kube:2.8.1","name":"weave","readinessProbe":{"httpGet":{"host":"127.0.0.1","path":"/status","port":6784}},"resources":{"requests":{"cpu":"50m","memory":"100Mi"}},"securityContext":{"privileged":true},"volumeMounts":[{"mountPath":"/weavedb","name":"weavedb"},{"mountPath":"/host/var/lib/dbus","name":"dbus"},{"mountPath":"/host/etc/machine-id","name":"machine-id","readOnly":true},{"mountPath":"/run/xtables.lock","name":"xtables-lock"}]},{"env":[{"name":"HOSTNAME","valueFrom":{"fieldRef":{"apiVersion":"v1","fieldPath":"spec.nodeName"}}}],"image":"docker.io/weaveworks/weave-npc:2.8.1","name":"weave-npc","resources":{"requests":{"cpu":"50m","memory":"100Mi"}},"securityContext":{"privileged":true},"volumeMounts":[{"mountPath":"/run/xtables.lock","name":"xtables-lock"}]}],"dnsPolicy":"ClusterFirstWithHostNet","hostNetwork":true,"initContainers":[{"command":["/home/weave/init.sh"],"image":"docker.io/weaveworks/weave-kube:2.8.1","name":"weave-init","securityContext":{"privileged":true},"volumeMounts":[{"mountPath":"/host/opt","name":"cni-bin"},{"mountPath":"/host/home","name":"cni-bin2"},{"mountPath":"/host/etc","name":"cni-conf"},{"mountPath":"/lib/modules","name":"lib-modules"},{"mountPath":"/run/xtables.lock","name":"xtables-lock"}]}],"priorityClassName":"system-node-critical","restartPolicy":"Always","securityContext":{"seLinuxOptions":{}},"serviceAccountName":"weave-net","tolerations":[{"effect":"NoSchedule","operator":"Exists"},{"effect":"NoExecute","operator":"Exists"}],"volumes":[{"hostPath":{"path":"/var/lib/weave"},"name":"weavedb"},{"hostPath":{"path":"/opt"},"name":"cni-bin"},{"hostPath":{"path":"/home"},"name":"cni-bin2"},{"hostPath":{"path":"/etc"},"name":"cni-conf"},{"hostPath":{"path":"/var/lib/dbus"},"name":"dbus"},{"hostPath":{"path":"/lib/modules"},"name":"lib-modules"},{"hostPath":{"path":"/etc/machine-id","type":"FileOrCreate"},"name":"machine-id"},{"hostPath":{"path":"/run/xtables.lock","type":"FileOrCreate"},"name":"xtables-lock"}]}},"updateStrategy":{"type":"RollingUpdate"}}}
      creationTimestamp: "2021-07-03T09:55:33Z"
      generation: 1
      labels:
        name: weave-net
      name: weave-net
      namespace: kube-system
    # ...

    쿠버네티스 네트워크 (3) Pod - Svc 통신

    아래 그림은 podservice가 통신을 나타내는 구조이다.

    출처: 인프런 강의 Devops를 위한 쿠버네티스 마스터 

    service 생성 시 ClusterIP를 할당 받으면 iptables에 적용한다. 그래서 각 pod으로 통신을 연결해줄 수 있다. 쿠버네티스netfilter를 통해 2-7계층까지 네트워크 통신을 지원한다.  한 번 이를 확인해보자. 터미널에 다음을 입력한다.

    $ kubectl get svc --all-namespaces
    NAMESPACE     NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
    default       kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  3d
    kube-system   kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   25d

     

    "CLUSTER-IP" 대역대인 10.96.x.xservice 리소스가 사용하는 대역이다. 이 대역대의 iptables를 확인해보자.

    $ sudo iptables -S -t nat | grep 10.96 
    # 53은 DNS 포트
    -A KUBE-SERVICES -d 10.96.0.10/32 -p tcp -m comment --comment "kube-system/kube-dns:dns-tcp cluster IP" -m tcp --dport 53 -j KUBE-SVC-ERIFXISQEP7F7OF4
    -A KUBE-SERVICES -d 10.96.0.10/32 -p tcp -m comment --comment "kube-system/kube-dns:metrics cluster IP" -m tcp --dport 9153 -j KUBE-SVC-JD5MR3NA4I4DYORP
    -A KUBE-SERVICES -d 10.96.0.1/32 -p tcp -m comment --comment "default/kubernetes:https cluster IP" -m tcp --dport 443 -j KUBE-SVC-NPX46M4PTMTKRN6Y
    -A KUBE-SERVICES -d 10.96.0.10/32 -p udp -m comment --comment "kube-system/kube-dns:dns cluster IP" -m udp --dport 53 -j KUBE-SVC-TCOU7JCQXEZGVUNU

     

    여러 개가 체인처럼 엮여 있는 것을 볼 수 있는데, 그냥 이는 내부 구현이고 중요한 것은 pod에서 service를 호출하게 되면, 쿠버네티스에 존재하는 내부 DNS 시스템에 의해서 연결된 다른 pod이 호출된다는 것이다.

    쿠버네티스 네트워크 (4) 외부 물리 클라이언트 통신

    다음은 외부 클라이언트에서 서비스를 호출했을 때 나타나는 플로우이다.

    출처: 인프런 강의 Devops를 위한 쿠버네티스 마스터 

    클라이언트에서 LoadBalancer를 통해 호출하게 되면 그 안에 route table에 의해서 node로, 그 후 안에 네트워크 인터페이스(eth0)와 netfilter를 통해서 service가 호출되고 그 후 pod이 호출된다. 외부에서는 node와 연결되고 node 내에서는 pod-svc의 플로우가 동작하는 것이다.

    쿠버네티스 네트워크 (5) CoreDNS

    pod에서 service를 호출할 수 있는 이유는 바로 CoreDNS라는 쿠버네티스의 DNS 서버 역할을 하는 컴포넌트가 있기 때문이다. 

     

    CoreDNS는 쿠버네티스 클러스터의 DNS 서버 역할을 수행한다. 역시 pod으로 구성되어서 동작하고 있으며. 각 미들웨어를 통해 로깅, 캐시, 쿠버네티스 질의하는 기능을 수행한다.

     

    일반적으로 service를 다음과 같이 호출할 수 있다.

    <svc_name>.<ns_name>.svc.cluster.local 형식으로 도메인 획득 가능

     

    이에 대한 실습을 진행한다. 먼저 "gurumee"라는 네임스페이스를 생성한다.

     

    src/ch09/k8s/coredns-ns-gurumee.yaml)

    apiVersion: v1
    kind: Namespace
    metadata:
      creationTimestamp: null
      name: gurumee
    spec: {}
    status: {}

     

    그 후, Deployment를 생성한다.

     

    src/ch09/k8s/coredns-simple-app-dep.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: simple-app-dep
      namespace: gurumee
      labels:
        app: simple-app
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: simple-app
      template:
        metadata:
          labels:
            app: simple-app
        spec:
          containers:
            - name: simple-app
              image: gurumee92/simple-app:v1
              ports:
                - containerPort: 8080

     

    그 다음 ClusterIP 형태로 Service를 통해 Deployment를 연결해준다.

     

    src/ch09/k8s/coredns-simple-app-svc.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: simple-app-svc
      namespace: gurumee
    spec:
      ports:
        - port: 8080
          targetPort: 8080
      selector:
        app: simple-app

     

    그 후 nginx를 기반으로 pod 1개를 실행한다.

    $ kubectl run nginx --image=nginx

     

    그 후 그 pod에서 curlsvc_name.ns_name:8080으로 호출해보자.

    $ kubectl exec -it nginx -- curl simple-app-svc.gurumee:8080
    Hello World v1 

     

    이렇게 떴다면 성공이다.

    쿠버네티스 스토리지 (1) 볼륨

    "볼륨"은 컨테이너가 외부 스토리지에 액세스하고 공유하는 방법이다. 다음과 같은 방법이 있다.

    • 임시 볼륨 : emptyDir (컨테이너 볼륨 공유)
    • 로컬 볼륨 : hostPath, local (노드 관리 목적)
    • 네트워크 볼륨 : NFS, glusterFS (외부 자원 공유 목적)
    • 네트워크 볼륨 (클라우드) : awsEBS, gcePersistentDisk

    이외에도 pvc, configMap 등이 있다.

    쿠버네티스 스토리지 (2) EmptyDir

    볼륨 EmptyDir을 통해 pod간 볼륨을 공유하게끔 만들 수 있다. 이제 다음과 같이 스크립트를 하나 작성한다.

     

    src/ch09/app/count.sh

    #!/bin/sh
    trap "exit" SIGINT
    mkdir /var/htdocs
    
    SET=$(seq 0 99999)
    for i in $SET
    do
      echo "RUNNING loop seq $i" > /var/htdocs/index.html
      sleep 10
    done

     

    그리고 build 하기 전에 chmod 777 명령어를 주어서 실행 파일 권한을 주자 Dockerfile을 다음과 같이 만든다.

     

    src/ch09/app/Dockerfile

    FROM busybox:latest
    
    ADD count.sh /bin/count.sh
    
    ENTRYPOINT /bin/count.sh

     

    그 후 자신의 ID로 이미지를 만들어서 push한다. 그 후 다음과 같이 리소스를 생성한다.

     

    src/ch09/k8s/volume-empty-dir.yaml

    ...
    apiVersion: v1
    kind: Pod
    metadata:
       name: volume-empty-dir
    spec:
       containers:
          - image: gurumee92/count
            name: html-generator
            volumeMounts:
               - mountPath: /var/htdocs/
                 name: html
          - image: httpd
            name: web-server
            volumeMounts:
               - mountPath: /usr/local/apache2/htdocs
                 name: html
                 readOnly: true
            ports:
               - containerPort: 80
       volumes:
          - name: html
            emptyDir: {}

     

    그 후 nginx를 기반으로 pod 1개를 실행한다.

    $ kubectl run nginx --image=nginx

     

    그러면 다음의 pod들이 생성되어진다.

    $ kubectl get pod -o wide
    NAME               READY   STATUS    RESTARTS   AGE     IP          NODE     NOMINATED NODE   READINESS GATES
    nginx              1/1     Running   0          2m55s   10.32.0.3   slave2   <none>           <none>
    volume-empty-dir   2/2     Running   0          6m34s   10.32.0.2   slave2   <none>           <none>

     

    이제 nginx 포드에서 volume-empty-dir 포드로 curl을 요청해보자.

    # 10.32.0.2 = volume-empty-dir IP
    $ kubectl exec -it nginx -- curl 10.32.0.2 
    RUNNING loop seq 48

     

    이제 만들어진지 480초가 지났다는 의미이다. 10초 간격으로 계속 curl을 요청하면 "seq" 값이 변하는 것을 확인할 수 있다.

    쿠버네티스 스토리지 (3) Hostpath

    hostPath 볼륨은 노드와 포드간 데이터 공유를 위해서 만들어지는 볼륨이다. 해당 노드의 파일 시스템에 있는 파일 혹은 디렉토리를 지정하기 때문에 노드에 떠 있는 포드들하고만 연결이 가능하다.

     

    주로 노드의 모니터링을 위해서 많이 사용된다. 이제 실습을 진행해보자. 먼저 워커 노드에서 다음을 명령한다.

    ## sudo 권한 획득 
    $ sudo -i
    
    ## 디렉토리 생성
    # mkdir -p /var/htdocs
    
    # echo "$HOSTNAME" > /var/htdocs/index.html

     

    그 후 다음 리소스를 생성한다.

     

    src/ch09/volume-hostpath.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: volume-hostpath
    spec:
      containers:
        - image: httpd
          name: web-server
          volumeMounts:
            - mountPath: /usr/local/apache2/htdocs
              name: html
              readOnly: true
          ports:
            - containerPort: 80
      volumes:
        - name: html
          hostPath:
            path: /var/htdocs
            type: Directory

     

    그 다음 아래 명령어를 입력하여 포드가 어디 노드에 생성되었는지 확인한다.

    $ kubectl get pod -o wide -w
    NAME               READY   STATUS    RESTARTS   AGE   IP          NODE     NOMINATED NODE   READINESS GATES
    volume-hostpath    1/1     Running   0          15s   10.40.0.3   slave1   <none>           <none>

     

    워커 노드 1("slave1")에 포드가 위치하고 있다. 이제 이 포드를 접속할 수 있도록 port-forward로 포트를 개방한다.

    $ kubectl port-forward hostpath-http 8888:80
    Forwarding from 127.0.0.1:8888 -> 80
    Forwarding from [::1]:8888 -> 80
    Handling connection for 8888

     

    이제 새 탭을 열어 다음을 입력한다.

    $ curl localhost:8888
    slave1

    "slave1"이 뜨는 것을 확인할 수 있다.

Designed by Tistory.