使用Helm3.6 安裝 Ingress-nginx


1 概述

NGINX Ingress Controller 是使用 Kubernetes Ingress 資源對象構建的,用 ConfigMap 來存儲 Nginx 配置的一種 Ingress Controller 實現。

安裝 ingress-nginx 有多種方式,本文使用 helm3.6 方式進行安裝。

其他安裝方式可以參考文檔:https://kubernetes.github.io/ingress-nginx/deploy/

本文 k8s 集群環境是在 centos7 系統上由 kubeadm 搭建的單 master 集群:

[root@k8s-master ~]# kubectl get nodes -o wide
NAME      STATUS   ROLES    AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION           CONTAINER-RUNTIME
master1   Ready    master   36d   v1.19.3   192.168.5.60   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   docker://19.3.11
node1     Ready    <none>   36d   v1.19.3   192.168.5.61   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   docker://19.3.11
node2     Ready    <none>   36d   v1.19.3   192.168.5.62   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   docker://19.3.11

2 helm介紹

Helm 是一個用於對需要在 k8s 上部署的復雜應用進行定義、安裝和更新。Helm 以 Char 的方式對應用軟件進行描述,可以方便地創建、版本化、共享和發布復雜的應用軟件。

2.1 helm的主要概念

  • Chart

Helm的應用包,采用tgz格式。類似於 Yum 的 RPM 包,其包含了一組定義 Kubernetes 資源相關的 YAML 文件,也稱為應用 Chart。

  • Repoistory

Helm 的應用倉庫,Repository 本質上是一個 Web 服務器,該服務器保存了一系列的 Chart 應用包以供用戶下載,並且提供了一個該 Repository 的 Chart 包的清單文件以供查詢,Helm可以同時管理多個不同的Repository。

Helm社區官方提供了stable和incubator倉庫,但Helm社區沒有打算獨占倉庫,而是允許其他人和組織也可以搭建倉庫。倉庫可以是公共倉庫,也可以是私有倉庫。

  • Release

在 Kubernetes 集群上運行的 Chart 的一個實例。在同一個集群上,一個 Chart 可以安裝很多次。每次安裝都會創建一個新的 Release。例如一個 MySQL Chart,如果想在服務器上運行兩個 MySQL 數據庫,就可以把這個 Chart 安裝兩次。每次安裝都會生成一個新的Release。

2.2 helm安裝

Helm安裝官方文檔:https://helm.sh/docs/intro/install/

這里安裝 helm v3 版本,直接從 github 下載源碼包:

# 下載
[root@k8s-master ~]# wget https://get.helm.sh/helm-v3.6.0-linux-amd64.tar.gz

# 解壓
[root@k8s-master ~]# tar -zxvf helm-v3.6.0-linux-amd64.tar.gz

# 移動到環境變量目錄里面即可
[root@k8s-master ~]# mv linux-amd64/helm /usr/local/bin/helm

# 輸出版本
[root@k8s-master ~]# helm version
version.BuildInfo{Version:"v3.6.3", GitCommit:"d506314abfb5d21419df8c7e7e68012379db2354", GitTreeState:"clean", GoVersion:"go1.16.5"}

2.3 chart包的目錄結構

# 創建一個chart,chart的名稱叫 helm-test
[root@k8s-master ~]# helm create helm-test
Creating helm-test
[root@k8s-master ~]# cd helm-test/

# 查看 chart 的目錄結構
[root@k8s-master helm-test]# tree .
.
├── charts								
├── Chart.yaml					
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml							

3 directories, 10 files
[root@k8s-master helm-test]# 

chart 是 Helm 的應用打包格式。chart 由一系列文件組成,這些文件描述了 Kubernetes 部署應用時所需要的資源。上面通過 helm 命令創建了一個 chart 包,目錄結構說明如下:

  • helm-test:是 chart 包的名稱
  • charts 目錄: 保存依賴文件的目錄,如果依賴其他的 chart,則會保存在這里
  • Chart.yaml 文件:用於描述 chart 信息的 yaml 文件,如版本信息等
  • values.yaml 文件:chart 支持在安裝的時根據參數進行定制化配置,而 values.yaml 則提供了這些配置參數的默認值,可以在安裝前根據需要修改 values.yaml 的參數
  • templates 目錄:各類 Kubernetes 資源的配置模板都放置在這里。Helm 會將 values.yaml 中的參數值注入到模板中生成標准的 YAML 配置文件

3 helm 安裝 ingress-nginx

3.1 添加 ingress-nginx 官方helm倉庫

[root@k8s-master ~]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
[root@k8s-master ~]# helm repo update

執行這一步的時候,我報錯了:

[root@k8s-master ~]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
Error: looks like "https://kubernetes.github.io/ingress-nginx" is not a valid chart repository or cannot be reached: Get "https://kubernetes.github.io/ingress-nginx/index.yaml": dial tcp [::1]:443: connect: connection refused

可以看到是無法訪問到 https://kubernetes.github.io ,估計是被牆了。ping 一下域名發現解析到了 127.0.0.1:

[root@k8s-master ~]# ping kubernetes.github.io
PING kubernetes.github.io (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.084 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.068 ms
^C
--- kubernetes.github.io ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.055/0.069/0.084/0.011 ms

本地檢查沒有配置 hosts 信息,所以這應該是 DNS 解析的問題,嘗試更換 DNS 服務器,114.114.144.144 或者 8.8.8.8 都是一樣不能訪問。於是找到站長之家,獲取一下 kubernetes.github.io 域名的 IP 地址:

獲取到 IP 地址后,選擇一個IP地址,配置本地hosts解析:

[root@k8s-master ~]# echo "https://ip.tool.chinaz.com/kubernetes.github.io" >> /etc/hosts

然后重新添加倉庫,可以看到已添加成功。

# 添加倉庫
[root@k8s-master ~]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
"ingress-nginx" has been added to your repositories

# 更新
[root@k8s-master ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "ingress-nginx" chart repository
Update Complete. ⎈Happy Helming!⎈

3.2 下載ingress-nginx的chart包

[root@k8s-master ~]# cd /usr/local/src/

# 查找ingress-nginx的chart包
[root@k8s-master src]# helm search repo ingress-nginx
NAME                            CHART VERSION   APP VERSION     DESCRIPTION                                       
ingress-nginx/ingress-nginx     4.0.1           1.0.0           Ingress controller for Kubernetes using NGINX a...

# 下載下來
[root@k8s-master src]# helm pull ingress-nginx/ingress-nginx

# 以tgz為后綴的包就是我們下載的chart包
[root@k8s-master src]# ls
helm-v3.6.3-linux-amd64.tar.gz  ingress-nginx-4.0.1.tgz  linux-amd64

# 解壓
[root@k8s-master src]# tar -zxvf ingress-nginx-4.0.1.tgz 

# 目錄結構如下
[root@k8s-master src]# cd ingress-nginx
[root@k8s-master ingress-nginx]# ls
CHANGELOG.md  Chart.yaml  ci  OWNERS  README.md  templates  values.yaml

3.3 修改 values.yaml 文件

下載下來的 chart 包,需要修改一下資源清單配置文件,修改 values.yaml 文件如下:

修改 ingress-nginx-contorller 的鏡像倉庫地址,默認是 k8s.gcr.io 國內無法訪問,這里用到github上一個同步 ingress-nginx-contorller 的倉庫 docker.io/willdockerhub/ingress-nginx-controller

修改 hostNetwork 的值為 true

dnsPolicy的值改為: ClusterFirstWithHostNet

nodeSelector 添加標簽: ingress: "true",用於部署 ingress-controller 到指定節點

kind類型更改為:DaemonSet

kube-webhook-certgen的鏡像地址改為國內倉庫地址 registry.aliyuncs.com/google_containers/kube-webhook-certgen

3.4 執行安裝

資源清單文件修改完成后,執行helm安裝:

# 先創建一個名稱空間
[root@k8s-master ~]# kubectl create ns ingress-nginx
namespace/ingress-nginx created

# 進入chart目錄
[root@k8s-master ~]# cd /usr/local/src/ingress-nginx

# helm安裝
[root@k8s-master ingress-nginx]# helm install ingress-nginx -n ingress-nginx .
NAME: ingress-nginx
LAST DEPLOYED: Wed Sep 15 10:17:09 2021
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller'

An example Ingress that makes use of the controller:

  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: 
    name: example
    namespace: foo
  spec:
    rules:
      - host: www.example.com
        http:
          paths:
            - backend:
                serviceName: exampleService
                servicePort: 80
              path: /
    # This section is only required if TLS is to be enabled for the Ingress
    tls:
        - hosts:
            - www.example.com
          secretName: example-tls

If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:

  apiVersion: v1
  kind: Secret
  metadata:
    name: example-tls
    namespace: foo
  data:
    tls.crt: <base64 encoded cert>
    tls.key: <base64 encoded key>
  type: kubernetes.io/tls
[root@k8s-master ingress-nginx]# 

出現上面的命令輸出表示安裝完成了,安裝完成后,需要給節點打上剛剛設置的標簽ingress=true,讓 Pod 調度到指定的節點,比如調度到 master 節點:

# 給master節點打上標簽 ingress=ture
[root@k8s-master ingress-nginx]# kubectl label node master1 ingress=true
node/master1 labeled

# k8s默認集群中,出於安全考慮,默認配置下Kubernetes不會將Pod調度到Master節點。測試環境無所謂,所以執行下面命令去除master的污點:
[root@k8s-master ingress-nginx]# kubectl taint node master1 node-role.kubernetes.io/master-

執行完成之后,就可以看到 ingress-nginx 部署到了master節點了:

[root@k8s-master ~]# kubectl get all -n ingress-nginx
NAME                                 READY   STATUS    RESTARTS   AGE
pod/ingress-nginx-controller-nldt4   1/1     Running   0          3m45s

NAME                                         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.103.248.36   <pending>     80:30318/TCP,443:30865/TCP   3m45s
service/ingress-nginx-controller-admission   ClusterIP      10.104.51.205   <none>        443/TCP                      3m46s

NAME                                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                         AGE
daemonset.apps/ingress-nginx-controller   1         1         1       1            1           ingress=true,kubernetes.io/os=linux   3m45s

Pod也是部署在了master節點:

[root@k8s-master ~]# kubectl get pods -n ingress-nginx -o wide
NAME                             READY   STATUS    RESTARTS   AGE     IP             NODE      NOMINATED NODE   READINESS GATES
ingress-nginx-controller-nldt4   1/1     Running   0          4m12s   192.168.5.60   master1   <none>           <none>

3.5 測試 ingress-nginx

創建后端的 nginx 的 Pod 和 Service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: svc-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - image: nginx:1.18.0
        name: svc-demo
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: svc-demo
spec:
  selector:  
    app: myapp
  ports:
  - targetPort: 80  # 后端Pod的端口
    port: 8080 # 服務要暴露的端口

查看 Pod 和 Service:

[root@k8s-master service]# kubectl get pods,svc 
NAME                           READY   STATUS    RESTARTS   AGE
pod/svc-demo-f9785fc46-hz6db   1/1     Running   1          7d22h
pod/svc-demo-f9785fc46-m99mj   1/1     Running   1          7d22h

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          36d
service/svc-demo     NodePort    10.106.152.13   <none>        8080:31195/TCP   29d

創建 ingress 規則,ingress-nginx.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
  name: example
spec:
  rules: # 一個ingress可以配置多個rules
  - host: foo.bar.com # 域名配置,可以不寫,匹配*,或者寫 *.bar.com
    http:
      paths: # 相當於nginx的location,同一個host可以配置多個path
      - backend:
          serviceName: svc-demo  # 代理到哪個svc
          servicePort: 8080 # svc的端口
        path: /

創建ingress:

[root@k8s-master service]#  kubectl apply -f ingress-nginx.yaml

[root@k8s-master service]# kubectl get ingress
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
example   <none>   foo.bar.com             80      21m

window的 hosts 配置解析:

192.168.5.60 foo.bar.com

瀏覽器訪問,可以看到已經成功通過ingress將請求轉發到后端Pod上了。

至此,一個簡單的ingress示例就完成了,本文over。

4 參考資料


免責聲明!

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



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