从零开始搭建 k8s 集群环境系列笔记:
- 从零开始搭建 k8s 集群环境 (一)—— 搭建镜像存储服和镜像服
- 从零开始搭建 k8s 集群环境 (二)—— 构建 Kubernetes 安装包
- 从零开始搭建 k8s 集群环境 (三)—— 搭建 Master 节点
- 从零开始搭建 k8s 集群环境 (四)—— 添加 Node 节点
- 从零开始搭建 k8s 集群环境 (五)—— 安装 Pod 网络
- 从零开始搭建 k8s 集群环境 (六)—— 部署 Dashboard UI
- 从零开始搭建 k8s 集群环境 (七)—— 部署 Ingress 服务
- 从零开始搭建 k8s 集群环境 (番外)—— 纯手动部署全套
接上步骤,我们已经成功初始化了 Master
和 Node01
节点,并将其加入到同一个集群内。但是两个节点目前均是 NotReady
状态,这是因为我们的集群还没有安装网络插件,而 k8s
不自带网络插件。
环境说明:
- Master:VBox虚拟机/Centos_7.5-1804/192.168.56.100
- Images:VBox虚拟机/Centos_7.5-1804/192.168.56.101
- Node01:VBox虚拟机/Centos_7.5-1804/192.168.56.102
软件环境说明:
- docker-ce-17.03.2
- kubernetes-v1.9.0
- harbor-v1.4.0
一、插件选择(翻译)
Calico
请参阅 Calico
文档以获得kubeadm quickstart、kubeadm安装指南和其他资源。
注意: 为了使网络策略正确地工作,您需要在
kubeadm init
时添加参数--pod-network-cidr=192.168.0.0/16
。Calico
只在amd64
上工作。
安装命令:
kubectl apply -f https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yaml
Canal
官方渠道设置指南在这里。
注意: 为了让
Canal
正确地工作,您需要在kubeadm init
时添加参数--pod-network-cidr=10.244.0.0/16
。Canal
只在amd64
上工作。
安装命令:
kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.7/rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.7/canal.yaml
Flannel
注意: 为了让
Flannel
正确地工作,您需要在kubeadm init
时添加参数--pod-network-cidr=10.244.0.0/16
。Flannel
可以在amd64
、arm
、arm64
和ppc64le
上进行工作,但要在amd64
以外的平台上工作,您必须手动下载清单,并使用选定的平台替换amd64
。 需要运行sysctl net.bridge.bridge-nf-call-iptables=1
将桥接的IPv4流量传递给iptables
的链。这是一些CNI插件
的工作要求,更多的信息请看这里。 有关Flannel
的更多信息,请看这里。
安装命令:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml
Romana
注意: 需要运行
sysctl net.bridge.bridge-nf-call-iptables=1
将桥接的IPv4流量传递给iptables
的链。这是一些CNI插件
的工作要求,更多的信息请看这里。 官方的Romana
设置指南在这里。
安装命令:
kubectl apply -f https://raw.githubusercontent.com/romana/romana/master/containerize/specs/romana-kubeadm.yml
Weave Net
注意: 需要运行
sysctl net.bridge.bridge-nf-call-iptables=1
将桥接的IPv4流量传递给iptables
的链。这是一些CNI插件
的工作要求,更多的信息请看这里。Weave Net
可以在amd64
、arm
、arm64
和ppc64le
上运行,无需任何额外的操作。Weave Net
默认设置hairpin
模式。这允许pod
通过他们的服务IP地址访问自己,如果他们不知道他们的PodIP
。 官方Weave Net
设置指南在这里。
安装命令:
kubectl apply -f https://cloud.weave.works/k8s/net
网络模块请大家自己选择,安装其实很容易~
我这里选用了 Flannel
和 Weave Net
两种进行实验。
二、部署测试服务
为了验证我们安装的 Pod
网络配置,我们先部署一个镜像作为我们的测试服务,用来对 Pod
网络的验证。
镜像对应的 Dockerfile 文件内容如下:
FROM centos:latest
MAINTAINER lx0758 lx0758@qq.com
RUN rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm && yum install nginx -y && systemctl enable nginx
EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
为什么不直接用
Nginx
的镜像:因为我们测试需要去容器里面测试集群内的网络访问情况,Nginx
镜像一些常用的工具都没有,所以就自己做了一个镜像。
测试服务对应的 http-test.yaml
文件内容如下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: http-test-dm
spec:
replicas: 3
template:
metadata:
labels:
name: http-test-dm
spec:
containers:
- name: http-test-con
image: registry.cn-shenzhen.aliyuncs.com/lx0758-per/http-test:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: http-test-ser
spec:
ports:
- port: 80
targetPort: 80
selector:
name: http-test-dm
可以看到,这个文件分别配置了 Deployment
和 Service
。运行的镜像是基于 CentOS
镜像,并在里面部署了一个 Nginx
服务器,用于模拟我们的 Http
服务。
部署完之后各项情况如下:
[root@localhost ~]# kubectl get deployment -o wide
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
http-test-dm 3 3 3 3 14m http-test-con registry.cn-shenzhen.aliyuncs.com/lx0758-per/http-test:latest name=http-test-dm
[root@localhost ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
http-test-dm-bcd8d9b5b-9cc99 1/1 Running 0 13m 10.244.0.30 localhost.master
http-test-dm-bcd8d9b5b-m79ql 1/1 Running 0 13m 10.244.2.15 localhost.node02
http-test-dm-bcd8d9b5b-m9dj2 1/1 Running 0 13m 10.244.1.27 localhost.node01
[root@localhost ~]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
http-test-ser ClusterIP 10.109.145.234 <none> 80/TCP 15m name=http-test-dm
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d <none>
三、安装Pod网络
注意事项
- 每个集群只能安装一种
pod
网络,这里是为了演示才把列出来两种。 - 两种网络都提供了阿里云镜像,如果使用阿里云镜像应该先下拉好镜像再应用yml文件。
- 某些网络插件需要在集群
Master
初始化时传入--pod-network-cidr
参数。 - 网络插件是以扩展方式安装的,所以在每次
reset
之后是需要重新装载yml
文件安装的。 - 多网卡环境时需要对插件的安装参数做修改,让插件知道应该使用哪张网卡去和其他
Node
通信。
Flannel
安装 Flannel
很简单,在 Master
执行提供的命令就可以了。考虑到镜像下载很慢,可以使用我的阿里云镜像,在所有节点(包括 Master
)把镜像先下载好再安装:
docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/flannel:v0.10.0-amd64
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/flannel:v0.10.0-amd64 quay.io/coreos/flannel:v0.10.0-amd64
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/flannel:v0.10.0-amd64
下载完镜像,然后再执行安装命令:
[root@localhost ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml
clusterrole "flannel" created
clusterrolebinding "flannel" created
serviceaccount "flannel" created
configmap "kube-flannel-cfg" created
daemonset "kube-flannel-ds" created
注意镜像只有一个: ·quay.io/coreos/flannel:v0.10.0-amd64·
Weave Net
安装 ·Weave Net· 同样也很简单,在 ·Master· 执行上面提供的命令就可以了。考虑到镜像下载很慢,可以使用我的阿里云镜像,在所有节点(包括 Master
)把镜像先下载好再安装:
docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/weave-npc:2.3.0
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/weave-npc:2.3.0 weaveworks/weave-npc:2.3.0
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/weave-npc:2.3.0
docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/weave-kube:2.3.0
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/weave-kube:2.3.0 weaveworks/weave-kube:2.3.0
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/weave-kube:2.3.0
注意镜像这里有两个:
weaveworks/weave-npc:2.3.0
weaveworks/weave-kube:2.3.0
下载完镜像,然后再执行安装命令。
[root@localhost ~]# kubectl apply -f https://cloud.weave.works/k8s/net
serviceaccount "weave-net" created
clusterrole "weave-net" created
clusterrolebinding "weave-net" created
role "weave-net" created
rolebinding "weave-net" created
daemonset "weave-net" created
安装完成
Pod
网络安装完毕之后,在查看 k8s nodes
就全部变为可用了:
[root@localhost ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
localhost.master Ready master 56m v1.9.0
localhost.node01 Ready <none> 55m v1.9.0
验证网络
正常情况下,安装 Pod
网络成功之后,各个节点的 Pod
的网络是可以 ping
通的:
# 先找出两个在不同节点的 Pod 分配到的 IP(没有的话部署一个)
[root@localhost ~]# kubectl get pod -o wide --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE
default http-test-dm-bcd8d9b5b-2z57z 1/1 Running 0 8h 10.244.2.95 localhost.node01
default http-test-dm-bcd8d9b5b-7kmxq 1/1 Running 0 8m 10.244.0.38 localhost.master
ingress-nginx default-http-backend-66954f958c-nrqvr 1/1 Running 1 9h 10.244.0.31 localhost.master
ingress-nginx nginx-ingress-controller-5b7fc4c8f6-xvszd 1/1 Running 0 17m 10.0.2.15 localhost.master
kube-system etcd-localhost.master 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-apiserver-localhost.master 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-controller-manager-localhost.master 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-dns-6f4fd4bdf-tdwrr 3/3 Running 3 9h 10.244.0.34 localhost.master
kube-system kube-flannel-ds-hxn8s 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-flannel-ds-jgprt 1/1 Running 0 9h 10.0.2.15 localhost.node01
kube-system kube-proxy-qq8nh 1/1 Running 0 9h 10.0.2.15 localhost.node01
kube-system kube-proxy-x5mkg 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-scheduler-localhost.master 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kubernetes-dashboard-6b78d59ffd-4zvcg 1/1 Running 1 9h 10.244.0.35 localhost.master
# 在 Master 尝试 Ping 另一个节点内 Pod 的 IP
[root@localhost ~]# ping 10.244.2.95
PING 10.244.2.95 (10.244.2.95) 56(84) bytes of data.
64 bytes from 10.244.2.95: icmp_seq=1 ttl=63 time=2.55 ms
64 bytes from 10.244.2.95: icmp_seq=2 ttl=63 time=2.00 ms
64 bytes from 10.244.2.95: icmp_seq=3 ttl=63 time=1.50 ms
64 bytes from 10.244.2.95: icmp_seq=4 ttl=63 time=1.07 ms
--- 10.244.2.95 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 1.074/1.784/2.555/0.553 ms
# 在 Master Pod 内尝试 Ping 另一个节点内 Pod 的 IP
[root@localhost ~]# kubectl exec -ti http-test-dm-bcd8d9b5b-7kmxq bash
[root@http-test-dm-bcd8d9b5b-7kmxq /]# ping 10.244.2.95
PING 10.244.2.95 (10.244.2.95) 56(84) bytes of data.
64 bytes from 10.244.2.95: icmp_seq=1 ttl=62 time=1.60 ms
64 bytes from 10.244.2.95: icmp_seq=2 ttl=62 time=1.69 ms
64 bytes from 10.244.2.95: icmp_seq=3 ttl=62 time=1.98 ms
64 bytes from 10.244.2.95: icmp_seq=4 ttl=62 time=2.08 ms
--- 10.244.2.95 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 1.600/1.842/2.089/0.204 ms
到这里可以确认,集群内所有 Pod
网络的都是互通的,说明我们的网络插件是安装正确的。
四、Pod DNS问题
上步骤我们成功安装了 Pod
网络,可是却发现 DNS
的 Pod
没运行:
[root@localhost ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-localhost.master 1/1 Running 0 3m
kube-system kube-apiserver-localhost.master 1/1 Running 0 2m
kube-system kube-controller-manager-localhost.master 1/1 Running 0 3m
kube-system kube-dns-6f4fd4bdf-btlhn 0/3 ContainerCreating 0 3m
kube-system kube-flannel-ds-7dqgv 1/1 Running 0 1m
kube-system kube-flannel-ds-pgxp7 1/1 Running 0 1m
kube-system kube-proxy-jfwrt 1/1 Running 0 3m
kube-system kube-proxy-mw7pz 1/1 Running 0 3m
kube-system kube-scheduler-localhost.master 1/1 Running 0 2m
在境外服务器重现之后发现是 k8s
还会去谷歌下拉 3个dns相关的镜像
。所以我又搞了阿里云:
#!/usr/bin/env bash
images=(
k8s-dns-sidecar-amd64:1.14.7
k8s-dns-kube-dns-amd64:1.14.7
k8s-dns-dnsmasq-nanny-amd64:1.14.7
)
for imageName in ${images[@]} ; do
docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/$imageName
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/$imageName gcr.io/google_containers/$imageName
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/$imageName
done
上面3个镜像只需要在 Master
机器上面安装即可。
pull
之后,貌似 dns
就运行起了。。。
额。。。如果始终运行不起,那你就 kubectl delete pod {pods} -n kube-system
杀掉 Pod
让它重启吧。。。我就是这样才运行起的。。。
[root@xg-6xyun-cn ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-xg-6xyun-cn 1/1 Running 0 8m
kube-system kube-apiserver-xg-6xyun-cn 1/1 Running 0 8m
kube-system kube-controller-manager-xg-6xyun-cn 1/1 Running 0 9m
kube-system kube-dns-6f4fd4bdf-8k446 3/3 Running 0 9m
kube-system kube-flannel-ds-wp4z7 1/1 Running 0 8m
kube-system kube-proxy-vwxbt 1/1 Running 0 9m
kube-system kube-scheduler-xg-6xyun-cn 1/1 Running 0 8m
验证 DNS
服务
[root@localhost ~]# kubectl exec -ti http-test-dm-bcd8d9b5b-2z5dz bash
[root@http-test-dm-bcd8d9b5b-2z5dz /]# curl 10.96.148.108
<!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>
[root@http-test-dm-bcd8d9b5b-2z5dz /]# curl http-test-ser
<!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>
五、问题汇总
kubeadm init 没加 –pod-network-cidr
Master
的 Pods
就会变成这样:
[root@localhost ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-localhost.master 1/1 Running 3 49m
kube-system kube-apiserver-localhost.master 1/1 Running 3 49m
kube-system kube-controller-manager-localhost.master 1/1 Running 3 49m
kube-system kube-dns-6f4fd4bdf-rpgw4 0/3 ContainerCreating 0 1h
kube-system kube-flannel-ds-dskzt 0/1 CrashLoopBackOff 22 49m
kube-system kube-flannel-ds-xj9l8 0/1 Error 2 2m
kube-system kube-proxy-n2hc8 1/1 Running 0 2m
kube-system kube-proxy-xdtcx 1/1 Running 3 1h
kube-system kube-scheduler-localhost.master 1/1 Running 3 49m
所以。。。重新初始化吧~
Flannel 多网卡环境 Pod 无法互访
这么问题我搞了半天,其实就是需要对 网络插件指定网卡,不然它也不知道用哪个网卡和其他节点通信呐~
由于 Flannel
使用默认路由的网卡接口,导致适用了外网网卡,致使pod之间无法访问。
所以需要指定使用相应网卡。在 command
参数增加 --iface=eth1
即可,修改 yaml 文件:
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-system
labels:
tier: node
app: flannel
spec:
template:
metadata:
labels:
tier: node
app: flannel
spec:
hostNetwork: true
nodeSelector:
beta.kubernetes.io/arch: amd64
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay.io/coreos/flannel:v0.10.0-amd64
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.10.0-amd64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
# 这里就是重点了
- --iface=eth1
···