欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

003.Kubernetes二进制部署准备

程序员文章站 2022-10-02 11:58:27
一 前置准备1.1 前置条件相应的充足资源的Linux服务器;设置相应的主机名,参考命令: 1 hostnamectl set-hostname k8smaster Mac及UUID唯一;若未关闭防火墙则建议放通相应端口,如下:Master节点—— 规则方向端口范围作用使用者TCPInbound64 ......

一 前置准备

1.1 前置条件

相应的充足资源的linux服务器;

设置相应的主机名,参考命令:

  1 hostnamectl set-hostname k8smaster

mac及uuid唯一;

若未关闭防火墙则建议放通相应端口,如下:

master节点——

规则

方向

端口范围

作用

使用者

tcp

inbound

6443*

kubernetes api server

all

tcp

inbound

2379-2380

etcd server client api

kube-apiserver, etcd

tcp

inbound

10250

kubelet api

self, control plane

tcp

inbound

10251

kube-scheduler

self

tcp

inbound

10252

kube-controller-manager

self

worker 节点——

规则

方向

端口范围

作用

使用者

tcp

inbound

10250

kubelet api

self, control plane

tcp

inbound

30000-32767

nodeport services**

all

其他更多前置准备见:

二 主要组件

2.1 核心组件

  • etcd:保存了整个集群的状态;
  • apiserver:提供了资源操作的唯一入口,并提供认证、授权、访问控制、api注册和发现等机制;
  • controller manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler:负责资源的调度,按照预定的调度策略将pod调度到相应的机器上;
  • kubelet:负责维护容器的生命周期,同时也负责volume(cvi)和网络(cni)的管理;
  • container runtime:负责镜像管理以及pod和容器的真正运行(cri);
  • kube-proxy:负责为service提供cluster内部的服务发现和负载均衡。

2.2 非核心组件

  • kube-dns:负责为整个集群提供dns服务;
  • ingress controller:为服务提供外网入口;
  • heapster:提供资源监控;
  • dashboard:提供gui;
  • federation:集群联邦提供跨可用区的集群;
  • fluentd-elasticsearch:提供集群日志采集、存储与查询。

延伸1:对master节点服务组件的理解:

master节点上面主要由四个模块组成:apiserver,schedule,controller-manager,etcd。

apiserver: apiserver负责对外提供restful的kubernetes api的服务,它是系统管理指令的统一接口,任何对资源的增删该查都要交给apiserver处理后再交给etcd,如架构图中所示,kubectl(kubernetes提供的客户端工具,该工具内部就是对kubernetes api的调用)是直接和apiserver交互的。

schedule: schedule负责调度pod到合适的node上,如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个node组成的列表,输出是pod和一个node的绑定,即将这个pod部署到这个node上。kubernetes目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法。

controller manager: 如果apiserver做的是前台的工作的话,那么controller manager就是负责后台的。每一个资源都对应一个控制器。而control manager就是负责管理这些控制器的,比如我们通过apiserver创建了一个pod,当这个pod创建成功后,apiserver的任务就算完成了。而后面保证pod的状态始终和我们预期的一样的重任就由controller manager去保证了。

etcd:etcd是一个高可用的键值存储系统,kubernetes使用它来存储各个资源的状态,从而实现了restful的api。

延伸2:对master节点服务组件的理解:

每个node节点主要由三个模板组成:kubelet、kube-proxy、runtime。

runtime:runtime指的是容器运行环境,目前kubernetes支持docker和rkt两种容器。

kube-proxy: 该模块实现了kubernetes中的服务发现和反向代理功能。kube-proxy支持tcp和udp连接转发,默认基于round robin算法将客户端流量转发到与service对应的一组后端pod。服务发现方面,kube-proxy使用etcd的watch机制,监控集群中service和endpoint对象数据的动态变化,并且维护一个service到endpoint的映射关系,从而保证了后端pod的ip变化不会对访问者造成影响。另外,kube-proxy还支持session affinity。

kublet:kublet是master在每个node节点上面的agent,是node节点上面最重要的模块,它负责维护和管理该node上的所有容器,但是如果容器不是通过kubernetes创建的,它并不会管理。本质上,它负责使pod的运行状态与期望的状态一致。

三 部署规划

3.1 节点规划


节点

ip

类型

运行服务
k8smaster01
172.24.8.71
kubernetes master节点
docker、etcd、kube-apiserver、kube-scheduler、kube-controller-manager、kubectl、kubelet、kube-nginx、flannel
k8smaster02
172.24.8.72
kubernetes master节点
docker、etcd、kube-apiserver、kube-scheduler、kube-controller-manager、kubectl、
kubelet、kube-nginx、flannel
k8smaster03
172.24.8.73
kubernetes master节点
docker、etcd、kube-apiserver、kube-scheduler、kube-controller-manager、kubectl、
kubelet、kube-nginx、flannel
k8snode01
172.24.8.74
kubernetes node节点1
docker、etcd、kubelet、proxy、flannel
k8snode03
172.24.8.75
kubernetes node节点2
docker、etcd、kubelet、proxy、flannel

提示:本实验使用三节点master部署,从而实现master的高可用。

3.2 组件及版本

  • kubernetes 1.14.2
  • docker 18.09.6-ce
  • etcd 3.3.13
  • flanneld 0.11.0
  • 插件:
    • coredns
    • dashboard
    • metrics-server
    • efk (elasticsearch、fluentd、kibana)
  • 镜像仓库:
    • docker registry
    • harbor

3.3 组件策略

kube-apiserver:

  • 使用节点本地 nginx 4 层透明代理实现高可用;
  • 关闭非安全端口 8080 和匿名访问;
  • 在安全端口 6443 接收 https 请求;
  • 严格的认证和授权策略 (x509、token、rbac);
  • 开启 bootstrap token 认证,支持 kubelet tls bootstrapping;
  • 使用 https 访问 kubelet、etcd,加密通信;

kube-controller-manager:

  • 3 节点高可用;
  • 关闭非安全端口,在安全端口 10252 接收 https 请求;
  • 使用 kubeconfig 访问 apiserver 的安全端口;
  • 自动 approve kubelet 证书签名请求 (csr),证书过期后自动轮转;
  • 各 controller 使用自己的 serviceaccount 访问 apiserver;

kube-scheduler:

  • 3 节点高可用;
  • 使用 kubeconfig 访问 apiserver 的安全端口;

kubelet:

  • 使用 kubeadm 动态创建 bootstrap token,而不是在 apiserver 中静态配置;
  • 使用 tls bootstrap 机制自动生成 client 和 server 证书,过期后自动轮转;
  • 在 kubeletconfiguration 类型的 json 文件配置主要参数;
  • 关闭只读端口,在安全端口 10250 接收 https 请求,对请求进行认证和授权,拒绝匿名访问和非授权访问;
  • 使用 kubeconfig 访问 apiserver 的安全端口;

kube-proxy:

  • 使用 kubeconfig 访问 apiserver 的安全端口;
  • 在 kubeproxyconfiguration 类型的 json 文件配置主要参数;
  • 使用 ipvs 代理模式;

集群插件:

  • dns:使用功能、性能更好的 coredns;
  • dashboard:支持登录认证;
  • metric:metrics-server,使用 https 访问 kubelet 安全端口;
  • log:elasticsearch、fluend、kibana;
  • registry 镜像库:docker-registry、harbor。

四 其他准备

4.1 手动添加解析

注意:以下4.1至4.7步骤可通过如下脚本快速实现:

  1 [root@k8smaster01 ~]# vi k8sinit.sh
  2 # modify author: xhy
  3 # modify date: 2019-06-23 22:19
  4 # version:
  5 #***************************************************************#
  6 # initialize the machine. this needs to be executed on every machine.
  7 
  8 # add host domain name.
  9 cat >> /etc/hosts << eof
 10 172.24.8.71 k8smaster01
 11 172.24.8.72 k8smaster02
 12 172.24.8.73 k8smaster03
 13 172.24.8.74 k8snode01
 14 172.24.8.75 k8snode02
 15 eof
 16 
 17 # add docker user
 18 useradd -m docker
 19 
 20 # disable the selinux.
 21 sed -i 's/^selinux=.*/selinux=disabled/' /etc/selinux/config
 22 
 23 # turn off and disable the firewalld.
 24 systemctl stop firewalld
 25 systemctl disable firewalld
 26 
 27 # modify related kernel parameters & disable the swap.
 28 cat > /etc/sysctl.d/k8s.conf << eof
 29 net.ipv4.ip_forward = 1
 30 net.bridge.bridge-nf-call-ip6tables = 1
 31 net.bridge.bridge-nf-call-iptables = 1
 32 net.ipv4.tcp_tw_recycle = 0
 33 vm.swappiness = 0
 34 vm.overcommit_memory = 1
 35 vm.panic_on_oom = 0
 36 net.ipv6.conf.all.disable_ipv6 = 1
 37 eof
 38 sysctl -p /etc/sysctl.d/k8s.conf >&/dev/null
 39 swapoff -a
 40 sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
 41 modprobe br_netfilter
 42 
 43 # add ipvs modules
 44 cat > /etc/sysconfig/modules/ipvs.modules <<eof
 45 #!/bin/bash
 46 modprobe -- ip_vs
 47 modprobe -- ip_vs_rr
 48 modprobe -- ip_vs_wrr
 49 modprobe -- ip_vs_sh
 50 modprobe -- nf_conntrack_ipv4
 51 eof
 52 chmod 755 /etc/sysconfig/modules/ipvs.modules
 53 bash /etc/sysconfig/modules/ipvs.modules
 54 
 55 # install rpm
 56 yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
 57 
 58 # create k8s directory $$ add system path
 59 mkdir -p  /opt/k8s/{bin,work} /etc/{kubernetes,etcd}/cert
 60 echo 'path=/opt/k8s/bin:$path' >>/root/.bashrc
 61 source /root/.bashrc
 62 
 63 # reboot the machine.
 64 reboot
  1 [root@k8smaster01 ~]# cat <<eof >> /etc/hosts
  2 172.24.8.71 k8smaster01
  3 172.24.8.72 k8smaster02
  4 172.24.8.73 k8smaster03
  5 172.24.8.74 k8snode01
  6 172.24.8.75 k8snode02
  7 eof

提示:所有节点均建议如上操作。

4.2 添加docker账户

  1 [root@k8smaster01 ~]# useradd -m docker

提示:所有节点均建议如上操作。

4.3 关闭selinux

  1 [root@k8smaster01 ~]# setenforce 0
  2 [root@k8smaster01 ~]# sed -i 's/^selinux=.*/selinux=disabled/' /etc/selinux/config

4.4 修正iptables

  1 [root@k8smaster01 ~]# systemctl stop firewalld
  2 [root@k8smaster01 ~]# systemctl disable firewalld			#关闭防火墙
  3 [root@k8smaster01 ~]# cat <<eof >> /etc/sysctl.d/k8s.conf
  4 net.bridge.bridge-nf-call-ip6tables = 1
  5 net.bridge.bridge-nf-call-iptables = 1
  6 net.ipv4.ip_forward = 1
  7 eof
  8 [root@k8smaster01 ~]# modprobe br_netfilter
  9 [root@k8smaster01 ~]# sysctl -p /etc/sysctl.d/k8s.conf

提示:所有节点均建议如上操作。

4.5 关闭swap

  1 [root@k8smaster01 ~]# sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
  2 [root@k8smaster01 ~]# echo "vm.swappiness = 0" >> /etc/sysctl.d/k8s.conf	#禁止使用 swap 空间,只有当系统 oom 时才允许使用它
  3 [root@k8smaster01 ~]# sysctl -p /etc/sysctl.d/k8s.conf

4.6 其他调整

  1 [root@k8smaster01 ~]# cat <<eof >> /etc/sysctl.d/k8s.conf
  2 vm.overcommit_memory = 1						# 不检查物理内存是否够用
  3 vm.panic_on_oom = 0							# 开启 oom
  4 net.ipv6.conf.all.disable_ipv6 = 1					# 关闭 ipv6
  5 eof
  6 [root@k8smaster01 ~]# sysctl -p /etc/sysctl.d/k8s.conf
  7 [root@k8smaster01 ~]# mkdir -p  /opt/k8s/{bin,work} /etc/{kubernetes,etcd}/cert	#创建相应目录
  8 [root@k8smaster01 ~]# yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget

提示:必须关闭 tcp_tw_recycle,否则和 nat 冲突,会导致服务不通;

关闭 ipv6,防止触发 docker bug。

4.7 加载ipvs

pod的负载均衡是用kube-proxy来实现的,实现方式有两种,一种是默认的iptables,一种是ipvs,相对iptables,ipvs有更好的性能。且当前ipvs已经加入到了内核的主干。

为kube-proxy开启ipvs的前提需要加载以下的内核模块:

  • ip_vs
  • ip_vs_rr
  • ip_vs_wrr
  • ip_vs_sh
  • nf_conntrack_ipv4
  1 [root@k8smaster01 ~]# cat > /etc/sysconfig/modules/ipvs.modules <<eof
  2 #!/bin/bash
  3 modprobe -- ip_vs
  4 modprobe -- ip_vs_rr
  5 modprobe -- ip_vs_wrr
  6 modprobe -- ip_vs_sh
  7 modprobe -- nf_conntrack_ipv4
  8 eof
  9 [root@k8smaster01 ~]# chmod 755 /etc/sysconfig/modules/ipvs.modules
 10 [root@k8smaster01 ~]# bash /etc/sysconfig/modules/ipvs.modules
 11 [root@k8smaster01 ~]# lsmod | grep -e ip_vs -e nf_conntrack_ipv4
 12 [root@k8smaster01 ~]# yum -y install ipvsadm

提示:所有节点均建议如上操作。

为了更好的管理和查看ipvs,可安装相应的管理工具《002.lvs管理工具的安装与使用》。

五 环境准备

5.1 配置免秘钥

为了更方便远程分发文件和执行命令,本实验配置master节点到其它节点的 ssh 信任关系。

  1 [root@k8smaster01 ~]# ssh-keygen -f ~/.ssh/id_rsa -n ''
  2 [root@k8smaster01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8smaster01
  3 [root@k8smaster01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8smaster02
  4 [root@k8smaster01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8smaster03
  5 [root@k8smaster01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8snode01
  6 [root@k8smaster01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8snode02

提示:此操作仅需要在master节点操作。

5.2 分发集群配置参数脚本

后续使用的环境变量都定义在文件 environment.sh 中,同时拷贝到所有节点的 /opt/k8s/bin 目录:

  1 #!/usr/bin/bash
  2 
  3 # 生成 encryptionconfig 所需的加密 key
  4 export encryption_key=$(head -c 32 /dev/urandom | base64)
  5 
  6 # 集群 master 机器 ip 数组
  7 export master_ips=(172.24.8.71 172.24.8.72 172.24.8.73)
  8 
  9 # 集群 master ip 对应的主机名数组
 10 export master_names=(k8smaster01 k8smaster02 k8smaster03)
 11 
 12 # 集群 node 机器 ip 数组
 13 export node_ips=(172.24.8.74 172.24.8.75)
 14 
 15 # 集群 node ip 对应的主机名数组
 16 export node_names=(k8snode01 k8snode02)
 17 
 18 # 集群所有机器 ip 数组
 19 export all_ips=(172.24.8.71 172.24.8.72 172.24.8.73 172.24.8.74 172.24.8.75)
 20 
 21 # 集群所有ip 对应的主机名数组
 22 export all_names=(k8smaster01 k8smaster02 k8smaster03 k8snode01 k8snode02)
 23 
 24 # etcd 集群服务地址列表
 25 export etcd_endpoints="https://172.24.8.71:2379,https://172.24.8.72:2379,https://172.24.8.73:2379"
 26 
 27 # etcd 集群间通信的 ip 和端口
 28 export etcd_nodes="k8smaster01=https://172.24.8.71:2380,k8smaster02=https://172.24.8.72:2380,k8smaster03=https://172.24.8.73:2380"
 29 
 30 # kube-apiserver 的反向代理(kube-nginx)地址端口
 31 export kube_apiserver="https://127.0.0.1:8443"
 32 
 33 # 节点间互联网络接口名称
 34 export iface="eth0"
 35 
 36 # etcd 数据目录
 37 export etcd_data_dir="/data/k8s/etcd/data"
 38 
 39 # etcd wal 目录,建议是 ssd 磁盘分区,或者和 etcd_data_dir 不同的磁盘分区
 40 export etcd_wal_dir="/data/k8s/etcd/wal"
 41 
 42 # k8s 各组件数据目录
 43 export k8s_dir="/data/k8s/k8s"
 44 
 45 # docker 数据目录
 46 export docker_dir="/data/k8s/docker"
 47 
 48 ## 以下参数一般不需要修改
 49 
 50 # tls bootstrapping 使用的 token,可以使用命令 head -c 16 /dev/urandom | od -an -t x | tr -d ' ' 生成
 51 bootstrap_token="41f7e4ba8b7be874fcff18bf5cf41a7c"
 52 
 53 # 最好使用 当前未用的网段 来定义服务网段和 pod 网段
 54 
 55 # 服务网段,部署前路由不可达,部署后集群内路由可达(kube-proxy 保证)
 56 service_cidr="10.254.0.0/16"
 57 
 58 # pod 网段,建议 /16 段地址,部署前路由不可达,部署后集群内路由可达(flanneld 保证)
 59 cluster_cidr="172.30.0.0/16"
 60 
 61 # 服务端口范围 (nodeport range)
 62 export node_port_range="30000-32767"
 63 
 64 # flanneld 网络配置前缀
 65 export flannel_etcd_prefix="/kubernetes/network"
 66 
 67 # kubernetes 服务 ip (一般是 service_cidr 中第一个ip)
 68 export cluster_kubernetes_svc_ip="10.254.0.1"
 69 
 70 # 集群 dns 服务 ip (从 service_cidr 中预分配)
 71 export cluster_dns_svc_ip="10.254.0.2"
 72 
 73 # 集群 dns 域名(末尾不带点号)
 74 export cluster_dns_domain="cluster.local"
 75 
 76 # 将二进制目录 /opt/k8s/bin 加到 path 中
 77 export path=/opt/k8s/bin:$path
  1 [root@k8smaster01 ~]# source environment.sh
  2 [root@k8smaster01 ~]# for all_ip in ${all_ips[@]}
  3   do
  4     echo ">>> ${all_ip}"
  5     scp environment.sh root@${all_ip}:/opt/k8s/bin/
  6     ssh root@${all_ip} "chmod +x /opt/k8s/bin/*"
  7   done