节点端口的 K8s 入口。初学者示例

K8s Ingress for nodeport. Example for beginners

你能帮帮我吗?我想为 nodeport 部署 Ingres。但我不明白这是否可能?

我试图在 Google 中找到一些信息,但我在 rails 上找到了用于负载平衡的 Ingress 或一些困难的示例 Ingress Ruby 等

ingress 背后的想法是您需要使用 ingress 控制器,如何公开 ingress 控制器完全取决于您,因为您将使用 Kubernetes 服务来公开它,例如,如果您想在您的结构的节点端口类似于:


service exposing nodeport ==> ingress controller ==> web app service (via ingress) ==> web app

这是一个通用流程,因为无论您如何公开入口控制器(LoadBalancer、NodePort 等),路由通常都基于主机名,即如果我的 NodePort 在 172.64.0.25:30965 上公开,那么我会将我的域指向该 IP 和基于它路由的主机的入口路由。可以找到很多关于此的文档 here(这是针对 Nginx 入口控制器的,但所有入口路由都非常相似)

下面我将尝试提供我能想到的最简单的示例。我将使用 nginxdemos/hello docker 图像作为示例。在本地这是这样工作的:

$docker run -p 80:80 -d nginxdemos/hello    
...
$curl -I http://localhost

HTTP/1.1 200 OK
Server: nginx/1.13.8
Date: Tue, 08 Oct 2019 06:14:52 GMT
Content-Type: text/html
Connection: keep-alive
Expires: Tue, 08 Oct 2019 06:14:51 GMT
Cache-Control: no-cache

酷。这是我们的后端部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-backend
  namespace: java2days
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-server
  template:
    metadata:
      labels:
        app: nginx-server
    spec:
      containers:
        - name: nginx-server
          image: nginxdemos/hello
          ports:
            - containerPort: 80
              name: server-port
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 15
            periodSeconds: 15
            timeoutSeconds: 3
          readinessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 15
            periodSeconds: 15
            timeoutSeconds: 3

很快我们就会有一个 nginx 服务器的 2 个副本。在云端某处的节点上 运行:

$kubectl get pods

NAME                            READY   STATUS    RESTARTS   AGE
nginx-backend-dfcdb9797-dnx7x   1/1     Running   0          21m
nginx-backend-dfcdb9797-pnrhn   1/1     Running   0          21m

现在让我们创建一个 NodePort 服务。这是服务 yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: java2days
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
      name: http
  selector:
    app: nginx-server
  type: NodePort

注意选择器,它匹配后端服务。现在是入口控制器的时候了。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: java2days
spec:
  rules:
    - http:
        paths:
          - backend:
              serviceName: nginx-service
              servicePort: 80
            path: /*

您将需要等待大约 5-10 分钟,直到 GCloud 为该 Ingress 提供 IP 地址。终于完成了,像这样:

$kubectl get ingress

NAME            HOSTS   ADDRESS         PORTS   AGE
nginx-ingress   *       x.y.z.p         80      15m

现在从我的本地机器:

$curl -I http://x.y.z.p

HTTP/1.1 200 OK

很好,它正在运行。如果您在浏览器中打开它并刷新多次,您将看到服务器 ID 发生变化并且负载平衡起作用。额外的阅读入口点 - here.

完成实验后不要忘记清理资源。

创建部署和服务

kubectl create deploy test --image httpd
kubectl expose deploy test --port 80 --target-port 80

检查服务是否正常

kubectl get svc

returns

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
test         ClusterIP   11.105.18.110   <none>        80/TCP    51s

然后

curl 11.105.18.110:80

returns

<html><body><h1>It works!</h1></body></html>

创建裸机入口控制器

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/baremetal/deploy.yaml

https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal

这个returns

namespace/ingress-nginx unchanged
serviceaccount/ingress-nginx unchanged
configmap/ingress-nginx-controller configured
clusterrole.rbac.authorization.k8s.io/ingress-nginx unchanged
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx unchanged
role.rbac.authorization.k8s.io/ingress-nginx unchanged
rolebinding.rbac.authorization.k8s.io/ingress-nginx unchanged
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
ingressclass.networking.k8s.io/nginx unchanged
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission configured
serviceaccount/ingress-nginx-admission unchanged
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
role.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created

为 nginx 控制器创建入口规则

kubectl apply -f -<<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test
  annotations:
    kubernetes.io/ingress.class: nginx  
spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: test
            port:
              number: 80
        path: /
        pathType: Prefix
EOF

Annotation "kubernetes.io/ingress.class: nginx" 需要将 Ingress 绑定到控制器

https://www.fairwinds.com/blog/intro-to-kubernetes-ingress-set-up-nginx-ingress-in-kubernetes-bare-metal

获取节点 ips

kubectl get no -o wide

NAME    STATUS   ROLES                  AGE     VERSION   INTERNAL-IP   
master  Ready    control-plane,master   6d20h   v1.21.0   134.156.0.81   
node1   Ready    <none>                 5d      v1.21.0   134.156.0.82   
node2   Ready    <none>                 6d19h   v1.21.0   134.156.0.83   
node3   Ready    <none>                 6d19h   v1.21.0   134.156.0.84  

找到入口控制器节点端口

kubectl get svc -n ingress-nginx 

NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    15.234.89.16    <none>        80:31505/TCP,443:32191/TCP   21m

它是 31505。通过您的一个节点上的入口节点端口访问测试服务,例如在 node1 134.156.0.82

curl 134.156.0.82:31505

returns

<html><body><h1>It works!</h1></body></html>

这是在 Google 云虚拟机上测试的,但没有 GKE