如何让 Kubernetes Ingress 端口 80 在裸机单节点集群上工作

How to get Kubernetes Ingress Port 80 working on baremetal single node cluster

我有一个使用 kubeadm 创建的裸机 kubernetes (v1.11.0) 集群,运行良好,没有任何问题。使用 calico 联网并使用 kubectl taint nodes 命令使其成为单节点集群。 (单节点是必需的)。

我需要运行 mydockerhub/sampleweb主机端口80上的静态网站图片。假设ubuntu服务器运行宁这个kubernetes的IP地址是192.168.8.10 .

如何使我的静态网站在 192.168.8.10:80 上可用或在本地 DNS 服务器上映射到它的主机名? (示例:frontend.sampleweb.local:80)。稍后我需要将 运行 不同端口上的其他服务映射到另一个子域。 (示例:backend.sampleweb.local:80 路由到端口 8080 上的服务 运行)。

我需要知道:

  1. 我可以在没有负载均衡器的情况下实现吗?

  2. 创建需要什么资源? (入口、部署等)

  3. 集群需要哪些额外的配置? (网络政策等)

    如果提供示例 yaml 文件,将不胜感激。

我是 kubernetes 世界的新手。我得到了端到端工作的示例 kubernetes 部署(如 sock-shop),没有任何问题。我尝试使用 NodePort 来访问该服务,但我需要 运行 将其 运行 精确地设置在主机上的端口 80 上,而不是 运行 将其连接到其他端口。我尝试了很多入口解决方案,但没有用。

我的设置截图:

我最近使用 traefik.io 配置了一个与您的要求相似的项目。

因此,我将展示一个包含 traefik 和入口的基本解决方案。

我专用了整个命名空间(你可以使用 kube-system),称为 traefik,并创建了一个 kubernetes serviceAccount:

apiVersion: v1
kind: Namespace
metadata:
  name: traefik
---
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: traefik
  name: traefik-ingress-controller

入口规则调用的 traefik 控制器需要 ClusterRole 及其绑定:

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
  namespace: traefik
  name: traefik-ingress-controller

traefin 控制器将被部署为守护进程(即根据定义,集群中的每个节点都有一个守护进程)并且 Kubernetes 服务专用于该控制器:

kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: traefik
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      containers:
      - name: traefik-ingress-lb
        image: traefik
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
        securityContext:
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        args:
        - --api
        - --kubernetes
        - --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
  namespace: traefik
  name: traefik-ingress-service
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      name: admin

最后一部分要求您为项目中的每个微服务创建一个服务,这里是一个示例:

apiVersion: v1
kind: Service
metadata:
  namespace: traefik
  name: my-svc-1
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - port: 80 
    targetPort: 8080

以及将请求转发到适当服务的入口(规则集):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: traefik
  name: ingress-ms-1
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: my-address-url
    http:
      paths:
      - backend:
          serviceName: my-svc-1
          servicePort: 80

在这个入口我写了一个主机URL,这将是你集群的入口点,所以你需要将名称解析到你的主K8S节点。如果您有更多节点可以成为主节点,那么建议使用负载均衡器(在这种情况下,主机 URL 将是 LB)。

查看 kubernetes.io 文档以明确 kubernetes 的概念。 traefik.io 也很有用。

希望对你有所帮助。

除了 Nicola Ben 的答案之外,您还必须在 traefik 服务中定义一个 externalIPs,只需按照 Nicola Ben 的步骤向服务添加一个 externalIPs 部分即可 "my-svc-1" .

apiVersion: v1
kind: Service
metadata:
  namespace: traefik
  name: my-svc-1
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - port: 80 
    targetPort: 8080
  externalIPs:
  - <IP_OF_A_NODE>

并且你可以在externalIP上定义更多。