[kubernetes-실습] ingress 간단 실습

# ingress 설정

- 많은 서비스들을 클러스터의 외부로 expose 시키거나 호스트 노드의 낮은 숫자의 포트로 expose 하기 위해 ingress controller 또는 service mesh를 적용해야 해야한다.

# 간단한 테스트를 위해 nginx deployment를 생성한다. 
# app 이름은 secondapp으로 한다.
ps0107@k8smaster1:~$ kubectl create deployment secondapp --image=nginx                                                               
deployment.apps/secondapp created

# 현재 deployment에 의해 사용되어지는 label 들을 찾아본다. 
# ingress controller 로 부터 적절한 service 로 트래픽을 주기 위해 label들을 사용한다.
ps0107@k8smaster1:~$ kubectl get deployments secondapp -o yaml | grep label -A2                                                        
labels:
app: secondapp
  name: secondapp
--                                                                                                                                         
labels:
app: secondapp
    spec:

# NodePort로 새로운 서버 expose
ps0107@k8smaster1:~$ kubectl expose deployment secondapp --type=NodePort --port=80
service/secondapp exposed

# 필요한 resource 에 접근이 가능해야 하기 때문에 RBAC 적용이 필요하다.
ps0107@k8smaster1:~$ vi ingress.rbac.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
  name: traefik-ingress-controller
  namespace: kube-system

# 새로운 role과 binding 생성
ps0107@k8smaster1:~$ kubectl create -f ingress.rbac.yaml
clusterrole.rbac.authorization.k8s.io/traefik-ingress-controller created
clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-controller created

# Traefik controller 생성하기 위해 yaml 파일 받음
ps0107@k8smaster1:~$ wget https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-ds.yaml -O traefik-ds.yaml

# hostNetwork 를 true로 적용. 예를들면 pod 자체 ip를 사용안하고 172.20.0.150 적용하여 사용
# [add]
# hostNetwork: true
# [remove]
# securityContext: 부터 블럭 삭제
ps0107@k8smaster1:~$ vi traefik-ds.yaml 
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
      name: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      containers:
      - image: traefik:v1.7
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
          hostPort: 8080
        args:
        - --api
        - --kubernetes
        - --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      name: admin

# ingress controller 생성
ps0107@k8smaster1:~$ kubectl create -f traefik-ds.yaml 
serviceaccount/traefik-ingress-controller created
daemonset.apps/traefik-ingress-controller created
service/traefik-ingress-service created

# ingress rule 설정
ps0107@k8smaster1:~$ vi ingress.rule.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-test
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: www.example.com
    http:
      paths:
      - backend:
          serviceName: secondapp
          servicePort: 80
        path: /

# ingress rule 생성
ps0107@k8smaster1:~$ kubectl create -f ingress.rule.yaml 
ingress.extensions/ingress-test created

# internal, external IP 주소로 test 할 수 있다. 
# nginx welcome 페이지를 확인 할 수 있다. ip a로 확인할수 있는데 k8smaster로 alias 걸려 있어서 해당 alis로 확인 가능
ps0107@k8smaster1:~$ ip a
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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc mq state UP group default qlen 1000
    link/ether 42:01:0a:92:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.146.0.2/32 brd 10.146.0.2 scope global ens4
       valid_lft forever preferred_lft forever
    inet6 fe80::4001:aff:fe92:2/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:ee:85:1a:67 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
4: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
    inet 192.168.0.1/32 brd 192.168.0.1 scope global tunl0
       valid_lft forever preferred_lft forever
5: califfb09e4ec60@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default 
    link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::ecee:eeff:feee:eeee/64 scope link 
       valid_lft forever preferred_lft forever
6: cali2a15a3c9f47@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default 
    link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::ecee:eeff:feee:eeee/64 scope link 
       valid_lft forever preferred_lft forever
28: cali7d5b4b81275@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default 
    link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::ecee:eeff:feee:eeee/64 scope link 
       valid_lft forever preferred_lft forever
ps0107@k8smaster1:~$ curl -H "Host: www.example.com" http://k8smaster/
......
<title>Welcome to nginx!</title>
......

ps0107@k8smaster1:~$ curl -H "Host: www.example.com" http://10.146.0.2/
......
<title>Welcome to nginx!</title>
......

# nginx thirdpage로 새로 deploying 함.
ps0107@k8smaster1:~$ kubectl create deployment thirdpage --image=nginx
deployment.apps/thirdpage created

# nodeport로 새로운 서버 expose
ps0107@k8smaster1:~$ kubectl expose deployment thirdpage --type=NodePort --port=80
service/thirdpage exposed

# 해당 컨테이너에 접속하여 thirdpage로 들어오는지 구분하기 위해 index.html 페이지를 수정한다.
ps0107@k8smaster1:~$ kubectl exec -it thirdpage-5958779549-stxjk -- /bin/bash
root@thirdpage-5958779549-stxjk:/# apt-get update
root@thirdpage-5958779549-stxjk:/# apt-get install vim -y
root@thirdpage-5958779549-stxjk:/# vi /usr/share/nginx/html/index.html # <- index.html 타이틀을 Third Page 로 수정해본다.
root@thirdpage-5958779549-stxjk:/# exit
exit
ps0107@k8smaster1:~$

# kubectl edit를 사용하여 ingress-test 설정에 thirdpage 설정 추가한다.
ps0107@k8smaster1:~$ kubectl edit ingress ingress-test   
  - host: thirdpage.org                                                                                                              
    http:                                                                                                                            
      paths:                                                                                                                         
      - backend:                                                                                                                     
          serviceName: thirdpage                                                                                                     
          servicePort: 80                                                                                                            
        path: /

ingress.extensions/ingress-test edited

# 설정이 잘되었는지 curl로 테스트 해본다.
ps0107@k8smaster1:~$ curl -H "Host: thirdpage.org" http://k8smaster
.....
<title>Third Page</title>
.....