😘作者简介:一名运维工作人员。
👊宣言:人生就是B(birth)和D(death)之间的C(choise),做好每一个选择。
🙏创作不易,动动小手给个点赞加关注吧,有什么意见评论区告诉我,一起学习。 

 一、前言

生产环境中有两种部署k8s的方法:

       

kubeadm
Kubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。

二进制包
从github下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。
小结:Kubeadm降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署Kubernetes集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。

这里就使用二进制的方式来部署k8s,在企业中一般也是使用二级制来部署。

1、kubernetes核心概念

  • k8s-master 负责任务调度,控制节点
  • k8s-node1 承载运行pod(容器)
  • k8s-node2 承载运行pod(容器

1)Master

Master主要负责资源调度,控制pod副本,和提供统一访问集群的入口。--核心节点也是管理节点

2)Node

Node是Kubernetes集群架构中运行Pod的服务节点。Node是Kubernetes集群操作的单元,用来承载被分配Pod的运行,是Pod运行的宿主机,由Master管理,并汇报容器状态给Master,同时根据Master要求管理容器生命周期。

3)Node IP

   Node节点的IP地址,是Kubernetes集群中每个节点的物理网卡的IP地址,是真实存在的物理网络,所有属于这个网络的服务器之间都能通过这个网络直接通信;

4)Pod

   Pod直译是豆荚,可以把容器想像成豆荚里的豆子,把一个或多个关系紧密的豆子包在一起就是豆荚(一个Pod)。在k8s中我们不会直接操作容器,而是把容器包装成Pod再进行管理运行于Node节点上, 若干相关容器的组合。Pod内包含的容器运行在同一宿主机上,使用相同的网络命名空间、IP地址和端口,能够通过localhost进行通信。Pod是k8s进行创建、调度和管理的最小单位,它提供了比容器更高层次的抽象,使得部署和管理更加灵活。一个Pod可以包含一个容器或者多个相关容器。

   Pod 就是 k8s 集群里的"应用";而一个平台应用,可以由多个容器组成。


二、服务器规划

1、一Matser双Node

因为电脑配置原因,做不了高可用,所以以一主二从为例。

1)服务器规划

主机IP组件
k8s-master        192.168.79.148

kube-apiserver,kube-controller-manager,kube-scheduler,etcd

k8s-node1

192.168.79.149

kubelet,kube-proxy,docker,etcd

k8s-node2192.168.79.150

kubelet,kube-proxy,docker,etcd

2)服务器架构

 Kubernetes Master:

集群控制节点,负责整个集群的管理和控制,基本上Kubernetes所有的控制命令都是发给它,它来负责具体的执行过程,我们后面所有执行的命令基本都是在Master节点上运行的;

包含如下组件:
1.Kubernetes API Server
作为Kubernetes系统的入口,其封装了核心对象的增删改查操作,以RESTful API接口方式提供给外部客户和内部组件调用。维护的REST对象持久化到Etcd中存储。

2.Kubernetes Scheduler
为新建立的Pod进行节点(node)选择(即分配机器),负责集群的资源调度。组件抽离,可以方便替换成其他调度器。

3.Kubernetes Controller
负责执行各种控制器,目前已经提供了很多控制器来保证Kubernetes的正常运行。
   Replication Controller
       管理维护Replication Controller,关联Replication Controller和Pod,保证Replication Controller定义的副本数量与实际运行Pod数量一致。

​  Deployment Controller
       管理维护Deployment,关联Deployment和Replication  Controller,保证运行指定数量的Pod。当Deployment更新时,控制实现Replication  Controller和 Pod的更新。

   Node Controller
      管理维护Node,定期检查Node的健康状态,标识出(失效|未失效)的Node节点。

   Namespace Controller
      管理维护Namespace,定期清理无效的Namespace,包括Namesapce下的API对象,比如Pod、Service等。

   Service Controller
      管理维护Service,提供负载以及服务代理。

   EndPoints Controller
      管理维护Endpoints,关联Service和Pod,创建Endpoints为Service的后端,当Pod发生变化时,实时更新Endpoints。

   Service Account Controller
      管理维护Service Account,为每个Namespace创建默认的Service Account,同时为Service Account创建Service Account Secret。

   Persistent Volume Controller
      管理维护Persistent Volume和Persistent Volume  Claim,为新的Persistent Volume Claim分配Persistent Volume进行绑定,为释放的Persistent  Volume执行清理回收。

   Daemon Set Controller
      管理维护Daemon Set,负责创建Daemon Pod,保证指定的Node上正常的运行Daemon Pod。

  Job Controller
      管理维护Job,为Jod创建一次性任务Pod,保证完成Job指定完成的任务数目

   Pod Autoscaler Controller
      实现Pod的自动伸缩,定时获取监控数据,进行策略匹配,当满足条件时执行Pod的伸缩动作。

Kubernetes Node:
除了Master,Kubernetes集群中的其他机器被称为Node节点,Node节点才是Kubernetes集群中的工作负载节点,每个Node都会被Master分配一些工作负载(Docker容器),当某个Node宕机,其上的工作负载会被Master自动转移到其他节点上去;

包含如下组件:
  1.Kubelet
    负责管控容器,Kubelet会从Kubernetes API Server接收Pod的创建请求,启动和停止容器,监控容器运行状态并汇报给Kubernetes API Server。

  2.Kubernetes Proxy
    负责为Pod创建代理服务,Kubernetes Proxy会从Kubernetes API  Server获取所有的Service信息,并根据Service的信息创建代理服务,实现Service到Pod的请求路由和转发,从而实现Kubernetes层级的虚拟转发网络。

  3.Docker Engine(docker),Docker引擎,负责本机的容器创建和管理工作;  
  4.网络插件:解决node之间pod的通信问题。

数据库

etcd数据库,可以部署到master、node上,推荐独立部署
分布式键值存储系统。用于保存集群状态数据,比如Pod、Service等对象信息

3)配置主机映射 

[root@k8s-master ~]# vim /etc/hosts
[root@k8s-master ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.79.148	k8s-master
192.168.79.149	k8s-node1
192.168.79.150	k8s-node2

 使用scp将hosts文件发送给node1和node2。


三、Etc集群

Etcd 是一个分布式键值存储系统,Kubernetes使用Etcd进行数据存储,所以先准备一个Etcd数据库,为解决Etcd单点故障,应采用集群方式部署,这里使用3台组建集群,可容忍1台机器故障,当然,你也可以使用5台组建集群,可容忍2台机器故障。

注:为了节省机器,这里与K8s节点机器复用。也可以独立于k8s集群之外部署,只要apiserver能连接到就行

1、准备cfssl证书生成工具

cfssl是一个开源的证书管理工具,使用json文件生成证书,相比openssl更方便使用。

cfssl工具的网盘

链接:https://pan.baidu.com/s/1zf6ZaDYS2r4OZWz0zHr7zQ?pwd=nar2 
提取码:nar2 

这里我用rz将本地的cfssl工具拷到虚拟机,然后给他们执行的命令,为了方便使用这些工具,将这些拷到/usr/bin目录下。

这样就可以直接使用cfssl、cfssl-certinfo、cfssljson这三个命令了。

2、生成Etcd证书

1)自签证书颁发机构(CA)

先创建工作目录,并进入到该目录

mkdir opt/etcd -p

cd opt/etcd

[root@k8s-master1 etcd]#vim ca-config.json
[root@k8s-master etcd]# cat ca-config.json 
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "www": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}


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

2)生成证书

[root@k8s-master etcd]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -


[root@k8s-master etcd]# ls
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem

可以看到当前目录多了两个ca-key.pem  ca.pem文件,这就是证书文件。

3)使用自签CA签发Etcd HTTPS证书

创建证书申请文件
[root@k8s-master1 etcd]# vim server-csr.json
[root@k8s-master etcd]# cat server-csr.json
{
    "CN": "etcd",
    "hosts": [
    "192.168.79.148",
    "192.168.79.149",
    "192.168.79.150"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing"
        }
    ]
}

上述文件hosts字段中IP为所有etcd节点的集群内部通信IP,一个都不能少。

#生成证书
[root@k8s-master1 etcd]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server

#查看证书生成情况
[root@k8s-master etcd]# ls *pem
ca-key.pem  ca.pem  server-key.pem  server.pem

又多出server-key.pem和server.pem文件。

3、部署Etcd集群

首先需要etcd的二进制文件。

etcd的二进制文件的网盘。

链接:https://pan.baidu.com/s/1va2DkgJSZ-lL5T5xBKVodg?pwd=j5gt 
提取码:j5gt 

1)获取etcd的软件包

注意:我这里为了防止etcd目录下文件太多太乱,先进入到了家目录,然后通过rz将本地的etcd包拷到虚拟机

2)解压etcd包

 解压后在etcd-v3.4.9-linux-amd64目录下有etcd和etcdctl两个可执行的文件。

[root@k8s-master ~]# tar xfz etcd-v3.4.9-linux-amd64.tar.gz

[root@k8s-master ~]# ls
anaconda-ks.cfg  cfssl_1.6.4_linux_amd64  cfssl-certinfo_1.6.4_linux_amd64  cfssljson_1.6.4_linux_amd64  etcd-v3.4.9-linux-amd64  etcd-v3.4.9-linux-amd64.tar.gz  opt

[root@k8s-master ~]# ls etcd-v3.4.9-linux-amd64
Documentation  etcd  etcdctl  README-etcdctl.md  README.md  READMEv2-etcdctl.md

3)创建工作目录并且将etcd和etcdctl拷到工作目录

[root@k8s-master ~]# mkdir -p /opt/etcd/{bin,cfg,ssl}
[root@k8s-master ~]# cp etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/
[root@k8s-master ~]# tree /opt/
/opt/
└── etcd
    ├── bin
    │   ├── etcd
    │   └── etcdctl
    ├── cfg
    └── ssl

这里在/opt/etcd/目录下创建了bin,cfg,ssl三个文件夹,bin存放的是命令文件,cfg存放的是 

4)创建etcd的配置文件

[root@k8s-master ~]# vim /opt/etcd/cfg/etcd.conf
[root@k8s-master ~]# cat /opt/etcd/cfg/etcd.conf
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.79.148:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.79.148:2379"

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.79.148:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.79.148:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.79.148:2380,etcd-2=https://192.168.79.149:2380,etcd-3=https://192.168.79.150:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

 *参数解释

•      ETCD_NAME:节点名称,集群中唯一

•      ETCD_DATA_DIR:数据目录

•      ETCD_LISTEN_PEER_URLS:集群通信监听地址,填本机ip

•      ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址,填本机ip

•      ETCD_INITIAL_ADVERTISE_PEERURLS:集群通告地址,填本机ip

•      ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址,填本机ip

•      ETCD_INITIAL_CLUSTER:集群节点地址

•      ETCD_INITIALCLUSTER_TOKEN:集群Token

•      ETCD_INITIALCLUSTER_STATE:加入集群的当前状态,new是新集群,existing表示加入已有集群

 5)system管理etcd

system管理etcd需要再/usr/lib/systemd/system下编写相应的service文件。

[root@k8s-master ~]# vim /usr/lib/systemd/system/etcd.service
[root@k8s-master ~]# cat /usr/lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--peer-cert-file=/opt/etcd/ssl/server.pem \
--peer-key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

注意这里的证书文件要记得拷到/opt/etcd/bin/目录下,这里system管理etcd读取的证书写到了这个目录,当然也可以改,就是为了方便整理,是放到了这个文件夹下。

[root@k8s-master ~]# cp  opt/etcd/*pem   /opt/etcd/ssl/
[root@k8s-master ~]# tree /opt/
/opt/
└── etcd
    ├── bin
    │   ├── etcd
    │   └── etcdctl
    ├── cfg
    │   └── etcd.conf
    └── ssl
        ├── ca-key.pem
        ├── ca.pem
        ├── server-key.pem
        └── server.pem

4 directories, 7 files

将这些证书和etcd.conf以及service的文件、etcd执行文件都要拷到node1和node2上,其中etcd.conf内需要更改ip。

6)拷贝文件到node1和node2并修改etcd.conf文件

6.1)node1和node2创建相同的工作目录

mkdir /opt/etcd/{bin,cfg,ssl} -p

拷贝etcd.conf文件
[root@k8s-master ~]# scp /opt/etcd/cfg/etcd.conf  k8s-node1:/opt/etcd/cfg/
  
[root@k8s-master ~]# scp /opt/etcd/cfg/etcd.conf  k8s-node2:/opt/etcd/cfg/


#拷贝证书
[root@k8s-master ~]# scp /opt/etcd/ssl/* k8s-node1:/opt/etcd/ssl/
   
[root@k8s-master ~]# scp /opt/etcd/ssl/* k8s-node2:/opt/etcd/ssl/


#拷贝etcd执行文件
[root@k8s-master ~]# scp /opt/etcd/bin/etcd k8s-node1:/opt/etcd/bin/
  
[root@k8s-master ~]# scp /opt/etcd/bin/etcd k8s-node2:/opt/etcd/bin/


#拷贝system管理etcd文件配置
[root@k8s-master ~]# scp /usr/lib/systemd/system/etcd.service  k8s-node1:/usr/lib/systemd/system/

[root@k8s-master ~]# scp /usr/lib/systemd/system/etcd.service  k8s-node2:/usr/lib/systemd/system/
6.2)修改node1上的etcd.conf文件

需要修改的位置:

ETCD_NAME

ETCD_LISTEN_PEER_URLS

ETCD_LISTEN_CLIENT_URLS

ETCD_INITIAL_ADVERTISE_PEER_URLS

ETCD_ADVERTISE_CLIENT_URLS

[root@k8s-node1 ~]# cat /opt/etcd/cfg/etcd.conf 
#[Member]
ETCD_NAME="etcd-2"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.79.149:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.79.149:2379"

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.79.149:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.79.149:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.79.148:2380,etcd-2=https://192.168.79.149:2380,etcd-3=https://192.168.79.150:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
6.3)修改node2上的etcd.conf文件 

需要修改的位置:

ETCD_NAME

ETCD_LISTEN_PEER_URLS

ETCD_LISTEN_CLIENT_URLS

ETCD_INITIAL_ADVERTISE_PEER_URLS

ETCD_ADVERTISE_CLIENT_URLS

[root@k8s-node2 ~]# cat /opt/etcd/cfg/etcd.conf 
#[Member]
ETCD_NAME="etcd-3"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.79.150:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.79.150:2379"

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.79.150:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.79.150:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.79.148:2380,etcd-2=https://192.168.79.149:2380,etcd-3=https://192.168.79.150:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

node1和node2都要改相应的位置。ETCD_NAME这里要保证不能重复。

 7)启动etcd

使用systemctl启动服务。

这里需要注意:单启动一个etcd,bash页面会进入等待状态,等待集群中的另一台启动,因为etcd启动至少需要集群中的两台都启动,才会真正的启动。

分别执行这三条命令:

systemctl daemon-reload 
systemctl start etcd.service 
systemctl enable etcd.service 

#master
[root@k8s-moster ~]# systemctl daemon-reload 
[root@k8s-moster ~]# systemctl start etcd.service 
[root@k8s-moster ~]# systemctl enable etcd.service 


#node1
[root@k8s-node1 ~]# systemctl daemon-reload 
[root@k8s-node1 ~]# systemctl start etcd.service 
[root@k8s-node1 ~]# systemctl enable etcd.service 


#node2
[root@k8s-node2 ~]# systemctl daemon-reload 
[root@k8s-node2 ~]# systemctl start etcd.service 
[root@k8s-node2 ~]# systemctl enable etcd.service 

因为添加了system控制etcd所以这里需要用systemctl  daemon-reload加载一下文件。 

8)查看etcd集群状态

[root@k8s-master ~]# /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.79.148:2379,https://192.168.79.149:2379,https://192.168.79.150:2379" endpoint health --write-out=table
+-----------------------------+--------+-------------+-------+
|          ENDPOINT           | HEALTH |    TOOK     | ERROR |
+-----------------------------+--------+-------------+-------+
| https://192.168.79.148:2379 |   true | 10.984284ms |       |
| https://192.168.79.149:2379 |   true | 11.169278ms |       |
| https://192.168.79.150:2379 |   true | 11.828544ms |       |
+-----------------------------+--------+-------------+-------+

 etcd部署成功!如果出现错误,可以查看/var/log/messages日志进行排错。


四、部署Master节点组件

Master节点组件:kube-apiserver,kube-controller-manager,kube-scheduler

1、下载kubernetes1.20的二进制包

将kubernetes-v1.20.4-server-linux-amd64.tar.gz拷到虚拟机

该包中包含了k8s中所需要的所有需要的组件。

该包在网盘中,链接如下:

链接:https://pan.baidu.com/s/1utWPPj-CJ08Tbx0AgKyMNA?pwd=xiji 
提取码:xiji 

[root@k8s-master k8s]# cd
[root@k8s-master ~]# rz

[root@k8s-master ~]# ls
anaconda-ks.cfg  cfssl_1.6.4_linux_amd64           cfssljson_1.6.4_linux_amd64  etcd-v3.4.9-linux-amd64.tar.gz                opt
ca               cfssl-certinfo_1.6.4_linux_amd64  etcd-v3.4.9-linux-amd64      kubernetes-v1.20.4-server-linux-amd64.tar.gz

还是一样,我先回到家目录然后把包拷到家目录中。

1)创建k8s的部署工作目录

[root@k8s-master ~]# mkdir /opt/kubernetes/{bin,cfg,ssl} -p
[root@k8s-master ~]# tree /opt/kubernetes/
/opt/kubernetes/
├── bin
├── cfg
└── ssl

3 directories, 0 files

2)拷贝需要的组件 

解压kubernetes包并将kubernetes/server/bin目录下中master需要的组件执行文件拷到工作目录下的bin文件夹下。

[root@k8s-master ~]# tar xfz kubernetes-v1.20.4-server-linux-amd64.tar.gz

[root@k8s-master ~]# cp kubernetes/server/bin/{kube-apiserver,kube-scheduler,kube-controller-manager} /opt/kubernetes/bin/
[root@k8s-master ~]# tree /opt/kubernetes/
/opt/kubernetes/
├── bin
│   ├── kube-apiserver
│   ├── kube-controller-manager
│   └── kube-scheduler
├── cfg
└── ssl

3 directories, 3 files

3)拷贝kubectl工具 

 将kubectl拷贝到/usr/bin目录下,kubectl是Kubernetes的命令行工具,可以用来管理Kubernetes集群。

[root@k8s-master ~]# cp kubernetes/server/bin/kubectl  /usr/bin/

2、部署kube-apiserver

作为Kubernetes系统的入口,其封装了核心对象的增删改查操作,以RESTful API接口方式提供给外部客户和内部组件调用。维护的REST对象持久化到Etcd中存储。

1)生成kube-apiserver证书

首先创建证书工作目录

[root@k8s-master ~]# mkdir ca/k8s -p
[root@k8s-master ~]# cd ca/k8s

自签证书颁发机构(CA)

[root@k8s-master k8s]# vim ca-config.json
[root@k8s-master k8s]# cat ca-config.json 
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}


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

生成证书

[root@k8s-master k8s]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

[root@k8s-master k8s]# ls 
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem

多出ca-csr.pem和ca-key.pem两个文件。

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

[root@k8s-master k8s]# vim server-csr.json
[root@k8s-master k8s]# cat server-csr.json
{
    "CN": "kubernetes",
    "hosts": [
      "10.0.0.1",
      "127.0.0.1",
      "192.168.79.148",    #master的ip    
      "192.168.79.149",    #node的ip
      "192.168.79.150",    #node2的ip
      "192.168.79.151",    #预留ip
      "192.168.79.133",    #预留ip
      "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"
        }
    ]
}

生成证书

#生成证书
[root@k8s-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@k8s-master k8s]# ls
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem  server.csr  server-csr.json  server-key.pem  server.pem

将生成的证书都拷贝到/opt/kubernetes/ssl文件夹,一共是四个pem文件。

[root@k8s-master ~]# cp ca/k8s/*pem /opt/kubernetes/ssl/
[root@k8s-master ~]# tree /opt/kubernetes/
/opt/kubernetes/
├── bin
│   ├── kube-apiserver
│   ├── kube-controller-manager
│   └── kube-scheduler
├── cfg
└── ssl
    ├── ca-key.pem
    ├── ca.pem
    ├── server-key.pem
    └── server.pem

3 directories, 7 files

多出两个serber-csr和server-key.pem文件。

2)kube-apiserver配置文件

--etcd-servers=要改为自己的集群ip

--bind-address=改为自己master的ip

--advertise-address=自己的master的ip

--service-cluster-ip-range=10.0.0.0/24虚拟网关不要改

[root@k8s-master ~]# vim /opt/kubernetes/cfg/kube-apiserver.conf
[root@k8s-master ~]# cat /opt/kubernetes/cfg/kube-apiserver.conf
KUBE_APISERVER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--etcd-servers=https://192.168.79.148:2379,https://192.168.79.149:2379,https://192.168.79.150:2379 \
--bind-address=192.168.79.148 \
--secure-port=6443 \
--advertise-address=192.168.79.148 \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/24 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--enable-bootstrap-token-auth=true \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--service-node-port-range=30000-32767 \
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \
--tls-cert-file=/opt/kubernetes/ssl/server.pem  \
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-issuer=api \
--service-account-signing-key-file=/opt/kubernetes/ssl/server-key.pem \
--etcd-cafile=/opt/etcd/ssl/ca.pem \
--etcd-certfile=/opt/etcd/ssl/server.pem \
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \
--requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \
--proxy-client-cert-file=/opt/kubernetes/ssl/server.pem \
--proxy-client-key-file=/opt/kubernetes/ssl/server-key.pem \
--requestheader-allowed-names=kubernetes \
--requestheader-extra-headers-prefix=X-Remote-Extra- \
--requestheader-group-headers=X-Remote-Group \
--requestheader-username-headers=X-Remote-User \
--enable-aggregator-routing=true \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"

参考说明

•      --logtostderr:启用日志

•      ---v:日志等级

•      --log-dir:日志目录

•      --etcd-servers:etcd集群地址                #k8s集群的所有阶段的ip

•      --bind-address:监听地址                        #master的ip地址

•      --secure-port:https安全端口

•      --advertise-address:集群通告地址                #master的ip地址

•      --allow-privileged:启用授权

•      --service-cluster-ip-range:Service虚拟IP地址段        #10.0.0.0/24这里不用改

•      --enable-admission-plugins:准入控制模块

•      --authorization-mode:认证授权,启用RBAC授权和节点自管理

•      --enable-bootstrap-token-auth:启用TLS bootstrap机制

•      --token-auth-file:bootstrap token文件

•      --service-node-port-range:Service nodeport类型默认分配端口范围

•      --kubelet-client-xxx:apiserver访问kubelet客户端证书

•      --tls-xxx-file:apiserver https证书

•      1.20版本必须加的参数:--service-account-issuer,--service-account-signing-key-file

•      --etcd-xxxfile:连接Etcd集群证书

•      --audit-log-xxx:审计日志

•      启动聚合层相关配置:--requestheader-client-ca-file,--proxy-client-cert-file,--proxy-client-key-file,--requestheader-allowed-names,--requestheader-extra-headers-prefix,--requestheader-group-headers,--requestheader-username-headers,--enable-aggregator-routing

3)配置token文件

Master apiserver启用TLS认证后,Node节点kubelet组件想要加入集群,必须使用CA签发的有效证书才能与apiserver通信,当Node节点很多时,签署证书是一件很繁琐的事情,因此有了TLS Bootstrapping机制,kubelet会以一个低权限用户自动向apiserver申请证书,kubelet的证书由apiserver动态签署。
认证大致工作流程如图所示:

#生成一个32位的随机码
[root@k8s-master ~]# head -c 16 /dev/urandom | od -An -t x | tr -d ' '
c47ffb939f5ca36231d9e3121a252940

[root@k8s-master ~]# vim /opt/kubernetes/cfg/token.csv
[root@k8s-master ~]# cat /opt/kubernetes/cfg/token.csv 
c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:node-bootstrapper"

这里的token可以自己自定义,需要和后续的配置保持一致,否则后面部署kubelet将会认证错误。 

4)systemd管理apiserver

[root@k8s-master ~]# vim /usr/lib/systemd/system/kube-apiserver.service
[root@k8s-master ~]# cat /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target

5)加载system配置并启动apiserver设置开机自启

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

 查看api-server的服务状态是running。

3、部署kube-controller-manager

负责执行各种控制器,目前已经提供了很多控制器来保证Kubernetes的正常运行。

1)编写配置文件

[root@k8s-master ~]# vim /opt/kubernetes/cfg/kube-controller-manager.conf
[root@k8s-master ~]# cat /opt/kubernetes/cfg/kube-controller-manager.conf
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--leader-elect=true \
--kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig \
--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=/opt/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem  \
--root-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \
--experimental-cluster-signing-duration=87600h0m0s"    #签证到期时间为10年

参数说明

•      --kubeconfig:连接apiserver配置文件

•      --leader-elect:当该组件启动多个时,自动选举(HA)

•      --cluster-signing-cert-file/--cluster-signing-key-file:自动为kubelet颁发证书的CA,与apiserver保持一致

2)生成kube-controller-manager证书

到 ca/k8s目录下。

#到k8s目录
[root@k8s-master ~]# cd ca/k8s

#编写生成证书的json文件
[root@k8s-master k8s]# vim kube-controller-manager-csr.json
[root@k8s-master k8s]# cat kube-controller-manager-csr.json
{
  "CN": "system:kube-controller-manager",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}

生成证书

#生成证书
[root@k8s-master k8s]# cfssl gencert -ca=/root/ca/k8s/ca.pem -ca-key=/root/ca/k8s/ca-key.pem -config=/root/ca/k8s/ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

#查看证书生成情况
[root@k8s-master k8s]# ls kube-controller-manager*
kube-controller-manager.csr  kube-controller-manager-csr.json  kube-controller-manager-key.pem  kube-controller-manager.pem

发现多出kube-controller-manager-key.pem、kube-controller-manager.pem两个文件

将生成的证书拷贝到kubernetes/ssl文件夹内。

[root@k8s-master k8s]# cp kube-controller-manager*pem /opt/kubernetes/ssl/
[root@k8s-master k8s]# tree /opt/kubernetes/
/opt/kubernetes/
├── bin
│   ├── kube-apiserver
│   ├── kube-controller-manager
│   └── kube-scheduler
├── cfg
│   ├── kube-apiserver.conf
│   ├── kube-controller-manager.conf
│   └── token.csv
└── ssl
    ├── ca-key.pem
    ├── ca.pem
    ├── kube-controller-manager-key.pem
    ├── kube-controller-manager.pem
    ├── server-key.pem
    └── server.pem

3 directories, 12 files

3)生成manager的kubeconfig文件

因为在生成该文件的时候会用到刚刚生成的证书,为了方便建议进入到存有manager证书的目录操作

[root@k8s-master k8s]# KUBE_CONFIG="/opt/kubernetes/cfg/kube-controller-manager.kubeconfig"    #生成kubeconfig文件的存放位置
[root@k8s-master k8s]# KUBE_APISERVER="https://192.168.79.148:6443"   #master的ip

执行以下四句命令。 

#设置集群参数
[root@k8s-master k8s]# kubectl config set-cluster kubernetes \
>   --certificate-authority=/opt/kubernetes/ssl/ca.pem \
>   --embed-certs=true \
>   --server=${KUBE_APISERVER} \
>   --kubeconfig=${KUBE_CONFIG}

#设置客户端认证参数
[root@k8s-master k8s]# kubectl config set-credentials kube-controller-manager   --client-certificate=./kube-controller-manager.pem   --client-key=/opt/kubernetes/ssl/kube-controller-manager-key.pem   --embed-certs=true   --kubeconfig=${KUBE_CONFIG}

#设置上下文参数
[root@k8s-master k8s]# kubectl config set-context default \
>   --cluster=kubernetes \
>   --user=kube-controller-manager \
>   --kubeconfig=${KUBE_CONFIG}
Context "default" created.

#设置默认上下文
[root@k8s-master k8s]# kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

 查看kubeconfig生成情况。

[root@k8s-master k8s]# tree /opt/kubernetes/
/opt/kubernetes/
├── bin
│   ├── kube-apiserver
│   ├── kube-controller-manager
│   └── kube-scheduler
├── cfg
│   ├── kube-apiserver.conf
│   ├── kube-controller-manager.conf
│   ├── kube-controller-manager.kubeconfig
│   └── token.csv
└── ssl
    ├── ca-key.pem
    ├── ca.pem
    ├── kube-controller-manager-key.pem
    ├── kube-controller-manager.pem
    ├── server-key.pem
    └── server.pem

3 directories, 13 files

在cfg,刚刚指定的位置生成了 kube-controller-manager.kubeconfig文件。

4)systemd管理controller-manager

[root@k8s-master k8s]# vim /usr/lib/systemd/system/kube-controller-manager.service
[root@k8s-master k8s]# cat /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/opt/kubernetes/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target

5)加载service并启动controller-manager,设置开机自启

[root@k8s-master k8s]# systemctl daemon-reload 
[root@k8s-master k8s]# systemctl start kube-controller-manager.service 
[root@k8s-master k8s]# systemctl enable kube-controller-manager.service

 启动成功!

 4、部署kube-scheduler

为新建立的Pod进行节点(node)选择(即分配机器),负责集群的资源调度。组件抽离,可以方便替换成其他调度器。

1)创建配置文件

[root@k8s-master k8s]# vim /opt/kubernetes/cfg/kube-scheduler.conf
[root@k8s-master k8s]# cat /opt/kubernetes/cfg/kube-scheduler.conf
KUBE_SCHEDULER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--leader-elect \
--kubeconfig=/opt/kubernetes/cfg/kube-scheduler.kubeconfig \
--bind-address=127.0.0.1"

参数说明

•      --kubeconfig:连接apiserver配置文件

•      --leader-elect:当该组件启动多个时,自动选举(HA)

2)生成kube-scheduler证书

[root@k8s-master k8s]# vim kube-scheduler-csr.json
[root@k8s-master k8s]# cat kube-scheduler-csr.json
{
  "CN": "system:kube-scheduler",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}

生成证书

#生成证书
[root@k8s-master k8s]# cfssl gencert -ca=/root/ca/k8s/ca.pem -ca-key=/root/ca/k8s/ca-key.pem -config=/root/ca/k8s/ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler

#查看证书生成情况
[root@k8s-master k8s]# ls kube-scheduler*
kube-scheduler.csr  kube-scheduler-csr.json  kube-scheduler-key.pem  kube-scheduler.pem

将证书拷贝到kubernetes/ssl文件夹。 

[root@k8s-master k8s]# cp kube-scheduler-key*pem /opt/kubernetes/ssl/

该文件夹下多出 kube-scheduler-key.pem 、kube-scheduler.pem两个文件。

3)生成schedule的kubeconfig文件

#指定生成kubeconfig的路径
[root@k8s-master k8s]# KUBE_CONFIG="/opt/kubernetes/cfg/kube-scheduler.kubeconfig"
#master的ip
[root@k8s-master k8s]# KUBE_APISERVER="https://192.168.79.148:6443"

执行以下四个命令 。

#设置集群参数
[root@k8s-master k8s]# kubectl config set-cluster kubernetes \
>   --certificate-authority=/opt/kubernetes/ssl/ca.pem \
>   --embed-certs=true \
>   --server=${KUBE_APISERVER} \
>   --kubeconfig=${KUBE_CONFIG}

#设置客户端认证参数
[root@k8s-master k8s-scheduler]# kubectl config set-credentials kube-scheduler \
>   --client-certificate=./kube-scheduler.pem \
>   --client-key=./kube-scheduler-key.pem \
>   --embed-certs=true \
>   --kubeconfig=${KUBE_CONFIG}

#设置上下文参数
[root@k8s-master k8s]# kubectl config set-context default \
>   --cluster=kubernetes \
>   --user=kube-scheduler \
>   --kubeconfig=${KUBE_CONFIG}

#设置默认上下文
[root@k8s-master k8s]# kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

查看kubeconfig生成情况。

[root@k8s-master k8s]# tree /opt/kubernetes/
/opt/kubernetes/
├── bin
│   ├── kube-apiserver
│   ├── kube-controller-manager
│   └── kube-scheduler
├── cfg
│   ├── kube-apiserver.conf
│   ├── kube-controller-manager.conf
│   ├── kube-controller-manager.kubeconfig
│   ├── kube-scheduler.conf
│   ├── kube-scheduler.kubeconfig
│   └── token.csv
└── ssl
    ├── ca-key.pem
    ├── ca.pem
    ├── kube-controller-manager-key.pem
    ├── kube-controller-manager.pem
    ├── kube-scheduler-key.pem
    ├── kube-scheduler.pem
    ├── server-key.pem
    └── server.pem

3 directories, 17 files

发现cfg下多出了kube-scheduler.kubeconfig文件,说明生成成功!

4)systemd管理scheduler

[root@k8s-master k8s]# vim /usr/lib/systemd/system/kube-scheduler.service
[root@k8s-master k8s]# cat /usr/lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf
ExecStart=/opt/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target

5)加载service配置,并启动scheduler,设置开机启动

[root@k8s-master k8s]# systemctl daemon-reload 
[root@k8s-master k8s]# systemctl start kube-scheduler.service
[root@k8s-master k8s]# systemctl enable kube-scheduler.service 

启动成功!

 5、查看集群状态

需要用到kubuctl工具。

1)生成kubectl连接集群的证书

[root@k8s-master k8s]# vim admin-csr.json
[root@k8s-master k8s]# cat admin-csr.json
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}

生成证书

#生成证书
[root@k8s-master k8s]# cfssl gencert -ca=/root/ca/k8s/ca.pem -ca-key=/root/ca/k8s/ca-key.pem -config=/root/ca/k8s/ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

#查看证书生成情况
[root@k8s-master k8s]# ls admin*
admin.csr  admin-csr.json  admin-key.pem  admin.pem

该文件夹下多出两个pem文件。

2)生成kubeconfig文件

 创建存放config的目录,这里在root下创建一个隐藏的文件夹,因为kubectl是个工具不是服务,就直接在root下创建隐藏的文件夹。

[root@k8s-master k8s]# mkdir /root/.kube

#设置两个变量分别表示生成的config的存放位置,和需要用到的master的ip
[root@k8s-master k8s]# KUBE_CONFIG="/root/.kube/config"
[root@k8s-master k8s]# KUBE_APISERVER="https://192.168.79.148:6443"

执行以下四句命令

#设置集群参数
[root@k8s-master k8s]# kubectl config set-cluster kubernetes \
    --certificate-authority=/opt/kubernetes/ssl/ca.pem \
    --embed-certs=true \
    --server=${KUBE_APISERVER} \
    --kubeconfig=${KUBE_CONFIG}

#设置客户端认证参数
[root@k8s-master k8s]# kubectl config set-credentials cluster-admin \
    --client-certificate=./admin.pem \
    --client-key=./admin-key.pem \
    --embed-certs=true \
    --kubeconfig=${KUBE_CONFIG}

#设置上下文参数
[root@k8s-master k8s]# kubectl config set-context default \
    --cluster=kubernetes \
    --user=cluster-admin \
    --kubeconfig=${KUBE_CONFIG}

#设置默认上下文
[root@k8s-master k8s]# kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

3)kubectl查看集群状态

[root@k8s-master k8s]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE             ERROR
controller-manager   Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   
scheduler            Healthy   ok                  
etcd-1               Healthy   {"health":"true"}   
etcd-2               Healthy   {"health":"true"}

#查看命名空间
[root@k8s-master k8s]# kubectl get ns
NAME              STATUS   AGE
default           Active   66m
kube-node-lease   Active   66m
kube-public       Active   66m
kube-system       Active   66m

集群状态都是healthy表示集群状态正常,如果出错,查看日志进行排错。


五、部署node组件

kubelet,kube-proxy,docker,etcd

注:两台node的操作是一样的。

1、安装docker

1)下载国内阿里云的docker源

[root@k8s-node1 ~]# wget -O /etc/yum.repos.d/docker-ce.repo  

2)安装docker(node节点都要安装)

[root@k8s-node1 ~]# yum install -y docker-ce

#配置加速器,为了加快docker从dockerhub上pull镜像的速度
[root@k8s-node1 ~]# sudo tee /etc/docker/daemon.json <<-'EOF'
  {
    "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
    "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
    "log-opts": {
      "max-size": "100m"
    },
    "storage-driver": "overlay2"
  }
  EOF
[root@k8s-node1 ~]# systemctl daemon-reload
[root@k8s-node1 ~]# systemctl start docker
[root@k8s-node1 ~]# systemctl enable docker

node1 

 node2

 2、创建node组件的工作目录并拷问文件(node都要创建)

#node1
[root@k8s-node1 ~]# mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
[root@k8s-node1 ~]# tree /opt/kubernetes/
/opt/kubernetes/
├── bin
├── cfg
├── logs
└── ssl

#node2
[root@k8s-node2 ~]# mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
[root@k8s-node2 ~]# tree /opt/kubernetes/
/opt/kubernetes/
├── bin
├── cfg
├── logs
└── ssl

master将kubelet和kube-proxy以及k8s需要的ca证书拷贝给node节点

kubelet和kube-proxy都在master的kubernetes包的server/bin目录下。

#传到node1
[root@k8s-master ~]# scp  kubernetes/server/bin/{kubelet,kube-proxy} k8s-node1:/opt/kubernetes/bin/

#传到node2
[root@k8s-master ~]# scp  kubernetes/server/bin/{kubelet,kube-proxy} k8s-node2:/opt/kubernetes/bin/

3、部署kubelet

负责管控容器,Kubelet会从Kubernetes API Server接收Pod的创建请求,启动和停止容器,监控容器运行状态并汇报给Kubernetes API Server。

1)创建配置文件(node都要创建)

#node1
[root@k8s-node1 ~]# vim /opt/kubernetes/cfg/kubelet.conf
KUBELET_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--hostname-override=k8s-node1 \
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \
--config=/opt/kubernetes/cfg/kubelet-config.yml \
--cert-dir=/opt/kubernetes/ssl \
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.0"

#node2
[root@k8s-node2 ~]# vim /opt/kubernetes/cfg/kubelet.conf
KUBELET_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--hostname-override=k8s-node2 \
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \
--config=/opt/kubernetes/cfg/kubelet-config.yml \
--cert-dir=/opt/kubernetes/ssl \
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.0"

注意: --hostname-override=不能一样。其余位置不用改。

参数说明

•      --hostname-override:显示名称,集群中唯一

•      --network-plugin:启用CNI

•      --kubeconfig:空路径,会自动生成,后面用于连接apiserver

•      --bootstrap-kubeconfig:首次启动向apiserver申请证书

•      --config:配置参数文件

•      --cert-dir:kubelet证书生成目录

•      --pod-infra-container-image:管理Pod网络容器的镜像

registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.0"这个镜像最好提前pull下来。

2)拉取镜像

#node1
[root@k8s-node1 ~]# docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.0

#node2
[root@k8s-node2 ~]# docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.0

3)配置参数文件(node都要配置)

[root@k8s-node1 ~]# vim /opt/kubernetes/cfg/kubelet-config.yml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.0.0.2
clusterDomain: cluster.local
failSwapOn: false
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 2m0s
    enabled: true
  x509:
    clientCAFile: /opt/kubernetes/ssl/ca.pem
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110

node1和node2这里的内容是一致的,所以可以只用使用scp拷到node2的 /opt/kubernetes/cfg/下

[root@k8s-node1 ~]# scp /opt/kubernetes/cfg/kubelet-config.yml k8s-node2:/opt/kubernetes/cfg/

4)生成kubelet初次加入集群引导kubeconfig文件

这里需要再master节点操作。

在生成kubernetes证书的目录下执行以下命令生成kubeconfig文件

#授权kubelet-bootstrap用户允许请求证书
[root@k8s-master k8s]# kubectl create clusterrolebinding kubelet-bootstrap \
  --clusterrole=system:node-bootstrapper \
  --user=kubelet-bootstrap

[root@k8s-master ~]# cd ca/k8s
[root@k8s-master k8s]# KUBE_CONFIG="/opt/kubernetes/cfg/bootstrap.kubeconfig"
[root@k8s-master k8s]# KUBE_APISERVER="https://192.168.79.148:6443"

#这里的token要和上面/opt/kubernetes/cfg/token.csv的token要一样
[root@k8s-master k8s]# TOKEN="c47ffb939f5ca36231d9e3121a252940"

执行设置集群参数、设置客户端认证参数、设置上下文参数、设置默认上下文四步。

#设置集群参数
[root@k8s-master k8s]# kubectl config set-cluster kubernetes \
    --certificate-authority=/opt/kubernetes/ssl/ca.pem \
    --embed-certs=true \
    --server=${KUBE_APISERVER} \
    --kubeconfig=${KUBE_CONFIG}

#设置客户端认证参数
[root@k8s-master k8s]# kubectl config set-credentials "kubelet-bootstrap" \
    --token=${TOKEN} \
    --kubeconfig=${KUBE_CONFIG}


#设置上下文参数
[root@k8s-master k8s]# kubectl config set-context default \
    --cluster=kubernetes \
    --user="kubelet-bootstrap" \
    --kubeconfig=${KUBE_CONFIG}

#设置默认上下文
[root@k8s-master k8s]# kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

5)将生成的kubeconfig拷贝到node节点

[root@k8s-master k8s]# scp /opt/kubernetes/cfg/bootstrap.kubeconfig  k8s-node1:/opt/kubernetes/cfg/

6)systemd管理kubelet(node执行)

这一步需要在node节点操作。

[root@k8s-node1 ~]# vim /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
After=docker.service

[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet.conf
ExecStart=/opt/kubernetes/bin/kubelet $KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

这里的配置,所有node都是一样的可以直接scp拷到node2的 /usr/lib/systemd/system/目录下

[root@k8s-node1 ~]# scp /usr/lib/systemd/system/kubelet.service k8s-node2:/usr/lib/systemd/system/

7)启动kubelet,设置开机自启

#node1
[root@k8s-node1 ~]# systemctl daemon-reload 
[root@k8s-node1 ~]# systemctl start kubelet.service
[root@k8s-node1 ~]# systemctl enable kubelet.service

#node2
[root@k8s-node2 ~]# systemctl daemon-reload 
[root@k8s-node2 ~]# systemctl start kubelet.service
[root@k8s-node2 ~]# systemctl enable kubelet.service

node1 

node2 

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

1)查看kubelet证书请求

在master上查看。

[root@k8s-master k8s]# kubectl  get csr
NAME                                                   AGE    SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-o3SeaoanVHssuQi5DVKfXQKhAJ39CROp4QidAE6u24U   2m5s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
node-csr-p6DbmorzFDSsdfCp7OIWfISKjKC60CKOp9dsCe9o63M   2m5s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending

可以看到该申请是pending状态。 

2)批准申请

kubectl  certificate  approve   申请的NAME

[root@k8s-master k8s]# kubectl certificate approve node-csr-o3SeaoanVHssuQi5DVKfXQKhAJ39CROp4QidAE6u24U

[root@k8s-master k8s]# kubectl certificate approve node-csr-node-csr-node-csr-node-csr-p6DbmorzFDSsdfCp7OIWfISKjKC60CKOp9dsCe9o63M


#再次查看发现状态变为了approve
[root@k8s-master k8s]# kubectl  get csr
NAME                                                   AGE     SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-o3SeaoanVHssuQi5DVKfXQKhAJ39CROp4QidAE6u24U   3m44s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued
node-csr-p6DbmorzFDSsdfCp7OIWfISKjKC60CKOp9dsCe9o63M   3m44s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued

3)查看node

[root@k8s-master k8s]# kubectl get node
NAME        STATUS   ROLES    AGE     VERSION
k8s-node1   NotReady    <none>   3h13m   v1.20.4
k8s-node2   NotReady    <none>   3h17m   v1.20.4

由于网络插件还没有部署,节点会没有准备就绪 NotReady 

5、部署kube-proxy

负责为Pod创建代理服务,Kubernetes Proxy会从Kubernetes API  Server获取所有的Service信息,并根据Service的信息创建代理服务,实现Service到Pod的请求路由和转发,从而实现Kubernetes层级的虚拟转发网络。

1)创建证书请求文件(在master节点)

在/root/ca/k8s下创建证书请求文件

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

生成证书

[root@k8s-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@k8s-master k8s]# ls kube-proxy*
kube-proxy.csr  kube-proxy-csr.json  kube-proxy-key.pem  kube-proxy.pem

2)生成kubeconfig文件(master节点)

#定义两个变量
[root@k8s-master k8s]# KUBE_CONFIG="/opt/kubernetes/cfg/kube-proxy.kubeconfig"
[root@k8s-master k8s]# KUBE_APISERVER="https://192.168.79.148:6443"

执行以下四条命令

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

#设置客户端认证参数
kubectl config set-credentials kube-proxy \
  --client-certificate=./kube-proxy.pem \
  --client-key=./kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=${KUBE_CONFIG}

#设置上下文参数
kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-proxy \
  --kubeconfig=${KUBE_CONFIG}

#设置默认上下文
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

3)将 kube-proxy.kubeconfig文件传到node节点的cfg下。

两个node都要传。

#传到node1
[root@k8s-master k8s]# scp /opt/kubernetes/cfg/kube-proxy.kubeconfig  k8s-node1:/opt/kubernetes/cfg/

#传到node2
[root@k8s-master k8s]# scp /opt/kubernetes/cfg/kube-proxy.kubeconfig  k8s-node2:/opt/kubernetes/cfg/

4)创建kube-proxy配置文件(node节点)

两个node一致。

[root@k8s-node1 ~]# vim /opt/kubernetes/cfg/kube-proxy.conf
KUBE_PROXY_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--config=/opt/kubernetes/cfg/kube-proxy-config.yml"

#拷贝到node2上
[root@k8s-node1 ~]# scp /opt/kubernetes/cfg/kube-proxy.conf k8s-node2:/opt/kubernetes/cfg/

5)配置kube-proxy参数文件(node节点)

[root@k8s-node1 ~]# vim /opt/kubernetes/cfg/kube-proxy-config.yml
[root@k8s-node1 ~]# cat /opt/kubernetes/cfg/kube-proxy-config.yml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
metricsBindAddress: 0.0.0.0:10249
clientConnection:
  kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: k8s-node1
clusterCIDR: 10.244.0.0/16

#拷贝到node2上
[root@k8s-node1 ~]# scp  kube-proxy.conf kube-proxy-config.yml kube-proxy.kubeconfig k8s-node2:/opt/kubernetes/cfg/

这里的hostnameOverride要改为自己本机的ip或者名。

修改node2上的 hostnameOverride为k8s-node2。

[root@k8s-node2 ~]# cat /opt/kubernetes/cfg/kube-proxy-config.yml 
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
metricsBindAddress: 0.0.0.0:10249
clientConnection:
  kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: k8s-node2
clusterCIDR: 10.244.0.0/16

6)system管理kube-proxy(node节点)

两个node一致。

[root@k8s-node1 ~]# vim /usr/lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Proxy
After=network.target

[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf
ExecStart=/opt/kubernetes/bin/kube-proxy $KUBE_PROXY_OPTS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

#拷贝到node2
[root@k8s-node1 ~]# scp /usr/lib/systemd/system/kube-proxy.service  k8s-node2:/usr/lib/systemd/system/

7)启动并设置开机启动

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

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

node1 

 node2

6、部署网络插件(Calico)

Calico是一个纯三层的数据中心网络方案,是目前Kubernetes主流的网络方案。

1)拷贝calico.yaml文件到node(master)

链接:https://pan.baidu.com/s/1QhZ3zUrD8OifY5n2FZ0ZZQ?pwd=b22c 
提取码:b22c 

并将该yaml问价拷贝到/opt/kubernetes/cfg/

2)部署Calico(master)

该插件是用yaml以pod的形式部署到node上的所以需要在master上使用kubectl工具。

这个时间可能会久一点几分钟也可能是十几分钟,直到看到status为running即可就代表部署完成。

[root@k8s-master k8s]# cd /opt/kubernetes/cfg/
[root@k8s-master cfg]# kubectl apply -f calico.yaml

#查看pods的创建情况
[root@k8s-master cfg]# kubectl get pods -n kube-system 
NAME                                      READY   STATUS    RESTARTS   AGE
calico-kube-controllers-97769f7c7-vjzdg   1/1     Running   0          99m
calico-node-dx6sr                         0/1     Running   0          8s
calico-node-nm4t2                         1/1     Running   0          99m

在node主机上查看ip可以看到多了一个网卡,这就是calico。

注:calico.yaml用到了DaemonSet控制器,意思是在所有node上都会创建一个该pod,以后新加入的node会自动创建一个calico的pod在主机上。

Logo

开源、云原生的融合云平台

更多推荐