前面的文章介绍了如何安装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.1443/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.1443/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.ingressIt 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