[kubernetes-실습] Service Resource

# Deploy A new Service

# nginx deployment 배포를 위한 yaml 파일 준비
ps0107@k8smaster1:~$ vi nginx-one.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-one
  labels:
    system: secondary
  namespace: accounting
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.11.1
        imagePullPolicy: Always
        name: nginx
        ports:
        - containerPort: 8080 #-> 포트는 8080으로 지정
          protocol: TCP
      nodeSelector: #-> nodeSelector는 secondOne으로 지정
        system: secondOne
 
# 현재 node에 설정된 라벨 확인
ps0107@k8smaster1:~$ kubectl get nodes --show-labels
NAME         STATUS   ROLES    AGE     VERSION   LABELS
k8smaster1   Ready    master   5d21h   v1.15.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8smaster1,kubernetes.io/os=linux,node-role.kubernetes.io/master=
k8sworker1   Ready    <none>   5d21h   v1.15.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8sworker1,kubernetes.io/os=linux

# yaml파일로 생성하려 시도하는데 namespace 가 없어서 실패
ps0107@k8smaster1:~$ kubectl create -f nginx-one.yaml
Error from server (NotFound): error when creating "nginx-one.yaml": namespaces "accounting" not found

# namespace 생성
ps0107@k8smaster1:~$ kubectl create ns accounting
namespace/accounting created

# 다시 nginx-one deployment 배포
ps0107@k8smaster1:~$ kubectl create -f nginx-one.yaml 
deployment.extensions/nginx-one created

# 생성된 pod 확인
# 두개의 pod 가 accounting namespace에 생성됨을 확인, 그러나 상태가 pendding 상태임
ps0107@k8smaster1:~$ kubectl -n accounting get pods
NAME                         READY   STATUS    RESTARTS   AGE
nginx-one-575db47668-fcgpf   0/1     Pending   0          19s
nginx-one-575db47668-mng7p   0/1     Pending   0          19s

# 생성된 pod의 상세 내용 확인
# 자세한 내용을 보면 아랫쪽 Events 에 FailedScheduling 을 볼 수도 있다. 
# 왜냐하면 node selector 가 secondOne을 찾는데 없어서 warning이 발생했다
ps0107@k8smaster1:~$ kubectl -n accounting describe pod nginx-one-575db47668-fcgpf 
Name:           nginx-one-575db47668-fcgpf
Namespace:      accounting
Priority:       0
Node:           <none>
Labels:         app=nginx
                pod-template-hash=575db47668
Annotations:    <none>
Status:         Pending
IP:             
Controlled By:  ReplicaSet/nginx-one-575db47668
Containers:
  nginx:
    Image:        nginx:1.11.1
    Port:         8080/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-m2wzl (ro)
Conditions:
  Type           Status
  PodScheduled   False 
Volumes:
  default-token-m2wzl:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-m2wzl
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  system=secondOne
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  61s (x2 over 61s)  default-scheduler  0/2 nodes are available: 2 node(s) did not match node selector.

# 해결하기 위해 노드에 label 부여해준다.
ps0107@k8smaster1:~$ kubectl label node k8sworker1 system=secondOne
node/k8sworker1 labeled

# 노드에 부여된 라벨을 확인한다.
ps0107@k8smaster1:~$ kubectl get nodes --show-labels
NAME         STATUS   ROLES    AGE     VERSION   LABELS
k8smaster1   Ready    master   5d21h   v1.15.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8smaster1,kubernetes.io/os=linux,node-role.kubernetes.io/master=
k8sworker1   Ready    <none>   5d21h   v1.15.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8sworker1,kubernetes.io/os=linux,system=secondOne

# 다시 pod 상태를 확인해본다. 정상 running 상태로 돌아왔다.
ps0107@k8smaster1:~$ kubectl -n accounting get pods
NAME                         READY   STATUS    RESTARTS   AGE
nginx-one-575db47668-fcgpf   1/1     Running   0          2m40s
nginx-one-575db47668-mng7p   1/1     Running   0          2m40s

# label을 통해 pod를 검색해본다.
# 모든 namespace 에서 app=nginx으로 select
ps0107@k8smaster1:~$ kubectl get pods -l app=nginx --all-namespaces
NAMESPACE    NAME                         READY   STATUS    RESTARTS   AGE
accounting   nginx-one-575db47668-fcgpf   1/1     Running   0          3m6s
accounting   nginx-one-575db47668-mng7p   1/1     Running   0          3m6s

# nginx-one을 svc expose 시킨다.
ps0107@k8smaster1:~$ kubectl -n accounting expose deployment nginx-one
service/nginx-one exposed

# nginx-one의 endpoint 확인
# pod 갯수대로 보임. yaml 파일 설정으로 인해 8080 포트로 expose 됨
ps0107@k8smaster1:~$ kubectl -n accounting get ep nginx-one
NAME        ENDPOINTS                             AGE
nginx-one   192.168.1.73:8080,192.168.1.74:8080   14s

# curl 테스트 실패 
# 현재 임의로 8080으로 부여했는데 실제 이미지의 오픈 포트로 설정해 줘야 한다.
ps0107@k8smaster1:~$ curl 192.168.1.73:8080
curl: (7) Failed to connect to 192.168.1.73 port 8080: Connection refused

# 실제 이미지 포트인 80으로 리슨되어 있다.
ps0107@k8smaster1:~$ curl 192.168.1.73:80
......
<title>Welcome to nginx!</title>
.....

# yaml 파일에서 수정한다 (8080->80)
ps0107@k8smaster1:~$ vi nginx-one.yaml                                                                                       
....
        ports:
        - containerPort: 80
....

# 다시 deployment를 생성하기 위해 기존것을 삭제한다.
ps0107@k8smaster1:~$ kubectl -n accounting delete deploy nginx-one
deployment.extensions "nginx-one" deleted

# svc 객체도 삭제후 다시 생성해 줘야 한다.
ps0107@k8smaster1:~$ kubectl -n accounting delete svc nginx-one
service "nginx-one" deleted

# 수정된 내용으로 deployment 생성
ps0107@k8smaster1:~$ kubectl create -f nginx-one.yaml 
deployment.extensions/nginx-one created

# 다시 svc expose 해줌.
ps0107@k8smaster1:~$ kubectl -n accounting expose deployment nginx-one 
service/nginx-one exposed

# endpoint 확인
ps0107@k8smaster1:~$ kubectl -n accounting get ep
NAME        ENDPOINTS                         AGE
nginx-one   192.168.1.75:80,192.168.1.76:80   22s

# 80으로 서비스 테스트 이상없음
ps0107@k8smaster1:~$ curl 192.168.1.75:80
....
<title>Welcome to nginx!</title>
....

# NodePort 설정

# service-lab이라는 이름으로 NodePort expose
ps0107@k8smaster1:~$ kubectl -n accounting expose deployment nginx-one --type=NodePort --name=service-lab
service/service-lab exposed

# accounting namespace의 service 들의 정보 확인
ps0107@k8smaster1:~$ kubectl -n accounting describe services
Name:              nginx-one
Namespace:         accounting
Labels:            system=secondary
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP:                10.107.173.54
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         192.168.1.75:80,192.168.1.76:80
Session Affinity:  None
Events:            <none>


Name:                     service-lab
Namespace:                accounting
Labels:                   system=secondary
Annotations:              <none>
Selector:                 app=nginx
Type:                     NodePort
IP:                       10.98.40.253
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30250/TCP
Endpoints:                192.168.1.75:80,192.168.1.76:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

# 클러스터의 외부 ip 주소 알아보자 
ps0107@k8smaster1:~$ kubectl cluster-info
Kubernetes master is running at https://k8smaster:6443
KubeDNS is running at https://k8smaster:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

# node port로 테스트 확인 (현재 master노드도 worker 노드로 사용중이다.)
ps0107@k8smaster1:~$ curl http://k8smaster:30250
.....
<title>Welcome to nginx!</title>
.....

# Label을 사용하여 Resource 관리

# 전체 namespace에서 app=nginx 로 라벨링 된 pod 들을 삭제
ps0107@k8smaster1:~$ kubectl delete pods -l app=nginx --all-namespaces
pod "nginx-one-8699d6df6d-56z6z" deleted
pod "nginx-one-8699d6df6d-794cq" deleted

# accounting namespace에서 app=nginx 라벨링된 pod 삭제
ps0107@k8smaster1:~$ kubectl -n accounting delete pods -l app=nginx
pod "nginx-one-8699d6df6d-4d4b7" deleted
pod "nginx-one-8699d6df6d-8dv9k" deleted

ps0107@k8smaster1:~$ kubectl -n accounting get pods
NAME                         READY   STATUS    RESTARTS   AGE
nginx-one-8699d6df6d-5k4zn   1/1     Running   0          13s
nginx-one-8699d6df6d-d5kff   1/1     Running   0          13s

# nginx-one  deployment에 라벨 확인
ps0107@k8smaster1:~$ kubectl -n accounting get deploy --show-labels
NAME        READY   UP-TO-DATE   AVAILABLE   AGE   LABELS
nginx-one   2/2     2            2           30m   system=secondary

# node 에 system 이라는 label 삭제
ps0107@k8smaster1:~$ kubectl label nodes k8sworker1 system-
node/k8sworker1 labeled

ps0107@k8smaster1:~$ kubectl get nodes --show-labels
NAME         STATUS   ROLES    AGE     VERSION   LABELS
k8smaster1   Ready    master   5d22h   v1.15.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8smaster1,kubernetes.io/os=linux,node-role.kubernetes.io/master=
k8sworker1   Ready    <none>   5d21h   v1.15.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8sworker1,kubernetes.io/os=linux