从零开始搭建 k8s 集群环境系列笔记:
- 从零开始搭建 k8s 集群环境 (一)—— 搭建镜像存储服和镜像服
- 从零开始搭建 k8s 集群环境 (二)—— 构建 Kubernetes 安装包
- 从零开始搭建 k8s 集群环境 (三)—— 搭建 Master 节点
- 从零开始搭建 k8s 集群环境 (四)—— 添加 Node 节点
- 从零开始搭建 k8s 集群环境 (五)—— 安装 Pod 网络
- 从零开始搭建 k8s 集群环境 (六)—— 部署 Dashboard UI
- 从零开始搭建 k8s 集群环境 (七)—— 部署 Ingress 服务
- 从零开始搭建 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 init
、kubeadm join
什么的,这也是高版本 k8s
中官方推荐的部署方式。
然后,我们回过头来看之前的整个部署过程:
- 安装
Docker
、Kubelet
、Kubectl
、Kubeadm
和cni
。 - 执行
kubeadm init
初始化Master
,kubeadm
写入初始化信息,kubelet
服务开始退出循环等待开始正常工作。 kubelet
服务初始化加载pause-amd64
、etcd-amd64
、kube-apiserver-amd64
、kube-scheduler-amd64
和kube-controller-manager-amd64
核心 Pod。- 然后安装 Pod 网络,
kubelet
又开始加载flannel
和k8s-dns-sidecar-amd64
、k8s-dns-kube-dns-amd64
、k8s-dns-dnsmasq-nanny-amd64
等网络相关 Pod。 - 经过以上步骤,我们的集群实际上已经开始工作。我们再接着就是部署一些附加服务。
不知道大家在部署过程中有没有注意到:当我们执行 kubeadm init
的时候,从控制台输出我们可以看到 kubeadm
先是启动 kubelet
服务,然后是自检,再然后写入配置、生成证书和预部署服务(/etc/kubernetes/manifests/)。我们基本可以确认:
kubeadm
这个程序实际上是一个 k8s 的引导程序(额、好像说的是废话。。。),由它启动 kubelet
并运行需要的 Pod,每个 Pod 提供不同的服务,组成 k8s 集群基本系统。
而网络上流传的版本,大多都是手动安装 k8s 的各个组件,比如 etcd
、flannel
等,这种做法虽然目前不是 k8s 官方推荐的,但考虑到如果 k8s 是部署到机型各不相同的物理环境,也不失是一个自定义 Node 的办法。
所以,为了更全面覆盖 k8s 集群部署内容,就补这么一篇不使用 kubeadm
的手动部署的过程记录。
环境准备
在操作之前,我们先处理所有节点都要做的事情:
禁用交换分区
# 关闭
swapoff -a
# 禁用
sed -i "s/\/dev\/mapper\/centos-swap/# \/dev\/mapper\/centos-swap/g" /etc/fstab
关闭防火墙
# 关闭并禁用
systemctl stop firewalld && systemctl disable firewalld
禁用SELinux
# 关闭
setenforce 0
# 禁用
sed -i "s/SELINUX=enforcing/SELINUX=disable/g" /etc/selinux/config
设置IPV4转发内核参数
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
证书对通信进行加密,本文档使用 CloudFlare
的 PKI
工具集 cfssl
来生成 Certificate Authority (CA)
证书和秘钥文件,CA
是自签名的证书,用来签名后续创建的其它 TLS
证书。
由于无证书版各种配置没有文档,部署之后
DNS
不能正常工作,楼主实验 N^n 次之后实在是无解,所以最后还是加了证书。
准备
下载 cfssl
工具
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
写入证书配置文件
cat >config.json<<EOF
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"profile": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
EOF
生成 CA
证书
# 创建文件夹
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 证书
# 创建文件夹
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 证书
# 创建文件夹
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 证书
# 创建文件夹
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 ..
验证证书
# 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
Etcd
是 k8s
集群中用来存取数据的很重要的组件,一般部署成集群,这里采用二进制安装。我这里没多苛刻的要求就单节点了,并且和 Master
同一台机器。
为了部署方便我们定义一些变量
# 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.pem
和 etcd-key.pem
)
# 创建证书目录
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
# 下载&解压
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
结尾
# 删除原有配置
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-apiserver
、 kube-scheduler
、kube-controller-manager
和 kubectl
,其中 kubectl
非必选)。
这里搭建 Master 只说了纯的 Master 节点,没有包含 docker
、flannel
、kubelet
和 kube-proxy
这些 Node 节点程序,如果需要把 Master 节点当做 Node 节点使用请参照 Node 节点配置安装即可。
为了部署方便我们定义一些变量
# 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.pem
和 master-key.pem
)
# 创建证书目录
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
版本。
Kubernetes 其他版本下载地址在 Kubernetes 仓库的变更记录中:CHANGELOG.md
其中
Downloads for vx.x.x
这个是各种脚本,Client Binaries
只包含kubectl
,Node Binaries
也只包含kubectl
、kubeadm
、kubelet
和kube-proxy
,而Server Binaries
才是我们需要的 kube 系列所有应用程序和基础镜像。
准备二进制文件
# 下载&解压
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-apiserver
的 service
文件(未启用 RBAC
权限控制)
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
配置并启动服务
systemctl daemon-reload
systemctl start kube-apiserver
systemctl enable kube-apiserver
systemctl status kube-apiserver
kube-scheduler
创建 kube-scheduler
的 service
文件
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
配置并启动服务
systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler
systemctl status kube-scheduler
kube-controller-manager
创建 kube-controller-manager
的 service
文件
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
配置并启动服务
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状态
kubectl get componentstatuses
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health": "true"}
创建 Node
的验证配置 node.kubeconfig
文件
# 设置集群参数
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 节点,必须安装 docker
、flannel
和 kubernetes
系列组件(包括 kubelet
和 kube-proxy
)。
为了部署方便我们定义一些变量
# 当前部署 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.pem
和 etcd-key.pem
)以及 Node
的验证配置
# 创建证书目录
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://download.docker.com/linux/centos/7/x86_64/stable/Packages/
https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/
# 下载
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 同样二进制安装,至于其他网络插件大家可以根据需要自行探索。
# 下载&解压
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 网络
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
版本。
Kubernetes 其他版本下载地址在 Kubernetes 仓库的变更记录中:CHANGELOG.md
其中
Downloads for vx.x.x
这个是各种脚本,Client Binaries
只包含kubectl
,Node Binaries
也只包含kubectl
、kubeadm
、kubelet
和kube-proxy
,而Server Binaries
才是我们需要的 kube 系列所有应用程序和基础镜像。
# 下载&解压
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
创建工作目录
mkdir -p /var/lib/kubelet
创建 kubelet
的 service
文件
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
配置并启动服务
systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet
systemctl status kubelet
kube-proxy
创建工作目录
mkdir -p /var/lib/kube-proxy
创建 kube-proxy
的 service
文件
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
配置并启动服务
systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy
systemctl status kube-proxy
安装插件
经过以上步骤,k8s
已经具备了它的核心能力,但要满足日常使用,还需要安装一些必要插件。
CoreDNS
DNS
作为 k8s
的首选插件,这里安装 CoreDNS
插件。
DNS
插件常见的有kube-dns
和CoreDNS
,在kubernetes
仓库中可以找到。
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns
原版CoreDNS
仓库,包含配置脚本和说明文档。
https://github.com/coredns/deployment/tree/master/kubernetes
首先下载 配置文件
和 yaml
文件
wget https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/deploy.sh
wget https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/coredns.yaml.sed
准备参数,注意需要和 Node 部署时保持一致
chmod +x deploy.sh
export CLUSTER_DNS_SVC_IP="10.1.0.2"
export CLUSTER_DNS_DOMAIN="cluster.local"
替换镜像
sed -i "s/image:.*/image: registry.cn-shenzhen.aliyuncs.com\/lx0758\/coredns:1.1.3/g" coredns.yaml.sed
安装 DNS
插件
./deploy.sh -i ${CLUSTER_DNS_SVC_IP} -d ${CLUSTER_DNS_DOMAIN} -t coredns.yaml.sed | kubectl apply -f -
Heapster
k8s
的监控组件,自动伸缩与及 Dashboard
都依赖与它。
# 下载 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
反向代理服务器。
# 下载 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
上。
# 下载配置文件
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