kubernetes 集群部署(TLS认证)
第1章 部署准备
1.1 组件版本 && 集群环境
1.1.1 组件版本
Kubernetes 1.8.3
Docker 18.03.1-ce
Etcd 3.2.9
Flanneld
TLS 认证通信(所有组件,如etcd、kubernetes master 和node)
RBAC 授权
kubelet TLS Bootstrapping
1
2
3
4
5
6
7
1.1.2 集群环境
[root@k8s_master ~]# uname -a
Linux k8s_master 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
[root@k8s_master ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
两台服务器(一台用作master一台用作slave)
10.0.0.190 k8s_master
10.0.0.191 k8s_slave
1
2
3
4
5
6
7
1.2 集群环境变量
BOOTSTRAP_TOKEN="8981b594122ebed7596f1d3b69c78223"
SERVICE_CIDR="10.254.0.0/16"
CLUSTER_CIDR="172.30.0.0/16"
NODE_PORT_RANGE="30000-32766"
ETCD_ENDPOINTS="http://10.0.0.190:2379"
FLANNEL_ETCD_PREFIX="/kubernetes/network"
CLUSTER_KUBERNETES_SVC_IP="10.254.0.1"
CLUSTER_DNS_SVC_IP="10.254.0.2"
CLUSTER_DNS_DOMAIN="cluster.local."
MASTER_URL="k8s-api.virtual.local"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
说明:将上面变量保存为: env.sh,然后将脚本拷贝到所有机器的/usr/k8s/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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
说明:为了方便,将/usr/k8s/bin设置成环境变量,为了重启也有效,可以将上面的export PATH=/usr/k8s/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 提供的证书进行验证。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
1
2
3
4
5
6
7
8
9
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
1
2
第3章 k8s集群部署
3.1 部署etcd服务
3.1.1 定义环境变量
export NODE_NAME=k8s_master # 当前部署的机器名称(随便定义,只要能区分不同机器即可)
export NODE_IP=10.0.0.190 # 当前部署的机器IP
export NODE_IPS="10.0.0.190" # etcd服务的 IP
export ETCD_NODES=k8s_master=http://10.0.0.190
source /usr/k8s/bin/env.sh
1
2
3
4
5
6
7
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 ~]# mv 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
1
2
3
4
5
6
3.1.3 创建etcd 的systemd unit 文件
[root@k8s_master ~]# mkdir -p /var/lib/etcd # 必须要先创建工作目录
[root@k8s_master ~]# cat > etcd.service <
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://10.0.0.190:2380 \
--listen-peer-urls=http://10.0.0.190:2380 \
--listen-client-urls=http://10.0.0.190:2379,http://127.0.0.1:2379 \
--advertise-client-urls=http://10.0.0.190:2379 \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
指定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
1
2
3
4
5
6
3.2 配置kubectl 命令行工具
说明:kubectl默认从~/.kube/config配置文件中获取访问kube-apiserver 地址、证书、用户名等信息,需要正确配置该文件才能正常使用kubectl命令。
需要将下载的kubectl 二进制文件和生产的~/.kube/config配置文件拷贝到需要使用kubectl 命令的机器上。
3.2.1 环境变量
[root@k8s_master ~]# source /usr/k8s/bin/env.sh
[root@k8s_master ~]# export KUBE_APISERVER="https://10.0.0.190:6443"
[root@k8s_master ~]# echo $KUBE_APISERVER
https://10.0.0.190:6443
1
2
3
4
变量KUBE_APISERVER 指定kubelet 访问的kube-apiserver 的地址,后续被写入~/.kube/config配置文件
3.2.2 下载并复制二进制文件到/usr/bin目录
[root@k8s_master ~]# wget https://dl.k8s.io/v1.8.3/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,kubefed} /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/k8s/bin:$PATH
1
2
3
4
5
6
7
3.2.3 创建admin 证书
3.2.3.1 kubectl 与kube-apiserver 的安全端口通信,需要为安全通信提供TLS 证书和密钥。创建admin 证书签名请求:
[root@k8s_master ~]# cd ssl/
cat > admin-csr.json <
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "System"
}
]
}
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
说明:
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/
1
2
3
4
5
6
7
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 \
--token=${BOOTSTRAP_TOKEN}
[root@k8s_master ssl]# kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin
[root@k8s_master ssl]# kubectl config use-context kubernetes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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=10.0.0.190 #当前部署节点的ip
[root@k8s_master ssl]# source /usr/k8s/bin/env.sh #导入全局环境变量
1
2
3.3.2 向etcd 写入集群Pod 网段信息
[root@k8s_master ssl]# etcdctl set /k8s/network/config '{"Network":"'172.30.0.0/16'", "SubnetLen": 24, "Backend": {"Type": "vxlan"}'
{"Network":"172.30.0.0/16", "SubnetLen": 24, "Backend": {"Type": "vxlan"}
[root@k8s-master ~]# etcdctl get /k8s/network/config
{ "Network": "172.30.0.0/16", "SubnetLen": 24, "Backend": { "Type": "vxlan" } }
1
2
3
4
写入的 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
1
2
3
4
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
EnvironmentFile=/etc/sysconfig/flanneld
EnvironmentFile=-/etc/sysconfig/docker-network
ExecStart=/usr/bin/flanneld-start $FLANNEL_OPTIONS
ExecStartPost=/usr/libexec/flannel/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=on-failure
[Install]
WantedBy=multi-user.target
WantedBy=docker.service
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
3.3.3.3 /etc/sysconfig/flanneld配置文件内容如下:
[root@k8s_master ~]# cat /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://10.0.0.190:2379"
FLANNEL_ETCD_PREFIX="/k8s/network"
#FLANNEL_OPTIONS=""
1
2
3
4
5
6
7
8
9
10
11
12
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
1
2
3
4
5
3.4 部署master 节点
3.4.1 kubernetes master 节点包含的组件有:
[root@k8s_master ~]# export NODE_IP=10.0.0.190 #当前部署master节点ip
[root@k8s_master ~]# source /usr/k8s/bin/env.sh
1
2
3.4.3 下载最新版本的二进制文件
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.8.md#server-binaries
[root@k8s_master ~]# wget https://dl.k8s.io/v1.8.3/kubernetes-server-linux-amd64.tar.gz
[root@k8s_master ~]# tar -xzvf kubernetes-server-linux-amd64.tar.gz
[root@k8s_master ~]# cd kubernetes
1
2
3
4
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/
1
3.4.4 创建kubernetes 证书
3.4.4.1 创建kubernetes 证书签名请求:
[root@k8s_master ~]# cat > kubernetes-csr.json <
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"${NODE_IP}",
"${MASTER_URL}",
"${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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
如果 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/
1
2
3
4
5
6
7
3.4.5 配置和启动kube-apiserver
3.4.5.1 创建kube-apiserver 使用的客户端token 文件
kubelet 首次启动时向kube-apiserver 发送TLS Bootstrapping 请求,kube-apiserver 验证请求中的token 是否与它配置的token.csv 一致,如果一致则自动为kubelet 生成证书和密钥。
[root@k8s_master ssl]# # 导入的 environment.sh 文件定义了 BOOTSTRAP_TOKEN 变量
[root@k8s_master ssl]# cat > token.csv <
EOF
[root@k8s_master ssl]# mv token.csv /etc/kubernetes/
1
2
3
4
5
3.4.5.2 创建kube-apiserver 的systemd unit文件
cat > kube-apiserver.service <
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
ExecStart=/usr/bin/kube-apiserver \
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--advertise-address=10.0.0.190 \
--bind-address=0.0.0.0 \
--insecure-bind-address=10.0.0.190 \
--authorization-mode=Node,RBAC \
--runtime-config=rbac.authorization.k8s.io/v1alpha1 \
--kubelet-https=true \
--experimental-bootstrap-token-auth \
--token-auth-file=/etc/kubernetes/ssl/token.csv \
--service-cluster-ip-range=10.254.0.0/16 \
--service-node-port-range=30000-32766 \
--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-servers=http://10.0.0.190:2379 \
--enable-swagger-ui=true \
--allow-privileged=true \
--apiserver-count=2 \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/lib/audit.log \
--event-ttl=1h \
--logtostderr=true \
--v=6
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
kube-apiserver 1.6 版本开始使用 etcd v3 API 和存储格式
–authorization-mode=RBAC 指定在安全端口使用RBAC 授权模式,拒绝未通过授权的请求
kube-scheduler、kube-controller-manager 一般和 kube-apiserver 部署在同一台机器上,它们使用非安全端口和 kube-apiserver通信
kubelet、kube-proxy、kubectl 部署在其它 Node 节点上,如果通过安全端口访问 kube-apiserver,则必须先通过 TLS 证书认证,再通过 RBAC 授权
kube-proxy、kubectl 通过使用证书里指定相关的 User、Group 来达到通过 RBAC 授权的目的
如果使用了 kubelet TLS Boostrap 机制,则不能再指定 –kubelet-certificate-authority、–kubelet-client-certificate 和 –kubelet-client-key 选项,否则后续 kube-apiserver 校验 kubelet 证书时出现 ”x509: certificate signed by unknown authority“ 错误
–admission-control 值必须包含 ServiceAccount,否则部署集群插件时会失败
–bind-address 不能为 127.0.0.1
–service-cluster-ip-range 指定 Service Cluster IP 地址段,该地址段不能路由可达
–service-node-port-range=${NODE_PORT_RANGE} 指定 NodePort 的端口范围
缺省情况下 kubernetes 对象保存在etcd/registry 路径下,可以通过 –etcd-prefix 参数进行调整
kube-apiserver 1.8版本后需要在–authorization-mode参数中添加Node,即:–authorization-mode=Node,RBAC,否则Node 节点无法注册
3.4.5.3 启动kube-apiserver
[root@k8s_master ~]# mv kube-apiserver.service /usr/lib/systemd/system/kube-apiserver.service
[root@k8s_master ~]# systemctl daemon-reload
[root@k8s_master ~]# systemctl enable kube-apiserver
[root@k8s_master ~]# systemctl start kube-apiserver
[root@k8s_master ~]# systemctl status kube-apiserver
1
2
3
4
5
3.4.6 配置和启动kube-controller-manager
3.4.6.1 创建kube-controller-manager 的systemd unit 文件
[root@k8s_master ~]# cat > kube-controller-manager.service <
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/usr/bin/kube-controller-manager \
--address=127.0.0.1 \
--master=http://10.0.0.190:8080 \
--allocate-node-cidrs=true \
--service-cluster-ip-range=10.254.0.0/16 \
--cluster-cidr=172.30.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 \
--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \
--root-ca-file=/etc/kubernetes/ssl/ca.pem \
--leader-elect=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
–address 值必须为 127.0.0.1,因为当前 kube-apiserver 期望 scheduler 和 controller-manager 在同一台机器
–master=http://${MASTER_URL}:使用http(非安全端口)与 kube-apiserver 通信
–cluster-cidr 指定 Cluster 中 Pod 的 CIDR 范围,该网段在各 Node 间必须路由可达(flanneld保证)
–service-cluster-ip-range 参数指定 Cluster 中 Service 的CIDR范围,该网络在各 Node 间必须路由不可达,必须和 kube-apiserver 中的参数一致
–cluster-signing-* 指定的证书和私钥文件用来签名为 TLS BootStrap 创建的证书和私钥
–root-ca-file 用来对 kube-apiserver 证书进行校验,指定该参数后,才会在Pod 容器的 ServiceAccount 中放置该 CA 证书文件
–leader-elect=true 部署多台机器组成的 master 集群时选举产生一处于工作状态的 kube-controller-manager 进程
3.4.6.2 启动kube-controller-manager
[root@k8s_master ~]# mv kube-controller-manager.service /usr/lib/systemd/system/
[root@k8s_master ~]# systemctl daemon-reload
[root@k8s_master ~]# systemctl start kube-controller-manager
[root@k8s_master ~]# systemctl status kube-controller-manager
[root@k8s_master ~]# systemctl enable kube-controller-manager
1
2
3
4
5
3.4.7 配置和启动kube-scheduler
3.4.7.1 创建kube-scheduler 的systemd unit文件
[root@k8s_master ~]# cat > kube-scheduler.service <
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/usr/bin/kube-scheduler \
--address=127.0.0.1 \
--master=http://10.0.0.190:8080 \
--leader-elect=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
–address 值必须为 127.0.0.1,因为当前 kube-apiserver 期望 scheduler 和 controller-manager 在同一台机器
–master=http://${MASTER_URL}:使用http(非安全端口)与 kube-apiserver 通信
–leader-elect=true 部署多台机器组成的 master 集群时选举产生一处于工作状态的 kube-controller-manager 进程
3.4.7.2 启动kube-scheduler
[root@k8s_master ~]# mv kube-scheduler.service /usr/lib/systemd/system
[root@k8s_master ~]# systemctl daemon-reload
[root@k8s_master ~]# systemctl start kube-scheduler
[root@k8s_master ~]# systemctl status kube-scheduler
[root@k8s_master ~]# systemctl enable kube-scheduler
1
2
3
4
5
3.4.7.3 验证master 节点
[root@k8s_master ~]# kubectl get componentstatuses
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health": "true"}
1
2
3
4
5
3.5 部署Node 节点
3.5.1 kubernetes Node 节点包含如下组件:
flanneld
docker
kubelet
kube-proxy
3.5.2 环境变量
[root@k8s_slave ~]# source /usr/k8s/bin/env.sh
[root@k8s_slave ~]# export KUBE_APISERVER="https://10.0.0.190:6443"
[root@k8s_slave ~]# echo $KUBE_APISERVER
https://10.0.0.190:6443
[root@k8s_slave ~]# export NODE_IP=10.0.0.191 #当前部署节点的ip
1
2
3
4
5
3.5.3 部署flanneld网络
yum -y install flanneld
1
3.5.3.1 配置flanneld配置文件
[root@k8s_slave ~]# cat /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://10.0.0.190:2379"
FLANNEL_ETCD_PREFIX="/k8s/network"
#FLANNEL_OPTIONS=""
1
2
3
4
5
6
7
8
9
10
11
12
3.5.3.2 启动flanneld服务
[root@k8s_slave ~]# systemctl start flannled
1
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
1
2
3
3.5.4.2 创建 docker 的 systemd unit 文件
[root@k8s_slave ~]# cat > docker.service <
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd \
$DOCKER_NETWORK_OPTIONS
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
#TasksMax=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
1
2
3
4
5
docker 从 1.13 版本开始,可能将 iptables FORWARD chain的默认策略设置为DROP,从而导致 ping 其它 Node 上的 Pod IP 失败,遇到这种情况时,需要手动设置策略为 ACCEPT:
[root@k8s_slave ~]# iptables -P FORWARD ACCEPT
1
并且把以下命令写入/etc/rc.local文件中,防止节点重启iptables FORWARD chain的默认策略又还原为DROP
[root@k8s_slave ~]# sleep 60 && /sbin/iptables -P FORWARD ACCEPT
1
为了加快 pull image 的速度,可以使用国内的仓库镜像服务器,同时增加下载的并发数。(如果 dockerd 已经运行,则需要重启 dockerd 生效。)
[root@k8s_slave ~]# cat /etc/docker/daemon.json
{
"max-concurrent-downloads": 10
}
1
2
3
4
3.5.5 安装和配置kubelet
3.5.5.1 从master上面拷贝证书文件到slave
[root@k8s_master kubernetes]# scp -r ./* 10.0.0.191:/etc/kubernetes/
1
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
1
2
说明:–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
1
2
3.5.5.2 下载最新的kubelet 和kube-proxy 二进制文件(前面下载kubernetes 目录下面其实也有):
[root@k8s_slave ~]# wget https://dl.k8s.io/v1.8.2/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/k8s/bin/
1
2
3
4
5
3.5.5.3 创建kubelet bootstapping kubeconfig 文件
[root@k8s_slave ~]# mkdir ssl && cd ssl
[root@k8s_slave ~]# 设置集群参数
[root@k8s_slave ~]# kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
[root@k8s_slave ~]# 设置客户端认证参数
[root@k8s_slave ~]# kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_TOKEN} \
--kubeconfig=bootstrap.kubeconfig
[root@k8s_slave ~]# 设置上下文参数
[root@k8s_slave ~]# kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=bootstrap.kubeconfig
[root@k8s_slave ~]# 设置默认上下文
[root@k8s_slave ~]# kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
[root@k8s_slave ~]# mv bootstrap.kubeconfig /etc/kubernetes/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
–embed-certs 为 true 时表示将 certificate-authority 证书写入到生成的 bootstrap.kubeconfig 文件中;
设置 kubelet 客户端认证参数时没有指定秘钥和证书,后续由 kube-apiserver 自动生成;
3.5.5.4 创建kubelet 的systemd unit 文件
[root@k8s_slave ssl]# mkdir /var/lib/kubelet # 必须先创建工作目录
[root@k8s_slave ]# cat > kubelet.service <
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=10.0.0.191 \
--hostname-override=10.0.0.191 \
--experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
--require-kubeconfig \
--cert-dir=/etc/kubernetes/ssl \
--cluster-dns=10.254.0.2 \
--cluster-domain=cluster.local \
--hairpin-mode promiscuous-bridge \
--allow-privileged=true \
--serialize-image-pulls=false \
--fail-swap-on=false \
--logtostderr=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-address 不能设置为 127.0.0.1,否则后续 Pods 访问 kubelet 的 API 接口时会失败,因为 Pods 访问的 127.0.0.1指向自己而不是 kubelet
如果设置了 –hostname-override 选项,则 kube-proxy 也需要设置该选项,否则会出现找不到 Node 的情况
–experimental-bootstrap-kubeconfig 指向 bootstrap kubeconfig 文件,kubelet 使用该文件中的用户名和 token 向 kube-apiserver 发送 TLS Bootstrapping 请求
管理员通过了 CSR 请求后,kubelet 自动在 –cert-dir 目录创建证书和私钥文件(kubelet-client.crt 和 kubelet-client.key),然后写入 –kubeconfig 文件(自动创建 –kubeconfig 指定的文件)
建议在 –kubeconfig 配置文件中指定 kube-apiserver 地址,如果未指定 –api-servers 选项,则必须指定 –require-kubeconfig 选项后才从配置文件中读取 kue-apiserver 的地址,否则 kubelet 启动后将找不到 kube-apiserver (日志中提示未找到 API Server),kubectl get nodes 不会返回对应的 Node 信息
–cluster-dns 指定 kubedns 的 Service IP(可以先分配,后续创建 kubedns 服务时指定该 IP),–cluster-domain 指定域名后缀,这两个参数同时指定后才会生效
3.5.5.5 启动kubelet
[root@k8s_slave ~]# mv kubelet.service /usr/lib/systemd/system/
[root@k8s_slave ~]# systemctl daemon-reload
[root@k8s_slave ~]# systemctl start kubelet
[root@k8s_slave ~]# systemctl status kubelet
[root@k8s_slave ~]# systemctl enable kubelet
1
2
3
4
5
3.5.5.6 通过kubelet 的TLS 证书请求
kubelet 首次启动时向kube-apiserver 发送证书签名请求,必须通过后kubernetes 系统才会将该 Node 加入到集群。查看未授权的CSR 请求:
[root@k8s_master ~]# kubectl get csr
NAME AGE REQUESTOR CONDITION
node-csr-VME_P37qMAy5qZaFQXIfbkI-L64nSEbUyyvtxYe7EAQ 1m kubelet-bootstrap Pending
[root@k8s_master ~]# kubectl get nodes
No resources found.
1
2
3
4
5
3.5.5.7 通过CSR 请求:
[root@k8s_master ~]# kubectl certificate approve node-csr-VME_P37qMAy5qZaFQXIfbkI-L64nSEbUyyvtxYe7EAQ
certificatesigningrequest "node-csr-VME_P37qMAy5qZaFQXIfbkI-L64nSEbUyyvtxYe7EAQ" approved
[root@k8s_master kubernetes]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
10.0.0.191 Ready
1
2
3
4
5
3.5.5.8 自动生成了kubelet kubeconfig 文件和公私钥:
[root@k8s_slave kubernetes]# ll /etc/kubernetes/kubelet.kubeconfig
-rw------- 1 root root 2277 Sep 16 03:31 /etc/kubernetes/kubelet.kubeconfig
[root@k8s_slave kubernetes]# ls -l /etc/kubernetes/ssl/kubelet*
-rw-r--r-- 1 root root 1042 Sep 16 03:31 /etc/kubernetes/ssl/kubelet-client.crt
-rw------- 1 root root 227 Sep 16 03:27 /etc/kubernetes/ssl/kubelet-client.key
-rw-r--r-- 1 root root 1107 Sep 16 03:25 /etc/kubernetes/ssl/kubelet.crt
-rw------- 1 root root 1679 Sep 16 03:25 /etc/kubernetes/ssl/kubelet.key
1
2
3
4
5
6
7
3.5.6 配置kube-proxy
3.5.6.1 创建kube-proxy 证书签名请求
[root@k8s_master ~]# cd /root/ssl
[root@k8s_master ssl]# cat > kube-proxy-csr.json <
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 客户端证书和私钥
[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 10.0.0.191:/root/ssl/ #从mastet节点拷贝到slave节点
[root@k8s_slave ssl]# mv kube-proxy*.pem /etc/kubernetes/ssl/
1
2
3
4
5
6
7
8
3.5.6.3 创建kube-proxy kubeconfig 文件
[root@k8s_slave ssl]# 设置集群参数
[root@k8s_slave 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_slave ssl]# 设置客户端认证参数
[root@k8s_slave 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_slave ssl]#设置上下文参数
[root@k8s_slave ssl]#kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
[root@k8s_slave ssl]# 设置默认上下文
[root@k8s_slave ssl]# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
[root@k8s_slave ssl]#mv kube-proxy.kubeconfig /etc/kubernetes/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
设置集群参数和客户端认证参数时 –embed-certs 都为 true,这会将 certificate-authority、client-certificate 和 client-key 指向的证书文件内容写入到生成的 kube-proxy.kubeconfig 文件中
kube-proxy.pem 证书中 CN 为 system:kube-proxy,kube-apiserver 预定义的 RoleBinding cluster-admin 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限
3.5.6.4 创建kube-proxy 的systemd unit 文件
[root@k8s_slave ssl]# mkdir -p /var/lib/kube-proxy # 必须先创建工作目录
cat > kube-proxy.service <
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=10.0.0.191 \
--hostname-override=10.0.0.191 \
--cluster-cidr=10.254.0.0/16 \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \
--logtostderr=true \
--v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
–hostname-override 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 iptables 规则
–cluster-cidr 必须与 kube-apiserver 的 –service-cluster-ip-range 选项值一致
kube-proxy 根据 –cluster-cidr 判断集群内部和外部流量,指定 –cluster-cidr 或 –masquerade-all 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT
–kubeconfig 指定的配置文件嵌入了 kube-apiserver 的地址、用户名、证书、秘钥等请求和认证信息
预定义的 RoleBinding cluster-admin 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限
3.5.6.5 启动kube-proxy
[root@k8s_slave ~]# mv kube-proxy.service /usr/lib/systemd/system/
[root@k8s_slave ~]# systemctl daemon-reload
[root@k8s_slave ~]# systemctl start kube-proxy
[root@k8s_slave ~]# systemctl status kube-proxy
[root@k8s_slave ~]# systemctl enable kube-proxy
1
2
3
4
5
3.6 验证集群功能
3.6.1 定义yaml 文件
[root@k8s_master nginx]# cat nginx_rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 1
selector:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
[root@k8s_master nginx]# cat nginx_svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: NodePort
ports:
[root@k8s_master nginx]# kubectl create -f nginx_rc.yaml
[root@k8s_master nginx]# kubectl create -f nginx_svc.yaml
作者:ljx1528
来源:CSDN
原文:https://blog.csdn.net/ljx1528/article/details/82729115?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!
转载于:https://blog.51cto.com/13456747/2298885