YAZONG 我的开源

Kubernetes(六)(迁移Kubernetes前准备)(6.5/6)部署ingress-nginx(上-下)(对照6-2/3)

  , , ,
0 评论0 浏览

上一节学习了K8S的服务发现、像service、DNS、endpoint、hostport,这些都是之前搭建的K8S集群所具备的能力,也就是可以直接使用这个方案去部署服务。但是还有一种域名访问的服务,叫ingress,是目前集群还不具备的能力,同时域名访问的需求几乎是每个公司要有的,所以必须要让集群具备这个能力。

选择一个比较主流的方案,把ingress-nginx在集群中部署起来,从而让K8S集群具备服务发现的能力。

image.png

https://kubernetes.io/docs/concepts/services-networking/ingress/”

https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/”

#ingress介绍略。

什么是ingress controller?

通常来说,配置一个WEB服务或负载均衡器是比较麻烦的,大部分的webserver的配置是非常相似的,一些应用是比较特殊,但大部分的配置可以使用相同的逻辑,并且得到想要的结果。

ingress controller是一个daemon,作为K8S的POD来运行的,会去监听apiserver的/ingresses地址,以便实时去更新ingress resource。

部署开始

#6-6停止了6-2/3双主复制的node-2

[root@node-1 ~]# mkdir ingress-nginx
[root@node-1 ~]# cd ingress-nginx 

mandatory.yaml内容

[root@node-1 ingress-nginx]# cat mandatory.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: default-http-backend
  labels:
    app.kubernetes.io/name: default-http-backend
    app.kubernetes.io/part-of: ingress-nginx
  namespace: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: default-http-backend
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: default-http-backend
        app.kubernetes.io/part-of: ingress-nginx
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - name: default-http-backend
          # Any image is permissible as long as:
          # 1. It serves a 404 page at /
          # 2. It serves 200 on a /healthz endpoint
          image: k8s.gcr.io/defaultbackend-amd64:1.5
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 30
            timeoutSeconds: 5
          ports:
            - containerPort: 8080
          resources:
            limits:
              cpu: 10m
              memory: 20Mi
            requests:
              cpu: 10m
              memory: 20Mi

---
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: default-http-backend
    app.kubernetes.io/part-of: ingress-nginx
spec:
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app.kubernetes.io/name: default-http-backend
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: udp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: nginx-ingress-role
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      # Defaults to "<election-id>-<ingress-class>"
      # Here: "<ingress-controller-leader>-<nginx>"
      # This has to be adapted if you change either parameter
      # when launching the nginx-ingress-controller.
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

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:
      serviceAccountName: nginx-ingress-serviceaccount
      hostNetwork: true
      nodeSelector:
        app: ingress
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.19.0
          args:
            - /nginx-ingress-controller
            - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
            - --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:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            # www-data -> 33
            runAsUser: 33
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1

---

手工拉取镜像

#这里不用docker拉取。注意是操作的containerd的k8s.io这个命名空间。
"5-6containerd"中配置的默认容器是containerd
[root@node-1 ingress-nginx]# grep image mandatory.yaml 
          # Any image is permissible as long as:
          image: k8s.gcr.io/defaultbackend-amd64:1.5
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.19.0
[root@node-2/3 ~]# ctr -n k8s.io i pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.19.0
[root@node-2/3 ~]# ctr -n k8s.io image list|grep ingress
[root@node-2/3 ~]# ctr -n k8s.io i pull registry.cn-hangzhou.aliyuncs.com/liuyi01/defaultbackend-amd64:1.5
#httpbackend是一个附属品,对主流程没有影响,当找不到页面时候会甩给它。
#公网拉取不下来的打tag
[root@node-2/3 ~]# ctr -n k8s.io i tag registry.cn-hangzhou.aliyuncs.com/liuyi01/defaultbackend-amd64:1.5  k8s.gcr.io/defaultbackend-amd64:1.5 
[root@node-2/3 ~]# ctr -n k8s.io image list|grep defaultbackend

image.png

设置label

#关于ingress nginx服务暴露:hostport方式
#作用:停止一个worker节点node-2的harbor,以host的形式去运行ingress controller,然后把ingress controller调度在这个节点上。
#通过什么形式去访问这个节点呢?可以给这个节点打一个标签,在调度的时候,通过标签选择器去选择这个节点。
[root@node-1或者2 ingress-nginx]# kubectl label node node-2 app=ingress
#这里的节点名称是node-2,给node-2打的标签是ingress。
node/node-2 labeled
2、1标签对应app=ingress的配置
#这里和label挂钩,否则ingress-nginx-controller的POD一直会处于pending状态。
[root@node-1 ingress-nginx]# vim mandatory.yaml
    spec:
#打完标签就可以修改配置文件了。大约在文件170行
#在serviceAccountName: nginx-ingress-serviceaccount和containers中加入下述三行!
	  serviceAccountName: nginx-ingress-serviceaccount
      hostNetwork: true		(选择)网络模式hostNetwork
      nodeSelector:			(加入)节点选择器
        app: ingress		(选择)固定的节点,节点的标签选择ingress
      containers:
        - name: nginx-ingress-controller

2、2停掉node-2的harbor
#这里的node-2指ingress-nginx部署到的节点,要保证此节点无80/443端口。
#这台节点部署了harbor,把它停掉,并不影响node-1代理node-3的harbor,那么6-3的双主复制暂时不用了。
[root@node-2 harbor]# docker-compose down
#释放并检查80和443端口,说明这个机器具有运行ingress controller的能力。
[root@node-2 harbor]# netstat -lntup|grep 80   
[root@node-2 harbor]# netstat -lntup|grep 443

关于ingress nginx服务暴露的说明

https://kubernetes.github.io/ingress-nginx”

https://github.com/kubernetes/ingress-nginx/”

image.png

image.png

定义了一个service,类型是nodeport,端口是80,容器端口也是80。

那么这里使用这个NodePort是可以的,但NodePort不是一个好的方案,并且K8S默认不允许NodePort暴露80和443的,NodePort默认是从30000开始,虽然可以修改这个值,但是也不会改成80和443这么小的一个值。

还有什么方式来暴露ingress nginx的服务呢?上节服务发现内容,暴露80端口,前提是暴露出来的端口也必须是80端口,因为作为服务的入口,nginx必须是80才能域名访问,否则访问哪个域名都需要加一个端口,不合适。

那么这里使用hostport,相当于以host的形式去运行ingress controller,有几点好处,首先host模式要比桥接bridge的效率要强一些,并且没有网络的转发,如果要用nodeport,那么任何一个节点都可以访问的,不知道运行哪个节点的话,那么相当于多一次转发。

那么以hostnetwork模式运行,就出现一个问题,那么80端口只会监听在当前实例运行的机器上,所以要指定一台或几台机器,比如实例数量2,在每台节点都运行一个实例,这是一个方式。

但是鉴于目前集群的情况,只有两个worker节点,都有harbor的80端口在监听,所以暂时停掉一个harbor,释放出80端口,然后把ingress controller调度在这个节点上。

这里停止node-2这个worker节点。

并检查80和443端口,说明这个机器具有运行ingress controller的能力。

通过什么形式去访问这个节点呢?可以给这个节点打一个标签,在调度的时候,通过标签选择器去选择这个节点。

这里的节点名称是node-2,标签是ingress。

打完label标签就可以修改配置文件mandatory.yaml。

首先修改网络模式,改成hostNetwork,加入节点选择器,固定的节点。

hostNetwork: true

  nodeSelector:

    app: ingress

这样mandatory.yaml文件就修改好了。

创建ingress-nginx

#如遇apply错误先删除
[root@node-1 ingress-nginx]# kubectl delete -f mandatory.yaml 
#创建
[root@node-1 ingress-nginx]# kubectl apply -f mandatory.yaml
#额外说明:应先不修改mandatory.yaml(不打标签),先测试"kubectl apply -f mandatory.yaml"是否成功,这里直接在一起搞了。
[root@node-1 ingress-nginx]# kubectl get all -n ingress-nginx

image.png

[root@node-1 ingress-nginx]# kubectl get nodes  
NAME     STATUS   ROLES    AGE    VERSION
node-2   Ready    <none>   5d6h   v1.20.2
node-3   Ready    <none>   5d6h   v1.20.2

[root@node-2 harbor]# netstat -lntup|grep 443
[root@node-2 harbor]# netstat -lntup|grep 80

image.png

案例测试ingress-nginx文件内容

#这里的文件可能随着K8S的升级,属性可能会有所改变。

#参考地址:

https://github.com/kubernetes/kubernetes/pull/89778”

https://www.cnblogs.com/dudu/p/15548461.html”

[root@node-1 ingress-nginx]# cat ingress-demo.yaml
#首先是一个Deployment,镜像是一个tomcat镜像,端口是8080,运行这个tomcat容器。
Deployment有了之后,Service通过Selector,会选中app:tomcat=demo,会选中上面的Deployment对应的POD,8080端口映射为service的80端口。
--这是一个比较标准的Deployment和Service的配置。

#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-demo
spec:
  selector:
    matchLabels:
      app: tomcat-demo
  replicas: 1
  template:
    metadata:
      labels:
        app: tomcat-demo
    spec:
      containers:
      - name: tomcat-demo
        image: registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine
        ports:
        - containerPort: 8080
---
#service
apiVersion: v1
kind: Service
metadata:
  name: tomcat-demo
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: tomcat-demo

---
#ingress
#old version: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tomcat-demo
spec:
  rules:
  - host: tomcat.mooc.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:              
            name: tomcat-demo        
            port:                
              number: 80
#这是新加的ingress,ingress新加的域名是tomcat.mooc.com,根路径/,所有的地址都会跳到这里,后端serviceName是上面service定义的名称,端口80。

案例测试ingress-nginx是否能用

[root@node-1 ingress-nginx]# pwd
/root/ingress-nginx
[root@node-1 ingress-nginx]# ll ingress-demo.yaml 
-rw-r--r-- 1 root root 844 Aug  9 12:17 ingress-demo.yaml
[root@node-1 ingress-nginx]# grep image ingress-demo.yaml 
        image: registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine
#"5-6containerd"中配置的默认容器是containerd
[root@node-2/3 ~]# ctr -n k8s.io i pull registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine
[root@node-2/3 ~]# ctr -n k8s.io image list|grep tomcat
[root@node-1 ingress-nginx]# kubectl create -f ingress-demo.yaml 
deployment.apps/tomcat-demo created
service/tomcat-demo created
ingress.networking.k8s.io/tomcat-demo created

#本机hosts和服务器hosts都加入
C:\Windows\System32\drivers\etc\hosts
10.0.0.22   tomcat.mooc.com
10.0.0.22   api.mooc.com
[root@node-1/2/3 ingress-nginx]# cat /etc/hosts
10.0.0.22   tomcat.mooc.com
10.0.0.22   api.mooc.com

[root@node-1 ingress-nginx]# kubectl get pod -o wide

image.png

案例测试ingress-nginx结果

#访问测试:http://api.mooc.com/

这个页面就是由default-http-backend的POD返回回来的。

404找不到对应的后端,因为并没有配置相应的ingress。

这个是由default-http-backend处理的,httpbackend是一个附属品,对主流程没有影响,当找不到页面的时候会甩给它。

image.png

#访问测试:http://tomcat.mooc.com/

#配置了相应的ingress了,也有service,但是service对应的POD处于不可用状态,所以是503。验证一下状态。

image.png

#镜像下载完成再去访问tomcat测试:http://tomcat.mooc.com/

#证明在这个域名下,所有的访问请求都会去对应的找到正确的backend。

#证明这个ingress controller可以正常工作的。

image.png


标题:Kubernetes(六)(迁移Kubernetes前准备)(6.5/6)部署ingress-nginx(上-下)(对照6-2/3)
作者:yazong
地址:https://blog.llyweb.com/articles/2022/11/11/1668107187285.html