本文首发于个人bloghtml
最近使用kops在aws宁夏区搭建了一套生产用的k8s集群,这里说下完整的过程,包括中间遇到的各类坑。node
AmazonEC2FullAccess,AmazonRoute53FullAccess,AmazonS3FullAccess,IAMFullAccess,AmazonVPCFullAccess
权限的IAM帐户echo "source <(kubectl completion bash)" >> ~/.bashrc && source ~/.bashrc
就是按照kopsc-cn的文档来就能够了,说下文档没有提到的几点:git
Makefile中有这么一段代码:github
ifeq ($(TARGET_REGION) ,cn-northwest-1)
CLUSTER_NAME ?= cluster.zhy.k8s.local
# copy from kope.io/k8s-1.12-debian-stretch-amd64-hvm-ebs-2019-05-13
# see https://github.com/nwcdlabs/kops-cn/issues/96
AMI ?= ami-068b32c3754324d44
ZONES ?= cn-northwest-1a,cn-northwest-1b,cn-northwest-1c
endif
复制代码
这个CLUSTER_NAME
要修改一下,否则建立出来集群名字就是cluster.zhy.k8s.local
,特别怪异。web
执行make edit-cluster
的时候能够修改下子网CIDR,默认子网是/16
,咱们修改为了/24
,缘由是咱们在vpc中已经建立了一个子网来放部署机和跳板机,若是/16
的话会形成子网IP段冲突。api
若是新建的集群要删除重建的话,在执行了make validate-cluster
以后须要手动检查下 ELB,subnet,routetable,EC2是否删除干净,而且清除.kube
文件夹。bash
默认建立的子网是public的,若是须要建立private的,能够本身建立private subnet和NAT,而后传给kops使用,具体参考这个issue。app
建立完毕以后能够部署一个很简单的应用上去,而后curl serviceName:serticePort
,确保集群能够正常使用。运维
部署完毕以后,有三个master节点,分布在三个可用区,这样在一个可用区挂了的时候,集群不受影响,还有两个普通节点,属于nodes
这个instanceGroup(kops的一个概念,对应一个aws的autoscale组)。curl
上面步骤成功以后,集群内部的service能够经过serviceName互相访问了,若是要暴露出去给Internet访问须要配置ingress。
咱们使用traefik-ingress做为ingress controller,因此首先部署traefik:
准备traefik使用的RBAC role文件: traefik-rbac.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: kube-system
复制代码
执行 kubectl apply -f traefik-rbac.yaml
使用Demonset的方式部署traefik,准备 traefik.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
name: traefik-ingress-controller
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
hostPort: 31742
- name: admin
containerPort: 8080
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
args:
- --api
- --kubernetes
- --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 8080
name: admin
复制代码
注意hostPort: 31742
这一句,很是关键,指的是到该Pod所在的Node的31742端口的流量,自动转交给该Pod处理。若是31742已经被占用了,能够换一个端口。
最后执行kubectl apply -f traefik.yaml
,而后执行kubectl -n kube-system get pod -w
,等待traefik-controller部署完毕便可。
上面建立集群的时候kops会建立一个classic elb,咱们须要删掉这个elb而后本身建立一个application elb,elb的流量转发规则是任何到80端口上的流量,都要转发到咱们上面建立的两个node节点的31742端口(和traefik的监听端口保持一致)。
而且配置好防火墙规则,elb能够连通到该Node组。
因此,整个外部流量进入集群的路径是这样的:
hostPort: 31742
的缘由,到31742端口的流量会由traefik-controller Pod处理这样就完成了外部流量到Pod的整个过程。
虽然有kops工具帮咱们简化了这个过程,自建k8s集群坑仍是多。好比咱们遇到了Node过一段时间就是NotReady
致使node上的pod被驱逐,问题居然是AMI的问题,coreos对aws的多网卡的机器支持很差,换成debian系统就行了(如今kops-cn默认就是debian系统了)😁。
出了问题须要从aws服务一致排查到k8s内部组件,对debug能力要求很高,尤为是须要对aws服务很是了解,对k8s内部组件很是了解,对于没作过运维的我挑战很大,固然中间收获也不少😆。