0%

从零开始搭建k8s集群环境(番外)——纯手动部署全套

系列目录:

今天周末,沉浸在 k8s 集群部署完成带来的极大满足中开始回顾之前看过的关于 k8s 的各种博客。。。然后,我觉得很有必要补一篇纯手动部署的文章。。。

环境说明:

  • Master:VBox虚拟机/Centos_7.5-1804/192.168.56.100
  • Images:VBox虚拟机/Centos_7.5-1804/192.168.56.101
  • Node01:VBox虚拟机/Centos_7.5-1804/192.168.56.102

软件环境说明:

  • docker-ce-18.03.1
  • kubernetes-v1.10.4
  • etcd-v3.3.7
  • flannel-v0.10.0

为什么补一篇

之所以还要补一篇,是因为之前七篇博客说得部署 k8s,都是用的 k8s 自带的 kubeadm 这个程序在部署,比如 kubeadm initkubeadm join 什么的,这也是高版本 k8s 中官方推荐的部署方式。

然后,我们回过头来看之前的整个部署过程:

  1. 安装 DockerKubeletKubectlKubeadmcni
  2. 执行 kubeadm init 初始化 Masterkubeadm 写入初始化信息,kubelet 服务开始退出循环等待开始正常工作。
  3. kubelet 服务初始化加载 pause-amd64etcd-amd64kube-apiserver-amd64kube-scheduler-amd64kube-controller-manager-amd64 核心 Pod。
  4. 然后安装 Pod 网络,kubelet 又开始加载 flannelk8s-dns-sidecar-amd64k8s-dns-kube-dns-amd64k8s-dns-dnsmasq-nanny-amd64 等网络相关 Pod。
  5. 经过以上步骤,我们的集群实际上已经开始工作。我们再接着就是部署一些附加服务。

不知道大家在部署过程中有没有注意到:当我们执行 kubeadm init 的时候,从控制台输出我们可以看到 kubeadm 先是启动 kubelet 服务,然后是自检,再然后写入配置、生成证书和预部署服务(/etc/kubernetes/manifests/)。我们基本可以确认: kubeadm 这个程序实际上是一个 k8s 的引导程序(额、好像说的是废话。。。),由它启动 kubelet 并运行需要的 Pod,每个 Pod 提供不同的服务,组成 k8s 集群基本系统。

而网络上流传的版本,大多都是手动安装 k8s 的各个组件,比如 etcdflannel等,这种做法虽然目前不是 k8s 官方推荐的,但考虑到如果 k8s 是部署到机型各不相同的物理环境,也不失是一个自定义 Node 的办法。

所以,为了更全面覆盖 k8s 集群部署内容,就补这么一篇不使用 kubeadm 的手动部署的过程记录。

环境准备

在操作之前,我们先处理所有节点都要做的事情:

禁用交换分区

1
2
3
4
5
# 关闭
swapoff -a

# 禁用
sed -i "s/\/dev\/mapper\/centos-swap/# \/dev\/mapper\/centos-swap/g" /etc/fstab

关闭防火墙

1
2
# 关闭并禁用
systemctl stop firewalld && systemctl disable firewalld

禁用SELinux

1
2
3
4
5
# 关闭
setenforce 0

# 禁用
sed -i "s/SELINUX=enforcing/SELINUX=disable/g" /etc/selinux/config

设置IPV4转发内核参数

1
2
3
4
5
6
7
8
cat>/etc/sysctl.d/kubernetes.conf<<'EOF'
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
EOF

modprobe br_netfilter
sysctl -p /etc/sysctl.d/kubernetes.conf

签发证书

kubernetes 系统各组件需要使用 TLS 证书对通信进行加密,本文档使用 CloudFlarePKI 工具集 cfssl 来生成 Certificate Authority (CA) 证书和秘钥文件,CA 是自签名的证书,用来签名后续创建的其它 TLS 证书。

由于无证书版各种配置没有文档,部署之后 DNS 不能正常工作,楼主实验 N^n 次之后实在是无解,所以最后还是加了证书。

准备

下载 cfssl 工具

1
2
3
4
5
6
7
8
9
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64
chmod +x cfssljson_linux-amd64
chmod +x cfssl-certinfo_linux-amd64
mv -f cfssl_linux-amd64 /usr/bin/cfssl
mv -f cfssljson_linux-amd64 /usr/bin/cfssljson
mv -f cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

写入证书配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cat >config.json<<EOF
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"profile": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
EOF

生成 CA 证书

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
# 创建文件夹
mkdir ca
# 写入证书请求文件
cat >ca/ca-csr.json<<EOF
{
"CN": "Kubernetes CA",
"hosts": [],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"ST": "ChengDu",
"L": "ChengDu",
"O": "Kubernetes",
"OU": "System"
}
]
}
EOF

# 生成证书
cd ca && cfssl gencert -initca ca-csr.json | cfssljson -bare ca && cd ..

生成 Etcd 证书

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
# 创建文件夹
mkdir etcd
# 写入证书请求文件
cat >etcd/etcd-csr.json<<EOF
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"10.1.0.1",
"10.2.0.1",
"192.168.56.100",
"192.168.56.101",
"192.168.56.102",
"192.168.56.103",
"192.168.56.104",
"192.168.56.105",
"192.168.56.106",
"192.168.56.107",
"192.168.56.108",
"192.168.56.109",
"192.168.56.110",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"ST": "ChengDu",
"L": "ChengDu",
"O": "Kubernetes",
"OU": "System"
}
]
}
EOF

# 生成证书
cd etcd && cfssl gencert -ca=../ca/ca.pem -ca-key=../ca/ca-key.pem -config=../config.json -profile=profile etcd-csr.json | cfssljson -bare etcd && cd ..

生成 Master 证书

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
# 创建文件夹
mkdir master
# 写入证书请求文件
cat >master/master-csr.json<<EOF
{
"CN": "master",
"hosts": [
"127.0.0.1",
"10.1.0.1",
"10.2.0.1",
"192.168.56.100",
"192.168.56.101",
"192.168.56.102",
"192.168.56.103",
"192.168.56.104",
"192.168.56.105",
"192.168.56.106",
"192.168.56.107",
"192.168.56.108",
"192.168.56.109",
"192.168.56.110",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"ST": "ChengDu",
"L": "ChengDu",
"O": "Kubernetes",
"OU": "System"
}
]
}
EOF

# 生成证书
cd master && cfssl gencert -ca=../ca/ca.pem -ca-key=../ca/ca-key.pem -config=../config.json -profile=profile master-csr.json | cfssljson -bare master && cd ..

生成 Node 证书

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
# 创建文件夹
mkdir node
# 写入证书请求文件
cat >node/node-csr.json<<EOF
{
"CN": "node",
"hosts": [
"127.0.0.1",
"10.1.0.1",
"10.2.0.1",
"192.168.56.100",
"192.168.56.101",
"192.168.56.102",
"192.168.56.103",
"192.168.56.104",
"192.168.56.105",
"192.168.56.106",
"192.168.56.107",
"192.168.56.108",
"192.168.56.109",
"192.168.56.110",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"ST": "ChengDu",
"L": "ChengDu",
"O": "Kubernetes",
"OU": "System"
}
]
}
EOF

# 生成证书
cd node && cfssl gencert -ca=../ca/ca.pem -ca-key=../ca/ca-key.pem -config=../config.json -profile=profile node-csr.json | cfssljson -bare node && cd ..

验证证书

1
2
3
4
5
6
7
8
9
10
11
# CA
cfssl-certinfo -cert ca/ca.pem

# Etcd
cfssl-certinfo -cert etcd/etcd.pem

# Master
cfssl-certinfo -cert master/master.pem

# Node
cfssl-certinfo -cert node/node.pem

我这里配置的三个证书授权的 DNS 都是一样的,所以用同一个也可以。但在实际部署生产环境的时候请视情况而定。另外我加了一个 Etcd 是为了适配存在独立的 Etcd 集群的情况。

开始部署

Etcd

Etcdk8s 集群中用来存取数据的很重要的组件,一般部署成集群,这里采用二进制安装。我这里没多苛刻的要求就单节点了,并且和 Master 同一台机器。

官网:https://coreos.com/etcd/

下载地址:https://github.com/coreos/etcd/releases/

为了部署方便我们定义一些变量

1
2
3
4
5
6
7
8
9
# Etcd节点IP,实际替换为部署 IP
export ETCD_IP="192.168.56.100"
# etcd 存储数据前缀
export ETCD_PREFIX="/atomic.io/network"
# etcd 集群服务地址列表
export ETCD_ENDPOINTS="https://192.168.56.100:2379"

# POD 网段 (Cluster CIDR),部署前路由不可达,**部署后**路由可达 (flanneld 保证)
export KUBE_CLUSTER_CIDR="10.2.0.0/16"

准备证书

Etcd 需要用到上面生成的 CA 证书公钥,Etcd 的公私钥(etcd.pemetcd-key.pem

1
2
3
4
5
6
# 创建证书目录
mkdir -p /etc/etcd/ssl

# 拷贝证书
cp -f ~/ca/ca.pem /etc/etcd/ssl
cp -f ~/etcd/{etcd.pem,etcd-key.pem} /etc/etcd/ssl

etcd

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
46
47
48
49
50
51
52
53
# 下载&解压
wget https://github.com/coreos/etcd/releases/download/v3.3.7/etcd-v3.3.7-linux-amd64.tar.gz
tar -zxvf etcd-v3.3.7-linux-amd64.tar.gz

# 拷贝可执行文件到系统环境
cp -r etcd-v3.3.7-linux-amd64/{etcd,etcdctl} /usr/bin/
chmod +x /usr/bin/{etcd,etcdctl}

# 创建工作目录
mkdir -p /var/lib/etcd/data

# 写 Service 文件
cat >/usr/lib/systemd/system/etcd.service<<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
# set GOMAXPROCS to number of processors
ExecStart=/usr/bin/etcd \\
--name=${ETCD_IP} \\
--data-dir=/var/lib/etcd/data/ \\
\\
--listen-client-urls=https://${ETCD_IP}:2379,http://127.0.0.1:2379 \\
--listen-peer-urls=https://${ETCD_IP}:2380 \\
--advertise-client-urls=https://${ETCD_IP}:2379,http://127.0.0.1:2379 \\
--initial-advertise-peer-urls=https://${ETCD_IP}:2380 \\
\\
--cert-file=/etc/etcd/ssl/etcd.pem \\
--peer-cert-file=/etc/etcd/ssl/etcd.pem \\
--key-file=/etc/etcd/ssl/etcd-key.pem \\
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \\
--trusted-ca-file=/etc/etcd/ssl/ca.pem \\
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \\
--client-cert-auth=true \\
--peer-client-cert-auth=true

Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

# 运行&开机启动
systemctl daemon-reload
systemctl start etcd
systemctl enable etcd
systemctl status etcd

添加 flannel 网络数据,注意 ETCD_PREFIX 配置的是前缀,需要跟上一个 config 结尾

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 删除原有配置
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--ca-file=/etc/etcd/ssl/ca.pem \
rm ${ETCD_PREFIX}/config

# 写入新配置
cat <<EOF | etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--ca-file=/etc/etcd/ssl/ca.pem \
mk ${ETCD_PREFIX}/config \
'{"Network":"'${KUBE_CLUSTER_CIDR}'","SubnetLen":24,"Backend":{"Type":"vxlan"}}'
EOF

Master

在 Master 节点,需要 kubernetes 系列组件(包括kube-apiserverkube-schedulerkube-controller-managerkubectl,其中 kubectl 非必选)。

这里搭建 Master 只说了纯的 Master 节点,没有包含 dockerflannelkubeletkube-proxy 这些 Node 节点程序,如果需要把 Master 节点当做 Node 节点使用请参照 Node 节点配置安装即可。

为了部署方便我们定义一些变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Master 节点IP地址,实际替换为部署 IP
export MASTER_IP="192.168.56.100"

# etcd 存储数据前缀
export ETCD_PREFIX="/atomic.io/network"
# etcd 集群服务地址列表
export ETCD_ENDPOINTS="https://192.168.56.100:2379"

# Master ApiServer 访问地址
export KUBE_APISERVER="https://${MASTER_IP}:6443"
# 服务网段 (Service CIDR),部署前必须路由不可达
export KUBE_SERVICE_CIDR="10.1.0.0/16"
# POD 网段 (Cluster CIDR),部署前路由不可达,**部署后**路由可达 (flanneld 保证)
export KUBE_CLUSTER_CIDR="10.2.0.0/16"
# 节点对外端口范围
export KUBE_PORT_RANGE="10000-60000"

准备证书

Master 需要用到上面生成的 CA 证书公钥,Master 的公私钥(master.pemmaster-key.pem

1
2
3
4
5
6
# 创建证书目录
mkdir -p /etc/kubernetes/ssl

# 拷贝证书
cp -f ~/ca/{ca.pem,ca-key.pem} /etc/kubernetes/ssl
cp -f ~/master/{master.pem,master-key.pem} /etc/kubernetes/ssl

kubernetes

由于这玩意儿在 yum 仓库里的版本十分老旧,就下载二进制文件安装,版本使用最新的 v1.10.4 版本。

官网: https://kubernetes.io/

Kubernetes 其他版本下载地址在 Kubernetes 仓库的变更记录中:CHANGELOG.md

其中 Downloads for vx.x.x 这个是各种脚本,Client Binaries 只包含 kubectlNode Binaries 也只包含 kubectlkubeadmkubeletkube-proxy,而 Server Binaries 才是我们需要的 kube 系列所有应用程序和基础镜像。

准备二进制文件

1
2
3
4
5
6
7
# 下载&解压
wget https://dl.k8s.io/v1.10.4/kubernetes-server-linux-amd64.tar.gz
tar zxvf kubernetes-server-linux-amd64.tar.gz

# 拷贝可执行文件到系统环境
cp -r kubernetes/server/bin/{kube-apiserver,kube-scheduler,kube-controller-manager,kubectl} /usr/bin/
chmod +x /usr/bin/{kube-apiserver,kube-scheduler,kube-controller-manager,kubectl}

kube-apiserver

创建 kube-apiserverservice 文件(未启用 RBAC 权限控制)

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
cat >/usr/lib/systemd/system/kube-apiserver.service<<EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
ExecStart=/usr/bin/kube-apiserver \\
--kubelet-https=true \\
#--authorization-mode=RBAC \\
--runtime-config=rbac.authorization.k8s.io/v1alpha1 \\
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
\\
--bind-address=${MASTER_IP} \\
--advertise-address=${MASTER_IP} \\
--insecure-bind-address=127.0.0.1 \\
\\
--service-node-port-range=${KUBE_PORT_RANGE} \\
--service-cluster-ip-range=${KUBE_SERVICE_CIDR} \\
\\
--client-ca-file=/etc/kubernetes/ssl/ca.pem \\
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \\
--tls-cert-file=/etc/kubernetes/ssl/master.pem \\
--tls-private-key-file=/etc/kubernetes/ssl/master-key.pem \\
--etcd-prefix=${ETCD_PREFIX} \\
--etcd-servers=${ETCD_ENDPOINTS} \\
--etcd-cafile=/etc/kubernetes/ssl/ca.pem \\
--etcd-certfile=/etc/kubernetes/ssl/master.pem \\
--etcd-keyfile=/etc/kubernetes/ssl/master-key.pem \\
\\
--enable-swagger-ui=true \\
--allow-privileged=true \\
--apiserver-count=1 \\
--event-ttl=1h \\
--v=2

Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

配置并启动服务

1
2
3
4
systemctl daemon-reload
systemctl start kube-apiserver
systemctl enable kube-apiserver
systemctl status kube-apiserver

kube-scheduler

创建 kube-schedulerservice 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat >/usr/lib/systemd/system/kube-scheduler.service<<EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/usr/bin/kube-scheduler \
--address=127.0.0.1 \
--master=http://127.0.0.1:8080 \
--leader-elect=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF

配置并启动服务

1
2
3
4
systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler
systemctl status kube-scheduler

kube-controller-manager

创建 kube-controller-managerservice 文件

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
cat >/usr/lib/systemd/system/kube-controller-manager.service<<EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/usr/bin/kube-controller-manager \\
--address=127.0.0.1 \\
--master=http://127.0.0.1:8080 \\
\\
--service-cluster-ip-range=${KUBE_SERVICE_CIDR} \\
--cluster-cidr=${KUBE_CLUSTER_CIDR} \\
--allocate-node-cidrs=true \\
--cluster-name=master \\
\\
--root-ca-file=/etc/kubernetes/ssl/ca.pem \\
--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 \\
\\
--leader-elect=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF

配置并启动服务

1
2
3
4
systemctl daemon-reload
systemctl start kube-controller-manager
systemctl enable kube-controller-manager
systemctl status kube-controller-manager

kubectl

kubectl 可以操作集群,上面 kube-apiserver 开启了 127.0.0.1 本地非安全端口,这里 kubectl 不需要配置就可以直接使用。

验证Master状态

1
2
3
4
5
6
kubectl get componentstatuses

NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health": "true"}

创建 Node 的验证配置 node.kubeconfig 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 设置集群参数
kubectl config set-cluster node-cluster \
--certificate-authority=/root/ca/ca.pem \
--server=${KUBE_APISERVER} \
--embed-certs=true \
--kubeconfig=/root/node/node.kubeconfig

# 设置用户认证参数
kubectl config set-credentials node-credentials \
--client-certificate=/root/node/node.pem \
--client-key=/root/node/node-key.pem \
--embed-certs=true \
--kubeconfig=/root/node/node.kubeconfig

# 设置上下文参数
kubectl config set-context node-context \
--cluster=node-cluster \
--user=node-credentials \
--kubeconfig=/root/node/node.kubeconfig

# 设置默认上下文
kubectl config use-context node-context \
--kubeconfig=/root/node/node.kubeconfig

Node

在 Node 节点,必须安装 dockerflannelkubernetes 系列组件(包括 kubeletkube-proxy)。

为了部署方便我们定义一些变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 当前部署 Node 的 IP
export NODE_IP="192.168.56.102"
# flannel 使用的网卡
export NODE_IFACE="eth1"

# etcd 存储数据前缀
export ETCD_PREFIX="/atomic.io/network"
# etcd 集群服务地址列表
export ETCD_ENDPOINTS="https://192.168.56.100:2379"

# Master 节点IP地址,实际替换为部署 IP
export KUBE_MASTER_IP="192.168.56.100"
# Master ApiServer 访问地址
export KUBE_APISERVER="https://${KUBE_MASTER_IP}:6443"
# 服务网段 (Service CIDR),部署前必须路由不可达
export KUBE_SERVICE_CIDR="10.1.0.0/16"
# kubernetes 服务 IP (预分配,一般是 SERVICE_CIDR 中第一个IP)
export KUBE_SERVICE_SVC_IP="10.1.0.1"
# 集群 DNS 服务 IP (从 SERVICE_CIDR 中预分配)
export KUBE_SERVICE_DNS_IP="10.1.0.2"
# 集群 DNS 域名
export KUBE_SERVICE_DNS_DOMAIN="cluster.local"

准备证书

Node 需要用到上面生成的 CA 证书公钥,Etcd 的公私钥(etcd.pemetcd-key.pem)以及 Node 的验证配置

1
2
3
4
5
6
7
8
9
10
11
# 创建证书目录
mkdir -p /etc/kubernetes/ssl

# Master 部署使用
cp -f ~/node/node.kubeconfig /etc/kubernetes
cp -f ~/etcd/{etcd.pem,etcd-key.pem} /etc/kubernetes/ssl

# Node 部署使用
scp root@${KUBE_MASTER_IP}:~/ca/ca.pem /etc/kubernetes/ssl
scp root@${KUBE_MASTER_IP}:~/etcd/{etcd.pem,etcd-key.pem} /etc/kubernetes/ssl
scp root@${KUBE_MASTER_IP}:~/node/node.kubeconfig /etc/kubernetes

docker

Docker 使用目前最新的 Docker-ce-18.03.1

官网:https://www.docker.com/

下载地址:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/ https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/

1
2
3
4
5
6
7
8
9
# 下载
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-18.03.1.ce-1.el7.centos.x86_64.rpm

# 安装 Docker 和依赖包
yum install -y docker*.rpm

# 运行&开机启动
systemctl start docker
systemctl enable docker

flannel

网络插件 Flannel 同样二进制安装,至于其他网络插件大家可以根据需要自行探索。

官网:https://coreos.com/flannel/

下载地址:https://github.com/coreos/flannel/releases

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
# 下载&解压
wget https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz
mkdir flannel-v0.10.0-linux-amd64 && tar -zxvf flannel-v0.10.0-linux-amd64.tar.gz -C ./flannel-v0.10.0-linux-amd64

# 拷贝执行文件到系统目录
cp -r flannel-v0.10.0-linux-amd64/{flanneld,mk-docker-opts.sh} /usr/bin/
chmod +x /usr/bin/{flanneld,mk-docker-opts.sh}

# 写入 Service 文件
cat >/usr/lib/systemd/system/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 \\
-iface=${NODE_IFACE} \\
-etcd-prefix=${ETCD_PREFIX} \\
-etcd-endpoints=${ETCD_ENDPOINTS} \\
\\
-etcd-cafile=/etc/kubernetes/ssl/ca.pem \\
-etcd-certfile=/etc/kubernetes/ssl/etcd.pem \\
-etcd-keyfile=/etc/kubernetes/ssl/etcd-key.pem

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

# 运行&开机启动
systemctl daemon-reload
systemctl start flanneld
systemctl enable flanneld
systemctl status flanneld

重写 Docker Service 设置 Docker 网络

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
cat >/usr/lib/systemd/system/docker.service<<'EOF'
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target firewalld.service

[Service]
Type=notify
EnvironmentFile=-/run/flannel/docker
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --log-level=error $DOCKER_NETWORK_OPTIONS
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process

[Install]
WantedBy=multi-user.target
EOF

# 重启 Docker
systemctl daemon-reload
systemctl restart docker

变动如下:

  • 添加配置文件引用 EnvironmentFile=-/run/flannel/docker
  • 添加启动参数 ExecStart=/root/local/bin/dockerd --log-level=error $DOCKER_NETWORK_OPTIONS

kubernetes

由于这玩意儿在 yum 仓库里的版本十分老旧,就下载二进制文件安装,版本使用最新的 v1.10.4 版本。

官网: https://kubernetes.io/

Kubernetes 其他版本下载地址在 Kubernetes 仓库的变更记录中:CHANGELOG.md

其中 Downloads for vx.x.x 这个是各种脚本,Client Binaries 只包含 kubectlNode Binaries 也只包含 kubectlkubeadmkubeletkube-proxy,而 Server Binaries 才是我们需要的 kube 系列所有应用程序和基础镜像。

1
2
3
4
5
6
7
# 下载&解压
wget https://dl.k8s.io/v1.10.4/kubernetes-server-linux-amd64.tar.gz
tar zxvf kubernetes-server-linux-amd64.tar.gz

# 拷贝可执行文件到系统环境
cp -r kubernetes/server/bin/{kubelet,kube-proxy} /usr/bin/
chmod +x /usr/bin/{kubelet,kube-proxy}

kubelet

创建工作目录

1
mkdir -p /var/lib/kubelet

创建 kubeletservice 文件

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
cat >/usr/lib/systemd/system/kubelet.service<<EOF
[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=${NODE_IP} \\
--hostname-override=${NODE_IP} \\
--pod-infra-container-image=registry.cn-shenzhen.aliyuncs.com/lx0758/pause-amd64:3.0 \\
--kubeconfig=/etc/kubernetes/node.kubeconfig \\
--cluster_dns=${KUBE_SERVICE_DNS_IP} \\
--cluster_domain=${KUBE_SERVICE_DNS_DOMAIN}. \\
--hairpin-mode=promiscuous-bridge \\
--allow-privileged=true \\
--serialize-image-pulls=false \\
--cgroup-driver=cgroupfs \\
--logtostderr=true \\
--v=2

Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF

配置并启动服务

1
2
3
4
systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet
systemctl status kubelet

kube-proxy

创建工作目录

1
mkdir -p /var/lib/kube-proxy

创建 kube-proxyservice 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cat >/usr/lib/systemd/system/kube-proxy.service<<EOF
[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=${NODE_IP} \\
--hostname-override=${NODE_IP} \\
--cluster-cidr=${KUBE_SERVICE_CIDR} \\
--kubeconfig=/etc/kubernetes/node.kubeconfig \\
--logtostderr=true \\
--v=2

Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

配置并启动服务

1
2
3
4
systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy
systemctl status kube-proxy

安装插件

经过以上步骤,k8s 已经具备了它的核心能力,但要满足日常使用,还需要安装一些必要插件。

CoreDNS

DNS 作为 k8s 的首选插件,这里安装 CoreDNS 插件。

DNS 插件常见的有 kube-dnsCoreDNS,在 kubernetes 仓库中可以找到。 https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns 原版 CoreDNS 仓库,包含配置脚本和说明文档。 https://github.com/coredns/deployment/tree/master/kubernetes

首先下载 配置文件yaml 文件

1
2
wget https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/deploy.sh
wget https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/coredns.yaml.sed

准备参数,注意需要和 Node 部署时保持一致

1
2
3
chmod +x deploy.sh
export CLUSTER_DNS_SVC_IP="10.1.0.2"
export CLUSTER_DNS_DOMAIN="cluster.local"

替换镜像

1
sed -i "s/image:.*/image: registry.cn-shenzhen.aliyuncs.com\/lx0758\/coredns:1.1.3/g" coredns.yaml.sed

安装 DNS 插件

1
./deploy.sh -i ${CLUSTER_DNS_SVC_IP} -d ${CLUSTER_DNS_DOMAIN} -t coredns.yaml.sed | kubectl apply -f -

Heapster

k8s 的监控组件,自动伸缩与及 Dashboard 都依赖与它。

官方网站:https://github.com/kubernetes/heapster

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 下载 yaml 文件
mkdir -p influxdb && cd influxdb
wget https://github.com/kubernetes/heapster/raw/master/deploy/kube-config/influxdb/heapster.yaml
wget https://github.com/kubernetes/heapster/raw/master/deploy/kube-config/influxdb/influxdb.yaml
wget https://github.com/kubernetes/heapster/raw/master/deploy/kube-config/influxdb/grafana.yaml
cd ..

# 修改镜像
sed -i "s/image:.*/image: registry.cn-shenzhen.aliyuncs.com\/lx0758\/heapster-amd64:v1.5.3/g" ./influxdb/heapster.yaml
sed -i "s/image:.*/image: registry.cn-shenzhen.aliyuncs.com\/lx0758\/heapster-grafana-amd64:v4.4.3/g" ./influxdb/grafana.yaml
sed -i "s/image:.*/image: registry.cn-shenzhen.aliyuncs.com\/lx0758\/heapster-influxdb-amd64:v1.3.3/g" ./influxdb/influxdb.yaml

# 应用插件
kubectl apply -f ./influxdb/

Ingress

集群内自动配置的 nginx 反向代理服务器。

官方网站:NGINX Ingress Controller

1
2
3
4
5
6
7
8
9
# 下载 yaml 文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

# 修改镜像
sed -i "s/image:.*defaultbackend.*/image: registry.cn-shenzhen.aliyuncs.com\/lx0758\/defaultbackend:1.4/g" mandatory.yaml
sed -i "s/image:.*nginx-ingress-controller.*/image: registry.cn-shenzhen.aliyuncs.com\/lx0758\/nginx-ingress-controller:0.15.0/g" mandatory.yaml

# 应用插件
kubectl apply -f mandatory.yaml

注意这个插件还需要用合适的方法暴露给外部使用,否则没有意义。比如在之前使用 kubeadm 部署时是对容器网络映射到物理机的方式进行暴露(hostNetwork: true)。

Node-problem-detector

kubernetes 集群管理对 node 的健康状态是无法感知的,pod 依旧会调度到有问题的 node 上,通过 DaemonSet 部署 node-problem-detector,向 apiserver 上报 node 的状态信息,使 node 的健康状态对上游管理可见,pod 不会再调度到有异常的 node 上。

官方网站:https://github.com/kubernetes/node-problem-detector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 下载配置文件
wget https://raw.githubusercontent.com/kubernetes/node-problem-detector/master/config/kernel-monitor.json

# 应用配置文件
mkdir /etc/kubernetes/config
mv kernel-monitor.json /etc/kubernetes/config/
kubectl create configmap node-problem-detector-config --from-file=/etc/kubernetes/config/ -n kube-system

# 下载 yaml 文件
wget https://github.com/kubernetes/node-problem-detector/raw/master/deployment/node-problem-detector.yaml

# 修改镜像
sed -i "s/image:.*/image: registry.cn-shenzhen.aliyuncs.com\/lx0758\/node-problem-detector:v0.2/g" node-problem-detector.yaml

# 应用插件
kubectl apply -f node-problem-detector.yaml -n kube-system

引用鸣谢

  1. 和我一步步部署 kubernetes 集群
  2. CentOS上手工部署kubernetes集群
  • 本文作者: 6x
  • 本文链接: https://6xyun.cn/article/60
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-ND 许可协议。转载请注明出处!