kubernetes v1.12 二进制方式集群部署
kubernetes v1.12 二进制方式集群部署1、部署环境软件版本操作系统CentOS Linux release 7.4.1708 (CoreDocker18.03.1-ceKubernetesv1.122、服务器角色角色ip组件k8s-master192.168.1.203kube-apiserver,kube-...
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://192.168.1.203: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/local/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 <<EOF
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
EOF
参数说明:
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 <<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
参数说明:
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
[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-scheduler
# systemctl restart kube-scheduler
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 ~]# wget 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_master 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_master 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_slave ~]# mkdir -p /etc/kubernetes/
[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系统服务文件
mkdir /var/lib/kubelet #创建kubelet服务目录
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/usr/bin/kubelet \
--address=192.168.233.131 \
--hostname-override=192.168.233.131 \
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0 \
--experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
--cert-dir=/etc/kubernetes/ssl \
--cluster-dns=10.254.0.2 \
--cluster-domain=cluster.local. \
--hairpin-mode hairpin-veth \
--allow-privileged=true \
--fail-swap-on=false \
--logtostderr=true \
--v=2 \
--logtostderr=false \
--log-dir=/etc/kubernetes/log
Restart=on-failure
RestartSec=5
3.5.5.5 启动
# systemctl daemon-reload
# systemctl enable kubelet
# systemctl restart kubelet
3.5.5.6 在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:/etc/kubernetes/ssl/ #从mastet节点拷贝到slave节点
[root@k8s_master ssl]# cp 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]#cp 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系统服务文件
mkdir /var/lib/kube-proxy #创建kube-proxy服务目录
cat /usr/lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/usr/bin/kube-proxy \
--bind-address=192.168.233.131 \
--hostname-override=192.168.233.131 \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \
--masquerade-all \
--logtostderr=true \
--v=2 \
--logtostderr=false \
--log-dir=/etc/kubernetes/log
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
3.5.6.5 启动
# 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
说明:出现以上问题说明正常
更多推荐
所有评论(0)