kubernetes简介


        在多台主机上都安装上kubernetes 相关程序,并通过这个应用程序协同工作,把多个主机当成一个主机来使用。在kubernetes 中主机是分角色的,k8s是一个有中心节点架构的集群系统 master/node模型,master节点一般有三个实现高可用,是唯一入口,node节点是真正的工作节点,运行容器的节点。客户端的请求发或启动容器的请求发给master,master有一个调度器去分析各node现有的可用资源状态,找一个最佳适配的node去运行,node去运行容器,容器会自动去下载镜像。

        客户端请求到达 kubernetes Cluster 后交给 API Server 负责接收并处理请求。master上有一个调度器 scheduler ,用来负责去观测每一个node之上的计算资源,并根据调度算法中的优选算法来决定调度那个节点上来启动容器来响应请求。

        控制器去监控每一个node节点上的容器是否监控,一旦发现某个容器不健康就向 API Server 发送请求,然后通过 Scheduler 从某个节点中挑一个合适的节点并启动一个容器。控制器还会持续性探测容器是否健康或是否符合要求。控制器有多个,控制器的监控状态由控制器管理器 Controller-Manager 来管理,这个Controller-Manager 在 master上。

        控制器并不直接调度容器运行,而是调度Pod,Pod可以理解为容器的外壳,把容器做了一层抽象的封装,Pod是kubernetes 上最小的调度逻辑单元。Pod内部主要是用来放容器的。kubernetes 做了一个逻辑组件叫Pod,在Pod内用来运行容器,一个Pod内可以包含多个容器,这多个容器共享同一个底层的网络名称空间net、uts、ipc是共享的,(user、mnt、pid是互相隔离的)。Pod相当于一个虚拟机,Pod内的容器彼此通讯2用lo,同一个组地址对外通信。Pod内容器之间还共享存储卷Volumn,相当于虚拟机的磁盘。一般情况下一个Pod运行一个容器,除非容器间有特殊的紧密联系,如果一个Pod运行多个容器有一个容器成为主容器。其他容器被成为边车,用来辅助主容器的运行。调度器调度的是Pod,Pod是一个原子单元,同一个Pod里的容器运行在同一个node之上。

        Node可以是任何形式的计算设备,多个node组成一个计算池,由kube Cluster 来统一管理。创建完Pod之后可以给Pod打上标签,通过标签的键和值来识别出Pod,这个选择过程使用标签选择器 Selecter 来选择。

        kubelet是node上的集群代理,请求的结果到达 API Server 再由 Scheduler 调度,node上的 kubelet 接收到任务后来执行,如启动Pod,创建存储券等等都由 kubelet 来执行,kubelet 并不启动容器,而是启动容器管理引擎,由容器管理引擎来启动容器。

master/node:

        master:API Server,Scheduler,Controller-Manager

        node:kubelet,docker,kube-proxy

Pod,Label,Label Selector

        Label:key=value

        Label Selector


Pod:

        自助式Pod,kubernetes管理的Pod,

        控制器管理的Pod

                ReplicationController

                ReplicaSet

                DaemonSet

                Job,Ctonjob

                HPA

HPA:

        HorizontalPodAutoscaler

        Pod 是有可能在其它节点上被重建的,重建后的Pod 跟原来的不是同一个只是运行的服务相同,Pod 的IP地址或主机名等信息都和原来的不一样了。这时的客户端访问服务是无法找到的,需要一个服务发现机制,kubernetes 为每种提供相同服务的Pod和客户端之间加了一个中间层,叫做 service 这个中间层的地址和名称都是固定的,当service 后面的某个Pod宕机了就会新建一个Pod 并关联到 service ,service 通过标签选择器来关联 Pod ,然后 service 再动态探测 Pod 的IP地址端口作为后端的服务,客户端只要连接 service 即可service 是DNAT规则。service 可以作为服务来提供访问但是却ping不同,因为它只是DNAT 规则没有协议栈,service 有名称,也是服务的名称,可以把service 的名称解析为 service 的IP,名称解析需要DNS服务,这时就需要安装DNS Pod 服务在 k8s 中。

CNI:

        Pod和Pod、容器、service、集群外部的客户端都要进行通信,所以要构建多个网络,节点网络、service网络也叫集群网络、Pod网络。这三个网 kubernetes 自己不提供,要依赖于第三方插件。节点网络在构建k8s集群之前就已近构建好了,集群网络和Pod网络就要插件来提供了。k8s 通过容器网络接口 CNI 来提供网络解决方案。只要遵循CNI来开发这个服务就能够作为k8s 的解决方案来使用。这个网络解决方案也可以运行在Pod上,但是需要共享节点的网络名称空间。

        CNI 插件有一款叫 flannel 提供网络配置,但是还需要提供网络策略功能。calico 即提供网络配置又提供网络策略。但是calico配置复杂,所以有了第三个项目叫 canel 结合两者的特性。

        kubernetes 的名称空间用来隔离不同的Pod,当一个集群上运行的Pod数量非常多的时候,Pod之间是互相干扰的,一类Pod可以运行在一个名称空间中,这个空间不是网络边界只是管理边界,如第一个名称空间运行开发环境,第二个名称空间运行生产环境,要删除开发命名空间可以把整个名称下的开发环境都删除掉。但是两个命名空间中的Pod是可以互相访问的,网络策略就是用来定义Pod之间是否可以访问的,通过生成 iptables 规则来隔离彼此之间的互相访问。



搭建


准备三个节点:master、node1、node2

cat >> /etc/hosts <<EOF
192.168.1.140 k8s-master
192.168.1.141 k8s-node1
192.168.1.142 k8s-node2
EOF

官方项目位置:https://github.com/kubernetes

阿里云镜像地址:https://opsx.alibaba.com/mirror

准备yum源:

配置docker的yum源:

wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

kubernetes的yum源:

cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

三个节点上安装:

yum install docker-ce
yum install kubelet-1.11.1-0 kubeadm-1.11.1-0 kubectl-1.11.1-0

systemctl start docker.service && systemctl enable docker.service
systemctl enable kubelet.service #不用启动

        在node节点上可以不安装 kubectl 这是命令行管理工具,node 一般都是在master上管理的。

打开桥接:

        k8s 会生成 iptables 规则需要打开内置的桥接功能,需要检查下面两项是否为1。

cat /proc/sys/net/bridge/bridge-nf-call-iptables 
cat /proc/sys/net/bridge/bridge-nf-call-ip6tables

同步集群之间的时间:

ntpdate ntp.sjtu.edu.cn

忽略swap错误:k8s默认不支持使用swap

vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--fail-swap-on=false"

或关闭swap:

swapoff -a
sed -i "s/^\/dev\/mapper\/centos-swap/#&/" /etc/fstab

下载镜像:

#!/bin/bash

images=(
    kube-apiserver:v1.18.20
    kube-controller-manager:v1.18.20
    kube-scheduler:v1.18.20
    kube-proxy:v1.18.20
    pause:3.2
    etcd:3.4.3-0
    coredns:1.6.7
)

for imageName in ${images[@]} ; do
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
    docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
    docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done

初始化master:

kubeadm init --kubernetes-version=v1.11.1 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.1.138 --ignore-preflight-errors=SystemVerification

        --apiserver-advertise-address=192.168.1.138  当前主机的IP

        --ignore-preflight-errors=SystemVerification  忽略docker版本报错选项

        --ignore-preflight-errors=Swap  忽略swap问题

初始化后注意下面的提示信:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubeadm join 192.168.1.138:6443 --token 7tvb4f.wljuocf85coaouss --discovery-token-ca-cert-hash sha256:1dd836ce8f274091169fa40413856bc37cd16ad10bc81314ec6a3cb058952f9e

将 node1 和 node2 加入到集群:

kubeadm join 192.168.1.138:6443 --token 7tvb4f.wljuocf85coaouss --discovery-token-ca-cert-hash sha256:1dd836ce8f274091169fa40413856bc37cd16ad10bc81314ec6a3cb058952f9e --ignore-preflight-errors=SystemVerification

查看组件状态信息:

kubectl get componentstatus
kubectl get cs #简写

安装 fannel:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

提示:如果安装失败,则可以执行 kubeadm reset 命令将主机恢复原状 , 重新执行 kubeadm init 命令再次进行安装。


将新节点加入到集群:

        有时节点不够用想加入新的节点,但是加入节点的hash值和token不见了,这是就可以用下面的命令将新的节点加入。

        新的节点要安装上docker、kubeadm、kubelet版本根据实际情况而定。

创建token:默认token有效期为一天,过期需要重新创建。

kubeadm token generate

使用hash值创建加入集群的join命令:

kubeadm token create 8rl94q.4g4y5yj39zlfb41v --print-join-command --ttl=0

得到的join命令如下:在要加入集群的节点上执行如下命令即可,节点就被加入了集群。

kubeadm join 192.168.1.140:6443 --token 8rl94q.4g4y5yj39zlfb41v --discovery-token-ca-cert-hash sha256:6adf08dd88964e98431efe4de74fb52278989c7606af0d20f514fdf13046a98a

--ttl=token过期时间,单位秒,0表示永不过期