Kubernetes Ingress 服务负载均衡

本文基于 Kubernetes 1.4.5 + Calico CNI 流水操作记录,关于 Kubernetes Ingress 资源的理论知识可参考官方文档 Ingress Resources

一、准备 Ingress 所需配置文件

# ls
dashboard-ingress.yaml  default-http-backend.yaml  default-tcp-configmap.yaml  nginx-ingress-lb.yaml
# cat default-http-backend.yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: default-http-backend
spec:
  replicas: 1
  selector:
    app: default-http-backend
  template:
    metadata:
      labels:
        app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: default-http-backend
        # Any image is permissable as long as:
        # 1. It serves a 404 page at /
        # 2. It serves 200 on a /healthz endpoint
        image: gcr.io/google_containers/defaultbackend:1.0
        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
# cat default-tcp-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: default-tcp-configmap

因为使用的 Calico cni 网络,基于主机的端口绑定有问题,所以这里采用的 hostNetwork 方式。 具体关于 CNI 的 issue 可参考 HostPort seemingly not working

# cat nginx-ingress-lb.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: nginx-ingress-lb
spec:
  template:
    metadata:
      labels:
        name: nginx-ingress-lb
    spec:
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      containers:
      - image: gcr.io/google_containers/nginx-ingress-controller:0.8.3
        name: nginx-ingress-lb
        imagePullPolicy: IfNotPresent
        securityContext:
          privileged: true
        readinessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          timeoutSeconds: 1
        # use downward API
        env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
        args:
        - /nginx-ingress-controller
        - --default-backend-service=kube-system/default-http-backend
        - --tcp-services-configmap=kube-system/default-tcp-configmap

二、创建 Ingress 所需要的资源

# kubectl create -f default-tcp-configmap.yaml --namespace=kube-system
# kubectl create -f default-http-backend.yaml --namespace=kube-system
# kubectl create -f nginx-ingress-lb.yaml --namespace=kube-system
# kubectl get configmap --namespace=kube-system
NAME                    DATA      AGE
default-tcp-configmap   1         1m
# kubectl get rc default-http-backend --namespace=kube-system
NAME                   DESIRED   CURRENT   READY     AGE
default-http-backend   1         1         1         1m
# kubectl get daemonsets --namespace=kube-system
NAME               DESIRED   CURRENT   NODE-SELECTOR   AGE
nginx-ingress-lb   2         2         <none>          1m

三、服务暴露

3.1 HTTP 服务暴露

HTTP 服务需要创建 kind 为 Ingress 的资源,以 kubernetes dashboard 为示例:

# cat dashboard-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubernetes-dashboard-ingress
  namespace: kube-system
spec:
  rules:
  - host: k8sui.test.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 80
# kubectl create -f dashboard-ingress.yaml
# kubectl get ingress -o wide
NAME                           HOSTS                ADDRESS                     PORTS     AGE
kubernetes-dashboard-ingress   k8sui.test.com       192.168.0.10,192.168.0.11   80        8s

修改 hosts 文件绑定域名到任何一个 nginx-ingress-lb 节点,即可通过 k8sui.test.com 即可成功访问 Kubernetes dashboard

3.2 TCP 服务暴露

TCP 服务暴露需要更新 configmap,以 redis 服务为例:

# cat default-tcp-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: default-tcp-configmap
data:
  9000: "default/redis:6379"
# kubectl replace -f default-tcp-configmap.yaml --namespace=kube-system

以上表示暴露 default namespace 下服务名为 redis,端口为 6379 的服务到 nginx-ingress-lb 所在节点的 9000 端口。

更新 configmap 之后通过 <任何一个节点IP>:9000 即可访问集群内部的 redis 服务

# redis-cli -h 192.168.0.10 -p 9000
192.168.0.10:9000> info
# Server
redis_version:3.2.5

关于 Kubernetes ingress controllers nginx 的更详细内容可以参看 ingress/controllers/nginx,包括 HTTPS、UDP 等实现方式。

–EOF–

Written by kumu on 09 November 2016