目录

3.2.2.1 K8S集群架构搭建及运行docker容器

1、Linux 操作系统原理

    1.1、计算机硬件

    1.2、操作系统

    1.3、Linux操作系统

    1.4、Linux系统的操作原理

2、K8S 集群架构图

3、K8S 集群部署架构

    3.1、Kubernetes的8个集群管理能力

    3.2、在Kubernetes中,service对象的4个特征

4、集群环境配置说明

    4.1、环境准备

    4.2、集群详情、组件版本

    4.3、环境说明

    4.4、主要配置策略

5、集群环境搭建安装(系统初始化和全局变量)

    5.1、设置主机名、添加docker账户

​     5.2、设置master可以无密码登录所有节点的root账户

     5.3、将可执行文件路径/opt/k8s/bin添加到PATH变量中

​     5.4、安装依赖包

     5.5、关闭防火墙

      5.6、关闭swap分区

      5.7、关闭SELinux

      5.8、关闭dnsmasq(可选)

     5.9、加载内核模块(可选)

     5.10、优化内核参数

     5.11、设置系统时区

     5.12、更新系统时间(可选)

     5.13、关闭无关的服务

     5.14、设置rsyslog和systemd journal

     5.15、创建相关目录

      5.16、升级内核、关闭 NUMA

      5.17、检查系统内核和模块是否适合运行docker(仅适用于linux系统)

      5.18、分发集群环境变量定义脚本(扩容时不需要执行该步骤)

6、HTTPS网络安全架构设计

    6.1、对称加密

    6.2、非对称加密

    6.3、数组证书

    6.4、数组证书的4种格式

    6.5、4种数组证书格式相互转换

    6.6、SSL证书

    6.7、Nginx集群环境SSL证书部署

7、集群环境搭建安装(创建 CA 证书和秘钥)

    7.1、安装cfssl工具

    7.2、创建根证书(CA)

    7.3、分发证书文件

8、集群环境搭建安装(部署kubectl命令行工具) 

    8.1、下载和分发kubectl命令行工具

     8.2、创建admin证书、私钥

     8.3、创建kubeconfig文件

      8.4、分发kubeconfig文件

3.2.2.2 K8S基于二进制集群架构搭建1

1、部署etcd集群

    1.1、下载和分发etcd二进制文件

    1.2、创建etcd证书和私钥

    1.3、创建etcd的systemd unit模板文件

    1.4、为各节点创建和分发etcd systemd unit文件

    1.5、启动etcd服务 

    1.6、验证服务状态

    1.7、查看当前的leader

​2、部署flannel网络

    2.1、下载和分发flannel二进制文件

    2.2、创建flannel证书和私钥

     2.3、向etcd写入集群Pod网段信息

     2.4、创建flannel的systemd unit文件

     2.5、分发flanneld systemd unit文件到所有节点

      2.6、启动flanneld服务

      2.7、检查分配给各flanneld的Pod网段信息

      2.8、验证各节点能通过Pod网段互通

3.2.2.3 K8S基于二进制集群架构搭建2

3.2.2.4 K8S基于二进制集群架构搭建3


3.2.2.1 K8S集群架构搭建及运行docker容器

1、Linux 操作系统原理

参考地址:https://product.pconline.com.cn/itbk/software/dnyw/1707/9626394.html
    一个计算机系统是硬件、软件的共生体,它们互相依赖、不可分割

    1.1、计算机硬件

        是由外围设备、处理器、内存、硬盘和其他电子设备组成的计算机发动机

    1.2、操作系统

        是控制硬件工作的,是用来和硬件打交道,为用户程序提供一个有限服务集的低级支撑软件。

    1.3、Linux操作系统

        在Linux中操作系统被称为“内核”,也称为“核心”。
        Linux内核的主要模块(组件)分为以下7部分:
            存储管理
            CPU和进程管理
            文件系统
            设备管理和驱动
            网络通信
            系统的初始化(引导)
            系统调用

        Linux内核被设计为“单内核”(monolithic)结构

    1.4、Linux系统的操作原理

        1、一切都是文件
        2、每个软件都有确定的用途

2、K8S 集群架构图

1、etcd一个高可用的K/V键值对存储和服务发现系统
2、flannel实现跨主机的容器网络的通信
3、kube-apiserver提供kubernetes集群的API调用
4、kube-controller-manager确保集群服务
5、kube-scheduler调度容器,分配到Node
6、kubelet在Node节点上按照配置文件中定义的容器规格 启动容器
7、kube-proxy提供网络代理服务 

3、K8S 集群部署架构

1个master + 2个node。存储集群etcd是单点集群(真实环境不推荐此做法,需要集群)。网络使用的是flannel虚拟二次网络。

    3.1、Kubernetes的8个集群管理能力

        1、多层次的安全防护和准入机制
        2、多租户应用支撑能力
        3、透明的服务注册和服务发现机制
        4、内建智能负载均衡器
        5、强大的故障发现和自我修复能力
        6、服务滚动升级和在线扩容能力
        7、可扩展的资源自动调度机制
        8、以及多粒度的资源管理能力

    3.2、在Kubernetes中,service对象的4个特征

        1、拥有一个唯一指定的名字
            eg:mysql-service
        2、拥有一个虚拟IP和端口号
            虚拟IP:Cluster IP、service IP、VIP
        3、能够提供某种远程服务能力
        4、被映射到提供这种服务能力的一组容器应用上

快速、在线体验kubernetes的功能:https://kubernetes.io/docs/tutorials/kubernetes-basics/
K8s官方下载地址:https://github.com/kubernetes

本文以下所有操作命令都参考老师的文档:E:\meWork\study\project\subject-3\subject-3-k8s\专题三-Kubernetes_学习文档-N.docx

4、集群环境配置说明

    4.1、环境准备

节点

ip 地址

操作系统

master

192.168.0.32

CentOS 7.8-x86_64

node1

192.168.0.33

CentOS 7.8-x86_64

node2

192.168.0.34

CentOS 7.8-x86_64

    4.2、集群详情、组件版本

OS:CentOS Linux release 7.8.2003 (Core)
Kubernetes:1.12.3(最低的版本要求是1.6)
Docker:18.09.0-ce(建议使用 Docker CE)
Etcd:3.3.10
Flannel:v0.10.0 (vxlan或者host-gw 网络)
TLS 认证通信 (所有组件,如 etcd、kubernetes master 和 node)
RBAC 授权
kubelet TLS BootStrapping
插件:Coredns、dashboardheapster(influxdb、grafana)、Metrics-Server、EFK(elasticsearch、fluentd、kibana)
镜像仓库:docker registry、harbor
私有docker镜像仓库harbor(harbor提供离线安装包,直接使用docker-compose启动即可)
    私有docker镜像仓库harbor的参官文档:
        安装文档:https://github.com/goharbor/harbor/blob/master/docs/install-config/installation-prereqs.md
        配置 https访问:https://github.com/goharbor/harbor/blob/master/docs/install-config/configure-https.md

    4.3、环境说明

Master:192.168.0.32

Node:192.168.0.33192.168.0.34

注意:192.168.0.32 这台主机 master 和 node 复用。所有生成证书、执行 kubectl 命令的操作都在这台节点上执行。一旦 node 加入到 kubernetes 集群之后就不需要再登陆node节点了。

    4.4、主要配置策略

        kube-apiserver:
            1、使用节点本地nginx4层透明代理实现高可用
            2、关闭非安全端口8080和匿名访问
            3、在安全端口6443接收https请求
            4、严格的认证和授权策略(x509、token、RBAC)
            5、开启bootstrap token认证,支持kubelet TLS bootstrapping
            6、使用https访问kubelet、etcd,加密通信
        kube-controller-manager:
            1、3节点高可用
            2、关闭非安全端口,在安全端口10252接收https请求
            3、使用kubeconfig访问apiserver的安全端口
            4、自动approve kubelet证书签名请求(CSR),证书过期后自动轮转
            5、各controller使用自己的ServiceAccount访问apiserver
        kube-scheduler:
            1、3节点高可用
            2、使用kubeconfig访问apiserver的安全端口
        kubelet:
            1、使用kubeadm动态创建bootstrap token,而不是在apiserver中静态配置
            2、使用TLS bootstrap机制自动生成client和server证书,过期后自动轮转
            3、在KubeletConfiguration类型的JSON文件配置主要参数
            4、关闭只读端口,在安全端口10250接收https请求,对请求进行认证和授权,拒绝匿名访问和非授权访问
            5、使用kubeconfig访问apiserver的安全端口
        kube-proxy:
            1、使用kubeconfig访问apiserver的安全端口
            2、在KubeProxyConfiguration类型的JSON文件配置主要参数
            3、使用ipvs代理模式
        集群插件:
            DNS:使用功能、性能更好的 coredns
            Dashboard:支持登录认证
            Metric:heapster、metrics-server,使用https访问kubelet安全端口
            Log:Elasticsearch、Fluend、Kibana
            Registry 镜像库:docker-registry、harbor

harbor私有镜像仓库:参考:https://github.com/goharbor/harbor

5、集群环境搭建安装(系统初始化和全局变量)

“5.3”到“5.17”的命令在master、node1、node2,3台机器上都需要执行

    5.1、设置主机名、添加docker账户

设置永久主机名称,然后xshell重新连接,就可以看到名称变成新的名称了

1、将主机名改为masterhostnamectl set-hostname master

2、为支持DNS解析主机名称,修改/etc/hosts文件:
cat >> /etc/hosts <<EOF
192.168.0.32 master master
192.168.0.33 node1 node1
192.168.0.34 node2 node2
EOF

3、添加docker账户:useradd -m docker


     5.2、设置master可以无密码登录所有节点的root账户

1、创建一个rsa的密钥:ssh-keygen -t rsa
2、将公钥文件放到master的root账户下:ssh-copy-id root@master
3、将公钥文件放到node1的root账户下:ssh-copy-id root@node1
4、将公钥文件放到node2的root账户下:ssh-copy-id root@node2

5、远程连接到node1上去:ssh root@node1

     5.3、将可执行文件路径/opt/k8s/bin添加到PATH变量中

后面会将k8s可执行组件的二进制文件,全部放到/opt/k8s/bin目录下,以这个目录作为标准。
为了执行命令时不用写全路径,需要将这个路添加到PATH变量中
1、添加环境变量:echo 'PATH=/opt/k8s/bin:$PATH' >>/root/.bashrc
2、查看是否添加成功:cat /root/.bashrc

     5.4、安装依赖包

在master、node1、node2都需要执行下面3个命令
1、安装依赖包1:yum install -y epel-release
2、安装依赖包2:yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
3、安装完毕后,检查ip_vs是否正常:/usr/sbin/modprobe ip_vs

     5.5、关闭防火墙

从“4.4、主要配置策略”可以知道需要用到很多端口,为了方便(避免每一个端点都在防火墙中配置放行),避免少配置了端口,导致安装失败,所以需要关闭防火墙。

1、关闭防火墙:systemctl stop firewalld
2、取消防火墙的自启动:systemctl disable firewalld
3、清除防火墙的规则策略1:iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
   清除防火墙的规则策略2:iptables -P FORWARD ACCEPT

      5.6、关闭swap分区

如果开启了swap分区,kubelet会启动失败
1、关闭swap分区:swapoff -a
2、注释/etc/fstab中swap的相应行:sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

      5.7、关闭SELinux

SELinux是linux内核的保护,如果开启SELinux,执行某些受保护的命令就会报错:Permission denied
1、关闭SELinux的命令1:setenforce 0
2、关闭SELinux的命令2:sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

      5.8、关闭dnsmasq(可选)

linux系统开启了dnsmasq后(eg:GUI环境),将系统DNS Server设置为 127.0.0.1,这会导致docker容器无法解析域名,需要关闭它:

systemctl stop dnsmasq

systemctl disable dnsmasq

     5.9、加载内核模块(可选)

如果是比较老的版本,就需要执行这个命令,新的版本就不用执行

modprobe ip_vs_rr

modprobe br_netfilter

     5.10、优化内核参数

这一步如果执行有一些报错不用理会,继续往下执行。(因为版本不一样,参数值有可能也不一样)

1、创建kubernetes.conf命令:
cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit_memory=1 # 不检查物理内存是否够用
vm.panic_on_oom=0 # 开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF

2、复制kubernetes.conf到/etc/sysctl.d下:cp kubernetes.conf  /etc/sysctl.d/kubernetes.conf
3、是/etc/sysctl.d/kubernetes.conf文件生效:sysctl -p /etc/sysctl.d/kubernetes.conf

     5.11、设置系统时区

#1、调整系统TimeZone
timedatectl set-timezone Asia/Shanghai
#2、将当前的UTC时间写入硬件时钟
timedatectl set-local-rtc 0
#3、重启依赖于系统时间的服务
systemctl restart rsyslog 
systemctl restart crond

     5.12、更新系统时间(可选)

ntpdate cn.pool.ntp.org

     5.13、关闭无关的服务

systemctl stop postfix && systemctl disable postfix

     5.14、设置rsyslog和systemd journal

systemd的journald 记录日志的3个优势:
    1、可以记录到内存或文件系统(默认记录到内存,对应的位置为/run/log/jounal)
    2、可以限制占用的磁盘空间、保证磁盘剩余空间
    3、可以限制日志文件大小、保存的时间

由于journald默认将日志转发给rsyslog,这会导致:
    1、日志写了多份
    2、/var/log/messages中包含了太多无关日志,不方便后续查看
    3、同时也影响系统性能

因为上面的问题,所以需要修改默认设置

#1、持久化保存日志的目录
mkdir /var/log/journal
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]

#2、持久化保存到磁盘
Storage=persistent

#3、压缩历史日志
Compress=yes

SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000

#4、最大占用空间10G
SystemMaxUse=10G

#5、单日志文件最大200M
SystemMaxFileSize=200M

#6、日志保存时间2周
MaxRetentionSec=2week

#7、不将日志转发到syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald

     5.15、创建相关目录

mkdir -p /opt/k8s/{bin,work} /opt/k8s/work/cert /etc/{kubernetes,etcd}/cert

      5.16、升级内核、关闭 NUMA

系统内核是3.10以下版本需要才需要升级内核、关闭 NUMA
查看系统内核版本:uname -a

      5.17、检查系统内核和模块是否适合运行docker(仅适用于linux系统)

1、下载check-config.sh文件:curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh > check-config.sh

我下载不了,直接用的老师给的check-config.sh文件,上传到虚拟机中,直接执行bash ./check-config.sh命令,也可以

2、bash ./check-config.sh

      5.18、分发集群环境变量定义脚本(扩容时不需要执行该步骤)

3个节点收执行这个命令,便于直接拖拽文件到xshell,上传到虚拟机对应目录。文件拖拽上传、下载的工具

yum install -y lrzsz

后续的部署步骤将使用environment.sh文件中定义的全局环境变量;
老师提供的文件在:http://59.111.92.219/q1906-java/subject-3/blob/master/subject-3-k8s/environment.sh

下面的命令只在master节点执行

根据自己的机器情况修改文件内容,然后将文件复制到所有节点的/opt/k8s/bin目录
export IFACE的就是IP配置文件的DEVICE值(查看网络接口名称):vim /etc/sysconfig/network-scripts/ifcfg-enp0s3

变成可执行文件:chmod +x environment.sh 
让环境变量文件生效:source environment.sh 

 读取环境变量文件,然后分发到其他节点:

for node_ip in ${NODE_IPS[@]}

  do

    echo ">>> ${node_ip}"

    scp /opt/k8s/bin/environment.sh root@${node_ip}:/opt/k8s/bin/

    ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"

  done

6、HTTPS网络安全架构设计

    6.1、对称加密

        “明文”通过“密钥”加密成“密文”;拿到“密文”,需要通过“密钥”解密成“明文”
    常见的对称加密算法有:DES、3DES、AES、Blowfish、IDEA、RC5、RC6

    6.2、非对称加密

        用“公钥”对“明文”加密,用“私钥”对“明文”解密
    常见的非对称加密算法有:RSA、Elagmal、背包算法、Rabin
    应用场景:SSH、HTTPS、TLS、电子证书、电子签名、电子身份证......

    6.3、数组证书

    数字证书就是识别网站(服务器)

    6.4、数组证书的4种格式

    1、Java Keystore(JKS)格式
        这是Java提供的密码库,通过Java Development Kit(JDK)工具包中的Keytool工具,生成Java Keystore(JKS)格式的证书文件。
            使用这个格式的软件有:Tomcat、Weblogic、JBoss
    2、PEM、KEY、CRT格式
        这是OpenSSl工具提供的密码库,生成PEM、KEY、CRT等格式的证书文件    
            使用这个格式的软件有:Apache、Nginx
    3、KDB格式
        这是使用IBM产品自带的iKeyman工具,生成KDB格式的证书文件。
            使用这个格式的软件是IBM的Web服务产品,eg:Websphere、IBM Http Server(IHS)
    4、PFX格式
        这是使用Windows自带的证书库生成PFX格式的证书
            使用这个格式的服务有:微软Windows Server中的Internet Information Services(IIS)服务

只有经过CA签发后才能得到真正的证书,详细了解数字证书:https://www.jianshu.com/p/42bf7c4d6ab8

    6.5、4种数组证书格式相互转换

 

    6.6、SSL证书

 SSL证书是数字证书的一种方式

SSLSecure Socket Layer安全套接字协议,提供两个安全服务:鉴别、保密

HTTPS就是HTTP的安全版,HTTP下加入SSL层


HTTPS协议主要作用:
    1、建立一个信息安全通道,来保证数据传输的安全
    2、确认网站的真实性

SSL/TLS:安全套接字协议(SSL)是Web浏览器与Web服务器之间安全交换信息的协议。

用于网站HTTPS化的SSL数字证书有3种类型:DV SSL(个人)、OV SSL(组织、企业)、EV SSL(大型企业、金融机构)

 

SSL证书的优势:
    1、简单快捷
        只需要申请一张证书,部署在服务器上,就可以在有效期内不用做其他操作
    2、显示直观
        部署SSL证书后,通过https访问网站,能在地址栏或地址栏右侧直接看到加密锁标志。
    3、身份认证
        能在证书信息里看到网站所有者公司信息,进而确认网站的有效性和真实性。 

    6.7、Nginx集群环境SSL证书部署

证书部署在Nginx上,在nginx.conf配置文件中加入如下配置:

7、集群环境搭建安装(创建 CA 证书和秘钥)

为确保安全,kubernetes系统各组件需要使用x509证书对通信进行加密和认证。
CA(Certificate Authority)是自签名的根证书,用来签名后续创建的其它证书。
本文档使用CloudFlare的PKI工具集cfssl创建所有证书
cfssl的github地址:https://github.com/cloudflare/cfssl

    7.1、安装cfssl工具

进入work目录:cd /opt/k8s/work
变成可执行文件:chmod +x /opt/k8s/bin/*

    7.2、创建根证书(CA)

        CA证书是集群所有节点共享的,只需要创建一个CA证书,后续创建的所有证书都由它签名。

第一步、创建配置文件CA配置文件:用于配置根证书的使用场景(profiles)和具体参数,后续在签名其它证书时需要指定特定场景。
    具体参数有:usage,过期时间、服务端认证、客户端认证、加密等
    signing:表示该证书可用于签名其它证书,生成的ca.pem证书中CA=TRUE;
    server auth:表示client可以用该该证书对server提供的证书进行验证;
    client auth:表示server可以用该该证书对client提供的证书进行验证;
cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF

第二步、创建证书签名请求文件 

CN:Common Name,kube-apiserver从证书中提取该字段作为请求的用户名(User Name),浏览器使用该字段验证网站是否合法;
O:Organization,kube-apiserver从证书中提取该字段作为请求用户所属的组(Group);
kube-apiserver将提取的User、Group作为RBAC授权的用户标识;

第三步、生成CA证书、私钥 

    7.3、分发证书文件

将生成的CA证书、秘钥文件、配置文件拷贝到所有节点的/etc/kubernetes/cert目录下:

source /opt/k8s/bin/environment.sh # 导入 NODE_IPS 环境变量

for node_ip in ${NODE_IPS[@]}

  do

    echo ">>> ${node_ip}"

    ssh root@${node_ip} "mkdir -p /etc/kubernetes/cert"

    scp ca*.pem ca-config.json root@${node_ip}:/etc/kubernetes/cert

  done

8、集群环境搭建安装(部署kubectl命令行工具) 

    8.1、下载和分发kubectl命令行工具

将如下文件拖拽上传到work目录

     8.2、创建admin证书、私钥

kubectl是kubernetes集群的命令行管理工具。
kubectl与apiserver https安全端口通信,apiserver对提供的证书进行认证和授权。
kubectl作为集群的管理工具,需要被授予最高权限。这里创建具有最高权限的admin证书。
第一步、创建证书签名请求
cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "study163"
    }
  ]
}
EOF

system:masters:kube-apiserver收到该证书后,将请求的Group设置为system:masters;
预定义的ClusterRoleBinding cluster-admin将Group system:masters与Role cluster-admin绑定,该Role授予所有API的权限;
该证书只会被kubectl当做client证书使用,所以hosts字段为空; 

 
第二步、生成证书和私钥

 cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \

  -ca-key=/opt/k8s/work/cert/ca-key.pem \

  -config=/opt/k8s/work/cert/ca-config.json \

  -profile=kubernetes admin-csr.json | cfssljson -bare admin

     8.3、创建kubeconfig文件

kubeconfig为kubectl的配置文件,包含访问apiserver的所有信息,eg:apiserver地址、CA证书、自身使用的证书

命令如下:

source /opt/k8s/bin/environment.sh

# 设置集群参数
kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/k8s/work/cert/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kubectl.kubeconfig

# 设置客户端认证参数
kubectl config set-credentials admin \
  --client-certificate=/opt/k8s/work/cert/admin.pem \
  --client-key=/opt/k8s/work/cert/admin-key.pem \
  --embed-certs=true \
  --kubeconfig=kubectl.kubeconfig

# 设置上下文参数
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=admin \
  --kubeconfig=kubectl.kubeconfig

# 设置默认上下文
kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig

certificate-authority:验证kube-apiserver证书的根证书;
client-certificate、--client-key:刚生成的admin证书、私钥,连接kube-apiserver时使用;
embed-certs=true:将ca.pem和admin.pem证书内容嵌入到生成的kubectl.kubeconfig文件中(不加时,写入的是证书文件路径);

      8.4、分发kubeconfig文件

分发到所有使用kubectl命令的节点:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p ~/.kube"
    scp kubectl.kubeconfig root@${node_ip}:~/.kube/config
  done

3.2.2.2 K8S基于二进制集群架构搭建1

1、部署etcd集群

    etcd是基于Raft的分布式key-value存储系统,常用于:服务发现、共享配置、并发控制(leader选举、分布式锁)。
etcd集群各节点的名称和IP如下:
        master:192.168.0.32
        node1:192.168.0.33
        node2:192.168.0.34

    1.1、下载和分发etcd二进制文件

前面已经将etcd的包上传到work目录,不需要再下载了 

分发二进制文件到集群所有节点:

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp etcd-v3.3.10-linux-amd64/etcd* root@${node_ip}:/opt/k8s/bin
    ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
  done

    1.2、创建etcd证书和私钥

第一步、创建证书签名请求

cd /opt/k8s/work/cert

cat > etcd-csr.json <<EOF
{
  "CN": "etcd",
  "hosts": [
    "127.0.0.1",
    "192.168.0.32",
    "192.168.0.33",
    "192.168.0.34"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "study163"
    }
  ]
}
EOF

hosts:指定授权使用该证书的etcd节点IP或域名列表,这里将etcd集群的三个节点IP都列在其中

第二步、生成证书、私钥

cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
    -ca-key=/opt/k8s/work/cert/ca-key.pem \
    -config=/opt/k8s/work/cert/ca-config.json \
    -profile=kubernetes etcd-csr.json | cfssljson -bare etcd

第三步、分发生成的证书和私钥到各etcd节点

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p /etc/etcd/cert"
    scp etcd*.pem root@${node_ip}:/etc/etcd/cert/
  done

    1.3、创建etcd的systemd unit模板文件

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > etcd.service.template <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos

[Service]
Type=notify
WorkingDirectory=${ETCD_DATA_DIR}
ExecStart=/opt/k8s/bin/etcd \\
  --data-dir=${ETCD_DATA_DIR} \\
  --wal-dir=${ETCD_WAL_DIR} \\
  --name=##NODE_NAME## \\
  --cert-file=/etc/etcd/cert/etcd.pem \\
  --key-file=/etc/etcd/cert/etcd-key.pem \\
  --trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
  --peer-cert-file=/etc/etcd/cert/etcd.pem \\
  --peer-key-file=/etc/etcd/cert/etcd-key.pem \\
  --peer-trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
  --peer-client-cert-auth \\
  --client-cert-auth \\
  --listen-peer-urls=https://##NODE_IP##:2380 \\
  --initial-advertise-peer-urls=https://##NODE_IP##:2380 \\
  --listen-client-urls=https://##NODE_IP##:2379,http://127.0.0.1:2379 \\
  --advertise-client-urls=https://##NODE_IP##:2379 \\
  --initial-cluster-token=etcd-cluster-0 \\
  --initial-cluster=${ETCD_NODES} \\
  --initial-cluster-state=new \\
  --auto-compaction-mode=periodic \\
  --auto-compaction-retention=1 \\
  --max-request-bytes=33554432 \\
  --quota-backend-bytes=6442450944 \\
  --heartbeat-interval=250 \\
  --election-timeout=2000
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

WorkingDirectory、--data-dir:指定工作目录和数据目录为${ETCD_DATA_DIR},需在启动服务前创建这个目录;
--wal-dir:指定wal目录,为了提高性能,一般使用SSD或者和--data-dir不同的磁盘;
--name:指定节点名称,当--initial-cluster-state值为new时,--name的参数值必须位于--initial-cluster列表中;
--cert-file、--key-file:etcd server与client通信时使用的证书和私钥;
--trusted-ca-file:签名client证书的CA证书,用于验证client证书;
--peer-cert-file、--peer-key-file:etcd与peer通信使用的证书和私钥;
--peer-trusted-ca-file:签名peer证书的CA证书,用于验证peer证书;

    1.4、为各节点创建和分发etcd systemd unit文件

第一步、替换模板文件中的变量,为各节点创建systemd unit文件

NODE_NAMES和NODE_IPS为相同长度的bash数组,分别为节点名称和对应的IP

source /opt/k8s/bin/environment.sh
for (( i=0; i < 3; i++ ))
  do
    sed -e "s/##NODE_NAME##/${NODE_NAMES[i]}/" -e "s/##NODE_IP##/${NODE_IPS[i]}/" etcd.service.template > etcd-${NODE_IPS[i]}.service 
  done

第二步、分发生成的systemd unit文件

文件重命名为 etcd.service

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp etcd-${node_ip}.service root@${node_ip}:/usr/lib/systemd/system/etcd.service
  done

    1.5、启动etcd服务 

    1、必须创建etcd数据目录和工作目录;
    2、etcd进程首次启动时会等待其它节点的etcd加入集群,命令systemctl start etcd会卡住一段时间,为正常现象

第一步、启动etcd服务

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p ${ETCD_DATA_DIR} ${ETCD_WAL_DIR}"
    ssh root@${node_ip} "systemctl daemon-reload && systemctl enable etcd && systemctl restart etcd " &
  done

第二步、检查启动结果

新开一个xshell窗口,运行如下命令,如果都是active (running),就说明已经启动正常了,直接在启动的窗口回车即可。

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "systemctl status etcd|grep Active"
  done

如果状态不是为active(running),就查看日志,确认原因:journalctl -u etcd

    1.6、验证服务状态

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ETCDCTL_API=3 /opt/k8s/bin/etcdctl \
    --endpoints=https://${node_ip}:2379 \
    --cacert=/opt/k8s/work/cert/ca.pem \
    --cert=/etc/etcd/cert/etcd.pem \
    --key=/etc/etcd/cert/etcd-key.pem endpoint health
  done

    1.7、查看当前的leader

source /opt/k8s/bin/environment.sh
ETCDCTL_API=3 /opt/k8s/bin/etcdctl \
  -w table --cacert=/opt/k8s/work/cert/ca.pem \
  --cert=/etc/etcd/cert/etcd.pem \
  --key=/etc/etcd/cert/etcd-key.pem \
  --endpoints=${ETCD_ENDPOINTS} endpoint status

2、部署flannel网络

    flannel是二次虚拟技术网络,在物理网络、docker网络进行了一次虚拟化,节点中的docker容器的Pod之间进行相互通信。

    2.1、下载和分发flannel二进制文件

前面已经将flannel的包上传到work目录,不需要再下载了 

1、创建flannel文件夹:mkdir flannel
2、解压flannel并放入flannel文件夹中:tar -xzvf flannel-v0.10.0-linux-amd64.tar.gz -C flannel

3、分发flannel二进制文件到集群所有节点

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp flannel/{flanneld,mk-docker-opts.sh} root@${node_ip}:/opt/k8s/bin/
    ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
  done

    2.2、创建flannel证书和私钥

flannel从etcd集群存取网段分配信息,而etcd集群启用了双向x509证书认证,所以需要为flanneld生成证书和私钥。

第一步、创建证书签名请求 

该证书只会被kubectl当做client证书使用,所以hosts字段为空(不需要做主机验证)

cd /opt/k8s/work/cert
cat > flanneld-csr.json <<EOF
{
  "CN": "flanneld",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "study163"
    }
  ]
}
EOF

第二步、生成证书和私钥 

cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
  -ca-key=/opt/k8s/work/cert/ca-key.pem \
  -config=/opt/k8s/work/cert/ca-config.json \
  -profile=kubernetes flanneld-csr.json | cfssljson -bare flanneld
ls flannel*pem

 第三步、将生成的证书和私钥分发到所有节点

cd /opt/k8s/work/cert
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p /etc/flanneld/cert"
    scp flanneld*.pem root@${node_ip}:/etc/flanneld/cert
  done

     2.3、向etcd写入集群Pod网段信息

注意:本步骤只需执行一次

1、flannel当前版本(v0.10.0)不支持etcd v3,故使用etcd v2 API写入配置key和网段数据;

2、写入的Pod网段${CLUSTER_CIDR}地址段如/16必须小于SubnetLen,必须与kube-controller-manager的--cluster-cidr参数值一致;

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/opt/k8s/work/cert/ca.pem \
  --cert-file=/opt/k8s/work/cert/flanneld.pem \
  --key-file=/opt/k8s/work/cert/flanneld-key.pem \
  set ${FLANNEL_ETCD_PREFIX}/config '{"Network":"'${CLUSTER_CIDR}'", "SubnetLen": 21, "Backend": {"Type": "vxlan"}}'

     2.4、创建flannel的systemd unit文件

mk-docker-opts.sh:脚本将分配给flanneld的Pod子网网段信息写入/run/flannel/docker文件,
                                   后续docker启动时使用这个文件中的环境变量配置docker0网桥;
flanneld:使用系统缺省路由所在的接口与其它节点通信,对于有多个网络接口(如内网和公网)的节点,
                 可以用-iface参数指定通信接口;
flanneld:运行时需要root权限;
-ip-masq: flanneld为访问Pod网络外的流量设置SNAT规则,同时将传递给Docker的变量--ip-masq(/run/flannel/docker 文件中)
                 设置为false,这样Docker将不再创建SNAT规则;Docker的--ip-masq为true时,
                        创建的SNAT规则比较“暴力”:将所有本节点Pod发起的、访问非docker0接口的请求做SNAT,
                                                                      这样访问其他节点Pod的请求来源IP会被设置为flannel.1接口的IP,
                                                                      导致目的Pod看不到真实的来源Pod IP。flanneld创建的SNAT规则比较温和,
                                                                     只对访问非Pod网段的请求做SNAT。

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > flanneld.service << EOF
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service

[Service]
Type=notify
ExecStart=/opt/k8s/bin/flanneld \\
  -etcd-cafile=/etc/kubernetes/cert/ca.pem \\
  -etcd-certfile=/etc/flanneld/cert/flanneld.pem \\
  -etcd-keyfile=/etc/flanneld/cert/flanneld-key.pem \\
  -etcd-endpoints=${ETCD_ENDPOINTS} \\
  -etcd-prefix=${FLANNEL_ETCD_PREFIX} \\
  -iface=${IFACE} \\
  -ip-masq
ExecStartPost=/opt/k8s/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=always
RestartSec=5
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF

     2.5、分发flanneld systemd unit文件到所有节点

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp flanneld.service root@${node_ip}:/usr/lib/systemd/system/
  done

      2.6、启动flanneld服务

1、启动flanneld服务

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "systemctl daemon-reload && systemctl enable flanneld && systemctl restart flanneld"
  done

2、检查启动结果

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "systemctl status flanneld|grep Active"
  done

如果状态不是为active(running),就查看日志,确认原因:journalctl -u etcd

      2.7、检查分配给各flanneld的Pod网段信息

1、查看集群Pod网段(/16):

source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/cert/ca.pem \
  --cert-file=/etc/flanneld/cert/flanneld.pem \
  --key-file=/etc/flanneld/cert/flanneld-key.pem \
  get ${FLANNEL_ETCD_PREFIX}/config

2、查看已分配的Pod子网段列表(/24):

source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/cert/ca.pem \
  --cert-file=/etc/flanneld/cert/flanneld.pem \
  --key-file=/etc/flanneld/cert/flanneld-key.pem \
  ls ${FLANNEL_ETCD_PREFIX}/subnets

3、查看某一Pod网段对应的节点IP和flannel接口地址:

source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/cert/ca.pem \
  --cert-file=/etc/flanneld/cert/flanneld.pem \
  --key-file=/etc/flanneld/cert/flanneld-key.pem \
  get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.16.0-21

从输出结果中可以看出:

1、172.30.16.0/21被分配给节点master(192.168.0.32);
2、VtepMAC为master节点的flannel.1网卡MAC地址

      2.8、验证各节点能通过Pod网段互通

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh ${node_ip} "/usr/sbin/ip addr show flannel.1|grep -w inet"
  done

 在各节点上ping所有flannel接口IP,确保能通:

下面的ip是“查看已分配的Pod子网段列表”中的ip
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh ${node_ip} "ping -c 1 172.30.16.0"
    ssh ${node_ip} "ping -c 1 172.30.72.0"
    ssh ${node_ip} "ping -c 1 172.30.232.0"
  done
 

3.2.2.3 K8S基于二进制集群架构搭建2

待续

3.2.2.4 K8S基于二进制集群架构搭建3

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐