原本没打算搞这个文章的,第一里面有瑕疵(没搞定的地方),第二在个人Ubuntu 18 Kubernetes集群的安装和部署 以及Helm的安装 也有安装,第三 和社区的问文章比较雷同 https://www.kubernetes.org.cn/5551.htmlhtml
kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每一个版本的发布都会同步更新,kubeadm会对集群配置方面的一些实践作调整,经过实验kubeadm能够学习到Kubernetes官方在集群配置上一些新的最佳实践。node
最近发布的Kubernetes 1.15.2中,kubeadm对HA集群的配置已经达到beta可用,说明kubeadm距离生产环境中可用的距离愈来愈近了。linux
在安装以前,须要先作以下准备。两台Centos 18以下:nginx
192.168.100.11 k8s-master 192.168.100.12 k8s-node
禁用防火墙:git
systemctl stop firewalld
systemctl disable firewalld
禁用SELINUX:github
setenforce 0 vi /etc/selinux/config SELINUX=disabled
建立vi /etc/sysctl.d/k8s.conf文件,添加以下内容:docker
net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1
执行命令使修改生效。json
modprobe br_netfilter
sysctl -p /etc/sysctl.d/k8s.conf
因为ipvs已经加入到了内核的主干,在全部的Kubernetes节点k8s-master和k8s-node上执行如下脚本:bootstrap
cat > /etc/sysconfig/modules/ipvs.modules <<EOF #!/bin/bash modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 EOF chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
上面脚本建立了的/etc/sysconfig/modules/ipvs.modules文件,保证在节点重启后能自动加载所需模块。 使用如下命令查看是否已经正确加载所需的内核模块。centos
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
接下来还须要确保各个节点上已经安装了ipset软件包。
为了便于查看ipvs的代理规则,最好安装一下ipvsadm管理工具。
若是以上前提条件若是不知足,则即便kube-proxy的配置开启了ipvs模式,也会退回到iptables模式。
Kubernetes从1.6开始使用CRI(Container Runtime Interface)容器运行时接口。默认的容器运行时仍然是Docker,使用的是kubelet中内置dockershim CRI实现。
安装docker的yum源:
yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
查看最新的Docker版本:
yum list docker-ce.x86_64 --showduplicates |sort -r
这里在各节点安装docker的18.09.7版本。
yum makecache fast yum install -y --setopt=obsoletes=0 docker-ce-18.09.7-3.el7 systemctl start docker systemctl enable docker
确认一下iptables filter表中FOWARD链的默认策略(pllicy)为ACCEPT。
根据文档CRI installation中的内容,对于使用systemd做为init system的Linux的发行版,使用systemd做为docker的cgroup driver能够确保服务器节点在资源紧张的状况更加稳定,所以这里修改各个节点上docker的cgroup driver为systemd。
建立或修改vi /etc/docker/daemon.json:
{ "exec-opts": ["native.cgroupdriver=systemd"] }
重启docker:
systemctl restart docker docker info | grep Cgroup Cgroup Driver: systemd
下面在各节点安装kubeadm和kubelet:
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF
测试地址https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64是否可用
curl https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 yum makecache fast yum install -y kubelet kubeadm kubectl
从安装结果能够看出还安装了cri-tools, kubernetes-cni, socat三个依赖:
运行kubelet –help能够看到原来kubelet的绝大多数命令行flag参数都被DEPRECATED了,
而官方推荐咱们使用–config指定配置文件,并在配置文件中指定原来这些flag所配置的内容。具体内容能够查看这里Set Kubelet parameters via a config file。这也是Kubernetes为了支持动态Kubelet配置(Dynamic Kubelet Configuration)才这么作的,参考Reconfigure a Node’s Kubelet in a Live Cluster。
kubelet的配置文件必须是json或yaml格式,具体可查看这里。
Kubernetes 1.8开始要求关闭系统的Swap,若是不关闭,默认配置下kubelet将没法启动。 关闭系统的Swap方法以下:
修改 /etc/fstab 文件,注释掉 SWAP 的自动挂载,使用确认swap已经关闭。 swappiness参数调整,修改 /etc/sysctl.d/k8s.conf添加下面一行:
执行sysctl -p /etc/sysctl.d/k8s.conf使修改生效。
在各节点开机启动kubelet服务:
使用 kubeadm config print init-defaults 能够打印集群初始化默认的配置,
从默认的配置中能够看到,可使用imageRepository定制在集群初始化时拉取k8s所需镜像的地址。基于默认配置定制出本次使用kubeadm初始化集群所需的配置文件kubeadm.yaml:
apiVersion: kubeadm.k8s.io/v1beta2 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.100.11 bindPort: 6443 nodeRegistration: taints: - effect: PreferNoSchedule key: node-role.kubernetes.io/master --- apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.15.3 networking: podSubnet: 10.244.0.0/16
使用kubeadm默认配置初始化的集群,会在master节点打上node-role.kubernetes.io/master:NoSchedule的污点,阻止master节点接受调度运行工做负载。这里测试环境只有两个节点,因此将这个taint修改成node-role.kubernetes.io/master:PreferNoSchedule。
在开始初始化集群以前可使用 kubeadm config images pull 预先在各个节点上拉取所k8s须要的docker镜像。
接下来使用kubeadm初始化集群,选择k8s-master做为Master Node,在k8s-master上执行下面的命令:
上面记录了完成的初始化输出的内容,根据输出的内容基本上能够看出手动初始化安装一个Kubernetes集群所须要的关键步骤。 其中有如下关键内容:
查看一下集群状态,确认个组件都处于healthy状态:
集群初始化若是遇到问题,可使用下面的命令进行清理:
kubeadm reset ifconfig cni0 down ip link delete cni0 ifconfig flannel.1 down ip link delete flannel.1 rm -rf /var/lib/cni/
接下来安装flannel network add-on:
curl -O https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml kubectl apply -f kube-flannel.yml
这里注意kube-flannel.yml这个文件里的flannel的镜像是0.11.0,quay.io/coreos/flannel:v0.11.0-amd64
若是Node有多个网卡的话,参考flannel issues 39701,目前须要在kube-flannel.yml中使用–iface参数指定集群主机内网网卡的名称,不然可能会出现dns没法解析。须要将kube-flannel.yml下载到本地,flanneld启动参数加上–iface=<iface-name>
使用kubectl get pod --all-namespaces=true -o wide 或者 kubectl get pod -n kube-system 确保全部的Pod都处于Running状态。
kubectl run curl --image=radial/busyboxplus:curl -it kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead. If you don't see a command prompt, try pressing enter. [ root@curl-5cc7b478b6-r997p:/ ]$
进入后执行nslookup kubernetes.default确认解析正常:
nslookup kubernetes.default Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: kubernetes.default Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
下面将node2这个主机添加到Kubernetes集群中,在node2上执行:
node2加入集群非常顺利,下面在master节点上执行命令查看集群中的节点:
kubectl get node NAME STATUS ROLES AGE VERSION k8s-master Ready master 12m v1.15.3 k8s-node Ready <none> 3m1s v1.15.3
2.5.1 如何从集群中移除Node
若是须要从集群中移除node2这个Node执行下面的命令:
在master节点上执行:
kubectl drain k8s-node --delete-local-data --force --ignore-daemonsets
kubectl delete node k8s-node
在node2上执行:
kubeadm reset ifconfig cni0 down ip link delete cni0 ifconfig flannel.1 down ip link delete flannel.1 rm -rf /var/lib/cni/
在node1上执行:
kubectl delete node node2
修改ConfigMap的kube-system/kube-proxy中的config.conf,mode: “ipvs”
以后重启各个节点上的kube-proxy pod:
kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}' [root@k8s-master ~]# kubectl get pod -n kube-system | grep kube-proxy kube-proxy-f9rnj 1/1 Running 0 39s kube-proxy-q6hks 1/1 Running 0 44s [root@k8s-master ~]# kubectl logs kube-proxy-f9rnj -n kube-system I0822 09:49:35.870937 1 server_others.go:170] Using ipvs Proxier. W0822 09:49:35.871397 1 proxier.go:401] IPVS scheduler not specified, use rr by default I0822 09:49:35.872146 1 server.go:534] Version: v1.15.3
日志中打印出了Using ipvs Proxier,说明ipvs模式已经开启。
愈来愈多的公司和团队开始使用Helm这个Kubernetes的包管理器,这里也将使用Helm安装Kubernetes的经常使用组件。
Helm由客户端命helm令行工具和服务端tiller组成,Helm的安装十分简单。 下载helm命令行工具到master节点node1的/usr/local/bin下,这里下载的2.14.1版本:
curl -O https://get.helm.sh/helm-v2.14.1-linux-amd64.tar.gz tar -zxvf helm-v2.14.1-linux-amd64.tar.gz cd linux-amd64/ cp helm /usr/local/bin/
为了安装服务端tiller,还须要在这台机器上配置好kubectl工具和kubeconfig文件,确保kubectl工具能够在这台机器上访问apiserver且正常使用。 这里的node1节点已经配置好了kubectl。
由于Kubernetes APIServer开启了RBAC访问控制,因此须要建立tiller使用的service account: tiller并分配合适的角色给它。 详细内容能够查看helm文档中的Role-based Access Control。 这里简单起见直接分配cluster-admin这个集群内置的ClusterRole给它。建立helm-rbac.yaml文件:
接下来使用helm部署tiller:
tiller默认被部署在k8s集群中的kube-system这个namespace下:
注意因为某些缘由须要网络能够访问gcr.io和kubernetes-charts.storage.googleapis.com,若是没法访问能够经过helm init –service-account tiller –tiller-image <your-docker-registry>/tiller:v2.13.1 –skip-refresh使用私有镜像仓库中的tiller镜像
最后在k8s-master上修改helm chart仓库的地址为azure提供的镜像地址:
为了便于将集群中的服务暴露到集群外部,须要使用Ingress。接下来使用Helm将Nginx Ingress部署到Kubernetes上。 Nginx Ingress Controller被部署在Kubernetes的边缘节点上,关于Kubernetes边缘节点的高可用相关的内容能够查看以前整理的Bare metal环境下Kubernetes Ingress边缘节点的高可用,Ingress Controller使用hostNetwork。
咱们将k8s-node(192.168.100.11)作为边缘节点,打上Label:
kubectl label node k8s-master node-role.kubernetes.io/edge= #kubectl label node k8s-master node-role.kubernetes.io/edge- #减号表示删除 kubectl get node
stable/nginx-ingress chart的值文件ingress-nginx.yaml以下:
controller: replicaCount: 1 hostNetwork: true nodeSelector: node-role.kubernetes.io/edge: '' affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx-ingress - key: component operator: In values: - controller topologyKey: kubernetes.io/hostname tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/master operator: Exists effect: PreferNoSchedule defaultBackend: nodeSelector: node-role.kubernetes.io/edge: '' tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/master operator: Exists effect: PreferNoSchedule
nginx ingress controller的副本数replicaCount为1,将被调度到node1这个边缘节点上。这里并无指定nginx ingress controller service的externalIPs,而是经过hostNetwork: true设置nginx ingress controller使用宿主机网络。
helm repo update helm install stable/nginx-ingress -n nginx-ingress --namespace ingress-nginx -f ingress-nginx.yaml kubectl get pod -n ingress-nginx -o wide
若是访问http://192.168.100.11返回default backend,则部署完成。
kubernetes-dashboard.yaml:
image: repository: k8s.gcr.io/kubernetes-dashboard-amd64 tag: v1.10.1 ingress: enabled: true hosts: - k8s.frognew.com annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" tls: - secretName: frognew-com-tls-secret hosts: - k8s.frognew.com nodeSelector: node-role.kubernetes.io/edge: '' tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/master operator: Exists effect: PreferNoSchedule rbac: clusterAdminRole: true
安装
helm install stable/kubernetes-dashboard -n kubernetes-dashboard --namespace kube-system -f kubernetes-dashboard.yaml kubectl -n kube-system get secret | grep kubernetes-dashboard-token kubectl describe -n kube-system secret/kubernetes-dashboard-token-xxx
在dashboard的登陆窗口使用上面的token登陆。
修改本机的hosts文件:192.168.100.11 k8s.frognew.com
从Heapster的github https://github.com/kubernetes/heapster中能够看到已经,heapster已经DEPRECATED。 这里是heapster的deprecation timeline。 能够看出heapster从Kubernetes 1.12开始从Kubernetes各类安装脚本中移除。
Kubernetes推荐使用metrics-server。咱们这里也使用helm来部署metrics-server。
metrics-server.yaml:
args: - --logtostderr - --kubelet-insecure-tls - --kubelet-preferred-address-types=InternalIP nodeSelector: node-role.kubernetes.io/edge: '' tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/master operator: Exists effect: PreferNoSchedule
使用下面的命令能够获取到关于集群节点基本的指标信息:
遗憾的是,当前Kubernetes Dashboard还不支持metrics-server。所以若是使用metrics-server替代了heapster,将没法在dashboard中以图形展现Pod的内存和CPU状况(实际上这也不是很重要,当前咱们是在Prometheus和Grafana中定制的Kubernetes集群中各个Pod的监控,所以在dashboard中查看Pod内存和CPU也不是很重要)。 Dashboard的github上有不少这方面的讨论,如https://github.com/kubernetes/dashboard/issues/2986,Dashboard已经准备在未来的某个时间点支持metrics-server。但因为metrics-server和metrics pipeline确定是Kubernetes在monitor方面将来的方向,因此推荐使用metrics-server。