安装ingress
(1)从仓库下载charts
helm pull stable/nginx-ingress
(2) 解压charts
tar -xf nginx-ingress-0.9.5.tgz
(3) 查看nginx-ingress目录
4)在nginx-ingress父目录执行安装ingress命令
## 第一个 nginx-ingress 是 release 名。第二个 nginx-ingress 是 chart 解压目录。 helm install nginx-ingress nginx-ingress -n kube-system
出现报错信息:
Error: unable to build kubernetes objects from release manifest: unable to recognize "": no matches for kind "Deployment" in version "extensions/v1beta1"
解决方案:
将nginx-ingress文件夹的deployment文件apiVersion修改为apps/v1
执行命令如下:
grep -irl "extensions/v1beta1" nginx-ingress | grep deploy | xargs sed -i 's#extensions/v1beta1#apps/v1#g'
出现报错信息:
Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: ValidationError(Deployment.spec): missing required field "selector" in io.k8s.api.apps.v1.DeploymentSpec
解决方案:
由于k8s1.16版本升级,需要Deployment.spec中加selector,所以愉快地加上就行了。
执行命令如下:
vi nginx-ingress/templates/controller-deployment.yaml
添加spec.selector代码块与metadata.labels对应
selector: matchLabels: app: {{ template "nginx-ingress.name" . }}
vi nginx-ingress/templates/default-backend-deployment.yaml
同上处理
重新执行部署命令:
##先卸载 helm uninstall nginx-ingress nginx-ingress -n kube-system
##再安装 helm install nginx-ingress nginx-ingress -n kube-system
结果如图表示安装成功:
我们发现服务一直pending状态,无法对外服务,这是因为helm默认部署是以LoadBalancer方式,这种方式需要平台的支持,比如在AWS、GCE或者阿里云等平台。而我们自己搭建的集群没办法使用这种方式。不过我们可以通过设置externalIPs的方式使用内部ip,再通过统一的负载均衡接入外网。
##先卸载 helm uninstall nginx-ingress nginx-ingress -n kube-system #重新启动 helm install my-nginx nginx-ingress --set rbac.create=true,controller.service.externalIPs[0]=192.168.37.101,controller.service.externalIPs[1]=192.168.37.102
kubectl get svc --all-namespaces NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx nginx-ingress-controller LoadBalancer 10.98.90.251 192.168.0.101,192.168.0.102 80:32478/TCP,443:31196/TCP 10s
我们指定集群中两个node的IP作为externalIPs,这样就能通过这两个个ip来引入外部流量。我们尝试从集群外部范围这两个个ip,
[root@CentOS-7-2 ~]# curl http://192.168.0.101:80 default backend - 404 [root@CentOS-7-2 ~]# curl http://192.168.0.102:80 default backend - 404
由于我们集群内部还没有服务,因此请求转到nginx-ingress的default backend中。
创建应用并使用nginx-ingress对外暴露服务,我们创建一个nginx web服务器作为测试,
--- apiVersion: v1 kind: Pod metadata: name: nginx namespace: ingress-nginx labels: app: web spec: hostNetwork: false containers: - name: nginx image: nginx --- kind: Service apiVersion: v1 metadata: name: webservice namespace: ingress-nginx spec: selector: app: web ports: - protocol: TCP port: 10080 targetPort: 80
创建该应用,
[root@CentOS-7-4 /home/k8s]# kubectl apply -f nginx.yaml pod/nginx created service/webservice created [root@CentOS-7-4 /home/k8s]# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE webservice ClusterIP 10.105.175.150 <none> 10080/TCP 6s
为了便于测试,我们进入这个pod将这个测试web服务的主页内容修改一下,
[root@CentOS-7-4 /home/k8s]# kubectl exec -ti nginx -n ingress-nginx -- /bin/bash root@nginx:/# echo "This is my webservice!" > /usr/share/nginx/html/index.html root@nginx:/# cat /usr/share/nginx/html/index.html This is my webservice! root@nginx:/# exit exit
确保服务正常,我们在集群内通过ClusterIP测试一下,
[root@CentOS-7-5 ~]# curl http://10.105.175.150:10080 This is my webservice!
可见,服务创建正常,但是该服务目前只能在集群内使用,集群外无法访问该服务。
下面我们通过ingress-nginx来将该服务暴露到集群外部。
首先定义我们的服务的对外要暴露的访问域名,这里假设为 webservice.com
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress annotations: ingress.kubernetes.io/rewrite-target: / namespace: ingress-nginx spec: rules: - host: webservice.com http: paths: - path: / backend: serviceName: webservice servicePort: 10080
之后创建ingress资源,
[root@CentOS-7-4 /home/k8s]# kubectl apply -f my-ingress.yaml ingress.extensions/test-ingress configured [root@CentOS-7-4 /home/k8s]# kubectl get ingress --all-namespaces NAMESPACE NAME HOSTS ADDRESS PORTS AGE ingress-nginx test-ingress webservice.com 80 8d
创建好后,我们试着在集群外部来访问。
[root@CentOS-7-2 ~]# curl -H "Host: webservice.com" http://192.168.0.101:80 This is my webservice! [root@CentOS-7-2 ~]# curl -H "Host: webservice.com" http://192.168.0.102:80 This is my webservice!
可见,通过ingress-nginx,我们在集群外部也能访问集群内部的服务。
此时我们可以查看下ingress-nginx内部的配置文件,
[root@CentOS-7-4 ~]# kubectl exec -ti my-nginx-nginx-ingress-controller-64c8cd5d6d-p4gr9 -n default -- /bin/bash
root@my-nginx-nginx-ingress-controller-64c8cd5d6d-p4gr9:/# cat /etc/nginx/nginx.conf ... upstream ingress-nginx-webservice-10080 { # Load balance algorithm; empty for round robin, which is the default least_conn; keepalive 32; server 10.244.3.25:80 max_fails=0 fail_timeout=0; } ... ## start server webservice.com server { server_name webservice.com ; listen 80; listen [::]:80; ... location / { port_in_redirect off; set $proxy_upstream_name "ingress-nginx-webservice-10080"; ... } ... } ## end server webservice.com
可见此时ingress-nginx里面已经自动生成了webservice服务的转发规则,无需我们手动再去添加。再看下后端服务ip10.244.3.25是哪个pod,
[root@CentOS-7-4 ~]# kubectl get pods --all-namespaces -o wide | grep 10.244.3.25 ingress-nginx nginx 1/1 Running 0 22h 10.244.3.25 centos-7-3 <none> <none>
正是我们启动的nginx服务。
这样就实现了将集群内部服务暴露到外部。