博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
kubernetes二进制部署单master节点
阅读量:801 次
发布时间:2019-03-25

本文共 43029 字,大约阅读时间需要 143 分钟。

目录


1、安装要求

在开始之前,部署Kubernetes集群机器需要满足以下几个条件:

  • 三台机器,操作系统 CentOS7.7(mini)

  • 硬件配置:2GBRAM,2vCPU+,硬盘30GB+

  • 集群中所有机器之间网络互通,且可访问外网

  • 采用NAT网络模型(依自己情况而定)

2、安装规划

(1)服务器规划

角色 IP
master 192.168.50.128
node0 192.168.50.128
node1 192.168.50.131
node2 192.168.50.132

(2)软件环境

软件 版本
Docker 19.03.12
kubernetes 1.18.6
etcd 3.4.9

(3)软件规划

主机 安装组件
master kube-apiserver,kube-controller-manager,kube-scheduler,etcd
node1 kubelet,kube-proxy,etcd
node2 kubelet,kube-proxy,etcd

3、初始化系统

3.1、分步骤操作

(1)配置主机名

master节点设置:

~]# hostnamectl set-hostname master

node1从节点设置:

~]# hostnamectl set-hostname node1

node2从节点设置:

~]# hostnamectl set-hostname node2

根据自己的节点命名情况来设置即可。

(2)添加hosts

所有的节点都要添加hosts解析记录

~]# cat >>/etc/hosts <

(3)配置免密

在master1节点生成密钥对,并分发给其他的所有主机。

[root@master ~]# ssh-keygen -t rsa -b 1200Generating public/private rsa key pair.Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa.Your public key has been saved in /root/.ssh/id_rsa.pub.The key fingerprint is:SHA256:OoMw1dARsWhbJKAQL2hUxwnM4tLQJeLynAQHzqNQs5s root@localhost.localdomainThe key's randomart image is:+---[RSA 1200]----+|*=X=*o*+         ||OO.*.O..         ||BO= + +          ||**o* o           ||o E .   S        ||   o . .         ||    . +          ||       o         ||                 |+----[SHA256]-----+
  • 分发公钥

[root@master ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub  root@master[root@master ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub  root@node1[root@master ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub  root@node2

(4)升级内核(建议)

通过下载kernel image的rpm包进行安装。

centos7:http://elrepo.org/linux/kernel/el7/x86_64/RPMS/

编写shell脚本升级内核

#!/bin/bash# ----------------------------# upgrade kernel by bomingit@126.com# ----------------------------yum localinstall -y kernel-lt*if [ $? -eq 0 ];then grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"fiecho "please reboot your system quick!!!"

注意:一定要重启机器

  • 验证内核版本

[root@master1 ~]# uname -r4.4.229-1.el7.elrepo.x86_64

(5)关闭防火墙、selinux

~]# systemctl disable --now firewalld~]# setenforce 0~]# sed -i 's/enforcing/disabled/' /etc/selinux/config 

(6)关闭swap分区

~]# swapoff -a~]# sed -i.bak 's/^.*centos-swap/#&/g' /etc/fstab

第一条是临时关闭,当然也可以使用第二条永久关闭,后者手动在/etc/fstab文件中将swap挂载所在的行注释掉即可。

(7)优化内核

~]# cat > /etc/sysctl.d/k8s.conf << EOFnet.bridge.bridge-nf-call-iptables = 1net.bridge.bridge-nf-call-ip6tables = 1net.ipv4.ip_forward=1vm.swappiness=0EOF

使其立即生效

~]# sysctl --system

(8)时区和时间同步

~]# ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime~]# yum install dnf -y~]# dnf makecache~]# dnf install ntpdate -y~]# ntpdate ntp.aliyun.com

(9)配置yum源

所有的节点均采用阿里云官网的base和epel源

~]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo~]# curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

3.2、一键执行脚本

(1)编写shell

将上面的第5-8步骤写成shell脚本自动化快速完成

#!/bin/sh#****************************************************************## ScriptName: init.sh# Author: boming# Create Date: 2020-06-23 22:19#***************************************************************##关闭防火墙systemctl disable --now firewalldsetenforce 0sed -i 's/enforcing/disabled/' /etc/selinux/config#关闭swap分区swapoff -ased -i.bak 's/^.*centos-swap/#&/g' /etc/fstab#优化系统cat > /etc/sysctl.d/k8s.conf << EOFnet.bridge.bridge-nf-call-iptables = 1net.bridge.bridge-nf-call-ip6tables = 1EOF#立即生效sysctl --system#时区ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime#配置阿里云的base和epel源curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repocurl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo#安装dnf工具yum install dnf -ydnf makecache#安装ntpdate工具dnf install ntpdate -y#同步阿里云时间ntpdate ntp.aliyun.com

在其他的节点执行此脚本跑一下即可。

4、部署Etcd集群

Etcd 是一个分布式键值存储系统,Kubernetes使用Etcd进行状态和数据存储,因此我们需要提前准备好Etcd,不过为解决Etcd单点故障问题,应采用集群方式部署,这里使用3台组建集群。

为了节约资源利用,我这里复用了两个node节点,这样子这三台主机便可组建一个集群。当然,建议是独立于k8s集群之外部署,毕竟数据很重要。

Etcd节点名称 IP
etcd-01 192.168.50.128
etcd-02 192.168.50.131
etcd-03 192.168.50.132

4.1、安装cfssl证书生成工具

在kubernetes中,使用openssl生成证书会及其麻烦,如果我们可以把预先的证书机构、使用期等时间写在json文件里面会更加高效和自动化。而cfssl就是这样的一款工具,cfssl采用go语言编写,是一个开源的证书管理工具,cfssljson用来从cfssl程序获取json输出,并将证书,密钥,csr和bundle写入文件中。

在master节点操作:

[root@master ~]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64[root@master ~]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64[root@master ~]# lscfssljson_linux-amd64  cfssl_linux-amd64

授权并重命名:

[root@master ~]# chmod +x cfssljson_linux-amd64[root@master ~]# chmod +x cfssl_linux-amd64[root@master ~]# mv cfssljson_linux-amd64 cfssljson[root@master ~]# mv cfssl_linux-amd64 cfssl[root@master ~]# lltotal 12364-rwxr-xr-x 1 root root 10376657 Mar 29  2016 cfssl-rwxr-xr-x 1 root root  2277873 Mar 29  2016 cfssljson

移动到环境变量/usr/local/bin目录下

[root@master ~]# mv cfssljson cfssl /usr/local/bin

4.2、创建认证中心(根CA中心)

由于kubernetes各组件需要使用x509证书对通信进行加密和认证,所以需要创建一套CA(Certificate Autority),是自签名的根证书,用来签名后续需要创建的其它证书;

这里创建的CA是一个私有的内部认证中心,这个认证中心也需要一个CA证书和相应的CA私钥,CA私钥需要妥善保管,任何拥有它的人,都可以充当CA颁发证书。

(1)创建请求证书的json配置文件

再次强调一下,CA证书的请求json文件是集群所有节点共享的,只需要创建一个,它后续创建的所有其它子CA证书的基础,子CA证书都会根据这里config中的profile段来生成证书的相关信息;

[root@master ~]# mkdir -pv ~/TLS/etcd && cd ~/TLS/etcd[root@master etcd]# cat > ca-config.json << EOF{  "signing": {    "default": {      "expiry": "87600h"    },    "profiles": {      "www": {         "expiry": "87600h",         "usages": [            "signing",            "key encipherment",            "server auth",            "client auth"        ]      }    }  }}EOF

ca-config.json 这个配置文件只是告诉我们颁发有什么功能的证书,它用于配置证书的使用场景(profile)和具体参数(usage、过期时间、服务端认证、客户端认证、加密等)。

default是默认策略,指定证书默认有效期是10年;

profiles是定义使用场景,这里只是kubernetes,其实可以定义多个场景,分别指定不同的过期时间,使用场景等参数,后续签名证书时使用某个profile;

signing: 表示该证书可用于签名其它证书,生成的ca.pem证书中的CA=TRUE;

server auth: 表示client 可以用该CA 对server 提供的证书进行校验;

client auth: 表示server 可以用该CA 对client 提供的证书进行验证。

(2)创建根CA证书签名请求文件

[root@master etcd]# cat > ca-csr.json << EOF{    "CN": "etcd CA",    "key": {        "algo": "rsa",        "size": 2048    },    "names": [        {            "C": "CN",            "L": "Beijing",            "ST": "Beijing"        }    ]}EOF

(3)生成证书

[root@master etcd]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -[root@master etcd]# ls -l ca*pem-rw------- 1 root root 1679 Jul 14 10:08 ca-key.pem-rw-r--r-- 1 root root 1359 Jul 14 10:08 ca.pem

gencert:生成新的key(密钥)和签名证书

--initca:初始化一个新ca

4.3、使用自签CA签发Etcd证书

(1)创建Etcd证书签名请求文件

[root@master etcd]# cat > server-csr.json << EOF{    "CN": "etcd",    "hosts": [    "192.168.50.128",    "192.168.50.131",    "192.168.50.132"    ],    "key": {        "algo": "rsa",        "size": 2048    },    "names": [        {            "C": "CN",            "L": "BeiJing",            "ST": "BeiJing"        }    ]}EOF

hosts字段中IP为所有etcd节点的集群内部通信IP,有几个etcd节点,就写多少个IP。当然,为方便后期扩容可以多些几个预留的IP。

(2)生成证书

[root@master etcd]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server[root@master etcd]# ls -l server*.pem-rw------- 1 root root 1679 Jul 14 10:18 server-key.pem-rw-r--r-- 1 root root 1383 Jul 14 10:18 server.pem

gencert: 生成新的key(密钥)和签名证书-initca:初始化一个新ca-ca:指明ca的证书-ca-key:指明ca的私钥文件 -config:指明请求证书的json文件-profile:与config中的profile对应,是指根据config中的profile段来生成证书的相关信息

(3)证书分发至其他etcd服务器

将前面两步创建的证书都分发给其他etcd节点。

写一个shell脚本,先在目标主机创建存放etcd证书的目录,接着复制证书

#!/bin/bashfor node in master node1 node2do ssh root@${node} "mkdir -pv /etc/etcd/ssl" scp ~/TLS/etcd/ca*.pem  root@${node}:/etc/etcd/ssl scp ~/TLS/etcd/server*.pem  root@${node}:/etc/etcd/ssldone

补充:事实上只需要分发ca.pem公钥即可,ca-key.pem是私钥,很多组件不需要,除非你确保使用它,你才分发到服务器上面,以免造成私钥泄露。不过我们不需要考虑太多,所以把私钥也分发到了服务器上面。

4.4、部署Etcd集群

以下在节点1操作,部署完成后,将节点1生成的所有的文件拷贝到节点2和节点3

(1)解压Etcd包并拷贝二进制执行程序

[root@master etcd]# cd [root@master ~]# tar xf etcd-v3.4.9-linux-amd64.tar.gz[root@master ~]# cp -a etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /usr/local/bin

(2)创建Etcd配置文件

[root@master ~]# mkdir -pv /etc/etcd/cfg[root@master ~]# cat >/etc/etcd/cfg/etcd.conf <

这里解释一下配置

配置选项 选项说明
ETCD_NAME 节点名称,如果ETCD_INITIAL_CLUSTER_STATE="new"这个值为new,哪么ETCD_NAME的参数值必须位于ETCD_INITIAL_CLUSTER列表中
ETCD_DATA_DIR 指定节点的数据存储目录(包括:节点ID、集群ID、集群初始化配置、Snapshot文件等),如果未指定,会写在当前目录
ETCD_LISTEN_PEER_URLS 与集群其它成员之间的通信地址
ETCD_LISTEN_CLIENT_URLS 监听本地端口,对外提供服务的地址
ETCD_INITIAL_ADVERTISE_PEER_URLS 通告给集群其它节点,本地的对等URL地址
ETCD_ADVERTISE_CLIENT_URLS 客户端URL,用于通告集群的其余部分信息
ETCD_INITIAL_CLUSTER 集群中的所有信息节点
ETCD_INITIAL_CLUSTER_TOKEN 集群的token,整个集群中保持一致
ETCD_INITIAL_CLUSTER_STATE 初始化集群状态,默认为new

(3)编写启动脚本,由systemd管理etcd

[root@master ~]# cat > /usr/lib/systemd/system/etcd.service << EOF[Unit]Description=Etcd ServerAfter=network.targetAfter=network-online.targetWants=network-online.target[Service]Type=notifyEnvironmentFile=/etc/etcd/cfg/etcd.confExecStart=/usr/local/bin/etcd \--cert-file=/etc/etcd/ssl/server.pem \--key-file=/etc/etcd/ssl/server-key.pem \--peer-cert-file=/etc/etcd/ssl/server.pem \--peer-key-file=/etc/etcd/ssl/server-key.pem \--trusted-ca-file=/etc/etcd/ssl/ca.pem \--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \--logger=zapRestart=on-failureLimitNOFILE=65536[Install]WantedBy=multi-user.targetEOF

说明一下etcd服务启动几个选项的意义:

配置选项 选项说明
--cert-file 客户端与服务器之间TLS证书文件的路径
--key-file 客户端与服务器之间TLS密钥文件的路径
--peer-cert-file 对等服务器TLS证书文件的路径
--peer-key-file` 对等服务器TLS密钥文件的路径
--trusted-ca-file 签名client证书的CA证书,用于验证client证书
--peer-trusted-ca-file 签名对等服务器证书的CA证书。

(4)分发配置文件和启动脚本

节点1的配置文件和systemd启动脚本都设置好了,所以现在传输一下节点2和节点3的服务配置

#! /bin/bashfor ip in node1 node2do ssh root@$ip "mkdir -pv /etc/etcd/cfg" scp -p /etc/etcd/cfg/etcd.conf root@$ip:/etc/etcd/cfg scp -p /usr/local/bin/{etcd,etcdctl} root@$ip:/usr/local/bin scp -p /usr/lib/systemd/system/etcd.service root@$ip:/usr/lib/systemd/systemdone

(5)修改其他etcd节点的配置文件

其他另外节点2和节点3分别修改etcd.conf配置文件中的节点名称和当前服务器IP

  • 节点2的etcd配置文件

#[Member]ETCD_NAME="etcd-02"ETCD_DATA_DIR="/var/lib/etcd/default.etcd"ETCD_LISTEN_PEER_URLS="https://192.168.50.131:2380"ETCD_LISTEN_CLIENT_URLS="https://192.168.50.131:2379,http://127.0.0.1:2379"#[Clustering]ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.50.131:2380"ETCD_ADVERTISE_CLIENT_URLS="https://192.168.50.131:2379"ETCD_INITIAL_CLUSTER="etcd-01=https://192.168.50.128:2380,etcd-02=https://192.168.50.131:2380,etcd-03=https://192.168.50.132:2380"ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"ETCD_INITIAL_CLUSTER_STATE="new"
  • 节点3的etcd配置文件

#[Member]ETCD_NAME="etcd-03"ETCD_DATA_DIR="/var/lib/etcd/default.etcd"ETCD_LISTEN_PEER_URLS="https://192.168.50.132:2380"ETCD_LISTEN_CLIENT_URLS="https://192.168.50.132:2379,http://127.0.0.1:2379"#[Clustering]ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.50.132:2380"ETCD_ADVERTISE_CLIENT_URLS="https://192.168.50.132:2379"ETCD_INITIAL_CLUSTER="etcd-01=https://192.168.50.128:2380,etcd-02=https://192.168.50.131:2380,etcd-03=https://192.168.50.132:2380"ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"ETCD_INITIAL_CLUSTER_STATE="new"

(6)所有节点启动etcd服务

在master节点执行一个脚本来。

#! /bin/bashfor ip in master node1 node2do  ssh root@$ip "systemctl daemon-reload && systemctl enable etcd; systemctl start etcd &"done

(7)检查etcd集群健康状态

  • 查看集群状态

[root@master ~]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/server.pem --key=/etc/etcd/ssl/server-key.pem --endpoints="https://192.168.50.128:2379,https://192.168.50.131:2379,https://192.168.50.132:2379" endpoint healthhttps://192.168.50.131:2379 is healthy: successfully committed proposal: took = 41.490498mshttps://192.168.50.128:2379 is healthy: successfully committed proposal: took = 46.119028mshttps://192.168.50.132:2379 is healthy: successfully committed proposal: took = 47.186334ms

如果打印的每个etcd节点显示都为healthy,说明集群部署成功。如有问题就查messages日志

  • 查看集群成员

[root@master ~]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/server.pem --key=/etc/etcd/ssl/server-key.pem --endpoints="https://192.168.50.128:2379,https://192.168.50.131:2379,https://192.168.50.132:2379" member list570016793c978bd8, started, etcd-03, https://192.168.50.132:2380, https://192.168.50.132:2379, falsea8ebf47328431d63, started, etcd-02, https://192.168.50.131:2380, https://192.168.50.131:2379, falseb7d726258a4a2d44, started, etcd-01, https://192.168.50.128:2380, https://192.168.50.128:2379, false

5、部署Docker

所有node节点都部署docker服务

(1)添加docker软件yum源

方法:浏览器打开mirrors.aliyun.com网站,找到docker-ce,即可看到镜像仓库yum源

~]# curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo~]# cat /etc/yum.repos.d/docker-ce.repo[docker-ce-stable]name=Docker CE Stable - $basearchbaseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/$basearch/stableenabled=1gpgcheck=1gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg......

写个脚本执行方便

for i in master node1 node2; do ssh root@$i "curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo";done

(2)安装docker-ce组件

列出所有可以安装的版本

~]# dnf list docker-ce --showduplicatesdocker-ce.x86_64       3:18.09.6-3.el7               docker-ce-stabledocker-ce.x86_64       3:18.09.7-3.el7               docker-ce-stabledocker-ce.x86_64       3:18.09.8-3.el7               docker-ce-stabledocker-ce.x86_64       3:18.09.9-3.el7               docker-ce-stabledocker-ce.x86_64       3:19.03.0-3.el7               docker-ce-stabledocker-ce.x86_64       3:19.03.1-3.el7               docker-ce-stabledocker-ce.x86_64       3:19.03.2-3.el7               docker-ce-stabledocker-ce.x86_64       3:19.03.3-3.el7               docker-ce-stabledocker-ce.x86_64       3:19.03.4-3.el7               docker-ce-stabledocker-ce.x86_64       3:19.03.5-3.el7               docker-ce-stable.....

这里我们安装18.09版本的docker-ce

~]# dnf install -y  docker-ce-18.09.9 docker-ce-cli-18.09.9

(3)启动docker并设置开机自启动

~]# systemctl enable --now docker

查看版本号,检测docker是否安装成功

~]# docker --versionDocker version 18.09.9, build 039a7df9ba

上面的这种查看docker client的版本的。建议使用下面这种方法查看docker-ce版本号,这种方法把docker的client端和server端的版本号查看的一清二楚。

~]# docker versionClient: Version:           18.09.9 API version:       1.39 Go version:        go1.11.13 Git commit:        039a7df9ba Built:             Wed Sep  4 16:51:21 2019 OS/Arch:           linux/amd64 Experimental:      falseServer: Docker Engine - Community Engine:  Version:          18.09.9  API version:      1.39 (minimum version 1.12)  Go version:       go1.11.13  Git commit:       039a7df  Built:            Wed Sep  4 16:22:32 2019  OS/Arch:          linux/amd64  Experimental:     false

(4)更换docker的镜像仓库地址

默认的镜像仓库地址是docker官方的,国内访问异常缓慢,因此更换为个人阿里云的源。

~]# cat > /etc/docker/daemon.json << EOF{  "registry-mirrors": ["https://f1bhsuge.mirror.aliyuncs.com"]}EOF

由于重新加载docker仓库源,所以需要重启docker

~]# systemctl restart docker

6、部署Master Node

我们操作的流程是

  • 制作集群证书

  • 部署kube-apiserver组件

  • 部署kube-controller-manager组件

  • 部署kube-scheduler组件

6.1、创建认证中心(根CA中心)

现在我们创建一套kubernetes集群的根CA证书。用于签发所有的k8s组件。

(1)创建请求证书的json配置文件

[root@master ~]# mkdir ~/TLS/k8s && cd ~/TLS/k8s[root@master k8s]# cat > ca-config.json << EOF{  "signing": {    "default": {      "expiry": "87600h"    },    "profiles": {      "kubernetes": {         "expiry": "87600h",         "usages": [            "signing",            "key encipherment",            "server auth",            "client auth"        ]      }    }  }}EOF

(2)创建根CA证书签名请求文件

[root@master k8s]# cat > ca-csr.json << EOF{    "CN": "kubernetes",    "key": {        "algo": "rsa",        "size": 2048    },    "names": [        {            "C": "CN",            "L": "Beijing",            "ST": "Beijing",            "O": "k8s",            "OU": "System"        }    ]}EOF

(3)生成证书

[root@master k8s]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -[root@master k8s]# ls *pemca-key.pem  ca.pem

6.2、使用自签CA签发kube-apiserver HTTPS证书

(1)创建kube-apiserver证书签名请求文件

[root@master k8s]# cat > server-csr.json << EOF{    "CN": "kubernetes",    "hosts": [      "10.0.0.1",      "127.0.0.1",      "192.168.50.128",      "192.168.50.131",      "192.168.50.132",      "kubernetes",      "kubernetes.default",      "kubernetes.default.svc",      "kubernetes.default.svc.cluster",      "kubernetes.default.svc.cluster.local"    ],    "key": {        "algo": "rsa",        "size": 2048    },    "names": [        {            "C": "CN",            "L": "BeiJing",            "ST": "BeiJing",            "O": "k8s",            "OU": "System"        }    ]}EOF

(2)生成证书

[root@master k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server[root@master k8s]# ls server*pemserver.pem server-key.pem

将上面临时目录生成的证书都复制在kubernetes的证书目录下:

[root@master k8s]# mkdir -pv /etc/kubernetes/ssl[root@master k8s]# cp -p ./{ca*pem,server*pem} /etc/kubernetes/ssl

6.3、部署kube-apiserver组件

kubernetes现托管在github上面,我们可以看到kubernetes任何版本的更新、下载等信息

点击右侧的Releases按钮,即可看到k8s版本,可以看到目前已经发布了671次版本。

目前最新的文档版本是1.18.5。不过这节课我演示的是1.18.4版本。

只需要下载一个server包就够了,包含了Master和Worker Node二进制文件

详情介绍:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.18.md

下载链接:https://dl.k8s.io/v1.18.4/kubernetes-server-linux-amd64.tar.gz

  • 国内下载

考虑到科学上网问题,因此给大家介绍一个链接:https://storage.googleapis.com/kubernetes-release/release/v1.18.4/kubernetes-server-linux-amd64.tar.gz

(1)创建目录并解压二进制包

kubernetes证书路径是/etc/kubernetes/ssl

配置文件路径是/etc/kubernetes/cfg

二进制可执行程序包直接放在环境变量/usr/local/bin

日志路径是/var/log/kubernetes

[root@master k8s]# cd && mkdir -pv /etc/kubernetes/cfg /var/log/kubernetes[root@master ~]# tar xf kubernetes-server-linux-amd64.tar.gz[root@master ~]# cd kubernetes/server/bin && cp kube-apiserver kube-scheduler kube-controller-manager kubectl /usr/local/bin

(2)部署kube-apiserver

创建kube-apiserver配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-apiserver.conf << EOFKUBE_APISERVER_OPTS="--logtostderr=false \\--v=2 \\--log-dir=/var/log/kubernetes \\--advertise-address=192.168.50.128 \\--default-not-ready-toleration-seconds=360 \\--default-unreachable-toleration-seconds=360 \\--max-mutating-requests-inflight=2000 \\--max-requests-inflight=4000 \\--default-watch-cache-size=200 \\--delete-collection-workers=2 \\--bind-address=192.168.50.128 \\--secure-port=6443 \\--allow-privileged=true \\--service-cluster-ip-range=10.0.0.0/24 \\--service-node-port-range=1024-32767 \\--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\--authorization-mode=RBAC,Node \\--enable-bootstrap-token-auth=true \\--token-auth-file=/etc/kubernetes/ssl/token.csv \\--kubelet-client-certificate=/etc/kubernetes/ssl/server.pem \\--kubelet-client-key=/etc/kubernetes/ssl/server-key.pem \\--tls-cert-file=/etc/kubernetes/ssl/server.pem  \\--tls-private-key-file=/etc/kubernetes/ssl/server-key.pem \\--client-ca-file=/etc/kubernetes/ssl/ca.pem \\--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \\--audit-log-maxage=30 \\--audit-log-maxbackup=3 \\--audit-log-maxsize=100 \\--audit-log-path=/var/log/kubernetes/k8s-audit.log \\--etcd-servers=https://192.168.50.128:2379,https://192.168.50.131:2379,https://192.168.50.132:2379 \\--etcd-cafile=/etc/etcd/ssl/ca.pem \\--etcd-certfile=/etc/etcd/ssl/server.pem \\--etcd-keyfile=/etc/etcd/ssl/server-key.pem"EOF--kubelet-certificate-authority=/etc/kubernetes/ssl/ca.pem \\

为了使用EOF保留换行符,所以要写两个\\

配置文件详细解释如下:

配置选项 选项说明
--logtostderr=false 输出日志到文件中(文件路径由--log-dir指定),不输出到标准错误控制台
--v=2 指定输出日志的级别
--advertise-address 向集群成员通知 apiserver 消息的 IP 地址,这个地址必须能够被集群中其他成员访问,如果 IP 地址为空,将会使用 --bind-address,如果未指定--bind-address,将会使用主机的默认接口地址
--etcd-servers 连接的 etcd 服务器列表 , 形式为(scheme://ip:port),使用逗号分隔
--etcd-cafile 用于etcd 通信的 SSL CA 文件
--etcd-certfile 用于 etcd 通信的的 SSL 证书文件
--etcd-keyfile 用于 etcd 通信的 SSL 密钥文件
--service-cluster-ip-range Service网络地址分配 ,CIDR 表示的 IP 范围,服务的 cluster ip 将从中分配, 一定不要和分配给 nodes 和 pods 的 IP 范围产生重叠
--bind-address 监听 --seure-port 的 IP 地址,被关联的接口必须能够被集群其它节点和 CLI/web 客户端访问,如果为空,则将使用所有接口(0.0.0.0
--secure-port=6443 用于监听具有认证授权功能的 HTTPS 协议的端口,默认值是6443
--allow-privileged 是否启用授权功能
--service-node-port-range Service使用的端口范围
--default-not-ready-toleration-seconds 表示 notReady状态的容忍度秒数
--default-unreachable-toleration-seconds 表示 unreachable状态的容忍度秒数:
--max-mutating-requests-inflight=2000 在给定时间内进行中可变请求的最大数量,当超过该值时,服务将拒绝所有请求,0 值表示没有限制(默认值 200)
--default-watch-cache-size=200 默认监视缓存大小,0 表示对于没有设置默认监视大小的资源,将禁用监视缓存
--delete-collection-workers=2 用于 DeleteCollection 调用的工作者数量,这被用于加速 namespace 的清理( 默认值 1)
--enable-admission-plugins 资源限制的相关配置
--authorization-mode 在安全端口上进行权限验证的插件的顺序列表,以逗号分隔的列表,包括:AlwaysAllow,AlwaysDeny,ABAC,Webhook,RBAC,Node.(默认值 "AlwaysAllow")
--enable-bootstrap-token-auth 启用此选项以允许 'kube-system' 命名空间中的'bootstrap.kubernetes.io/token' 类型密钥可以被用于 TLS 的启动认证
--token-auth-file 声明bootstrap token文件
--kubelet-certificate-authority 证书 authority 的文件路径
--kubelet-client-certificate 用于 TLS 的客户端证书文件路径
--kubelet-client-key 用于 TLS 的客户端证书密钥文件路径
--tls-private-key-file 包含匹配--tls-cert-file的 x509 证书私钥的文件
--service-account-key-file 包含 PEM 加密的 x509 RSA 或 ECDSA 私钥或公钥的文件,用于验证 ServiceAccount 令牌,如果设置该值,--tls-private-key-file 将会被使用,指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用
--audit-log-maxage 基于文件名中的时间戳,旧审计日志文件的最长保留天数
--audit-log-maxbackup 旧审计日志文件的最大保留个数
--audit-log-maxsize 审计日志被轮转前的最大兆字节数
--audit-log-path 如果设置,表示所有到apiserver的请求都会记录到这个文件中,‘-’表示写入标准输出

(3)启用TLS Bootstrapping机制

当集群开启了 TLS 认证后,每个节点的 kubelet 组件都要使用由 apiserver 使用的 CA 签发的有效证书才能与 apiserver 通讯;此时如果节点多起来,为每个节点单独签署证书将是一件非常繁琐的事情;

TLS bootstrapping 功能就是让 node节点上的kubelet组件先使用一个预定的低权限用户连接到 apiserver,然后向 apiserver 申请证书,kubelet 的证书由 apiserver 动态签署;

  • 生成token值

[root@localhost ~]# head -c 16 /dev/urandom | od -An -t x | tr -d ' '14f2afa0b6ccc53350972c4d2942d452
  • 生成token文件:

[root@master ~]# cat > /etc/kubernetes/ssl/token.csv << EOF14f2afa0b6ccc53350972c4d2942d452,kubelet-bootstrap,10001,"system:node-bootstrapper"EOF

把上面的token值拿下来,后面的照着写就行。

(4)创建kube-apiserver启动脚本

[root@master ~]# cat > /usr/lib/systemd/system/kube-apiserver.service << EOF[Unit]Description=Kubernetes API ServerDocumentation=https://github.com/kubernetes/kubernetesAfter=network.target[Service]EnvironmentFile=/etc/kubernetes/cfg/kube-apiserver.confExecStart=/usr/local/bin/kube-apiserver \$KUBE_APISERVER_OPTSRestart=on-failureRestartSec=10Type=notifyLimitNOFILE=65536[Install]WantedBy=multi-user.targetEOF

上面的变量引用符号$前面加上转义符\,这是在使用EOF写入文件需要注意的地方。

(5)启动并设置开机启动

[root@master ~]# systemctl daemon-reload[root@master ~]# systemctl start kube-apiserver[root@master ~]# systemctl enable kube-apiserver

(6)授权kubelet-bootstrap用户允许请求证书

[root@master ~]# kubectl create clusterrolebinding kubelet-bootstrap \--clusterrole=system:node-bootstrapper \--user=kubelet-bootstrapclusterrolebinding.rbac.authorization.k8s.io/kubelet-bootstrap created

6.4、部署kube-controller-manager

kube-controller-manager(k8s控制器管理器)是一个守护进程,它通过kube-apiserver监视集群的共享状态(kube-apiserver收集或监视到的一些集群资源状态,供kube-controller-manager或其它客户端watch), 控制器管理器并尝试将当前的状态向所定义的状态迁移(移动、靠近),它本身是有状态的,会修改集群状态信息,如果多个控制器管理器同时生效,则会有一致性问题,所以kube-controller-manager的高可用,只能是主备模式,而kubernetes集群是采用租赁锁实现leader选举,需要在启动参数中加入                                --leader-elect=true

(1)创建controller-manager配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-controller-manager.conf << EOFKUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\--v=2 \\--log-dir=/var/log/kubernetes \\--leader-elect=flase \\--master=127.0.0.1:8080 \\--bind-address=127.0.0.1 \\--allocate-node-cidrs=true \\--cluster-cidr=10.244.0.0/16 \\--service-cluster-ip-range=10.0.0.0/24 \\--cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \\--cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem  \\--root-ca-file=/etc/kubernetes/ssl/ca.pem \\--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \\--experimental-cluster-signing-duration=87600h0m0s"EOF

配置文件详细解释如下:

配置选项 选项意义
--leader-elect 高可用时启用选举功能。这里只有一个controller-manager,所以不需要启用选举功能
--master 通过本地非安全本地端口8080连接apiserver
--bind-address 监控地址
--allocate-node-cidrs 是否应在node节点上分配和设置Pod的CIDR
--cluster-cidr Controller Manager在启动时如果设置了--cluster-cidr参数,那么为每个没有设置Spec.PodCIDR的Node节点生成一个CIDR地址,并用该CIDR地址设置节点的Spec.PodCIDR属性,防止不同的节点的CIDR地址发生冲突
--service-cluster-ip-range 集群Services 的CIDR范围
--cluster-signing-cert-file 指定用于集群签发的所有集群范围内证书文件(根证书文件)
--cluster-signing-key-file 指定集群签发证书的key
--root-ca-file 如果设置,该根证书权限将包含service acount的toker secret,这必须是一个有效的PEM编码CA 包
--service-account-private-key-file 包含用于签署service account token的PEM编码RSA或者ECDSA私钥的文件名
--experimental-cluster-signing-duration 证书签发时间

(2)创建controller-manager启动脚本

[root@master ~]# cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF[Unit]Description=Kubernetes Controller ManagerDocumentation=https://github.com/kubernetes/kubernetesAfter=network.target[Service]EnvironmentFile=/etc/kubernetes/cfg/kube-controller-manager.confExecStart=/usr/local/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTSRestart=on-failureRestartSec=5[Install]WantedBy=multi-user.targetEOF

(3)启动并设置开机启动

[root@master ~]# systemctl daemon-reload[root@master ~]# systemctl start kube-controller-manager[root@master ~]# systemctl enable kube-controller-manager

6.5、部署kube-scheduler

调度器的职责主要是为新创建的pod在集群中寻找最合适的node,并将pod调度到Node上,Scheduler调度器运行在master节点,它的核心功能是监听apiserver来获取节点上为空的pod,然后为pod创建一个binding指示pod应该调度到哪个节点上,调度结果写入apiserver。

(1)创建scheduler配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-scheduler.conf << EOFKUBE_SCHEDULER_OPTS="--logtostderr=false \\--v=2 \\--log-dir=/var/log/kubernetes \\--leader-elect=false \\--master=http://127.0.0.1:8080 \\--bind-address=127.0.0.1 \\--address=127.0.0.1"EOF

(2)创建scheduler服务启动脚本

[root@master ~]# cat > /usr/lib/systemd/system/kube-scheduler.service << EOF[Unit]Description=Kubernetes SchedulerDocumentation=https://github.com/kubernetes/kubernetesAfter=network.target[Service]EnvironmentFile=/etc/kubernetes/cfg/kube-scheduler.confExecStart=/usr/local/bin/kube-scheduler \$KUBE_SCHEDULER_OPTSRestart=on-failureRestartSec=5[Install]WantedBy=multi-user.targetEOF

(3)启动并设置开机启动

[root@master ~]# systemctl daemon-reload[root@master ~]# systemctl start kube-scheduler[root@master ~]# systemctl enable kube-scheduler

6.6、查看集群状态

所有组件都已经启动成功,通过kubectl工具查看当前集群组件状态:

[root@master ~]# kubectl get csNAME                 STATUS    MESSAGE             ERRORscheduler            Healthy   ok                  controller-manager   Healthy   ok                  etcd-1               Healthy   {"health":"true"}   etcd-2               Healthy   {"health":"true"}   etcd-0               Healthy   {"health":"true"}   

看到第二列的状态值都是Healthy,说明Master节点组件运行正常。

7、部署Work Node

对于我们这里的二进制部署的一主多从,在企业中适合测试环境,因此为了更多的复用机器资源,主master节点也应该作为node节点跑pod。

下面依然在master这个节点上操作,让其再成为节点

7.1、拷贝二进制文件至node0节点

  • 复制二进制包

将kubernetes解压的二进制包程序kubelet,kube-proxy复制到本地环境变量路径下。

[root@master ~]# cd kubernetes/server/bin[root@master bin]# cp kubelet kube-proxy /usr/local/bin[root@master bin]# cd

7.2、部署kubelet服务

(1)创建kubelet.conf配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kubelet.conf << EOFKUBELET_OPTS="--logtostderr=false \\--v=2 \\--log-dir=/var/log/kubernetes \\--hostname-override=node0 \\--container-runtime=docker \\--network-plugin=cni \\--kubeconfig=/etc/kubernetes/cfg/kubelet.kubeconfig \\--bootstrap-kubeconfig=/etc/kubernetes/cfg/bootstrap.kubeconfig \\--config=/etc/kubernetes/cfg/kubelet-config.yml \\--cert-dir=/etc/kubernetes/ssl \\--image-pull-progress-deadline=15m \\--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1"EOF

配置文件解释说明

配置选项 选项意义
--hostname-override 用来配置该节点在集群中显示的主机名,kubelet设置了-–hostname-override参数后,kube-proxy也需要设置,否则会出现找不到Node的情况
--container-runtime 指定容器运行时引擎
--network-plugin 启用CNI网络插件
--kubeconfig kubelet作为客户端使用的kubeconfig认证文件,此文件是由kube-controller-mananger生成的
--bootstrap-kubeconfig 指定令牌认证文件
--config 指定kubelet配置文件
--cert-dir 设置kube-controller-manager生成证书和私钥的目录
--image-pull-progress-deadline 镜像拉取进度最大时间,如果在这段时间拉取镜像没有任何进展,将取消拉取,默认:1m0s
--pod-infra-container-image 每个pod中的network/ipc名称空间容器将使用的镜像

(2)kubelet-config.yml配置参数文件

[root@master ~]# cat > /etc/kubernetes/cfg/kubelet-config.yml << EOFkind: KubeletConfigurationapiVersion: kubelet.config.k8s.io/v1beta1address: 0.0.0.0port: 10250readOnlyPort: 10255cgroupDriver: cgroupfsclusterDNS:- 10.0.0.2clusterDomain: cluster.local failSwapOn: falseauthentication:  anonymous:    enabled: false  webhook:    cacheTTL: 2m0s    enabled: true  x509:    clientCAFile: /etc/kubernetes/ssl/ca.pem authorization:  mode: Webhook  webhook:    cacheAuthorizedTTL: 5m0s    cacheUnauthorizedTTL: 30sevictionHard:  imagefs.available: 15%  memory.available: 100Mi  nodefs.available: 10%  nodefs.inodesFree: 5%maxOpenFiles: 1000000maxPods: 110EOF

简单说几个比较重要的选项配置意义

配置选项 选项意义
address kubelet 服务监听的地址
port: 10250 kubelet 服务的端口,默认 10250
readOnlyPort 没有认证/授权的只读 kubelet 服务端口 ,设置为 0 表示禁用,默认 `10255
clusterDNS DNS 服务器的IP地址列表
clusterDomain 集群域名, kubelet 将配置所有容器除了主机搜索域还将搜索当前域

(3)生成bootstrap.kubeconfig文件

生成 kubelet bootstrap kubeconfig 配置文件

[root@master ~]# kubectl config set-cluster kubernetes \  --certificate-authority=/etc/kubernetes/ssl/ca.pem \  --embed-certs=true \  --server=https://192.168.50.128:6443 \  --kubeconfig=bootstrap.kubeconfig[root@master ~]# kubectl config set-credentials "kubelet-bootstrap" \  --token=14f2afa0b6ccc53350972c4d2942d452 \  --kubeconfig=bootstrap.kubeconfig                          # 与token.csv里保持一致[root@master ~]# kubectl config set-context default \  --cluster=kubernetes \  --user="kubelet-bootstrap" \  --kubeconfig=bootstrap.kubeconfig[root@master ~]# kubectl config use-context default --kubeconfig=bootstrap.kubeconfig[root@master ~]# ls -l *.kubeconfig-rw------- 1 root root 2168 Jul 14 21:41 bootstrap.kubeconfig

拷贝到配置文件路径/etc/kubernetes/cfg

[root@master ~]# cp -p bootstrap.kubeconfig /etc/kubernetes/cfg

(4)创建kubelet服务启动脚本

[root@master ~]# cat > /usr/lib/systemd/system/kubelet.service << EOF[Unit]Description=Kubernetes KubeletAfter=docker.service[Service]EnvironmentFile=/etc/kubernetes/cfg/kubelet.confExecStart=/usr/local/bin/kubelet \$KUBELET_OPTSRestart=on-failureRestartSec=10LimitNOFILE=65536[Install]WantedBy=multi-user.targetEOF

(5)启动并设置开机启动

[root@master ~]# systemctl daemon-reload[root@master ~]# systemctl start kubelet[root@master ~]# systemctl enable kubelet

(6)部署CNI容器网络

CNI,全名叫做:容器网络接口。是CNCF旗下的一个项目,由一组用于配置容器的网络接口的规范和库组成。CNI主要用于解决容器网络互联的配置并支持多种网络模型。

[root@master ~]# cd ~[root@master ~]#  wget https://github.com/containernetworking/plugins/releases/download/v0.8.6/cni-plugins-linux-amd64-v0.8.6.tgz[root@master ~]# mkdir -pv /opt/cni/bin[root@master ~]# tar xf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin[root@master ~]# ls /opt/cni/binbandwidth  bridge  dhcp  firewall  flannel  host-device  host-local  ipvlan  loopback  macvlan  portmap  ptp  sbr  static  tuning  vlan

7.3、批准kubelet证书申请并加入集群

(1)查看kubelet证书请求

[root@master ~]# kubectl get csrNAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITIONnode-csr-N6eV-2UjPO6-dv67Co_lM9BGyF-BQGQ1R_rJz0rGQ3A   22m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending

此命令可以看到所有请求,所有为pending状态,则是需要批准的。

(2)批准申请

把上面的命令的NAME字段的值拿过来。

[root@master ~]# kubectl certificate approve `kubectl get csr | grep "Pending" | awk '{print $1}'`certificatesigningrequest.certificates.k8s.io/node-csr-N6eV-2UjPO6-dv67Co_lM9BGyF-BQGQ1R_rJz0rGQ3A approved
  • 查看节点

[root@master ~]# kubectl get nodeNAME    STATUS     ROLES    AGE   VERSIONnode0   NotReady   
   3s    v1.18.4

注意:这里的STATUS状态值还是notReady,是因为网络插件还没有部署好。接着往下即可。

7.4、部署kube-proxy服务

kube-proxy是什么,这里就不得不提前说下service,service是一组Pod的抽象集合,它相当于一组Pod的负载均衡器,负责将请求分发到对应的pod,kube-proxy就是负责service的实现的,当请求到达service时,它通过label关联到后端并转发到某个Pod;kube-proxy提供了三种负载均衡模式:用户空间、iptables、ipvs,我们采用的是iptables负载均衡模式。

(1)创建kube-proxy配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-proxy.conf << EOFKUBE_PROXY_OPTS="--logtostderr=false \\--v=2 \\--log-dir=/var/log/kubernetes \\--config=/etc/kubernetes/cfg/kube-proxy-config.yml"EOF

(2)kube-proxy-config.yml配置参数文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-proxy-config.yml << EOFkind: KubeProxyConfigurationapiVersion: kubeproxy.config.k8s.io/v1alpha1bindAddress: 0.0.0.0healthzBindAddress: 0.0.0.0:10256metricsBindAddress: 0.0.0.0:10249clientConnection:  burst: 200  kubeconfig: /etc/kubernetes/cfg/kube-proxy.kubeconfig  qps: 100hostnameOverride: node0clusterCIDR: 10.0.0.0/24EOF

简单说一下上面配置的选项意义

选项配置 选项意义
clientConnection 与kube-apiserver交互时的参数设置
burst: 200 临时允许该事件记录值超过qps设定值
kubeconfig kube-proxy 客户端连接 kube-apiserver 的 kubeconfig 文件路径设置
qps: 100 与kube-apiserver交互时的QPS,默认值5
bindAddress kube-proxy监听地址
healthzBindAddress 用于检查服务的IP地址和端口
metricsBindAddress metrics服务的ip地址和端口。默认:127.0.0.1:10249
clusterCIDR kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT
hostnameOverride 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 ipvs 规则;

(3)生成kube-proxy.kubeconfig证书

创建证书请求文件

[root@master ~]# cd ~/TLS/k8s[root@master k8s]# cat > kube-proxy-csr.json << EOF{  "CN": "system:kube-proxy",  "hosts": [],  "key": {    "algo": "rsa",    "size": 2048  },  "names": [    {      "C": "CN",      "L": "BeiJing",      "ST": "BeiJing",      "O": "k8s",      "OU": "System"    }  ]}EOF

生成证书

[root@master k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy[root@master k8s]# ls kube-proxy*pemkube-proxy-key.pem  kube-proxy.pem

(4)生成kubeconfig文件

kube-proxy是作为kube-apiserver的客户端,由于我们启用了TLS,所以需要认证访问,这里我们需要使用到之前生成的证书。

[root@master k8s]# kubectl config set-cluster kubernetes \  --certificate-authority=/etc/kubernetes/ssl/ca.pem \  --embed-certs=true \  --server=https://192.168.50.128:6443 \  --kubeconfig=kube-proxy.kubeconfig[root@master k8s]# kubectl config set-credentials kube-proxy \  --client-certificate=./kube-proxy.pem \  --client-key=./kube-proxy-key.pem \  --embed-certs=true \  --kubeconfig=kube-proxy.kubeconfig[root@master k8s]# kubectl config set-context default \  --cluster=kubernetes \  --user=kube-proxy \  --kubeconfig=kube-proxy.kubeconfig[root@master k8s]# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

拷贝到配置文件指定的路径下:

[root@master k8s]# cp kube-proxy.kubeconfig /etc/kubernetes/cfg/

(5)创建kube-proxy服务启动脚本

[root@master k8s]# cat > /usr/lib/systemd/system/kube-proxy.service << EOF[Unit]Description=Kubernetes ProxyAfter=network.target[Service]EnvironmentFile=/etc/kubernetes/cfg/kube-proxy.confExecStart=/usr/local/bin/kube-proxy \$KUBE_PROXY_OPTSRestart=on-failureRestartSec=10LimitNOFILE=65536[Install]WantedBy=multi-user.targetEOF

(6)启动并设置开机启动

[root@master ~]# systemctl daemon-reload[root@master ~]# systemctl start kube-proxy[root@master ~]# systemctl enable kube-proxy

7.5、授权apiserver访问kubelet

在执行kubectl exec、run、logs 等命令时,apiserver会转发到kubelet。这里定义 RBAC规则,授权apiserver调用kubelet API"

[root@master ~]# cat > apiserver-to-kubelet-rbac.yaml << EOFapiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:  annotations:    rbac.authorization.kubernetes.io/autoupdate: "true"  labels:    kubernetes.io/bootstrapping: rbac-defaults  name: system:kube-apiserver-to-kubeletrules:  - apiGroups:      - ""    resources:      - nodes/proxy      - nodes/stats      - nodes/log      - nodes/spec      - nodes/metrics      - pods/log    verbs:      - "*"---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:  name: system:kube-apiserver  namespace: ""roleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: system:kube-apiserver-to-kubeletsubjects:  - apiGroup: rbac.authorization.k8s.io    kind: User    name: kubernetesEOF

(1)访问授权

[root@master ~]# kubectl apply -f apiserver-to-kubelet-rbac.yamlclusterrole.rbac.authorization.k8s.io/system:kube-apiserver-to-kubelet createdclusterrolebinding.rbac.authorization.k8s.io/system:kube-apiserver created

7.6、部署Flannel网络插件

Flannel是 CoreOS 团队针对 Kubernetes 设计的一个覆盖网络(Overlay Network)工具,其目的在于帮助每一个使用 Kuberentes 的 CoreOS 主机拥有一个完整的子网。Flannel通过给每台宿主机分配一个子网的方式为容器提供虚拟网络,它基于Linux TUN/TAP,使用UDP封装IP包来创建overlay网络,并借助etcd维护网络的分配情况

(1)下载flannel配置文件

[root@master ~]# curl -o kube-flannel.yml  https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

事实上很多用户都不能成功,因为国内网络受限,所以可以这样子来做。修改hosts文件,加上如下解析记录

 199.232.28.133  raw.githubusercontent.com

(2)更换flannel镜像源

编辑镜像源,默认的镜像地址我们修改一下。把yaml文件中所有的quay.io修改为 quay-mirror.qiniu.com

[root@master ~]# sed -i 's/quay.io/quay-mirror.qiniu.com/g' kube-flannel.yml

此时保存保存退出。在master节点执行此命令。

[root@master ~]# kubectl apply -f kube-flannel.yml podsecuritypolicy.policy/psp.flannel.unprivileged createdclusterrole.rbac.authorization.k8s.io/flannel createdclusterrolebinding.rbac.authorization.k8s.io/flannel createdserviceaccount/flannel createdconfigmap/kube-flannel-cfg createddaemonset.apps/kube-flannel-ds-amd64 createddaemonset.apps/kube-flannel-ds-arm64 createddaemonset.apps/kube-flannel-ds-arm createddaemonset.apps/kube-flannel-ds-ppc64le createddaemonset.apps/kube-flannel-ds-s390x created

这样子就可以成功拉取flannel镜像了。当然你也可以直接使用我提供给大家的kube-flannel.yml文件

  • 查看flannel是否正常

如果你想查看flannel这些pod运行是否正常,使用如下命令:

[root@master ~]# kubectl get pods -n kube-systemNAME                          READY   STATUS    RESTARTS   AGEkube-flannel-ds-amd64-n5z2w   1/1     Running   0          2m6s

注意:稍等1-3分钟后,如果第三字段STATUS不是处于Running状态的话,并且STATUS字段数值一直在渐渐变大,说明flannel是异常的,需要排查问题所在。

  • 查看节点

[root@master ~]# kubectl get nodesNAME    STATUS   ROLES    AGE   VERSIONnode0   Ready    
   10m   v1.18.4

目前节点状态是Ready,表示集群节点现在是可用的

(3)无法拉取镜像解决方法

如果有以下报错:

Normal   BackOff    24m (x6 over 26m)   kubelet, master3   Back-off pulling image "quay-mirror.qiniu.com/coreos/flannel:v0.12.0-amd64"  Warning  Failed     11m (x64 over 26m)  kubelet, master3   Error: ImagePullBackOff

或者是

Error response from daemon: Get https://quay.io/v2/: net/http: TLS handshake timeout

上面的这些都表示是网络问题不能拉取镜像,我这里给大家提前准备了flannel的镜像。导入一下就可以了。

[root@master1 ~]# docker load -i flannel.tar

7.7、部署CoreDNS解析插件

CoreDNS用于集群中Pod解析Service的名字,Kubernetes基于CoreDNS用于服务发现功能。

安装CoreDNS1.6.7(目前较新版本)。如果之前修改了PodIP的网段,那么这里需要自行修改此文件的ClusterIP参数。其他可保持不变

spec: selector:    k8s-app: kube-dns  clusterIP: 10.0.0.2       #根据自己情况修改此值

(1)构建CoreDNS

[root@master ~]# kubectl apply -f coredns.yaml

查看Pod状态

[root@master ~]# kubectl -n kube-system get pod | grep corednscoredns-64d575f97f-52kjv      1/1     Running   0          2d5h

(2)解析测试

kubectl run -it --rm busybox-dns --image=busybox:1.28.4 shIf you don't see a command prompt, try pressing enter./ # nslookup kubernetesServer:    10.0.0.2Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.localName:      kubernetesAddress 1: 10.0.0.1 kubernetes.default.svc.cluster.local

只要能出结果,解析就是没有问题的。

8、继续增加Work Node

8.1、部署第二个node节点

(1)拷贝部署好的node相关文件到新节点

在master节点操作,把文件远程复制给node节点

[root@master ~]# scp -p /usr/local/bin/{kubelet,kube-proxy} root@node1:/usr/local/bin[root@master ~]# scp -pr /etc/kubernetes root@node1:/etc[root@master ~]# scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@node1:/usr/lib/systemd/system[root@master ~]# scp -pr /opt/cni root@node1:/opt

(2)删除kubelet证书和kubeconfig

在node1节点上操作

[root@node1 ~]# rm -rf /etc/kubernetes/cfg/kubelet.kubeconfig[root@node1 ~]# rm -rf /etc/kubernetes/ssl/kubelet*

(3)修改主机名

[root@node1 ~]# vim /etc/kubernetes/cfg/kubelet.conf

修改为--hostname-override-=node1

[root@node1 ~]# vim /etc/kubernetes/cfg/kube-proxy-config.yml

修改为hostnameOverride: node1

(4)启动并设置开机启动

[root@node1 ~]# systemctl daemon-reload[root@node1 ~]# systemctl enable --now kubelet kube-proxy

(5)批准node节点申请

下面的是在master节点操作的

[root@master ~]# kubectl get csrNAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITIONnode-csr-N6eV-2UjPO6-dv67Co_lM9BGyF-BQGQ1R_rJz0rGQ3A   41m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issuednode-csr-hJkIg6lFyeDTORq2Y_xNS7qsU0kQCQh_ZqL0Zj_rfrE   98s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending

上面的CONDITIONPending状态的表示将要被加入集群的节点。所以记录前面的NAME字段

[root@master ~]# kubectl certificate approve `kubectl get csr | grep Pending| awk '{print $1}'`certificatesigningrequest.certificates.k8s.io/node-csr-hJkIg6lFyeDTORq2Y_xNS7qsU0kQCQh_ZqL0Zj_rfrE approved

(6)查看node状态

稍等两分钟

[root@master ~]# kubectl get nodesNAME    STATUS   ROLES    AGE   VERSIONnode0   Ready    
   28m   v1.18.4node1   Ready    
   11m   v1.18.4

8.2、部署第三个node节点

按照上面的前五步继续执行即可。做完之后如下所示:

[root@master ~]# kubectl get nodesNAME    STATUS   ROLES    AGE   VERSIONnode0   Ready    
   28m   v1.18.4node1   Ready    
   11m   v1.18.4node2   Ready    
   3m   v1.18.4

至此,二进制单节点集群部署已经完成,接下来我们可以测试一下集群是否可用。

9、测试kubernetes集群

(1)、创建一个nginx的pod

现在我们在kubernetes集群中创建一个nginx的pod,验证是否能正常运行。

在master节点执行一下步骤:

[root@master1 ~]# kubectl create deployment nginx --image=nginxdeployment.apps/nginx created[root@master1 ~]# kubectl expose deployment nginx --port=80 --type=NodePortservice/nginx exposed

现在我们查看pod和service

[root@master1 ~]# kubectl get pod,svc -o wide

打印的结果中,前半部分是pod相关信息,后半部分是service相关信息。我们看service/nginx这一行可以看出service暴漏给集群的端口是30249。记住这个端口。

然后从pod的详细信息可以看出此时pod在node2节点之上。node2节点的IP地址是192.168.50.132

(2)、访问nginx验证集群

那现在我们访问一下。打开浏览器(建议火狐浏览器),访问地址就是:http://192.168.50.132:30249

10、安装dashboard

10.1、创建dashboard

(1)创建并运行

先把dashboard的配置文件下载下来。由于我们之前已经添加了hosts解析,因此可以下载。

[root@master1 ~]# curl -o recommended.yaml https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:

大概在此文件的32-44行之间,修改为如下:

kind: ServiceapiVersion: v1metadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard  namespace: kube-systemspec:  type: NodePort       #加上此行  ports:    - port: 443      targetPort: 8443      nodePort: 30001     #加上此行,端口30001可以自行定义  selector:    k8s-app: kubernetes-dashboard
  • 运行此yaml文件

[root@master1 ~]# kubectl apply -f recommended.yaml namespace/kubernetes-dashboard createdserviceaccount/kubernetes-dashboard createdservice/kubernetes-dashboard createdsecret/kubernetes-dashboard-certs created...service/dashboard-metrics-scraper createddeployment.apps/dashboard-metrics-scraper created

(2)测试是否正常

[root@master1 ~]# kubectl get pods -n kubernetes-dashboardNAME                                         READY   STATUS    RESTARTS   AGEdashboard-metrics-scraper-694557449d-mlnl4   1/1     Running   0          2m31skubernetes-dashboard-9774cc786-ccvcf         1/1     Running   0          2m31s

主要是看status这一列的值,如果是Running,并且RESTARTS字段的值为0(只要这个值不是一直在渐渐变大),就是正常的,目前来看是没有问题的。我们可以继续下一步。

查看此dashboard的pod运行所在的节点

从上面可以看出,kubernetes-dashboard-9774cc786-ccvcf运行所在的节点是node2上面,并且暴漏出来的端口是30001,所以访问地址是:https://192.168.50.132:30001

(3)浏览器访问URL

用火狐浏览器访问,访问的时候会让输入token,从此处可以查看到token的值。

[root@master1 ~]# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

把上面的token值输入进去即可进去dashboard界面。

不过现在我们虽然可以登陆上去,但是我们权限不够还查看不了集群信息,因为我们还没有绑定集群角色,同学们可以先按照上面的尝试一下,再来做下面的步骤

10.2、cluster-admin管理员角色绑定

[root@master1 ~]# kubectl create serviceaccount dashboard-admin -n kube-system[root@master1 ~]# kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin[root@master1 ~]# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

再次使用输出的token登陆dashboard即可。

 

转载地址:http://cdvyk.baihongyu.com/

你可能感兴趣的文章