[雲端] K8s / Ingress
===
###### tags: `雲端 / K8s`
###### tags: `雲端`, `K8s`, `ingress`
<br>
<br><br>
[TOC]
<br>
## [Kubernetes 基礎教學(二)實作範例:Pod、Service、Deployment、Ingress](https://medium.com/@C.W.Hu/kubernetes-implement-ingress-deployment-tutorial-7431c5f96c3e)

### 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)
- 在叢集內,開放 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 上的示意圖

- 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 上的示意圖

- 直接輸入 **```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

<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/)

<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)