0
点赞
收藏
分享

微信扫一扫

使用rancher自建k8s集群

全栈工程师开发手册 (作者:栾鹏)
架构系列文章

建设前准备

申请docker 仓库

因为总需要存放镜像的仓库,内网可以自己部署harbor,在外网可以官方docker hub,或者阿里云、腾讯云

将基础组件推送到内网仓库

如果能连接外网的客户忽略。

内网无法连接外网,需要我们提前拉好镜像。关于镜像的版本与rancher版本、k8s版本有关。

比如我这里使用的是rancher v2.3.2,k8s使用的是v1.15.5

使用rancher自建k8s集群_k8s


使用rancher自建k8s集群_docker_02


不过依赖镜像是在安装rancher server以后才看到的。所以可以先安装rancher server,然后看看要用的k8s版本,然后再在rancher官网拉取需要的镜像。比如rancher v2.3.2,k8s v1.15.5依赖的镜像。在官网https://github.com/rancher/rancher/releases/tag/v2.3.2 中 找到 依赖的镜像txt文件

使用rancher自建k8s集群_内网_03


https://github.com/rancher/rancher/releases/download/v2.3.2/rancher-images.txt

将依赖镜像在开发网拉取下来,然后重新tag成内网仓库地址,推送到内网仓库上,后面需要在内网每个机器上拉取下来,再tag成原始镜像名。例如

外网网机器
docker pull rancher/rancher-agent:v2.3.2
docker tag rancher/rancher-agent:v2.3.2 docker.oa.com:8080/public/rancher/rancher-agent:v2.3.2

内网机器
docker pull docker.oa.com:8080/public/rancher/rancher-agent:v2.3.2 
docker tag docker.oa.com:8080/public/rancher/rancher-agent:v2.3.2 rancher/rancher-agent:v2.3.2

由于依赖镜像比较多,可以写一个脚本,批量的拉取和tag。

例如idc机器脚本

docker login xx.xx.xx.xx:8080 -u xx -p xxxxxxx

docker pull docker.oa.com:8080/public/rancher/fluentd:v0.1.17
docker tag docker.oa.com:8080/public/rancher/fluentd:v0.1.17 rancher/fluentd:v0.1.17 
docker pull docker.oa.com:8080/public/rancher/istio-citadel:1.3.3
docker tag docker.oa.com:8080/public/rancher/istio-citadel:1.3.3 rancher/istio-citadel:1.3.3
...

初始化节点

因为idc网络每台机器的hostname是一样的,而且是大写开头,在rancher中无法添加到k8s集群,需要将hostname设置为小写不同命名。

修改机器hostname

hostname=`ifconfig eth1 | grep 'inet '| awk '{print $2}' | head -n 1 | awk -F. {'printf("node%03d%03d%03d%03d\n", $1, $2, $3, $4)'}`
echo $hostname
# hostname=$1
hostnamectl set-hostname ${hostname}

echo "127.0.0.1 ${hostname}" >> /etc/hosts
echo "::1 ${hostname}" >> /etc/hosts

配置dns

由于每台机器的dns情况配置不一样,所以最好统一化dns配置。

安装升级docker

每台机器的docker版本都各式各样,统一化docker版本,安装目录,私有仓库等。

# 关停docker
service docker stop

# 卸载存在的老版本docker
yum remove -y docker-ce 
yum remove -y docker 
yum remove -y docker-common 

# 查看是否还有docker残渣
rpm -qa | grep docker

# 创建docker的存储路径,因为docker使用的存储很大,默认根目录磁盘很小
# rm -rf /data/docker/ 
mkdir -p /data/docker/ 

# 安装docker,顺带安装调试工具
yum install docker-ce -y 
yum install -y htop docker-compose
yum install -y wireshark

# 停止docker,修改配置
systemctl stop docker

# 将源docker目录下文件,复制到新目录下
cp -R /var/lib/docker/* /data/docker/ 

# 将docker新目录写入到配置文件中
sed -i "s/containerd.sock/containerd.sock --graph \/data\/docker /g" /usr/lib/systemd/system/docker.service 
mkdir -p /etc/docker/

# 将私有仓库写入到配置文件中
echo '{ "insecure-registries":["docker.oa.com:8080"] } ' > /etc/docker/daemon.json 

# 重载配置
systemctl daemon-reload 

# 重启docker
systemctl start docker 

# 删除原目录数据
rm -rf /var/lib/docker

拉取基础镜像

运行上面的镜像拉取脚本,将依赖镜像拉取到机器,并tag成原始镜像名。

部署rancher server

rancher server 有高可用部署方案,可以参考官网https://rancher.com/docs/rancher/v2.x/en/installation/how-ha-works/

使用rancher自建k8s集群_内网_04


需要打通ssh,或者跳板机的ssh。如果没有固定的ssh账号,所以采用的单容器部署模式。不过如果可以,建议尝试高可用模式。

找一台机器作为rancher server,如果你的集群比较大,建议找好一点的机器,因为这个rancher server无法替换。

sudo docker run -d --restart=unless-stopped -p 443:443 --privileged --name=myrancher -e AUDIT_LEVEL=3 rancher/rancher:v2.3.2

部署以后就可以打开https://xx.xx.xx.xx:443/了。

第一次进入要添加管理员密码和rancher server的https访问地址。

配置高可用

官方提供的几种高可用方案,要么需要ssh互联,需要需要跳板机账号密码都无法在idc环境实现。并且使用单容器模式部署的时候,docker service或者机器重启,rancher server都会报异常。一直报wait k3s start。下面提供一种方案能使单容器模式下,机器重启rancher server仍可用。

$ docker stop $RANCHER_CONTAINER_NAME
$ docker create --volumes-from $RANCHER_CONTAINER_NAME --name rancher-data rancher/rancher:$RANCHER_CONTAINER_TAG
# 先备份一遍
$ docker run --volumes-from rancher-data -v $PWD:/backup alpine tar zcvf /backup/rancher-data-backup-$RANCHER_VERSION-$DATE.tar.gz /var/lib/rancher
$ docker run -d --volumes-from rancher-data --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher:latest

然后就可以把原有容器删除掉了。这个新启动的容器,在docker service重启后是可以继续正常工作的。

配置认证过期

rancher server的证书有效期是一年,在一年后,rancher server会报证书过期。通过下面的方式你可以创建新的证书。

docker stop $RANCHER_CONTAINER_NAME
docker start $RANCHER_CONTAINER_NAME 
docker exec -it $RANCHER_CONTAINER_NAME sh -c "mv k3s/server/tls k3s/server/tls.bak" 
docker logs --tail 3 $RANCHER_CONTAINER_NAME 
# Something similar to the below will appear: 
# 2021/01/03 03:07:01 [INFO] Waiting for server to become available: Get https://localhost:6443/version?timeout=30s: x509: certificate signed by unknown authority 
# 2021/01/03 03:07:03 [INFO] Waiting for server to become available: Get https://localhost:6443/version?timeout=30s: x509: certificate signed by unknown authority 
# 2021/01/03 03:07:05 [INFO] Waiting for server to become available: Get https://localhost:6443/version?timeout=30s: x509: certificate signed by unknown authority 
docker stop $RANCHER_CONTAINER_NAME 
docker start $RANCHER_CONTAINER_NAME

部署k8s集群

进去rancher server,选择添加集群,选择自定义集群。填写集群名称

使用rancher自建k8s集群_内网_05


选择kubernetes版本(注意:这个的版本第一次打开时可能刷新不出来,需要等待1~2分钟再刷新才能显示出来)

之后选择编辑yaml文件。

这个yaml文件中控制着k8s基础组件的启动方式。比如kubelet的启动参数,api-server的启动参数。

比如这里修改ip网段和修改api-server的启动参数

services:
    etcd:
      backup_config:
        enabled: true
        interval_hours: 12
        retention: 6
        safe_timestamp: false
      creation: 12h
      extra_args:
        election-timeout: '5000'
        heartbeat-interval: '500'
      gid: 0
      retention: 72h
      snapshot: false
      uid: 0
    kube-api:
      always_pull_images: false
      pod_security_policy: false
      service_node_port_range: 10-32767
      service_cluster_ip_range: 172.16.0.0/17  
      extra_args:     
        enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,NodeRestriction,TaintNodesByCondition,PersistentVolumeClaimResize"
    kube-controller:
      cluster_cidr: 172.16.128.0/17
      service_cluster_ip_range: 172.16.0.0/17
    kubelet:
      cluster_dns_server: 172.16.0.10
    kubeproxy: {}
    scheduler: {}

如果有其他的参数需要后面修改,也可以在这里修改yaml文件,然后升级集群。

修改后直接进入下一步。这里可以选择节点的角色。etcd用来部署k8s的数据库,可以多个节点etcd。control相当于k8s的master,用来部署控制组件,可以在多个节点的部署k8s master节点,实现k8s高可用。worker相当于k8s的工作节点。

我们可以在rancher server这台机器可以添加为etcd/control角色。(如果你只有一台机器或者只是简单尝试,可以把所有角色都选上)

使用rancher自建k8s集群_内网_06

复制web中显示的命令,直接在rancher server上粘贴命令,这样就部署了一个k8s集群。只不过现在还没有worker节点。

粘贴后等待部署就行了。

使用rancher自建k8s集群_k8s_07


部署完成的样子

使用rancher自建k8s集群_kubernetes_08

部署完成后需要部分修正。

1、metric-server默认镜像拉取是Always,修改成imagePullPolicy: IfNotPresent
2、nginx如果不想使用,或者因为端口占用只在部分机器上使用,可以添加亲密度不启动或者在部分机器上启动。

affinity:
   nodeAffinity:
     requiredDuringSchedulingIgnoredDuringExecution:
       nodeSelectorTerms:
       - matchExpressions:
         
         - key: ingress-nginx
           operator: In
           values:
           - "true"

3、coredns在资源limits太小了,可以取消coredns的limits限制,不然dns非常慢,整个集群都会缓慢

机器扩容

现在k8s集群已经有了一个master节点,还没有worker节点,或者想添加更多master/worker节点就要机器扩容了。

使用rancher自建k8s集群_kubernetes_09

在集群主机界面,点击编辑集群

修改docker目录为上面修改的docker根目录/data/docker,然后选择角色为worker(根据自己的需求选择角色)

使用rancher自建k8s集群_rancher_10

复制命令到目标主机上运行,等待安装就可以了。

rancher/k8s 多用户

集群部署好了,需要添加多种权限类型的用户来管理。可以使用rancher来实现k8s的rbac的多用户。

登录rancher,先在全局添加用户

使用rancher自建k8s集群_rancher_11

根据需要在全局/集群/项目中创建角色

使用rancher自建k8s集群_kubernetes_12


添加或者编辑角色,为角色授权

使用rancher自建k8s集群_docker_13

将全局用户添加到集群或者项目成员中

使用rancher自建k8s集群_docker_14


添加时为用户绑定角色

使用rancher自建k8s集群_kubernetes_15

这样就成功创建了用户-绑定了角色-赋予了权限。

用户登录效果

使用rancher自建k8s集群_kubernetes_16

客户端kubectl

如果你不会使用rancher界面或者不习惯使用rancher界面,可以使用kubectl或者kubernetes-dashboard。

使用rancher自建k8s集群_内网_17

点击Kubeconfig文件可以看到config的内容,通过内容可以看到,kube-apiserver可以使用rancher-server(端口443)的api接口,或者kube-apiserver(端口6443)的接口控制k8s集群。由于6443端口在idc网络里面并不能暴露到外面,所以主要使用rancher-server的443端口代理k8s-apiserver的控制。提示,如果你的rancher server 坏了,你可以在内网通过6443端口继续控制k8s集群。

下载安装不同系统办公电脑对应的kubectl,然后复制config到~/.kube/config文件。就可以通过命令访问k8s集群了。

使用rancher自建k8s集群_rancher_18

kubernetes-dashboard

如果你喜欢用k8s-dashboard,可以自己安装dashboard。参考git。

使用rancher自建k8s集群_kubernetes_19

这样我们就完成k8s的部署。

节点清理

如果安装失败需要重新安装,有时需要彻底清理节点。清理过程比较麻烦,这里整理了一个脚本放在git上。

#!/usr/bin/env bash 

sudo docker rm -f $(sudo docker ps -qa)
sudo rm -rf /etc/ceph \
       /etc/cni \
       /etc/kubernetes \
       /opt/cni \
       /opt/rke \
       /run/secrets/kubernetes.io \
       /run/calico \
       /run/flannel \
       /var/lib/calico \
       /var/lib/etcd \
       /var/lib/cni \
       /var/lib/kubelet \
       /var/lib/rancher/rke/log \
       /var/log/containers \
       /var/log/pods \
       /var/run/calico \
       /var/etcd

for mount in $(mount | grep tmpfs | grep '/var/lib/kubelet' | awk '{ print $3 }') /var/lib/kubelet /var/lib/rancher; do umount $mount; done
for m in $(sudo tac /proc/mounts | sudo awk '{print $2}'|sudo grep /var/lib/kubelet);do
 sudo umount $m||true
done
sudo rm -rf /var/lib/kubelet/
for m in $(sudo tac /proc/mounts | sudo awk '{print $2}'|sudo grep /var/lib/rancher);do
 sudo umount $m||true
done
sudo rm -rf /var/lib/rancher/
sudo rm -rf /run/kubernetes/
sudo docker volume rm $(sudo docker volume ls -q)
sudo docker ps -a
sudo docker volume ls

rm -f /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db

IPTABLES="/sbin/iptables"
cat /proc/net/ip_tables_names | while read table; do
  $IPTABLES -t $table -L -n | while read c chain rest; do
      if test "X$c" = "XChain" ; then
        $IPTABLES -t $table -F $chain
      fi
  done
  $IPTABLES -t $table -X
done

sudo systemctl restart containerd
sudo systemctl restart docker

rancher架构图

使用rancher自建k8s集群_kubernetes_20

上面的操作完成,现在再回来看一下rancher的架构图。

rancher使用全部容器化的形式来部署k8s集群,能大幅度降低k8s集群扩部署/缩容的门槛。可以使用rancher来扩缩容 etcd,k8s-master,k8s-worker。k8s集群(包括etcd)的增删节点动作是由rancher server节点控制,由rancher agent来执行的。在新节点上通过运行rancher agent容器,来访问rancher server 获取要执行的部署命令。部署对应的k8s组件容器(包含kubelet,api-server,scheduler,controller等)。

rancher本身并不改变k8s的基础组件和工作原理,k8s的架构依然是下面图形中的工作模式。只不过多了一个认证代理(auth proxy),也就是前面说的config文件中的rancher server中的接口。

kubernetes架构图

使用rancher自建k8s集群_kubernetes_21


举报

相关推荐

0 条评论