前言
我想玩玩k8s,但是我的云服务器是内网不互通的,装了好久,所以记录一下
安装docker
yum update -y
##安装docker
yum install -y docker
##更换成国内镜像
cat <<EOF> /etc/docker/daemon.json
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://registry.docker-cn.com"
]
}
EOF
## 开机自启动docker
systemctl enable docker
systemctl start docker
安装kubeadm kubelet kubectl
##更换yum里面的k8s源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
#关闭
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
#安装kubectl等组件
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
#启动kubelet
systemctl enable --now kubelet
# 加载br_netfilter模块,使用lsmod查看开启的模块
yum install -y bridge-utils.x86_64
modprobe br_netfilter
#修改路由
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
# 关闭防火墙
systemctl disable firewalld
# k8s要求关闭swap (qxl)
swapoff -a && sysctl -w vm.swappiness=0
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
到此准备工作就完事了
内网不互通的解决办法
(这里写的是我解决问题的思路–虽然都是百度,安装过程在下面)
我首先想到的是百度,查找到了这篇文章
内网不在一个网段的两台云服务器搭建K8S 遇到的坑及解决方案
使用nat进行转发,这样安装是能够安装成功的,但是flannel网络的问题并没有解决,因为flannel记录的ip是你的内网ip。
[root@instance-l33lcu5d ~]#kubectl describe node instance-l33lcu5d
Name: instance-l33lcu5d
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=instance-l33lcu5d
kubernetes.io/os=linux
node-role.kubernetes.io/master=
Annotations: flannel.alpha.coreos.com/backend-data: {"VtepMAC":"0a:20:4b:67:0c:1c"}
flannel.alpha.coreos.com/backend-type: vxlan
flannel.alpha.coreos.com/kube-subnet-manager: true
flannel.alpha.coreos.com/public-ip: 192.168.48.4
kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
通过上述命令可以看到,flannel给打的注解是public-ip +内网地址 。虽然我设置了转发,但是flannel还是没有打通集群中pod的通信。
菜鸟又找到了一篇文章:不同nat设备后的网络节点如何组成一个k8s集群
在这个大佬的回答里说了一句flannel的文档有答案。
这句话很简单,就是当node设置了external ip的时候,flannel会自动给node加一个注解public-ip-overwrite,然后会基于这个ip去重置flannel网络。
但是我找了好久也没找到如何给node设置external ip,但是我转念一想,我自己加一个注解不就行了
kubectl annotate nodes instance-l33lcu5d flannel.alpha.coreos.com/public-ip-overwrite=180.76.155.95
kubectl annotate nodes instance-jak59008 flannel.alpha.coreos.com/public-ip-overwrite=106.12.206.160
kubectl annotate nodes instance-8x864u54 flannel.alpha.coreos.com/public-ip-overwrite=106.13.82.225
果然,有了这个注解,flannel的public-ip被修改了。 然后直接kubectl apply -f flannel.yml 再部署一下kubectl apply -f ingress-nginx.yml。试一下
可以看到我部署了ingress-nginx的pod,他的pod ip是10.244.3.3,部署的机器是instance-8x864u54 ,我现在的机器是master节点root@instance-l33lcu5d 。测试一下集群访问pod ip;
因为我没有配置ingress,所以这里显示404,ok,集群与pod通信没问题了,
这里查一下ingress的服务,暴露的端口是32626
去浏览器测试一下
完美,通过nodeport方式部署的service能够正确访问到pod。
但是因为内网不互通的原因,除非在iptables 加上nat转发,也就是第一篇文档里面说的哪种方式,不然kubectl exec 的方式进入容器会有点问题
但是也可以去node节点直接使用docker exec,所以这个也就不算什么问题了
安装
因为我的内网不互通,所以kubeadm init的时候选择的是外网ip,但是我用的是百度云服务器,所以没有外网网卡
kubeadm init --kubernetes-version=v1.17.0 --image-repository registry.aliyuncs.com/google_containers --apiserver-advertise-address=[public ip] --pod-network-cidr=10.244.0.0/16
因为没有外网网卡,但是选择了外网ip,所以初始化的时候会出点问题。 k8s安装的时候会写入文件,在这个阻塞的时候, 我们去改一下配置
vim /etc/kubernetes/manifests/etcd.yml
将这两处改成这样就行了
等初始化成功后,拿着它提供的token去node执行命令加入集群;
加入集群后查看node;
给node加上注解publuc-ip-overwrite,方便flannel正确注册子网
kubectl annotate nodes instance-l33lcu5d flannel.alpha.coreos.com/public-ip-overwrite=180.76.155.95
kubectl annotate nodes instance-jak59008 flannel.alpha.coreos.com/public-ip-overwrite=106.12.206.160
kubectl annotate nodes instance-8x864u54 flannel.alpha.coreos.com/public-ip-overwrite=106.13.82.225
安装网络插件flannel:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
安装ingress-nginx
ingress-nginx的镜像不是很好下。但是我们可以先用docker的方式下载
docker pull quay.mirrors.ustc.edu.cn/kubernetes-ingress-controller/nginx-ingress-controller:0.26.2
docker tag quay.mirrors.ustc.edu.cn/kubernetes-ingress-controller/nginx-ingress-controller:0.26.2 quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.2
安装
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.2/deploy/static/provider/baremetal/service-nodeport.yaml
安装dashboard并配置https访问
安装dashboard
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc1/aio/deploy/recommended.yaml
配置https并使用ingress转发
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: sudooom-dashboard
namespace: kubernetes-dashboard
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" # 这里必须加,因为dashboard要求https访问
spec:
rules:
- host: dashboard.sudooom.com
http:
paths:
- path: /
backend:
serviceName: kubernetes-dashboard
servicePort: 443
配置一下dns解析,我加了一个dashboard.sudooom.com
通过浏览器访问
因为其他账号没有权限,我给dashboard配置一个权限高的账号
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
kubectl apply -f dashboard_auth.yml
查询这个账号的token
kubectl -n kube-system describe secret `kubectl describe sa admin-user -n kube-system|grep 'Mountable secrets'|awk '{print $3}'`
输入token就可以登录了