這里直接是安裝和演示的過程,概念理論部分自行到官網學習,就不再贅述了。
Ingress 介紹:https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
一、k8s 安裝 ingress-nginx
下載 Ingress-nginx yaml文件
[root@k8s-master01 ingress-nginx]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
[root@k8s-master01 ingress-nginx]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
[root@k8s-master01 ingress-nginx]# ls
mandatory.yaml service-nodeport.yaml
mandatory.yaml
下載后需要添加hostNetwork: true
,否則無法通過 K8s 節點 IP 地址綁定域名外部訪問。
ingress-controller 會直接使用 K8s 物理機的 DNS 來解析域名,而不再使用 K8s 內部的 DNS 來解析域名。
mandatory.yaml
配置修改如下:
...
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:
# wait up to five minutes for the drain of connections
# 添加 hostNetwork: true
hostNetwork: true
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
kubernetes.io/os: linux
service-nodeport.yaml
配置
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
- name: https
port: 443
targetPort: 443
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
修改好后,開始安裝 Ingress-nginx
[root@k8s-master01 ingress-nginx]# kubectl apply -f mandatory.yaml
[root@k8s-master01 ingress-nginx]# kubectl apply -f service-nodeport.yaml
查看 Ingress Pod 是否 Running 狀態
[root@k8s-master01 ingress-nginx]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-6979d75b9d-fqf8v 1/1 Running 0 73s
二、創建實例測試 Ingress
my-nginx.yml
配置文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx:latest
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
run: my-nginx
type: ClusterIP
ports:
- protocol: TCP
port: 8080
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: test.ingress.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 8080
創建 Deployment、service、ingress
[root@k8s-master01 ingress-nginx]# kubectl apply -f my-nginx.yml
deployment.apps/my-nginx created
service/nginx-service created
ingress.networking.k8s.io/example-ingress created
檢查是否創建成功
[root@k8s-master01 ingress-nginx]# kubectl get ingress -o wide
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress <none> test.ingress.com 10.233.31.38 80 40s
[root@k8s-master01 ingress-nginx]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-6d97ddfff5-7jkp6 1/1 Running 0 44s
[root@k8s-master01 ingress-nginx]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 30d
nginx-service ClusterIP 10.233.39.79 <none> 8080/TCP 48s
nginx-ingress-controller
所在的節點與域名做好hosts
綁定,就可以訪問后端 Pod 服務了
[root@k8s-master01 ingress-nginx]# kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-controller-6979d75b9d-fqf8v 1/1 Running 0 9m49s 192.168.3.248 k8s-node01 <none> <none>
[root@k8s-master01 ingress-nginx]# vim /etc/hosts
[root@k8s-master01 ingress-nginx]# tail -1 /etc/hosts
192.168.3.248 test.ingress.com
我這里nginx-ingress-controller
所在的節點是 k8s-node01,它的IP地址是192.168.3.248,所以把剛剛自定義的域名進行綁定解析。
訪問成功test.ingress.com
域名
三、優化 Ingress-nginx
通過上述的實驗,我們可以發現默認是 Deployment 類型,將 Ingress 改為 DaemonSet 類似,讓每個工作節點運行一個 ingress-controller,這樣可以達到高可用效果,某個節點宕機了,不會影響 Ingress 工作。
其實生成環境的做法是在 K8s 工作節點上安裝 keepalive ,通過 VIP 作為對外 IP地址與域名解析。
- 將 Deployment 改為 DaemonSet;並刪掉 replicas;
- 添加字段 hostNetwork: true(剛剛在上面已經添加了)
- nodeSelector:給工作節點打上標簽,master 節點不會部署。
把之前的 ingress-controller 刪除掉,修改配置文件后,重新創建:
[root@k8s-master01 ingress-nginx]# kubectl delete -f mandatory.yaml
修改 mandatory.yaml 配置文件:
[root@k8s-master01 ingress-nginx]# vim mandatory.yaml
對 master 設置污點,其他工作節點都部署
[root@k8s-master01 ingress-nginx]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 30d v1.21.5
k8s-node01 Ready worker 30d v1.21.5
k8s-node02 Ready worker 30d v1.21.5
[root@k8s-master01 ingress-nginx]# kubectl taint nodes k8s-master01 node-role.kubernetes.io/master=true:NoSchedule
node/k8s-master01 tainted
重新創建 Ingress-nginx,以及查看狀態
[root@k8s-master01 ingress-nginx]# kubectl apply -f mandatory.yaml
[root@k8s-master01 ingress-nginx]# kubectl get pod -n ingress-nginx -o wide
無論域名綁定那個工作節點IP地址,都可以解析到后端的 Pod 服務了,一個節點宕機了不會影響 Ingress 工作。
最后,以上屬於測試環境實驗,想要真正的 Ingress 高可用,還是得結合 Keepalived 或者 SLB 一起實現。