kubernetes v1.12 二进制方式集群部署

版权声明:转载请注明出处,否则自行负责所有后果 https://blog.csdn.net/ljx1528/article/details/85341755

kubernetes v1.12 二进制方式集群部署

0、kubernetes各组件介绍

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

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

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

controller manager: 如果APIServer做的是前台的工作的话,那么controller manager就是负责后台的。每一个资源都对应一个控制器。而control manager就是负责管理这些控制器的,比如我们通过APIServer创建了一个Pod,当这个Pod创建成功后,APIServer的任务就算完成了。

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

Node节点:
每个Node节点主要由三个模板组成:kublet, kube-proxy

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

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

1、部署环境

软件 版本
操作系统 CentOS Linux release 7.4.1708 (Core
Docker 18.03.1-ce
Kubernetes v1.12

2、服务器角色

角色 ip 组件
k8s-master 192.168.1.203 kube-apiserver,kube-controller-manager,kube-scheduler,etcd
k8s_slave 192.168.1.204 kubelet,kube-proxy,docker,flannel,etcd

3、集群环境变量

# TLS Bootstrapping 使用的Token,可以使用命令 head -c 16 /dev/urandom | od -An -t x | tr -d ' ' 生成
BOOTSTRAP_TOKEN="8981b594122ebed7596f1d3b69c78223"

# 建议使用未用的网段来定义服务网段和Pod 网段
# 服务网段(Service CIDR),部署前路由不可达,部署后集群内部使用IP:Port可达
SERVICE_CIDR="10.254.0.0/16"
# Pod 网段(Cluster CIDR),部署前路由不可达,部署后路由可达(flanneld 保证)
CLUSTER_CIDR="172.30.0.0/16"

# 服务端口范围(NodePort Range)
NODE_PORT_RANGE="30000-32766"            #创建pod后分配端口范围

# etcd服务地址列表
ETCD_ENDPOINTS="http://10.0.0.190:2379"   #etcd服务地址

# flanneld 网络配置前缀
FLANNEL_ETCD_PREFIX="/k8s/network"

# kubernetes 服务IP(预先分配,一般为SERVICE_CIDR中的第一个IP)
CLUSTER_KUBERNETES_SVC_IP="10.254.0.1"

# 集群 DNS 服务IP(从SERVICE_CIDR 中预先分配)
CLUSTER_DNS_SVC_IP="10.254.0.2"

# 集群 DNS 域名
CLUSTER_DNS_DOMAIN="cluster.local."

说明:将上面变量保存为: env.sh,然后将脚本拷贝到所有机器的/usr/local/bin目录
第2章 创建CA 证书和密钥
kubernetes 系统各个组件需要使用TLS证书对通信进行加密,这里我们使用CloudFlare的PKI 工具集cfssl 来生成Certificate Authority(CA) 证书和密钥文件, CA 是自签名的证书,用来签名后续创建的其他TLS 证书。
2.1 安装 CFSSL

[root@k8s_master ~]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
[root@k8s_master ~]# chmod +x cfssl_linux-amd64
[root@k8s_master ~]# mv cfssl_linux-amd64 /usr/bin/cfssl

[root@k8s_master ~]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
[root@k8s_master ~]# chmod +x cfssljson_linux-amd64
[root@k8s_master ~]# mv cfssljson_linux-amd64 /usr/bin/cfssljson

[root@k8s_master ~]# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
[root@k8s_master ~]# chmod +x cfssl-certinfo_linux-amd64
[root@k8s_master ~]# mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

[root@k8s_master ~]# export PATH=/usr/k8s/bin:$PATH
[root@k8s_master ~]# mkdir ssl && cd ssl
[root@k8s_master ssl]# cfssl print-defaults config > config.json
[root@k8s_master ssl]# cfssl print-defaults csr > csr.json

说明:为了方便,将/usr/local/bin设置成环境变量,为了重启也有效,可以将上面的export PATH=/usr/local/bin:$PATH添加到/etc/rc.local文件中。
2.2 创建CA
2.2.1 修改上面创建的config.json文件为ca-config.json:

[root@k8s_master ssl]# cat ca-config.json
{
    "signing": {
        "default": {
            "expiry": "8760h"         #证书的有效时间
        },
        "profiles": {
            "kubernetes": {
                "expiry": "8760h",        #证书的有效时间
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}

参数说明:
config.json:可以定义多个profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个profile;
signing: 表示该证书可用于签名其它证书;生成的ca.pem 证书中CA=TRUE;
server auth: 表示client 可以用该CA 对server 提供的证书进行校验;
client auth: 表示server 可以用该CA 对client 提供的证书进行验证。

2.2.2、修改CA 证书签名为ca-csr.json

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


参数说明:
CN: Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名(User Name)。浏览器使用该字段验证网站是否合法。
O: Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组(Group)。

2.2.2.1 生成CA 证书和私钥

[root@k8s_master ssl]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca
2018/09/15 09:08:00 [INFO] generating a new CA key and certificate from CSR
2018/09/15 09:08:00 [INFO] generate received request
2018/09/15 09:08:00 [INFO] received CSR
2018/09/15 09:08:00 [INFO] generating key: rsa-2048
2018/09/15 09:08:00 [INFO] encoded CSR
2018/09/15 09:08:00 [INFO] signed certificate with serial number 388728220321633548679905650114339188496612614157
[root@k8s_master ssl]# ls ca*
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem

2.2.3 分发证书
2.2.3.1 将生成的CA 证书、密钥文件、配置文件拷贝到所有机器的/etc/kubernetes/ssl目录下面

[root@k8s_master ssl]# mkdir -p /etc/kubernetes/ssl
[root@k8s_master ssl]# cp ca* /etc/kubernetes/ssl

第3章 k8s集群部署
3.1 部署etcd服务
3.1.1 定义环境变量

export NODE_NAME=k8s_master  # 当前部署的机器名称(随便定义,只要能区分不同机器即可)
export NODE_IP=192.168.1.203    # 当前部署的机器IP
export NODE_IPS="192.168.1.203" # etcd服务的 IP
# etcd的IP和端口
export ETCD_NODES=k8s_master=http://192.168.1.203
# 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
source /usr/local/bin/env.sh

3.1.2 下载etcd 二进制文件
3.1.2.1 到https://github.com/coreos/etcd/releases页面下载最新版本的二进制文件

[root@k8s_master ~]# wget https://github.com/coreos/etcd/releases/download/v3.2.9/etcd-v3.2.9-linux-amd64.tar.gz
[root@k8s_master ~]# tar xf etcd-v3.2.9-linux-amd64.tar.gz
[root@k8s_master ~]# cp etcd-v3.2.9-linux-amd64/etcd* /usr/bin/
[root@k8s_master ~]# ll /usr/bin/etcd*
-rwxrwxr-x 1 1000 1000 17123360 Oct  6  2017 /usr/bin/etcd
-rwxrwxr-x 1 1000 1000 14640128 Oct  6  2017 /usr/bin/etcdctl

3.1.3 创建etcd 的systemd unit 文件

[root@k8s_master ~]# mkdir -p /var/lib/etcd    # 必须要先创建工作目录
[root@k8s_master ~]# cat > etcd.service <<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=/var/lib/etcd/
ExecStart=/usr/bin/etcd \\
  --name=k8s_master \\
  --initial-advertise-peer-urls=http://192.168.1.203:2380 \\
  --listen-peer-urls=http://192.168.1.203:2380 \\
  --listen-client-urls=http://192.168.1.203:2379,http://127.0.0.1:2379 \\
  --advertise-client-urls=http://192.168.1.203:2379 \\
  --data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

指定etcd的工作目录和数据目录为/var/lib/etcd,需要在启动服务前创建这个目录
3.1.3.1 启动etcd 服务

[root@k8s_master ~]# mv etcd.service /usr/lib/systemd/system/
[root@k8s_master ~]# systemctl start etcd
[root@k8s_master ~]# systemctl daemon-reload
[root@k8s_master ~]# systemctl start etcd
[root@k8s_master ~]# systemctl status etcd
[root@k8s_master ~]# systemctl enable etcd

3.2 配置kubectl 命令行工具
说明:kubectl默认从~/.kube/config配置文件中获取访问kube-apiserver 地址、证书、用户名等信息,需要正确配置该文件才能正常使用kubectl命令。
需要将下载的kubectl 二进制文件和生产的~/.kube/config配置文件拷贝到需要使用kubectl 命令的机器上。
3.2.1 环境变量

[root@k8s_master ~]# source /usr/local/bin/env.sh
[root@k8s_master ~]# export KUBE_APISERVER="https://192.168.1.203:6443"
[root@k8s_master ~]# echo $KUBE_APISERVER
https://192.168.1.203:6443

变量KUBE_APISERVER 指定kubelet 访问的kube-apiserver 的地址,后续被写入~/.kube/config配置文件
3.2.2 下载并复制二进制文件到/usr/bin目录

https://github.com/kubernetes/kubernetes/releases    (k8s各版本下载)
下载二进制包:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.12.md
[root@k8s_master ~]# wget https://dl.k8s.io/v1.12.0/kubernetes-server-linux-amd64.tar.gz
[root@k8s_master ~]# tar xf kubernetes-server-linux-amd64.tar.gz
[root@k8s_master ~]# cp kubernetes/server/bin/kubectl /usr/bin/
[root@k8s_master ~]# ll /usr/bin/kube*
-rwxr-x--- 1 root root 52269537 Sep 15 10:10 /usr/bin/kubectl
-rwxr-x--- 1 root root 55868971 Sep 15 10:10 /usr/bin/kubefed
[root@k8s_master ~]# export PATH=/usr/local/bin:$PATH

3.2.3 创建admin 证书
3.2.3.1 kubectl 与kube-apiserver 的安全端口通信,需要为安全通信提供TLS 证书和密钥。创建admin 证书:

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

说明:
1)后续kube-apiserver使用RBAC 对客户端(如kubelet、kube-proxy、Pod)请求进行授权
2)kube-apiserver 预定义了一些RBAC 使用的RoleBindings,如cluster-admin 将Group system:masters与Role cluster-admin绑定,该Role 授予了调用kube-apiserver所有API 的权限
3)O 指定了该证书的Group 为system:masters,kubectl使用该证书访问kube-apiserver时,由于证书被CA 签名,所以认证通过,同时由于证书用户组为经过预授权的system:masters,所以被授予访问所有API 的劝降
4)hosts 属性值为空列表
3.2.4 生成admin 证书和私钥:

[root@k8s_master ssl]# cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem \
  -ca-key=/etc/kubernetes/ssl/ca-key.pem \
  -config=/etc/kubernetes/ssl/ca-config.json \
  -profile=kubernetes admin-csr.json | cfssljson -bare admin
[root@k8s_master ssl]# ls admin*
admin.csr  admin-csr.json  admin-key.pem  admin.pem
[root@k8s_master ssl]# mv admin*.pem /etc/kubernetes/ssl/

3.2.5 创建kubectl kubeconfig 文件

# 设置集群参数
[root@k8s_master ssl]# kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER}
# 设置客户端认证参数
[root@k8s_master ssl]# kubectl config set-credentials admin \
  --client-certificate=/etc/kubernetes/ssl/admin.pem \
  --embed-certs=true \
  --client-key=/etc/kubernetes/ssl/admin-key.pem 
# 设置上下文参数
[root@k8s_master ssl]# kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=admin
# 设置默认上下文
[root@k8s_master ssl]# kubectl config use-context kubernetes

(1)、admin.pem证书O 字段值为system:masters,kube-apiserver 预定义的 RoleBinding cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 相关 API 的权限
(2)、生成的kubeconfig 被保存到 ~/.kube/config 文件
3.2.5.1 分发kubeconfig 文件
将/.kube/config文件拷贝到运行kubectl命令的机器的/.kube/目录下去。
3.3 部署Flannel 网络
kubernetes 要求集群内各节点能通过Pod 网段互联互通,下面我们来使用Flannel 在所有节点上创建互联互通的Pod 网段的步骤。
3.3.1 环境变量

[root@k8s_master ssl]# export NODE_IP=192.168.1.203  #当前部署节点的ip
[root@k8s_master ssl]# source /usr/local/bin/env.sh    #导入全局环境变量

3.3.2 向etcd 写入集群Pod 网段信息

[root@k8s_master ssl]# etcdctl set /k8s/network/config '{"Network":"'172.30.0.0/16'"}'
{"Network":"172.30.0.0/16"}
[root@k8s-master ~]# etcdctl get /k8s/network/config
{ "Network": "172.30.0.0/16" }

写入的 Pod 网段(172.30.0.0/16) 必须与kube-controller-manager 的 --cluster-cidr 选项值一致;
3.3.3 安装和配置flanneld
3.3.3.1 前往flanneld release页面下载最新版的flanneld 二进制文件

[root@k8s_master ~]# mkdir flannel
[root@k8s_master ~]# wget https://github.com/coreos/flannel/releases/download/v0.9.0/flannel-v0.9.0-linux-amd64.tar.gz
[root@k8s_master ~]# tar -xzvf flannel-v0.9.0-linux-amd64.tar.gz -C flannel
[root@k8s_master ~]# cp flannel/{flanneld,mk-docker-opts.sh} /usr/bin

3.3.3.2 创建flanneld的systemd unit 文件

[root@k8s_master ~]# 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=/usr/bin/flanneld \\
  -etcd-endpoints=${ETCD_ENDPOINTS} \\
  -etcd-prefix=${FLANNEL_ETCD_PREFIX}
ExecStartPost=/usr/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=on-failure

[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF
1)	mk-docker-opts.sh脚本将分配给flanneld 的Pod 子网网段信息写入到/run/flannel/docker 文件中,后续docker 启动时使用这个文件中的参数值为 docker0 网桥
2)	flanneld 使用系统缺省路由所在的接口和其他节点通信,对于有多个网络接口的机器(内网和公网),可以用 --iface 选项值指定通信接口(上面的 systemd unit 文件没指定这个选项)

3.3.3.4 启动flanneld

[root@k8s_master ~]# mv flanneld.service /usr/lib/systemd/system/
[root@k8s_master ~]# systemctl daemon-reload
[root@k8s_master ~]# systemctl start flannel
[root@k8s_master ~]# systemctl status flanneld
[root@k8s_master ~]# systemctl enable flanneld

3.4 部署master 节点
3.4.1 kubernetes master 节点包含的组件有:

1.	kube-apiserver
2.	kube-scheduler
3.	kube-controller-manager

说明:目前这3个组件需要部署到同一台机器上:

(1)、kube-scheduler、kube-controller-manager 和 kube-apiserver 三者的功能紧密相关;
(2)、同时只能有一个 kube-scheduler、kube-controller-manager 进程处于工作状态,如果运行多个,则需要通过选举产生一个 leader;
(3)、master 节点与node 节点上的Pods 通过Pod 网络通信,所以需要在master 节点上部署Flannel 网络。
3.4.2 环境变量

[root@k8s_master ~]# export MASTER_IP=192.168.1.203  #当前部署master节点ip
[root@k8s_master ~]# source /usr/local/bin/env.sh

3.4.3 下载最新版本的二进制文件

https://github.com/kubernetes/kubernetes/releases     #k8s版本下载连接
[root@k8s_master ~]#  wget https://dl.k8s.io/v1.12.0/kubernetes-server-linux-amd64.tar.gz
[root@k8s_master ~]#  tar -xzvf kubernetes-server-linux-amd64.tar.gz
[root@k8s_master ~]#  cd kubernetes

3.4.3.1 将二进制文件拷贝到/usr/bin目录

[root@k8s_master ~]# cp -r server/bin/{kube-apiserver,kube-controller-manager,kube-scheduler,kube-proxy,kubelet} /usr/bin/

3.4.4 创建kubernetes 证书
3.4.4.1 创建kubernetes 证书签名请求:

[root@k8s_master ~]# cat > kubernetes-csr.json <<EOF
{
  "CN": "kubernetes",
  "hosts": [
    "127.0.0.1",
    "${MASTER_IP}",
    "${CLUSTER_KUBERNETES_SVC_IP}",
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster",
    "kubernetes.default.svc.cluster.local"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF

 如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表,所以上面分别指定了当前部署的 master 节点主机 IP 以及apiserver 负载的内部域名
 还需要添加 kube-apiserver 注册的名为 kubernetes 的服务 IP (Service Cluster IP),一般是 kube-apiserver --service-cluster-ip-range 选项值指定的网段的第一个IP,如 “10.254.0.1”
3.4.4.2 生成kubernetes 证书和私钥:

[root@k8s_master ssl]# cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem \
  -ca-key=/etc/kubernetes/ssl/ca-key.pem \
  -config=/etc/kubernetes/ssl/ca-config.json \
  -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
[root@k8s_master ssl]# ls kubernetes*
kubernetes.csr  kubernetes-csr.json  kubernetes-key.pem  kubernetes.pem
[root@k8s_master ssl]# mv kubernetes*.pem /etc/kubernetes/ssl/

3.4.5 配置和启动kube-apiserver
3.4.5.1 创建kube-apiserver 使用的客户端token 文件
kubelet 首次启动时向kube-apiserver 发送TLS Bootstrapping 请求,kube-apiserver 验证请求中的token 是否与它配置的token.csv 一致,如果一致则自动为kubelet 生成证书和密钥。

#导入的env.sh文件定义了BOOTSTRAP_TOKEN变量
[root@k8s_master ssl]# cat > token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
[root@k8s_master ssl]# mv token.csv /etc/kubernetes/

3.4.5.1 创建apiserver配置文件:

# cat /etc/kubernetes/cfg/kube-apiserver 

KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=http://192.168.1.203:2379 \
--bind-address=0.0.0.0 \
--secure-port=6443 \
--advertise-address=192.168.1.203 \
--allow-privileged=true \
--service-cluster-ip-range=10.254.0.0/16 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction \
--insecure-bind-address=192.168.1.203 \
--authorization-mode=RBAC,Node \
--enable-bootstrap-token-auth \
--token-auth-file=/etc/kubernetes/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/etc/kubernetes/ssl/kubernetes.pem  \
--tls-private-key-file=/etc/kubernetes/ssl/kubernetes-key.pem \
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/etc/kubernetes/ssl/ca.pem \
--etcd-certfile=/etc/kubernetes/ssl/kubernetes.pem \
--etcd-keyfile=/etc/kubernetes/ssl/kubernetes-key.pem"

配置好前面生成的证书,确保能连接etcd。
参数说明:

–logtostderr 启用日志
—v 日志等级
–etcd-servers etcd集群地址
–bind-address 监听地址
–secure-port https安全端口
–advertise-address 集群通告地址
–allow-privileged 启用授权
–service-cluster-ip-range Service虚拟IP地址段
–enable-admission-plugins 准入控制模块
–authorization-mode 认证授权,启用RBAC授权和节点自管理
–enable-bootstrap-token-auth 启用TLS bootstrap功能,后面会讲到
–token-auth-file token文件
–service-node-port-range Service Node类型默认分配端口范围
3.4.5.2 systemd管理apiserver:

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

[Service]
EnvironmentFile=-/etc/kubernetes/cfg/kube-apiserver
ExecStart=/usr/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target

3.4.5.3 启动:

# systemctl daemon-reload
# systemctl enable kube-apiserver
# systemctl restart kube-apiserver

3.4.6 配置和启动kube-scheduler
3.4.6.1 创建schduler配置文件:

[root@k8s_master cfg]# pwd
/etc/kubernetes/cfg
[root@k8s_master cfg]# cat kube-scheduler 
KUBE_SCHEDULER_OPTS="--logtostderr=true \
--v=4 \
--master=192.168.1.203:8080 \
--leader-elect"

参数说明:

–master 连接本地apiserver
–leader-elect 当该组件启动多个时,自动选举(HA)

3.4.6.2 systemd管理schduler组件:

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

[Service]
EnvironmentFile=-/etc/kubernetes/cfg/kube-scheduler
ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target

3.4.6.3 启动:

# systemctl daemon-reload
# systemctl enable kube-apiserver
# systemctl restart kube-apiserver

3.4.7 配置和启动kube-controller-manager
3.4.7.1 创建controller-manager配置文件

[root@k8s_master cfg]# cat /etc/kubernetes/cfg/kube-controller-manager 
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=true \
--v=4 \
--master=192.168.1.203:8080 \
--leader-elect=true \
--address=127.0.0.1 \
--service-cluster-ip-range=10.254.0.0/16 \
--cluster-name=kubernetes \
--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"

3.4.7.2 systemd管理controller-manager组件

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

[Service]
EnvironmentFile=-/etc/kubernetes/cfg/kube-controller-manager
ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target

3.4.7.3 启动:

# systemctl daemon-reload
# systemctl enable kube-controller-manager
# systemctl restart kube-controller-manager

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

[root@k8s_master ~]# kubectl get cs
NAME                 STATUS    MESSAGE              ERROR
scheduler            Healthy   ok                   
controller-manager   Healthy   ok                   
etcd-0               Healthy   {"health": "true"} 

3.5 部署Node 节点

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

3.5.1 kubernetes Node 节点包含如下组件:
 flanneld
 docker
 kubelet
 kube-proxy
3.5.2 环境变量

[root@k8s_slave ~]# source /usr/local/bin/env.sh
[root@k8s_slave ~]# export KUBE_APISERVER="https://192.168.1.203:6443"
[root@k8s_slave ~]# echo $KUBE_APISERVER
https://192.168.1.203:6443
[root@k8s_slave ~]# export NODE_IP=192.168.1.204  #当前部署节点的ip

3.5.3 部署flanneld网络

[root@k8s_slave ~]# mkdir flannel
[root@k8s_slave ~]# wget https://github.com/coreos/flannel/releases/download/v0.9.0/flannel-v0.9.0-linux-amd64.tar.gz
[root@k8s_slave ~]# tar -xzvf flannel-v0.9.0-linux-amd64.tar.gz -C flannel
[root@k8s_slave ~]# cp flannel/{flanneld,mk-docker-opts.sh} /usr/bin

3.5.3.1 创建flanneld的systemd unit 文件

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=/usr/bin/flanneld \\
  -etcd-endpoints=${ETCD_ENDPOINTS} \\
  -etcd-prefix=${FLANNEL_ETCD_PREFIX}
ExecStartPost=/usr/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=on-failure

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

3.5.3.2 启动flanneld服务

cp flanneld.service /usr/lib/systemd/system/
systemctl daemon-reload
systemctl enable flanneld
systemctl start flanneld
systemctl status flanneld

3.5.4 部署docker
3.5.4.1 下载最新的 docker 二进制文件

[root@k8s_slave ~]# https://download.docker.com/linux/static/stable/x86_64/docker-18.03.1-ce.tgz
[root@k8s_slave ~]# tar -xvf docker-18.03.1-ce.tgz
[root@k8s_slave ~]# cp docker/docker* /usr/bin

3.5.4.2 创建 docker 的 systemd unit 文件

[root@k8s_slave ~]# cat docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.io

[Service]
EnvironmentFile=-/run/flannel/docker
ExecStart=/usr/bin/dockerd --log-level=error $DOCKER_NETWORK_OPTIONS
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Delegate=yes
KillMode=process

[Install]
WantedBy=multi-user.target

3.5.4.3 启动docker

[root@k8s_slave ~]# mv docker.service /usr/lib/systemd/system/
[root@k8s_slave ~]# systemctl daemon-reload
[root@k8s_slave ~]# systemctl start docker
[root@k8s_slave ~]# systemctl status docker
[root@k8s_slave ~]# systemctl enable docker

 docker 从 1.13 版本开始,可能将 iptables FORWARD chain的默认策略设置为DROP,从而导致 ping 其它 Node 上的 Pod IP 失败,遇到这种情况时,需要手动设置策略为 ACCEPT:

[root@k8s_slave ~]# iptables -P FORWARD ACCEPT

 并且把以下命令写入/etc/rc.local文件中,防止节点重启iptables FORWARD chain的默认策略又还原为DROP

[root@k8s_slave ~]# sleep 60 && /sbin/iptables -P FORWARD ACCEPT

3.5.5 安装和配置kubelet
3.5.5.1 从master上面拷贝证书文件到slave

[root@k8s_master ~]# cd /etc/kubernetes/
[root@k8s_master kubernetes]# scp -r ./* 192.168.1.204:/etc/kubernetes/

 kubelet 启动时向kube-apiserver 发送TLS bootstrapping 请求,需要先将bootstrap token 文件中的kubelet-bootstrap 用户赋予system:node-bootstrapper 角色,然后kubelet 才有权限创建认证请求(certificatesigningrequests):

[root@k8s_slave kubernetes]# kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
clusterrolebinding "kubelet-bootstrap" created

说明:–user=kubelet-bootstrap 是文件 /etc/kubernetes/token.csv 中指定的用户名,同时也写入了文件 /etc/kubernetes/bootstrap.kubeconfig
 另外1.8 版本中还需要为Node 请求创建一个RBAC 授权规则:

[root@k8s_slave kubernetes]# kubectl create clusterrolebinding kubelet-nodes --clusterrole=system:node --group=system:nodes
clusterrolebinding "kubelet-nodes" created

3.5.5.2 下载最新的kubelet 和kube-proxy 二进制文件(前面下载kubernetes 目录下面其实也有)

[root@k8s_slave ~]# wget https://dl.k8s.io/v1.12.0/kubernetes-server-linux-amd64.tar.gz
[root@k8s_slave ~]# tar -xzvf kubernetes-server-linux-amd64.tar.gz
[root@k8s_slave ~]# cd kubernetes
[root@k8s_slave ~]# tar -xzvf  kubernetes-src.tar.gz
[root@k8s_slave ~]# cp -r ./server/bin/{kube-proxy,kubelet} /usr/bin/

3.5.5.3 创建kubelet bootstapping kubeconfig 文件
#以下需要在master上面创建,创建完成后copy到每个node节点即可

[root@k8s_master ~]# mkdir ssl && cd ssl
#设置集群参数
[root@k8s_mster ~]#  kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=bootstrap.kubeconfig
#设置客户端认证参数
[root@k8s_master ~]# kubectl config set-credentials kubelet-bootstrap \
  --token=${BOOTSTRAP_TOKEN} \
  --kubeconfig=bootstrap.kubeconfig
[root@k8s_master ~]# 设置上下文参数
[root@k8s_master ~]# kubectl config set-context default \
  --cluster=kubernetes \
  --user=kubelet-bootstrap \
  --kubeconfig=bootstrap.kubeconfig
#设置默认上下文
[root@k8s_master ~]# kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
[root@k8s_master ~]# cp bootstrap.kubeconfig /etc/kubernetes/
[root@k8s_master ~]# scp bootstrap.kubeconfig 192.168.1.204:/etc/kubernetes/

 --embed-certs 为 true 时表示将 certificate-authority 证书写入到生成的 bootstrap.kubeconfig 文件中;
 设置 kubelet 客户端认证参数时没有指定秘钥和证书,后续由 kube-apiserver 自动生成;
3.5.5.4 创建kubelet配置文件

[root@k8s_slave cfg]# cat /etc/kubernetes/cfg/kubelet
KUBELET_OPTS="--logtostderr=true \
--v=4 \
--hostname-override=192.168.1.204 \
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \
--config=/etc/kubernetes/cfg/kubelet.config \
--cert-dir=/etc/kubernetes/ssl \
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"

参数说明:

–hostname-override 在集群中显示的主机名
–kubeconfig 指定kubeconfig文件位置,会自动生成
–bootstrap-kubeconfig 指定刚才生成的bootstrap.kubeconfig文件
–cert-dir 颁发证书存放位置
–pod-infra-container-image 管理Pod网络的镜像
3.5.5.5 其中/etc/kubernetes/cfg/kubelet.config配置文件如下:

[root@k8s_slave cfg]# cat /etc/kubernetes/cfg/kubelet.config 
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS: ["10.254.0.2"]
clusterDomain: cluster.local
failSwapOn: false
authentication:
  anonymous:
    enabled: True
  webhook:
    enbaled: false

3.5.5.5 systemd管理kubelet组件

[root@k8s_slave cfg]# cat /usr/lib/systemd/system/kubelet.service 
[Unit]
Description=Kubernetes Kubelet
After=docker.service
Requires=docker.service

[Service]
EnvironmentFile=/etc/kubernetes/cfg/kubelet
ExecStart=/usr/bin/kubelet $KUBELET_OPTS
Restart=on-failure
KillMode=process

[Install]
WantedBy=multi-user.target

3.5.5.6 启动

# systemctl daemon-reload
# systemctl enable kubelet
# systemctl restart kubelet

3.5.5.7 在Master审批Node加入集群:

启动后还没加入到集群中,需要手动允许该节点才可以。
在Master节点查看请求签名的Node:

# kubectl get csr
# kubectl certificate approve XXXXID
# kubectl get node

3.5.6 配置kube-proxy(master创建好后copy到slave节点即可)
3.5.6.1 创建kube-proxy 证书签名请求

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

 CN 指定该证书的 User 为 system:kube-proxy
 kube-apiserver 预定义的 RoleBinding system:node-proxier 将User system:kube-proxy 与 Role system:node-proxier绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限
 hosts 属性值为空列表
3.5.6.2 生成kube-proxy 客户端证书和私钥(从master创建后好copy到slave节点)

[root@k8s_master ssl]# cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem \
  -ca-key=/etc/kubernetes/ssl/ca-key.pem \
  -config=/etc/kubernetes/ssl/ca-config.json \
  -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
[root@k8s_master ssl]# ls kube-proxy*
kube-proxy.csr  kube-proxy-csr.json  kube-proxy-key.pem  kube-proxy.pem
[root@k8s_master ssl]# scp kube-proxy* 192.168.1.204:/root/ssl/     #从mastet节点拷贝到slave节点
[root@k8s_slave ssl]# mv kube-proxy*.pem /etc/kubernetes/ssl/

3.5.6.3 创建kube-proxy kubeconfig 文件(从master创建后好copy到slave节点)

#设置集群参数
[root@k8s_master ssl]# kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kube-proxy.kubeconfig
#设置客户端认证参数
[root@k8s_master ssl]# kubectl config set-credentials kube-proxy \
  --client-certificate=/etc/kubernetes/ssl/kube-proxy.pem \
  --client-key=/etc/kubernetes/ssl/kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-proxy.kubeconfig
#设置上下文参数
[root@k8s_master ssl]#kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-proxy \
  --kubeconfig=kube-proxy.kubeconfig
[root@k8s_master ssl]# 设置默认上下文
[root@k8s_master ssl]# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
[root@k8s_master ssl]#mv kube-proxy.kubeconfig /etc/kubernetes/
[root@k8s_master ssl]#scp kube-proxy.kubeconfig 192.168.1.204:/etc/kubernetes/

3.5.6.4 创建kube-proxy配置文件

[root@k8s_slave ~]# cat /etc/kubernetes/cfg/kube-proxy 
KUBE_PROXY_OPTS="--logtostderr=true \
--v=4 \
--hostname-override=192.168.1.204 \
--cluster-cidr=172.30.0.0/16 \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig"

3.5.6.5 systemd管理kube-proxy组件

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

[Service]
EnvironmentFile=-/etc/kubernetes/cfg/kube-proxy
ExecStart=/usr/bin/kube-proxy $KUBE_PROXY_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target

3.5.6.6 启动

# systemctl daemon-reload
# systemctl enable kube-proxy
# systemctl restart kube-proxy

4、查看集群状态

[root@k8s_master ~]# kubectl get cs
NAME                 STATUS    MESSAGE              ERROR
controller-manager   Healthy   ok                   
scheduler            Healthy   ok                   
etcd-0               Healthy   {"health": "true"}   

[root@k8s_master ~]# kubectl get nodes
NAME            STATUS   ROLES    AGE   VERSION
192.168.1.204   Ready    <none>   21h   v1.12.0

5、运行一个测试示例
5.1、创建一个Nginx Web,测试集群是否正常工作

[root@k8s_master ~]# kubectl run nginx --image=nginx --replicas=2
[root@k8s_master ~]# kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort

5.2、查看Pod,Service:

[root@k8s_master ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
nginx-dbddb74b8-796hj       1/1     Running   0          21h
nginx-dbddb74b8-bvxtk       1/1     Running   0          21h

[root@k8s_master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.254.0.1     <none>        443/TCP          23h
nginx        NodePort    10.254.60.19   <none>        88:30960/TCP     21h

5.3、验证是否可用

[root@k8s_master ~]# curl -I 192.168.1.204:30960
HTTP/1.1 200 OK
Server: nginx/1.15.8
Date: Sat, 29 Dec 2018 09:05:57 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 25 Dec 2018 09:56:47 GMT
Connection: keep-alive
ETag: "5c21fedf-264"
Accept-Ranges: bytes
说明:出现以上问题说明正常

扫码拉群一起讨论有关k8s的更多问题
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ljx1528/article/details/85341755