---
# System prepended metadata

title: '[雲端] K8s / Ingress'
tags: [雲端, 雲端 / K8s, ingress, K8s]

---

[雲端] K8s / Ingress
===
###### tags: `雲端 / K8s`
###### tags: `雲端`, `K8s`, `ingress`

<br>

![](https://i.imgur.com/vsCp0RX.png)<br><br>

[TOC]

<br>

## [Kubernetes 基礎教學（二）實作範例：Pod、Service、Deployment、Ingress](https://medium.com/@C.W.Hu/kubernetes-implement-ingress-deployment-tutorial-7431c5f96c3e)
![](https://i.imgur.com/EgVch8A.png)



###  deploy-demo.yam 
```yaml=
apiVersion: apps/v1
kind: Deployment
metadata:
  name: a-kuard
spec:
  template:
    metadata:
      name: kuard-pod
      labels:
        app: kuard        
    spec:
      containers:
      - name: kuard-container
        image: gcr.io/kuar-demo/kuard-amd64:1
        ports: 
        - containerPort: 8080
  selector:
    matchLabels:
      app: kuard
  replicas: 3

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: b-nginx
spec:
  template:
    metadata:
      name: nginx-pod
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx-container
        image: nginx
        ports:
        - containerPort: 8080
  selector:
    matchLabels:
      app: nginx
  replicas: 3
```
- 若 replicas 太多，可事後透過 kubectl scale 指令調整
    ```k8s
    kubectl scale deployment a-kuard --replicas=2
    ```
    
- 查看現有的 pods
    ```
    > kubectl get pods
    NAME                       READY   STATUS    RESTARTS   AGE
    b-nginx-69cfb869c4-x2pt6   1/1     Running   0          44h
    b-nginx-69cfb869c4-n5qf5   1/1     Running   0          44h
    b-nginx-69cfb869c4-4557m   1/1     Running   0          4h57m
    a-kuard-7947d7769f-6wcx6   1/1     Running   0          44h
    a-kuard-7947d7769f-k9tgh   1/1     Running   0          44h
    ```
- 建立 service 來存取 pod 時，service 會隨機存取 pod，猶如 load balance

<br>

### service-demo.yam 
```yaml=
apiVersion: v1
kind: Service
metadata:
  name: a-kuard-service
spec:
  selector:
    app: kuard
  type: NodePort
  ports:
  - name: 80-to-8080-kuard
    port: 80
    targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: b-nginx-service
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
  - name: 80-to-80-nginx
    port: 80
    targetPort: 80
```
- Rancher 上的示意圖
    [![](https://i.imgur.com/uiU8cc9.png)](https://i.imgur.com/uiU8cc9.png)
- 在叢集內，開放 pod 的存取
    - a-kuard-service (Cluster IP: 10.43.47.68, port:80) 對到 kuard pod (port:8080)
    - b-nginx-service (Cluster IP: 10.43.5.36, port:80) 對到 nginx pod (port:80)
- 在叢集外，開放 service 的存取
    - 沒指定 nodePort，nodePort 會隨機配置
    - externalIP:nodePort1 對到 a-kuard-service  (Cluster IP: 10.43.47.68, port:80) 
        <img src="https://i.imgur.com/qj7mm3r.png" style="border: 1px solid"/>
        <br>
    - externalIP:nodePort2 對到 b-nginx-service (Cluster IP: 10.43.5.36, port:80)
        <img src="https://i.imgur.com/uUeI3cF.png" style="border: 1px solid"/>

<br>

### ingress-demo.yam (v1)
```yaml=
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: load-balance-service
spec:
  rules:
  - host: a-kuard.com
    http:
      paths:
      - backend:
          serviceName: a-kuard-service
          servicePort: 80
  - host: b-nginx.com
    http:
      paths:
      - backend:
          serviceName: b-nginx-service
          servicePort: 80
```
- Rancher 上的示意圖
    ![](https://i.imgur.com/kcgzarP.png)

- serviceName 是綁訂目前已有的 service 的 name

- servicePort 是對外開放的 port (供瀏覽器存取)，不是 a-kuard-service 的 port
    - 輸入 **```a-kuard.com:80```** (詳見底下 DNS 設定)
        會轉到 a-kuard-service
    - 輸入 **```b-nginx.com:80```** (詳見底下 DNS 設定)
        會轉到 b-nginx-service
    - 直接輸入 **```192.168.56.87```** ，無法轉到任何 service，
        會顯示```404 page not found```
    
- 它台電腦的瀏覽器，若想要瀏覽 a-kuard.com, b-nginx.com
    需要在 /etc/hosts 添加
    ```
    $ nano /etc/hosts
    ...
    192.168.56.87 a-kuard.com
    192.168.56.87 b-nginx.com
    ```
    <img src="https://i.imgur.com/1IMdjf9.png" style="border: 1px solid"/>
    <br>
    <br>
    <img src="https://i.imgur.com/fcKA0UZ.png" style="border: 1px solid"/>

### ingress-demo.yam (v2)
```yaml=
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: load-balance-service
spec:
  rules:
  - host: a-kuard.com
    http:
      paths:
      - backend:
          serviceName: a-kuard-service
          servicePort: 80
  - host: b-nginx.com
    http:
      paths:
      - backend:
          serviceName: b-nginx-service
          servicePort: 80

  # the default backend
  backend:
    serviceName: a-kuard-service
    servicePort: 80
```
- 第 21~23 行，可以設置預設的 backend

- Rancher 上的示意圖
    ![](https://i.imgur.com/zgSXQhw.png)
    
- 直接輸入 **```192.168.56.87```** ，可以轉到 a-kuard-service
    <img src="https://i.imgur.com/CklzMn6.png" style="border: 1px solid"/>

<br>

## apiVersion
> Ingress apiVersion 參數值不同，格式欄位也可能不同

- 例如：
    ```
    v1beta:  <-- 常見的範本
    backend:
      - serviceName: xxx
      - servicePort: yyy

    ---
    
    v1：
    backend:
      - service
         - name: xxx
         - port:
             number: yyy
    ```
- 參考資料
    - [Expecting apiVersion - networking.k8s.io/v1 instead of extensions/v1beta1](https://github.com/kubernetes/kubernetes/issues/94761)




<br>

## Debug
- 基本範例
    ```yaml
    apiVersion: extensions/v1beta1 
    kind: Ingress
    metadata:
      name: {{ include "tj-helm-whale-ingress-demo2.name" . }} 
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - http:
          paths:
          - path: {{ .Values.ingress.path }} 
            backend:
              serviceName: {{ .Values.ingress.serviceName }}
              servicePort: {{ .Values.ingress.servicePort }}
    ```
    - ```nginx.ingress.kubernetes.io/rewrite-target: /``` 參數是必要的
- 查看 ingress name
    ```
    $ ku get ing
    Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
    NAME                          CLASS    HOSTS   ADDRESS        PORTS   AGE
    tj-helm-whale-ingress-demo2   <none>   *       10.98.112.86   80      4m32s
    ```
    - ingress name 為 ```tj-helm-whale-ingress-demo2```

- 查看 tj-helm-whale-ingress-demo2 細節
    ```
    $ ku describe ing tj-helm-whale-ingress-demo2
    Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
    Name:             tj-helm-whale-ingress-demo2
    Namespace:        default
    Address:          10.98.112.86
    Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
    Rules:
      Host        Path  Backends
      ----        ----  --------
      *           
                  /blue   tjdemo3-tj-helm-whale-ingress-demo2:80 (10.244.0.34:3000,10.244.1.80:3000)
    Annotations:  meta.helm.sh/release-name: tjdemo3
                  meta.helm.sh/release-namespace: default
                  nginx.ingress.kubernetes.io/rewrite-target: /
    Events:
      Type    Reason  Age    From                      Message
      ----    ------  ----   ----                      -------
      Normal  CREATE  4m36s  nginx-ingress-controller  Ingress default/tj-helm-whale-ingress-demo2
      Normal  UPDATE  4m26s  nginx-ingress-controller  Ingress default/tj-helm-whale-ingress-demo2
    ```
    - address 為 ```10.98.112.86```
    - path 為 ```/blue```
    - :warning: **注意**
        - Backends 欄位的 service name 有沒有對應到你要的 service
        - Helm3 建立出來的 service name 好像對不起來？以至於無法存取...
    - 進行測試
        ```
        $ curl 10.98.112.86/blue
        ```
- 查看對外的 ingress service
    ```bash
    $ ku get svc -o wide -n ingress-nginx
    NAME            TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE    SELECTOR
    ingress-nginx   NodePort   10.98.112.86   <none>        80:30511/TCP,443:30152/TCP   4d2h   app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx
    ```
    ```
    $ ku describe svc ingress-nginx -n ingress-nginx
    Name:                     ingress-nginx
    Namespace:                ingress-nginx
    Labels:                   app.kubernetes.io/name=ingress-nginx
                              app.kubernetes.io/part-of=ingress-nginx
    Annotations:              <none>
    Selector:                 app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx
    Type:                     NodePort
    IP:                       10.98.112.86
    Port:                     http  80/TCP
    TargetPort:               80/TCP
    NodePort:                 http  30511/TCP
    Endpoints:                10.244.1.19:80
    Port:                     https  443/TCP
    TargetPort:               443/TCP
    NodePort:                 https  30152/TCP
    Endpoints:                10.244.1.19:443
    Session Affinity:         None
    External Traffic Policy:  Cluster
    Events:                   <none>
    ```
    - 進行測試
        ```
        $ curl 127.0.0.1:30511/blue
        ```
        http://203.145.218.3:30511/blue
        ![](https://i.imgur.com/kyJwhIu.png)


<br>

## 參考資料
- [[K8s官方] Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
- Kubernetes 基礎教學
    - [Kubernetes 基礎教學（一）原理介紹](https://medium.com/@C.W.Hu/kubernetes-basic-concept-tutorial-e033e3504ec0)
        - worker node
            - kubelet
                - 角色
                    - worker node 上的管理員
                - 職責
                    - 負責管理該 node 上的 pod 的狀態
                    - 負責與 master node 溝通
            - kube-proxy
                - 角色
                    - worker node 上的傳訊員
                - 職責
                    - 負責更新該 node 上的 iptables  (負責啟用 k8s 服務的網路規則)
                    - 負責網路連線的轉發
            - container runtime
                - 角色
                    - worker node 上的容器執行者
                        - k8s: docker engine
                        - k3s: containerd (containerd is based on the Docker Engine's core container runtime)
                - 職責
                    - 負責該 node 上的容器執行
        - master node
            - k8s 的指揮中心
            - controller-manager
                - k8s 裡一個個負責監視 cluster 狀態的程序
                    - Node Controller
                    - Replication Controller
    - [Kubernetes 基礎教學（二）實作範例：Pod、Service、Deployment、Ingress](https://medium.com/@C.W.Hu/kubernetes-implement-ingress-deployment-tutorial-7431c5f96c3e) :+1: :100: 
    - [Kubernetes 基礎教學（三）Helm 介紹與建立 Chart](https://medium.com/@C.W.Hu/kubernetes-helm-chart-tutorial-fbdad62a8b61)
    
- [[官網] 一个最小的 Ingress 资源示例：](https://kubernetes.io/zh/docs/concepts/services-networking/ingress/)
    ![](https://i.imgur.com/2rrKY9p.png)

<br>

## 待消化資料
- [How To Set Up an Nginx Ingress on DigitalOcean Kubernetes Using Helm](https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nginx-ingress-on-digitalocean-kubernetes-using-helm)