K8S学习笔录 - 部署学习使用的集群

1,101 阅读4分钟

阅读原文

学习一下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

文件内容如下 最少需要修改两处

  1. 机器IP
  2. 镜像仓库地址
...
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节点

  1. 可以直接通过使用Master环境初始化后提供的命令来加入集群(其他参数可以自行扩展),命令在Master初始化完成后有提供

    kubeadm join IP:PORT --token TOKEN --discovery-token-ca-cert-hash HASH

  2. 或者使用kubeadm生成文件形式来加入

    1. 生成配置文件 sudo kubeadm config print join-defaults > join-config.yaml
    2. 修改配置文件
    3. 加入集群 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 来创建一个 PodService

$ 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不通的


虽说一头雾水,反正跑起来了,可以继续往下学习了...