前面的文章介绍了如何安装kubernetes集群,集群部署完毕之后就可以在上面部署服务了。服务部署完之后如何访问集群中的服务呢? 
访问部署在kubernetes中的服务有两种情况,一种是在kubernetes集群内部访问,另一种是在集群外部访问服务。

在集群内部访问

Clusterip

Clusterip是集群内部的私有ip,在集群内部访问服务非常方便,直接通过service的Clusterip访问。如果安装了kube-dns可以使用serviceName的方式访问服务。

请看下面例子 
创建一个nginx服务,名称是my-nginx

[root@vmnode1 ~]# cat my-nginx.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
# 创建my-nginx
[root@vmnode1 ~]# kubectl create -f ./my-nginx.yaml
[root@vmnode1 ~]# kubectl expose deploy my-nginx
[root@vmnode1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.254.0.1              443/TCP   36d
my-nginx     ClusterIP   10.254.180.15           80/TCP    6m

在集群中创建一个pod,通过ServiceName访问nginx服务

[root@vmnode1 ~]# kubectl run -it --image=radial/busyboxplus  sh

##通过ServerName访问nginx
/ # curl http://my-nginxWelcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer tonginx.org.
Commercial support is available atnginx.com.

Thank you for using nginx.

在集群外部访问

1. Nodeport

把service的port映射到每个节点内部指定port上,所有节点内部映射的port都一样。 
看下面例子

#删除my-nginxkubectl delete svc/my-nginx
kubectl delete deploy/my-nginx123

修改my-nginx.yaml增加NodePort,在每个节点内部暴露30001端口

[root@vmnode1 ~]# cat my-nginx.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:  name: my-nginx
spec:
  replicas: 2
  template:
    metadata:
      labels:        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80---apiVersion: v1
kind: Service
metadata:  name: my-nginx
  labels:    run: my-nginx
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30001
  selector:    run: my-nginx
  #创建my-nginx服务
  kubectl create -f ./my-nginx.yaml

我的集群由四个几点构成 
vmnode1 192.168.123.81 
vmnode2 192.168.123.82 
vmnode3 192.168.123.83 
vmnode4 192.168.123.84

在集群之外,通过任何一个节点的ip+nodeport都可以访问集群中服务

[root@vmnode5 ~]# curl  
[root@vmnode5 ~]# curl  
[root@vmnode5 ~]# curl  
[root@vmnode5 ~]# curl http://192.168.123.84:30001

2. Loadbalancer

使用NodeIp+Nodeport的方式实现,利用云平台提供的loadbalance服务,像aws、azure、openstack、gce都提供了loadbalance服务

这里不做介绍了

3. Ingress

Ingress 使用开源的反向代理负载均衡器来实现对外暴漏服务,比如 Nginx、Apache、Haproxy等。Nginx Ingress 一般有三个组件组成:

  • Nginx 反向代理负载均衡器

  • Ingress Controller 可以理解为控制器,它通过不断的跟 Kubernetes API 交互,实时获取后端 Service、Pod 等的变化,比如新增、删除等,然后结合 Ingress 定义的规则生成配置,然后动态更新上边的 Nginx 负载均衡器,并刷新使配置生效,来达到服务自动发现的作用。

  • Ingress 则是定义规则,通过它定义某个域名的请求过来之后转发到集群中指定的 Service。它可以通过 Yaml 文件定义,可以给一个或多个 Service 定义一个或多个 Ingress 规则。

下载地址 
https://github.com/kubernetes/ingress-nginx/archive/nginx-0.11.0.tar.gz

ingress-nginx文件位于deploy目录下,各文件的作用:

  • configmap.yaml:提供configmap可以在线更行nginx的配置

  • default-backend.yaml:提供一个缺省的后台错误页面 404

  • namespace.yaml:创建一个独立的命名空间 ingress-nginx

  • rbac.yaml:创建对应的role rolebinding 用于rbac

  • tcp-services-configmap.yaml:修改L4负载均衡配置的configmap

  • udp-services-configmap.yaml:修改L4负载均衡配置的configmap

  • with-rbac.yaml:有应用rbac的nginx-ingress-controller组件

修改with-rbac.yaml

apiVersion: extensions/v1beta1
kind: Daemonsetmetadata:
  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
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.11.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
            - --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      nodeSelector:
        custom/ingress-controller-ready: "true"

需要修改的地方:

  • kind: DaemonSet:官方原始文件使用的是deployment,replicate 为 1,这样将会在某一台节点上启动对应的nginx-ingress-controller pod。外部流量访问至该节点,由该节点负载分担至内部的service。测试环境考虑防止单点故障,改为DaemonSet然后删掉replicate ,配合亲和性部署在制定节点上启动nginx-ingress-controller pod,确保有多个节点启动nginx-ingress-controller pod,后续将这些节点加入到外部硬件负载均衡组实现高可用性。

  • hostNetwork: true:添加该字段,暴露nginx-ingress-controller pod的服务端口(80)

  • nodeSelector: 增加亲和性部署,有custom/ingress-controller-ready 标签的节点才会部署该DaemonSet

为需要部署nginx-ingress-controller的节点设置lable

kubectl label nodes vmnode2 custom/ingress-controller-ready=true
kubectl label nodes vmnode3 custom/ingress-controller-ready=true
kubectl label nodes vmnode4 custom/ingress-controller-ready=true

加载yaml文件

kubectl create -f namespace.yaml
kubectl create -f default-backend.yaml
kubectl create -f configmap.yaml
kubectl create -f tcp-services-configmap.yaml
kubectl create -f udp-services-configmap.yaml
kubectl create -f rbac.yaml
kubectl create -f with-rbac.yaml

查看pod是否正常创建

##下载镜像可能会比较慢,等待一会所有pod都是Running状态,按Ctrl + c 退出
[root@vmnode1 deploy]# kubectl get pods --namespace=ingress-nginx  --watch
NAME                                    READY     STATUS    RESTARTS   AGEdefault-
http-backend-6c59748b9b-hc8q9   1/1       Running   0          6m
nginx-ingress-controller-7fmlp          1/1       Running   1          13d
nginx-ingress-controller-j95fb          1/1       Running   1          13d
nginx-ingress-controller-ld2jw          1/1       Running   1          13d

测试ingress 
创建一个apache的Service

[root@vmnode1 ~]# cat my-apache.yaml api
Version: extensions/v1beta1
kind: Deployment
metadata:  
name: my-apache
spec:
  replicas: 2
  template:
    metadata:
      labels:        
      run: my-apache
    spec:
      containers:
      - name: my-apache
        image: httpd:2.4
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:  
name: my-apache
  labels:   
   run: my-apache
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30002
  selector:    
  run: my-apache


[root@vmnode1 ~]# kubectl create -f ./my-apache.yaml my-nginx
不用改,使用上面已经创建好的,如果没有自己创建一下
[root@vmnode1 ~]# cat my-nginx.yamlapi
Version: extensions/v1beta1
kind: Deployment
metadata:  
name: my-nginx
spec:
  replicas: 2
  template:
    metadata:
      labels:        
      run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:  
name: my-nginx
  labels:    
  run: my-nginx
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30001
  selector:    
  run: my-nginx

现在集群中有两个服务,一个是my-apache,另一个是my-nginx

[root@vmnode1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.254.0.1             443/TCP        51d
my-apache    NodePort    10.254.239.1           80:30002/TCP   8m
my-nginx     NodePort    10.254.66.98           80:30001/TCP   14d

配置ingress转发文件

[root@vmnode1 ~]# vi test-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingressmetadata:
  name: test-ingress
  namespace: defaultspec:
  rules:
  - host: test.apache.ingress
    http:
      paths:
      - path: /
        backend:
          serviceName: my-apache
          servicePort: 80
  - host: test.nginx.ingress
    http:
      paths:
      - path: /
        backend:
          serviceName: my-nginx
          servicePort: 80

host: 对应的域名 
path: url上下文 
backend:后向转发 到对应的 serviceName: servicePort:

[root@vmnode1 ~]# kubectl apply -f test-ingress.yaml
[root@vmnode1 ~]# kubectl get ingress
NAME           HOSTS                                    ADDRESS   PORTS     AGE
test-ingress   test.apache.ingress,test.nginx.ingress             80        1m

本文 nginx-ingress-controller运行在vmnode2,vmnode3,vmnode4三个节点上。如果网络中有dns服务器,在dns中把这两个域名映射到nginx-ingress-controller运行的任意一个节点上,如果没有dns服务器只能修改host文件了。

备注: 
正规的做法是在vmnode2,vmnode3,vmnode4这三个节点上安装keepalive,生成一个vip。在dns上把域名和vip做映射。

我这里直接在vmnode1节点上操作了。

##192.168.123.82,192.168.123.83,192.168.123.84 三个ip任选。
[root@vmnode1 ~]# echo '192.168.123.82 test.apache.ingress' >> /etc/hosts
[root@vmnode1 ~]# echo '192.168.123.83 test.nginx.ingress' >> /etc/hosts

测试test.nginx.ingress

[root@vmnode1 ~]# curl test.nginx.ingress
Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer tonginx.org.
Commercial support is available atnginx.com.

Thank you for using nginx.

测试test.apache.ingress

[root@vmnode1 ~]# curl test.apache.ingress

It works!

如果不修改hosts文件可以通过下面的命令测试

##通过-H 指定模拟的域名
[root@vmnode1 ~]# curl -v http://192.168.123.83 -H 'host: test.apache.ingress'
[root@vmnode1 ~]# curl -v http://192.168.123.83 -H 'host: test.nginx.ingress'

参考资料

https://jimmysong.io/kubernetes-handbook/practice/traefik-ingress-installation.html 
http://blog.csdn.net/hekanhyde/article/details/78672931 
https://github.com/kubernetes/ingress-nginx/tree/master/deploy 
https://kubernetes.io/docs/concepts/services-networking/ingress/

本文转载自:https://blog.csdn.net/newcrane/article/details/79092577