前面的文章介绍了如何安装kubernetes集群,集群部署完毕之后就可以在上面部署服务了。服务部署完之后如何访问集群中的服务呢? 

访问部署在kubernetes中的服务有两种情况,一种是在kubernetes集群内部访问,另一种是在集群外部访问服务。

在集群内部访问

Clusterip

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

请看下面例子 

创建一个nginx服务,名称是my-nginx

[root@vmnode1 ~]# cat my-nginx.yaml apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: my-nginxspec:  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 svcNAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGEkubernetes   ClusterIP   10.254.0.1      
        443/TCP   36dmy-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 andworking. Further configuration is required.

For online documentation and support please refer to

nginx.org.
Commercial support is available at
nginx.com.

Thank you for using nginx.

在集群外部访问

1. Nodeport

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

看下面例子

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

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

[root@vmnode1 ~]# cat my-nginx.yamlapiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: my-nginxspec:  replicas: 2  template:    metadata:      labels:        run: my-nginx    spec:      containers:      - name: my-nginx        image: nginx:1.7.9        ports:        - containerPort: 80---apiVersion: v1kind: Servicemetadata:  name: my-nginx  labels:    run: my-nginxspec:  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 规则。

下载地址 

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/v1beta1kind: 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=truekubectl label nodes vmnode3 custom/ingress-controller-ready=truekubectl label nodes vmnode4 custom/ingress-controller-ready=true

加载yaml文件

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

查看pod是否正常创建

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

测试ingress 

创建一个apache的Service

[root@vmnode1 ~]# cat my-apache.yaml apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: my-apachespec:  replicas: 2  template:    metadata:      labels:              run: my-apache    spec:      containers:      - name: my-apache        image: httpd:2.4        ports:        - containerPort: 80---apiVersion: v1kind: Servicemetadata:  name: my-apache  labels:      run: my-apachespec:  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.yamlapiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: my-nginxspec:  replicas: 2  template:    metadata:      labels:              run: my-nginx    spec:      containers:      - name: my-nginx        image: nginx:1.7.9        ports:        - containerPort: 80---apiVersion: v1kind: Servicemetadata:  name: my-nginx  labels:      run: my-nginxspec:  type: NodePort  ports:  - port: 80    targetPort: 80    nodePort: 30001  selector:      run: my-nginx

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

[root@vmnode1 ~]# kubectl get svcNAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGEkubernetes   ClusterIP   10.254.0.1     
        443/TCP        51dmy-apache    NodePort    10.254.239.1   
        80:30002/TCP   8mmy-nginx     NodePort    10.254.66.98   
        80:30001/TCP   14d

配置ingress转发文件

[root@vmnode1 ~]# vi test-ingress.yamlapiVersion: extensions/v1beta1kind: 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 ingressNAME           HOSTS                                    ADDRESS   PORTS     AGEtest-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.ingressWelcome to nginx!

Welcome to nginx!

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

For online documentation and support please refer to

nginx.org.
Commercial support is available at
nginx.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://blog.csdn.net/newcrane/article/details/79092577