Kubernetes跨主机通信时的注意事项

我们知道docker的两个主机之间容器是不能直接通讯的,Kubernetes也没有自带解决这个问题,

部署Kubernetes的时候大多使用flannel或者calico插件带来的解决方案,

本文不对这两个解决方案做对比,这是你在选择前应该自己去了解的。本文旨在填网络部分的坑

接受所有ip的数据包转发

新建文件/etc/systemd/system/docker.service.d/iptables.conf并填入以下内容保存

[Service]

ExecStartPost=/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT

这样不同主机都能直接访问到pod的网络了

使用内网穿透技术映射主机端口到公网

内网穿透的技术有很多,常用的方法有:

  • ssh/autossh
  • ngfork
  • frp (本文将介绍该方法)

github地址:https://github.com/fatedier/frp

frp为传统的C/S结构,可分为客户端和服务端,其中

  • frpc(客户端) 运行在内网环境
  • frps(服务端)运行在有公网IP的服务器

编写frpc.ini文件,例如:

[common] server_addr = 公网IP server_port = frps运行的端口 token = 一串随机字符用来防止未经授权的使用  [appName] type = tcp local_ip = 127.0.0.1 local_port = 需要映射的本地端口 remote_port = 映射成公网服务器的端口

服务器端frps.ini就更简单了

[common] bind_port = 服务端运行的端口 token = 一串随机字符用来防止未经授权的使用 ;允许被使用的端口范围 allow_ports = 40000-50000 

假设frps 运行在 1.2.3.4:34567,客户端(192.168.1.5)把本机的80端口映射成了38888端口,则链路如下

192.168.1.5:80 <-> 1.2.3.4:34567 <-> 1.2.3.4:38888

提高映射服务可靠性

请使用supervisor分配守护frpc/frps即可达到理想可靠性

 

 

配置docker使用代理和镜像仓库加速

由于配置、启动k8s的过程中,需要从gcr仓库拉取镜像,而一般情况下是会被墙挡住而造成拉取失败,这时,一种解决方法就是挂上梯子,让docker通过梯子去拉取镜像

启动梯子

此处省略,假设梯子启动后监听本地的1080端口

即 socks5://127.0.0.1:1080

配置docker使用代理

新版docker服务都是使用systemd来管理的,此方法适用于ubuntu 16.04+ / centos7+

# mkdir /etc/systemd/system/docker.service.d

# vim /etc/systemd/system/docker.service.d/http-proxy.conf

填入以下内容

[Service]

Environment="HTTP_PROXY=socks5://127.0.0.1:1080/" "HTTPS_PROXY=socks5://127.0.0.1:1080/"

保存并退出后,执行以下命令重新加载配置并重启docker服务

# systemctl daemon-reload && systemctl restart docker

运行docker info可能看到有HTTP_PROXY和HTTPS_PROXY字样即为成功

最好再docker pull 镜像名 验证下代理网络是否正常

配置镜像仓库加速拉取(可选)

修改dockerd的配置文件(没有就新建一个)

# vim /etc/docker/daemon.json

加上registry-mirrors,例如:(以下使用中科大的docker hub)

{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}

保存并退出后,重启docker服务

# systemctl restart docker

安装k8s通用的Web UI(kubernetes-dashboard)

我们打算安装k8s官方的UI界面,这个界面能显示所有的工作负载,包括运行的Nodes,Services,Pods,Jobs,Relica sets等k8s资源。

首先你需要连接VPN,不然的话,运行接下来的 kubectl create命令后,你会发现新建的pod会报ImagePullBackOff的错误

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml

!!!!本文以下内容为原创,不走官方预留的神坑

本文直接给出一份魔改后的kubernetes-dashboard.yaml,已经踩过了ca证书、存活检查、集群账号权限等等一些的坑,并将kubernetes-dashboard锁死在master节点上(为了方便内网穿透)

魔改后:

1. 关闭自动生成ca证书

2. 开启HTTP访问(31110端口)

3. 原HTTPS访问映射到31111端口

4. 心跳检测改为访问HTTP /

5. dashboard使用集群超级管理员cluster-admin,妈妈再也不用担心我不够权限了

6. dashboard锁死在master节点上跑

# kubectl apply -f kubernetes-dashboard.yaml

顺便完善下集群监控

# kubectl apply -f grafana.yaml

# kubectl apply -f heapster-rbac.yaml

# kubectl apply -f heapster.yaml

# kubectl apply -f influxdb.yaml

安装完毕后,访问 http://master节点的IP:31110 即可管理你的k8s集群

部署应用程序到kubernetes集群

第一步:在master 节点上创建一个deployment

# kubectl create deployment nginx --image=nginx deployment.apps/nginx created

检查执行效果,可以看到一个叫nginx的deployment创建成功了

# kubectl get deployments NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE nginx     1         1         1            1           1m

第二步:创建一个service,并暴露80端口

kubectl create service nodeport nginx --tcp 80:80

检查执行效果,可以看到一个叫nginx的service创建成功了,这里kubectl get svc是kubectl get services的简写

# kubectl create service nodeport nginx --tcp 80:80 service/nginx created

# kubectl get svc NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        1d nginx        NodePort    10.96.248.169    <none>        80:31088/TCP   11s

执行下面的命令验证一下nginx有没有部署成功(顺带测试下容器间网络通信)

# curl 10.96.248.169 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>     body {         width: 35em;         margin: 0 auto;         font-family: Tahoma, Verdana, Arial, sans-serif;     } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p>  <p><em>Thank you for using nginx.</em></p> </body> </html>

清理现场

# kubectl delete deployments/nginx services/nginx deployment.extensions "nginx" deleted service "nginx" deleted

快速搭建Kubernetes集群(基于Ubuntu)

K8s集群部署有三种方式:

  • kubeadm (联网安装,本文以此为基础)
  • minikube(联网安装)
  • 二进制包(通常离线安装)

本文只使用两台虚拟机,一台是Master节点,一台是Node节点:

主机名 ip 系统 配置 工作目标
kube-master 10.71.11.84 Ubuntu 16.04 2C4G Master节点
kube-slave 10.71.11.83 Ubuntu 16.04 4C8G Node节点

准备工作

1. 修改主机名及配置主机名映射

例如对于Master节点

echo kube-master > /etc/hostname
vim /etc/hosts
 127.0.0.1    kube-master 10.71.11.83  kube-slave

在Node节点上执行类似操作,注意不要搞混ip和主机名

2. 配置软件源(这里用了中科大的源)

cat <<EOF > /etc/apt/sources.list.d/kubernetes.list deb [trusted=yes] http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main EOF

3.关闭系统 Swap

因为Kubernetes v1.8+ 要求关闭系统 Swap

① 临时关闭swap swapoff -a

② 永久关闭swap vim /etc/fstab 注释所有带swap字样的行

更新源并安装kubeadm, kubectl, kubelet软件包

apt-get update -y && apt-get install -y kubelet kubeadm kubectl --allow-unauthenticated

安装docker(当前kubeadm不支持docker.ce)

apt-get install docker.io -y

加载内核模块(可选)

modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr modprobe ip_vs_sh modprobe nf_conntrack_ipv4

正式开始

使用kubeadmin初始化master节点

这个下载镜像的过程涉及翻墙,因为会从gcr的站点下载容器镜像,不然初始化不成功, 这里要指定apiserver-advertise-address 及pod的虚拟子网pod-network-cidr

kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=10.71.11.84

如果出错,请根据错误信息查询错误详情,解决错误后执行kubeadmin reset还原至错误前状态

如果看到”Your Kubernetes master has initialized successfully!”字样,说明master节点已创建成功,可以进入下一步

配置kubectl

mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config

将slave节点加入到集群

在kube-slave上运行:

kubeadm join --token aa78f6.8b4cafc8ed26c34f --discovery-token-ca-cert-hash sha256:0fd95a9bc67a7bf0ef42da968a0d55d92e52898ec37c971bd77ee501d845b538  10.71.11.84:6443

上面的token和sha256都需要根据实际情况生成并填入,具体请看kubeadm生成的token过期后,集群增加节点

在Master 上运行kube get nodes, 可以看到结果如下:

NAME          STATUS   ROLES    AGE     VERSION kube-master   Ready    master   15h     v1.13.4 kube-slave    Ready    <none>   15h     v1.13.4

安装网络插件canal

canal官方文档参考,如下网址下载2个文件并且安装,其中一个是配置canal的RBAC权限,一个是部署canal的DaemonSet。但笔者是从这里(Installing a pod network add-on)参考的,根据kubeadm init时用到的--pod-network-cidr=10.244.0.0/16,所以选择了canal

kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/rbac.yaml kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/canal.yaml

可以看到输出:

clusterrole.rbac.authorization.k8s.io "calico" created clusterrole.rbac.authorization.k8s.io "flannel" created clusterrolebinding.rbac.authorization.k8s.io "canal-flannel" created clusterrolebinding.rbac.authorization.k8s.io "canal-calico" created configmap "canal-config" created daemonset.extensions "canal" created customresourcedefinition.apiextensions.k8s.io "felixconfigurations.crd.projectcalico.org" created customresourcedefinition.apiextensions.k8s.io "bgpconfigurations.crd.projectcalico.org" created customresourcedefinition.apiextensions.k8s.io "ippools.crd.projectcalico.org" created customresourcedefinition.apiextensions.k8s.io "clusterinformations.crd.projectcalico.org" created customresourcedefinition.apiextensions.k8s.io "globalnetworkpolicies.crd.projectcalico.org" created customresourcedefinition.apiextensions.k8s.io "networkpolicies.crd.projectcalico.org" created serviceaccount "canal" created

执行如下命令,可以就可以查看canal的安装状态

# kubectl get pod -n kube-system -o wide NAME                                    READY   STATUS    RESTARTS   AGE     IP            NODE          NOMINATED NODE   READINESS GATES canal-547kn                             3/3     Running   34         47h     10.71.11.84   kube-master   <none>           <none> canal-j76k9                             3/3     Running   15         47h     10.71.11.83   kube-slave    <none>           <none> coredns-86c58d9df4-5mnm4                1/1     Running   14         2d15h   10.244.0.45   kube-master   <none>           <none> coredns-86c58d9df4-b76qw                1/1     Running   14         2d15h   10.244.0.44   kube-master   <none>           <none> etcd-kube-master                        1/1     Running   15         2d15h   10.71.11.84   kube-master   <none>           <none> kube-apiserver-kube-master              1/1     Running   17         2d15h   10.71.11.84   kube-master   <none>           <none> kube-controller-manager-kube-master     1/1     Running   19         2d15h   10.71.11.84   kube-master   <none>           <none> kube-proxy-q2v5x                        1/1     Running   11         2d15h   10.71.11.83   kube-slave    <none>           <none> kube-proxy-sqvbh                        1/1     Running   16         2d15h   10.71.11.84   kube-master   <none>           <none> kube-scheduler-kube-master              1/1     Running   15         2d15h   10.71.11.84   kube-master   <none>           <none>

第一步大功告成!