学习一下K8S相关知识,先搞个K8S的集群作为学习环境
由于以搭建完成提供后续学习使用的环境,所以一切以简单方便快捷为标准 主要因为现在啥也不懂,先跑起来再说
在学习过程中,我拥有三台物理机,所以一台用来做Master,两台台用来做Node
安装Docker和K8S相关组件
到阿里云镜像上去找对应的国内镜像,上有安装方案,不再赘述。
docker安装可以使用脚本
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
装完后应有下列可执行程序
- docker
- kubectl
- kubeadm
- kubelet
启动服务
sudo systemctl enable kubelet
sudo systemctl start kubelet
sudo systemctl enable docker
sudo systemctl start docker
kubeadm: 1.17.0 kubectl: 1.17.0 kubelet: 1.17.0 docker: 19.03.5
DEBIAN 9的可以参考下面的脚本
#!/bin/bash
if [[ ${USER} != root ]]
then
echo "PLEASE RUN WITH ROOT INSTEAD OF ${USER}!!"
exit;
fi
# 这里面会执行 apt update 和 apt-get install apt-transport-https
# 不执行此条shell安装docker的自行执行更新和安装apt-transport-https包
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" > /etc/apt/sources.list.d/kubernetes.list
apt update
apt install -y kubelet kubeadm kubectl
# 阿里云的Docker镜像加速,没有的话可以忽略
echo "{ \"registry-mirrors\": [\"https://<key>.mirror.aliyuncs.com\"] }" > /etc/docker/daemon.json
初始化集群Master
使用 kubeadm 工具初始化集群
其中可以使用 sudo kubeadm init --config=init-config.yaml 初始化配置(默认配置文件可以通过 sudo kubeadm config print init-defaults > init-config.yaml 输出到文件)
但是使用配置文件的方式无法使用 pod-netowrk-cidr 参数
sudo kubeadm config print init-defaults > init-config.yaml
文件内容如下 最少需要修改两处
- 机器IP
- 镜像仓库地址
...
localAPIEndpoint:
advertiseAddress: <master-ip> #换成Master机器的IP
bindPort: 6443
...
---
...
imageRepository: registry.aliyuncs.com/google_containers #换成阿里云的容器镜像
...
完成上述步骤之后,需要执行这些命令来使 kubectl 变得可用
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
加入集群一个Node节点
-
可以直接通过使用Master环境初始化后提供的命令来加入集群(其他参数可以自行扩展),命令在Master初始化完成后有提供
kubeadm join IP:PORT --token TOKEN --discovery-token-ca-cert-hash HASH -
或者使用kubeadm生成文件形式来加入
- 生成配置文件
sudo kubeadm config print join-defaults > join-config.yaml - 修改配置文件
- 加入集群
sudo kubeadm join --config=join-config.yaml
- 生成配置文件
网络插件
这个是用来连通集群内所有节点的网络,使得整个集群都处于一个内网状态中
使用 weave 网络插件,简单,而且自带DNS功能,可以直接使用 POD 的名字来通信
(怎么实现的我也不知道,也不知道他们之间还有啥区别)
在Master执行下面命令
$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
serviceaccount/weave-net configured
clusterrole.rbac.authorization.k8s.io/weave-net configured
clusterrolebinding.rbac.authorization.k8s.io/weave-net configured
role.rbac.authorization.k8s.io/weave-net configured
rolebinding.rbac.authorization.k8s.io/weave-net configured
daemonset.apps/weave-net configured
执行完之后 kubectl get nodes 中的 STATUS 一列在一段时间后会变成 Ready
IP重复
在安装完插件后发现有一个 weave-net 的Pod启动失败。检查之下发现报错
$ k8s kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-9d85f5447-bnl6h 0/1 ContainerCreating 0 102s
coredns-9d85f5447-ctjsf 0/1 ContainerCreating 0 102s
etcd-aliyun-master 1/1 Running 0 87s
kube-apiserver-aliyun-master 1/1 Running 0 87s
kube-controller-manager-aliyun-master 1/1 Running 0 87s
kube-proxy-8l68s 1/1 Running 0 102s
kube-scheduler-aliyun-master 1/1 Running 0 87s
weave-net-cpssv 1/2 CrashLoopBackOff 3 86s
$ k8s kubectl logs -c weave weave-net-cpssv -n kube-system
Network 10.32.0.0/12 overlaps with existing route 10.0.0.0/8 on host
weave默认使用10.32.0.0/12段,然而在某些情况下可能该IP段被占用,需要修改weave服务使用的IP段
在weave官网的changing-configuration-options部分查看到可以使用 IPALLOC_RANGE 环境变量来修改weave服务实用的IP段
$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&env.IPALLOC_RANGE=172.32.0.0/12"
serviceaccount/weave-net configured
clusterrole.rbac.authorization.k8s.io/weave-net configured
clusterrolebinding.rbac.authorization.k8s.io/weave-net configured
role.rbac.authorization.k8s.io/weave-net configured
rolebinding.rbac.authorization.k8s.io/weave-net configured
daemonset.apps/weave-net configured
$ k8s kubectl get nodes
NAME STATUS ROLES AGE VERSION
aliyun-master Ready master 17m v1.17.0
测试集群网络通信是否正常
看起来现在是好了,需要验证一下集群是否工作正常
在Master上进行下列操作
在集群中创建一个Nginx服务
创建文件 nginx.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 1
selector:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
selector:
app: nginx
通过使用 kubectl 来创建一个 Pod 和 Service
$ kubectl create -f nginx.yaml
replicationcontroller/nginx created
service/nginx created
检查一下Pod状态,重点观察Events的内容来判断服务是否创建成功
$ kubectl describe pods
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/nginx-rqnlj to work-node
Normal Pulling 3m10s kubelet, work-node Pulling image "nginx"
Normal Pulled 2m58s kubelet, work-node Successfully pulled image "nginx"
Normal Created 2m57s kubelet, work-node Created container nginx
Normal Started 2m57s kubelet, work-node Started container nginx
或者使用另一个命令观察 Status
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-rqnlj 1/1 Running 0 3m07s
单机情况下可能遇到的问题
Warning FailedScheduling 4s (x3 over 5s) default-scheduler 0/1 nodes are available: 1 node(s) had taints that the pod didn't tolerate.
由于Master节点默认带有污点 node-role.kubernetes.io/master:NoSchedule ,所以无法直接部署容器到Master节点上
所以只要删除了Master节点的污点,或者让部署的Pod容忍该污点即可。我们选择删除Master节点污点
$ k8s kubectl taint node aliyun-master node-role.kubernetes.io/master-
node/aliyun-master untainted
再看Deployment应该就已经部署在Master节点上了
在集群中临时启动一个容器进行检测
查看集群中服务的集群IP
$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 49m <none>
nginx ClusterIP 10.102.126.244 <none> 80/TCP 29m app=nginx
使用一下命令临时创建一个容器使用
kubectl run --generator=run-pod/v1 busybox --rm -ti --image=busybox -- /bin/sh
在看到 / 之后,在容器内执行 wget nginx 或者 wget 10.102.126.244
如果有一个index.html被下载下来,说明容器与Node节点上的nginx服务网络互通,整个集群是没有问题的
否则... 就是出了什么问题,作为菜鸡得我也不知道会有啥情况发生...
不要尝试使用 ping 集群IP来测试是否相通
因为集群IP实际上是一个虚地址,是由若干条iptables规则转发工作的。如果iptables中没有对ICMP的包进行设置规则是ping不通的
虽说一头雾水,反正跑起来了,可以继续往下学习了...