Kubernetes服務發布之Ingress


一、什么是Ingress

Ingress是通過service來關聯pod的,通過ingress controller實現pod的負載均衡,從而實現全局的負載均衡。

二、Ingress的安裝

首先安裝helm管理工具:https://helm.sh/docs/intro/install/

使用helm安裝ingress:https://kubernetes.github.io/ingress-nginx/deploy/#using-helm

2.1 添加helm倉庫

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

2.2 查看並下載helm軟件包 

# helm search repo ingress-nginx
NAME                           CHART VERSION    APP VERSION    DESCRIPTION                                       
ingress-nginx/ingress-nginx    4.0.8            1.0.5          Ingress controller for Kubernetes using NGINX a...

# helm pull ingress-nginx/ingress-nginx
# helm pull ingress-nginx/ingress-nginx --version 3.6.0     # 也可以指定版本下載 

2.3 修改對應的配置

# tar xf ingress-nginx-4.0.8.tgz 
# cd ingress-nginx/
# vim values.yaml

a、ingress-nginx/controller、ingress-nginx/kube-webhook-certgen和defaultbackend-amd64鏡像地址,需要將k8s.gcr.io倉庫中的鏡像同步至公司內網鏡像倉庫
b、將digest注釋
c、hostNetwork設置為 true
d、dnsPolicy設置為 ClusterFirstWithHostNet
Default:繼承Pod所在宿主機的DNS設置 ClusterFirst:優先使用Kubernetes環境的DNS服務(如CoreDNS提供的域名解析服務),將無法解析的域名轉發到從宿主機
ClusterFirstWithHostNet:與ClusterFirst相同,對於以hostNetwork模式運行的Pod,應明確指定使用該策略。
繼承的DNS服務器。
None:忽略Kubernetes環境的DNS配置,通過spec.dnsConfig自定義DNS配置。
e、NodeSelector添加ingress: "true"部署至指定節點
f、類型更改為kind: DaemonSet

# sed -n '186p;12p;13p;14p;18p;19p;598p;599p;600p;604p;605p;721p;722p;723p;727p;59p;83p;284p' values.yaml 
  image:
    registry: registry.cn-hangzhou.aliyuncs.com/lzlx
    image: ingress-nginx-controller
    tag: "v1.0.5"
   # digest: sha256:55a1fcda5b7657c372515fe402c3e39ad93aa59f6e4378e82acd99912fe6028d
  dnsPolicy: ClusterFirstWithHostNet
  hostNetwork: true  # 需要修改dnspolicy為
  kind: DaemonSet
  nodeSelector:
      image:
        registry: registry.cn-hangzhou.aliyuncs.com/lzlx
        image: ingress-nginx-kube-webhook-certgen
        tag: v1.1.1
       # digest: sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
  image:
    registry: estry.cn-hangzhou.aliyuncs.com/lzlx
    image: defaultbackend-amd64
    tag: "1.5"

2.4 部署ingress-nginx,將節點打上label ingress=true,然后將節點IP地址加入到clb負載均衡中

kubectl label node k8s-node3 ingress=true
kubectl create ns ingress-nginx
helm install ingress-nginx -n ingress-nginx .

三、創建一個ingress實例

3.1 創建 nginx web服務

# cat nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: mynginx
        image: nginx:1.18.0
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 500m
            memory: 1024Mi
          limits:
            cpu: 1000m
            memory: 2048Mi
# kubectl create -f nginx.yaml

3.2 創建service

# cat nginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: default
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - name: http
    port: 80
    targetPort: 80
# kubectl create -f nginx-service.yaml

3.3 創建ingress

官方參考鏈接:https://kubernetes.io/zh/docs/concepts/services-networking/ingress/

# cat nginx-ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress.lzlx.com
spec:
  rules:
  - host: ingress.lzlx.com
    http:
      paths:
      - path: /
        pathType: Prefix         # Exact:精確匹配URL路徑,且區分大小寫。 Prefix:基於以/ 分隔的 URL 路徑前綴匹配。匹配區分大小寫,並且對路徑中的元素逐個完成。
        backend:
          service:
            name: nginx-service
            port:
              number: 80
  ingressClassName: nginx        # 如果集群版本 >= 1.19使用新ingressClassName: nginx屬性代替注釋。
# kubectl create -f nginx-ingress.yaml 

3.4 綁定hosts進行訪問,ip地址為k8s-node3部署ingress服務的那台機器。

四、ingress的配置

4.1 Redirect,訪問域名重定向到baidu.com

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress.lzlx.com
  annotations:
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
spec:
  rules:
  - host: ingress.lzlx.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
  ingressClassName: nginx

它會自動在ingress-nginx-controller中增加相關的配置

# kubectl exec -it ingress-nginx-controller-5s4fw -n ingress-nginx -- bash
$ cat /etc/nginx/nginx.conf | grep baidu.com
            return 301 https://www.baidu.com;

4.2 rewrite ,訪問rewrite.lzlx.com/foo/bar/下的任意內容會重定向到/目錄下

# cat nginx-rewrite.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rewrite.lzlx.com
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1   # 這里指重定向到/,然后加上所有的參數
spec:
  ingressClassName: nginx
  rules:
  - host: rewrite.lzlx.com
    http:
      paths:
      - path: /foo/bar/(.+)
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
# kubectl exec -it nginx-deployment-76447d65c-694gr -- bash root@nginx-deployment-76447d65c-694gr:/# cat /usr/share/nginx/html/b.txt this is html dir

 4.3 ssl 證書配置

https://kubernetes.github.io/ingress-nginx/user-guide/tls/

生成證書,生產環境都是購買的通用證書,使用Default SSL Certificate,可以在ingress前面加個nginx proxy將證書配置到nginx proxy上,然后再反向代理到后端的ingress 80端口即可。

上傳域名證書,將域名證書創建成secret

# kubectl create secret tls m-test.com --key m-test.com.key --cert m-test.com.crt -n default
secret/m-test.com created

# kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-zxp2q   kubernetes.io/service-account-token   3      34d
m-test.com            kubernetes.io/tls                     2      6s

創建ingress文件

# cat nginx-lzlx.m-test.com.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: lzlx.m-test.com
spec:
  ingressClassName: nginx
  rules:
  - host: lzlx.m-test.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
  tls:
  - hosts:
    - lzlx.m-test.com
    secretName: m-test.com

# kubectl create -f nginx-lzlx.m-test.com.yaml 

創建完成再訪問的時候會自動https跳轉,如果想取消自動跳轉加上下面的參數

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: lzlx.m-test.com
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"

4.4 黑白名單配置

Annotations:只對指定的ingress生效

ConfigMap:全局生效

黑名單可以使用ConfigMap去配置,白名單建議使用Annotations去配置。

# cat nginx-lzlx.m-test.com.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: lzlx.m-test.com
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.0.1/24"  # 允許的白名單IP

黑名單配置

# kubectl edit  cm -n ingress-nginx ingress-nginx-controller -oyaml

apiVersion: v1
data:
  allow-snippet-annotations: "true"
  block-cidrs: 120.22.1.33                   # 要加入黑名單的IP地址

# kubectl delete pod -n ingress-nginx --all  # 重啟ingress pod,生產慎用

4.5 匹配請求頭,如果是移動設備則跳轉到m.baidu.com。server-snippet用來寫比較復雜的語法

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
        set $agentflag 0;

        if ($http_user_agent ~* "(Mobile)" ){
          set $agentflag 1;
        }

        if ( $agentflag = 1 ) {
          return 301 https://m.baidu.com;
        }

4.6 金絲雀 canary實現灰度發布

創建一個v2版本的ingress,使它的流量和正常的比為50%。

# cat www.test.com-canary.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: www.test.com-v2                                    # 和正常的ingress入口做一個區分
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"             # 開啟灰度發布,必須先啟用canary
    nginx.ingress.kubernetes.io/canary-weight: "50"        # 權重比例,50%的走canary 這個版本
spec:
  ingressClassName: nginx
  rules:
  - host: www.test.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service-v2
            port:
              number: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service-v2
spec:
  type: ClusterIP
  selector:
    app: nginx-v2
  ports:
  - name: http
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-v2
  template:
    metadata:
      labels:
        app: nginx-v2
    spec:
      containers:
      - name: mynginx
        image: nginx:1.18.0
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 500m
            memory: 1024Mi
          limits:
            cpu: 1000m
            memory: 2048Mi
# kubectl create -f www.test.com-canary.yaml 
# kubectl exec -it nginx-deployment-v2-6888df4554-pl7vz -- bash
# echo "v2" > /usr/share/nginx/html/index.html        # 將canary版本的主頁設置為v2,普通版本的設置為v1
# kubectl get ingress
NAME                     CLASS   HOSTS                    ADDRESS         PORTS     AGE
www.test.com-v1          nginx   www.test.com             10.111.38.227   80        2d23h
www.test.com-v2          nginx   www.test.com             10.111.38.227   80        2d22h

# curl www.test.com  # 進行測試
v2
# curl www.test.com
v2
# curl www.test.com
v1
# curl www.test.com
v1

nginx.ingress.kubernetes.io/canary-by-header:用於通知 Ingress 將請求路由到 Canary Ingress 中指定的服務的標頭。當請求頭設置為 時always,它將被路由到金絲雀。當標頭設置為 時never,它永遠不會被路由到金絲雀。對於任何其他值,標頭將被忽略,並按優先級將請求與其他金絲雀規則進行比較。

nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的標頭值,用於通知 Ingress 將請求路由到 Canary Ingress 中指定的服務。當請求頭設置為這個值時,它將被路由到金絲雀。對於任何其他標頭值,標頭將被忽略,並按優先級將請求與其他金絲雀規則進行比較。此注釋必須與 一起使用。注釋是 的擴展,nginx.ingress.kubernetes.io/canary-by-header允許自定義標頭值而不是使用硬編碼值。如果nginx.ingress.kubernetes.io/canary-by-header未定義注釋,則沒有任何影響。

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: www.test.com-v2
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "user"
    nginx.ingress.kubernetes.io/canary-by-header-value: "leon"

#  curl -H "user: leon" www.test.com
v2
# curl www.test.com
v1

4.7 http登錄認證

官方樣例:https://kubernetes.github.io/ingress-nginx/examples/auth/basic/

# yum install httpd -y      # 安裝htpasswd命令

# htpasswd -c auth leon     # -c 參數創建auth密碼文件 (必須是auth否則會報 ingress auth 503 Service Temporarily Unavailable) 用戶名是leon輸入密碼
New password: 
Re-type new password: 
Adding password for user leon

# kubectl create secret generic auth-wwwtest --from-file=auth     # 使用剛生成的auth-wwwtest文件,創建auth-wwwtest 的secret

# kubectl get secret auth-wwwtest -o yaml
apiVersion: v1
data:
  auth-wwwtest: bHpseDokYXByMSR1N2hYZlliZiR2OEFjYmFQcWdRdFYvUlJlNmpMQ3kxCg==
kind: Secret
metadata:
  - apiVersion: v1
  name: auth-wwwtest
  namespace: default
type: Opaque

# cat www.test.com.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: www.test.com-v1
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: auth-wwwtest
    nginx.ingress.kubernetes.io/auth-realm: 'describe auth'

# kubectl apply -f www.test.com.yaml 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM