---
# System prepended metadata

title: '[k8s] ingress resource'
tags: [kubernetes]

---

[k8s] ingress resource
=======
###### tags: `kubernetes`

![](https://i.imgur.com/FqIno7m.png)
:::info
+ manages external access to the services in a cluster, typically HTTP.
+ 可設定每一個endpoint的規則，以及對應的路徑，如果要有***basic-auth***或者是***TLS***，也是在這設定
:::

:::warning
Ingress 本身並沒有提供負載平衡的功能，還需要透過 Ingress Controller 來實現。Ingress 目前主要支援兩種型別 ***GCE*** 與 ***Nginx***。


> 負載平衡(Load Balancing)：以往我們可以透過外部的資源，像是 AWS ELB 來實現，將流量分配給不同的機器。而 Kubernetes 現在也提供了一個內部工具 Ingress Controller ，讓我們自己可以在 Kubernetes Cluster 中實現 Load Balancing 而無需透過外部資源。
:::

![](https://i.imgur.com/R6T1KDX.jpg)

# annotations
`Ingress-Controller` 會去讀取 Ingress 的設定，然後來進行後續的動作。假想一個情況，系統內同時有多個 Ingress-Controller 的實現，使用者要==如何指派該 Ingress 要使用哪一個 Ingress-Controller 來使用?==

並由各個 Ingress-Controller 自行決定看到什麼樣的資訊來進行什麼處理。

此外，不同的 Ingress-Server 提供的功能與使用方式都不同，基本上 Ingress Resource ***很難有一個完美的介面來滿足所有的實現***，因此大部分的情況下，不同的 Ingress-Controller/Ingress-Server 都會要求使用者在 Annotation 的部分使用特定的字眼來描述額外的功能
```yaml=
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
```
```yaml=
# 設定ingress的auth型態、對應的secret，auth-realm 其實就是瀏覽器會顯示給用戶的內容
metada:
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: "Authentication Required - foo"
```

## What is the rewrite-target
### if without `rewrite-target`
`http://<ingress-service>:<ingress-port>/watch` --> `http://<watch-service>:<port>/watch`
`http://<ingress-service>:<ingress-port>/wear` --> `http://<wear-service>:<port>/wear`


### example 1
> `replace("/path","/")`
```yaml=
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  namespace: critical-space
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /pay
        backend:
          serviceName: pay-service
          servicePort: 8282
```

### example 2 (better one)
![image](https://hackmd.io/_uploads/Hk_X1DONa.png =500x)


```yaml=
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  rules:
  - host: rewrite.bar.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /something(/|$)(.*)
```


# best practices
## example 1: 將不同路徑的請求對應到不同的 Service 物件
```yaml=
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
  name: ingress-wear-watch
  namespace: app-space
spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: wear-service
            port:
              number: 8080
        path: /wear
        pathType: Prefix
      - backend:
          service:
            name: video-service
            port:
              number: 8080
        path: /stream
        pathType: Prefix
```

### how to create 
```shell=
kubectl create -f ./ingress-example-1.yaml
kubectl get ing
```

## example 2: 將不同 domain name 的請求對應到不同的 Service 物件
```yaml=
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-2
spec:
  rules:
  - host: helloworld-v1.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: hellworld-v1
          servicePort: 80
  - host: helloworld-v2.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: helloworld-v2
          servicePort: 80
```
+ ***rules***: 代表這個 Ingress 的轉發規則
+ ***host***: 設定可以連接到 Service 物件的網域名稱
+ ***path***: 設定可以連接到 Service 物件的路徑名稱
+ ***serviceName***: 設定欲連接到的 Service 名稱，這裡要填寫的就是 Service 中在 metadata 內寫上的 name
+ ***servicePort***: 設定要經由哪個 port 連接到 Service 物件
## example 3：支援終止 SSL (SSL termination)

![](https://i.imgur.com/X0Pj8uG.png =400x)

```yaml=
apiVersion: v1
kind: Secret
metadata:
  name: ssh-secret
  namespace: default
type: Opaque
data:
  tls.crt: base64_encoded_cert
  tls.key: base64_encoded_key
```

```yaml=
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: web
  namespace: whale
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
    - hosts:
        - ar-remoteassist.ddns.net
      secretName: ssh-secret
  rules:
    - host: blue.demo.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: blue-service
                port:
                  number: 8080
```
 