上一篇博客 介绍了如何在 Kubernetes 上部署一个无状态容器,但最后将 Service 暴露成 NodePort 时,
由于 k8s 的限制,默认情况下端口只能是 30000-32767,基本无法对外提供服务。
所幸的是除了 Service 提供的外部负载均衡 外,还可以使用 Ingress 控制器从处理流量。
官方提供了 Nginx Ingress Controller,可以较为方便的部署 Nginx 作为入流量控制器,部署过程可以参考官方文档,但我对官方的配置做了一些修改。
Nginx Ingress Controller 官方文档参考:https://kubernetes.github.io/ingress-nginx/deploy/
首先部署命名空间,默认后端(处理 404等),配置等,与官方一致。
1 2 3 4 5 6 7 8 curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/namespace.yaml \ | kubectl apply -f - curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/default-backend.yaml \ | kubectl apply -f - curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/configmap.yaml \ | kubectl apply -f -
接着需要为 RBAC 配置角色和权限:
1 2 curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/rbac.yaml \ | kubectl apply -f -
部署 Nginx 官方的配置文件使用 Deployment 的方式部署单副本到任意一台 worker 机器,但我修改了一些配置,改变了以下行为:
Nginx 部署在 master 机器上,使用 master 的入口 ip 提供服务
官方文档部署完后仍然需要使用 Service 做转发,在没有 ELB 的情况下仍需使用 NodePort 方式暴露在高端口上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-ingress-controller namespace: ingress-nginx spec: selector: matchLabels: app: ingress-nginx template: metadata: labels: app: ingress-nginx annotations: prometheus.io/port: '10254' prometheus.io/scrape: 'true' spec: serviceAccountName: nginx-ingress-serviceaccount hostNetwork: true affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/master operator: Exists tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule containers: - name: nginx-ingress-controller image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.14.0 args: - /nginx-ingress-controller - --default-backend-service=$(POD_NAMESPACE)/default-http-backend - --configmap=$(POD_NAMESPACE)/nginx-configuration - --annotations-prefix=nginx.ingress.kubernetes.io 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 securityContext: runAsNonRoot: false
对官方配置的修改主要有以下几处:
使用 hostNetwork
配置将服务暴露在外网接口:L19
使用亲和性配置 限制服务只能部署在 master 上:L20-26
使用 tolerations
配置允许在 master 上部署此服务:L27-30
删除了对 tcp 和 udp 直接转发的配置,目前还用不到
Tolerations 默认情况下 Kubernetes 不在 master 上部署各种服务,使用了 taint 的机制限制某个 node 的能力,可以查看一下 master 上的 taint:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 列出所有节点 kubectl --kubeconfig=./kubeconfig get nodes NAME STATUS ROLES AGE VERSION spc1d17xmk-master-1 Ready master 2d v1.10.2 spc1d17xmk-worker-1 Ready <none> 2d v1.10.2 spc1d17xmk-worker-2 Ready <none> 2d v1.10.2 // 查看 master 节点 kubectl --kubeconfig=./kubeconfig describe node spc1d17xmk-master-1 Name: spc1d17xmk-master-1 Roles: master // Omitted Taints: node-role.kubernetes.io/master:NoSchedule // Omitted
可以看到 master 节点上的 key 为 node-role.kubernetes.io/master
指定了 NoSchedule
限制,可以阻止其它 pod 被部署到这个节点上。
因此如果想要让 pod 部署在这里,需要在 pod 上指定 tolerations
配置,表示某个 pod 可以容忍被配置了这个 taint 的节点。
Taints 和 Tolerations 是一组非常精巧的设计,组合使用时可以允许某些 pod 被部署在当前节点,但阻止其它 pod 的部署。
配置 Ingress 官方的 Ingress 文档已经非常清楚的描述了如何配置。
1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: submodule-checker-ingress spec: rules: - host: YOUR.HOST.NAME http: paths: - backend: serviceName: submodule-checker-service servicePort: 7777
配置完成后将域名解析到 k8s 集群的主节点上,即可访问服务内的 pod。
参考链接
NodePort: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
Affinity: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
Tolerations: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
Ingress: https://kubernetes.io/docs/concepts/services-networking/ingress/