Ingress 是 Kubernetes 中一個進階的服務元件,提供比基本 Service 更多的功能,例如驗證、負載平衡、路由過濾等。但是, Kubernetes 預設是沒有 IngressController 的(我印象中是這樣啦),因此我們需要在使用 Ingress 之前,你需要先手動建立一個 Ingress Controller,並為其配置相應的資源。
因為這次資源有點多,所以我們先建立一個新的 Namespace,這裡命名為 ingress-nginx:
# ingress-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
然後,使用 Nginx 創建兩個簡單的 Pod 和相應的 Service:
# nginx-pods-and-services.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod1
namespace: default
labels:
app: nginx-pod1
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod2
namespace: default
labels:
app: nginx-pod2
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service-1
spec:
selector:
app: nginx-pod1
ports:
- protocol: TCP
port: 8081
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service-2
spec:
selector:
app: nginx-pod2
ports:
- protocol: TCP
port: 8082
targetPort: 80
接下來,進入 Pod 內修改顯示的內容,通常位置在 /usr/share/nginx/html/index.html
:
kubectl exec -it pod nginx-pod1 -- bash
然後建立 Ingress Controller:
# ingress-controller.yaml
# ...(之前的 ConfigMap、ServiceAccount、Role、RoleBinding 的內容)
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
hostNetwork: true
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
kubernetes.io/os: linux
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.33.0
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
runAsUser: 101
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
# ...(之後的 livenessProbe、readinessProbe、lifecycle 等的內容)
然後,建立相應的 LimitRange 資源和 Ingress 服務:
# ingress-limits-and-service.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
limits:
- min:
memory: 90Mi
cpu: 100m
type: Container
---
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
nodePort: 30080
- name: https
port: 443
targetPort: 443
protocol: TCP
nodePort: 30443
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
最後,建立 Ingress 資源,將不同路由映射到不同的後端 Pod:
# ingress-resource.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: my.example.com # 要轉的域名 -> http://"my.example.com"/pod1
http:
paths:
- path: /pod1 # 自訂的path
pathType: Prefix
backend:
service:
name: nginx-service-1
port:
number: 8081
- path: /pod2
pathType: Prefix
backend:
service:
name: nginx-service-2
port:
number: 8082
這樣,你就可以透過不同的路由進入到不同的後端 Pod 了。