部署好Kubernetes之后
我们到部署Kubernetes的堡垒机上(有Kops)
【方式一】Kops提供的IngressNginx
Kops提供的IngressNginx参考 Kops ngress-nginx
运行下面命令完成,权限和服务ingress服务的启动
curl -L -# https://raw.githubusercontent.com/kubernetes/kops/master/addons/ingress-nginx/v1.6.0.yaml -o ingress-nginx.yaml
kubectl apply -f ingress-nginx.yaml
注意上面的这个文件中有几个镜像可能会拉去失败,所以可能大家需要自己找国内搬运的镜像。
使用的镜像列表
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.18.0
k8s.gcr.io/defaultbackend:1.4
【方式二】官方方式安装 【推荐】
Ingress Nginx 的安装方式推荐参考 kubernetes Ingress-nginx
这一步是启动ingress-nginx-controller控制器
curl -L -# https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml -o mandatory.yaml
kubectl apply -f mandatory.yaml
配置该控制器的L4层负载均衡代理(TCP/UDP)
curl -L -# https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/aws/service-l4.yaml -o service-l4.yaml
curl -L -# https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/aws/patch-configmap-l4.yaml -o patch-configmap-l4.yaml
kubectl apply -f service-l4.yaml
kubectl apply -f patch-configmap-l4.yaml
如果使用了Websocket在Apply之前首先修改一下service-l4.yaml
中的配置
注意: 官方的安装方案与KOPS提供的有些不同,命名控制不是
kube-ingress
而是ingress-nginx
如何转移镜像
查看一下ingress-nginx.yaml
文件中使用的镜像
cat ingress-nginx.yaml |grep image
接下来我们到我们的自己主机上开始转移工作
首先尝试直接pull
显然也不行。
这个时候我们可以尝试到 hub.docker.com 上寻找,该镜像。
使用该镜像的名称作为关键字搜索,如: defaultbackend
可以找到一个名为**mirrorgooglecontainers/defaultbackend-amd64
** 的镜像,该镜像时Google在DockerHub上的镜像,因此我们就用它。
找到对应版本,然后点击Pull
docker pull mirrorgooglecontainers/defaultbackend-amd64:1.4
提示:
amd64
表示处理器的架构,一般来说X86都是这个架构。
可以看到已经成功pull
接下来我们给刚才Pull到的镜像打上Tag然后Push到我们AWS上的ECR上,首先得创建对应的仓库哦。
docker tag mirrorgooglecontainers/defaultbackend-amd64:1.4 ******.dkr.ecr.cn-northwest-1.amazonaws.com.cn/google/defaultbackend:1.4
docker push ******.dkr.ecr.cn-northwest-1.amazonaws.com.cn/google/defaultbackend:1.4
仓库地址和用户名这里就替换成实际创建的地址
推送完成之后,修改ingress-nginx.yaml
中defaultbackend
镜像为我们刚才推送的地址******.dkr.ecr.cn-northwest-1.amazonaws.com.cn/google/defaultbackend:1.4
,搬运工作就已经完成了。
在AWS上运行的K8S默认就是支持ECR的不需要任何配置就可以使用,请参考: 使用 AWS EC2 Container Registry
ingress-nginx就特殊些,他是托管于quay.io
他在dockerhub上没有镜像,因此我们可以从国内的Azure镜像上下载到。
docker pull quay.azk8s.cn/kubernetes-ingress-controller/nginx-ingress-controller:0.18.0
启动失败问题
启动之后使用
kubectl get svc ingress-nginx -n kube-ingress
如果使用官方安装则使用
kubectl get svc ingress-nginx -n ingress-nginx
如果 EXTERNAL-IP
一一直处于<panding>
状态
接下可以使用下面命令查看一下相关服务创建情况:
kubectl describe svc ingress-nginx -n kube-ingress
如果使用官方安装则使用
kubectl describe svc ingress-nginx -n ingress-nginx
错误提示消息为 : kube-ingress/ingress-nginx: could not find any suitable subnets for creating the ELB
也就是说在Kubernetes所属的集群中没有合适的子网部署我们的ingress-nginx服务。
原因
原因是:默认情况下 ingress-nginx 会在公有子网中创建一个ELB负载均衡器,如果我们的Kubernetes集群中没有公有子网(也就是没有一个子网的0.0.0.0/0
路由到Internet网关上igw
),那么创建ingress的创建就会失败。
解决
该问题可以通过两种方式解决:
- 在
ingress-nginx/v1.6.0.yaml
的Service里面增加一个注解,设置创建一个内部的负载均衡器。这样的话就只能是在私有子网中使用Ingress服务,不能把私有子网的服务暴露到公有子网上。 - 到AWS的控制台上找到Kubernetes所处的VPC,增加一个公有子网,然后打上标签。这样就可以在公网上访问到Kubernetes在私有子网中的服务。
方案1:
然后编辑该文件
vi ingress-nginx.yaml
在文件中找到
在metadata.annotations
中加上下面的注解内容
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
如下所示
然后应用我们的修改
kubectl apply -f ingress-nginx.yaml
然后我们再次查看服务状态
kubectl get svc ingress-nginx -n kube-ingress
可以看到EXTERNAL-IP
已经有一个域名了,接下来还可以到AWS控制台中的 负载均衡器 确认该ELB。
可以看到他监听了部署了ingress-nginx实例的端口。
方案2:
如果在Kubernetes所处的VPC中已经存在了公有子网,那么这里只需要设置一下标签就可以。
如果事先没有公有子网,那么创建一个Internet 网关,然后在VPC中增加一个公有子网(子网的
0.0.0.0/0
路由到Internet网关上igw
),然后在公有子网上加上集群相关的标签。
到子网中
加入下面标签
键 | 值 |
---|---|
KubernetesCluster | 值是集群名称(cluster.unisign.k8s.local ) |
kubernetes.io/cluster/your_cluster_name | 注意键中的your_cluster_name 要替换为你定义的集群名称(cluster.unisign.k8s.local ), 值是资源拥有的类型(owner 、shared ),这里设置为共享类型shared |
kubernetes.io/role/elb | 值为1 ,表明该子网为公有子网,他将会被专用于公有子网的负载均衡器所注册和使用。(列如Ingress网络所需要的负载均衡器) |
配置请参考 集群 VPC 注意事项
编辑好之后,保存重新设置ingress
kubectl apply -f ingress-nginx.yaml
注意如果之前设置过 内网类型的ingress的需要把那个给删除
kubectl delete -f ingress-nginx.yaml
查看部署的ingress状态,可以看部署已经完成
kubectl get svc ingress-nginx -n kube-ingress
到AWS控制台上同样可以看到创建好的ELB。
接下我们通过启动一个nginx服务的方式来测试一下这个ingress是否可用。
vi test-ingress.yaml
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.17.3
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
ports:
- port: 80
targetPort: 80
selector:
app: web
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
创建完成之后我们在可以测试前得调整一下参数,由于中国区的AWS的80、443端口如果没有进行备案是无法访问的,所以说我们得到负载均衡器那边调整一下映射的端口。
查看一下映射的dns
kubectl get ingress web
登录AWS控制台 EC2 中的 负载均衡器,找到对应dns的负载均衡器,然后选择监听器页面,点击编辑
增加一个和80端口映射同一个实例端口的TCP协议的10080端口映射规则。
然后在 描述Tab下找到 安全组,记录该安全组
然后在EC2的安全组中搜索该组, 选中之后点击入站,编辑
增加一个10080的tcp规则,允许所有域名访问
保存后我们打CMD或者是终端 使用curl
测试刚才的ingress代理的服务
curl -H "Host: foo.bar.com" http://a6caee2c4db7711e9a5a60a4dc25616b-2070699106.cn-northwest-1.elb.amazonaws.com.cn:10080/
请将
http://a6caee2c4db7711e9a5a60a4dc25616b-2070699106.cn-northwest-1.elb.amazonaws.com.cn:10080/
替换成你具体的负载均衡dns哦
可以看到确实返回我们创建的测试的nginx服务的欢迎页面。
参考
[1]. kops.github.https://github.com/kubernetes/kops/tree/master/addons/ingress-nginx
[2]. internal elbs in AWS.josdotso.github.https://github.com/kubernetes/kubernetes/issues/17620
[3]. 如何将面向公众的负载均衡器连接到具有私有 IP 地址的 EC2 实例?.aws.doc.https://aws.amazon.com/cn/premiumsupport/knowledge-center/public-load-balancer-private-ec2/
[4]. 集群 VPC 注意事项 . aws .doc . https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/network_reqs.html
[5]. docker/kubernetes国内源/镜像源解决方式 . Xinkun . https://xuxinkun.github.io/2019/06/11/cn-registry/