背景:对于k8s学习者,有一个真实的环境十分重要,但要用二进制搭建一个学习环境是一件十分复杂的过程,查了一下网上的文档,大多数都是几台服务器来搭建集群的,本文以一台机器用二进制的方法搭建一个简单的k8s集群。
操作系统: centos 7
虚拟机
ip:192.168.225.132
1)下载etcd
使用版本3.4.7 ,下载地址
https://github.com/etcd-io/etcd/releases/download/v3.4.7/etcd-v3.4.7-linux-amd64.tar.gz
2)解压后建立下图显示的目录结构
bin 存放解压出来的两个程序文件 etcd 和etcdctl,,所有执行文件需要在命令行使用chmod 777 文件名,赋予执行权限
cfg 存放配置文件
data 存放数据文件
ssl 存放自生成证书
3)安装生成https证书软件cfssl
curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl
curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson /usr/local/bin/cfssl-certinfo
4)在ssl目录生成相关https证书
首先,建立如下3个配置文件
新建etcd-ca-config.json,具体内容如下:
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"www": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
新建etcd-ca-csr.json,具体内容如下:
{
"CN": "etcd CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
新建etcd-server-csr.json,具体内容如下,其中标红的ip地址为需要安装的机器ip地址和本地地址
{
"CN": "etcd",
"hosts": [
"192.168.225.132",
"127.0.0.1"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
然后,在ssl目录下执行如下2条命令:
命令1:cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare etcd-ca –
命令2:cfssl gencert -ca=etcd-ca.pem -ca-key=etcd-ca-key.pem -config=etcd-ca-config.json -profile=www etcd-server-csr.json | cfssljson -bare etcd-server
最终结果如下图,表示所有https证书生成成功
5)编写配置文件,在cfg目录下新建配置文件,文件名为etcd,具体内容如下,标红的ip地址要etcd-server-csr.json厘米设定的一致
#[Member]
ETCD_NAME="etcd01"
ETCD_DATA_DIR="/root/k8s/data/etcd" #数据保存路径
ETCD_LISTEN_PEER_URLS="https://192.168.225.132:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.225.132:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.225.132:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.225.132:2379"
#ETCD_INITIAL_CLUSTER="etcd01=https://192.168.225.132:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-0"
ETCD_INITIAL_CLUSTER_STATE="new"
#具体https证书路径
ETCD_CERT_FILE="/root/k8s/ssl/etcd-server.pem"
ETCD_KEY_FILE="/root/k8s/ssl/etcd-server-key.pem"
ETCD_TRUSTED_CA_FILE="/root/k8s/ssl/etcd-ca.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_PEER_CERT_FILE="/root/k8s/ssl/etcd-server.pem"
ETCD_PEER_KEY_FILE="/root/k8s/ssl/etcd-server-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/root/k8s/ssl/etcd-ca.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
6)编写服务启动文件,注意标红部分
使用命令:vi /usr/lib/systemd/system/etcd.service,录入如下配置内容:
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
User=root
EnvironmentFile=-/root/k8s/cfg/etcd #配置文件所在路径
WorkingDirectory=/var/lib/etcd/ #手工预先建立的目录
ExecStart=/root/k8s/bin/etcd #程序执行文件所在目录
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
7)启动etcd服务,在命令行输入如下命令:
systemctl daemon-relaod
systemctl start etcd
如果没有报错,可以使用systemctl status etcd查看服务最终结果,具体如下图
8)检查节点健康情况
首先,将etcd执行文件所在路径加入系统路径
在命令行输入命令:vim /etc/profile
在文件末尾添加 PATH=/root/k8s/bin:$PATH:$HOME
运行source /etc/profile 使配置生效
然后,运行 etcdctl --cacert=/root/k8s/ssl/etcd-ca.pem --cert=/root/k8s/ssl/etcd-server.pem --key=/root/k8s/ssl/etcd-server-key.pem --endpoints="https://192.168.225.132:2379" --write-out=table endpoint health
标红的ip 是etcd安装机器的ip
具体返回结果如下图,表示etcd安装完成
1)关闭部署机器的防火墙
systemctl stop firewalld
systemctl disable firewalld
2)关闭selinux
临时关闭:setenforce 0
永久关闭:修改/etc/selinux/config文件中设置SELINUX=disabled
验证结果:getenforce
3)关闭 swap
临时关闭:swapoff -a
永久关闭: vi /etc/fstab 注释带swap行
验证结果:free -m 显示swap是0
4)关闭dnsmasq
service dnsmasq stop && systemctl disable dnsmasq
5)安装docker
首先,配置相关参数
cat > /etc/sysctl.d/kubernetes.conf <
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
EOF
运行如下命令查看配置
sysctl -p /etc/sysctl.d/kubernetes.conf
然后,利用yum 安装docker,逐一执行如下命令
cd /etc/yum.repos.d/
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum clean all ;yum repolist -y
yum install docker-ce -y
systemctl start docker
systemctl enable docker
如果安装成功,可以使用systemctl status docker查看docker状态,具体如下图:
6)下载相关文件,建立相关目录
使用k8s版本为1.18.2,下载地址:
https://dl.k8s.io/v1.18.2/kubernetes-server-linux-amd64.tar.gz
解压后,建立如下的目录结构
bin 放置从压缩包解压出来的执行文件,所有执行文件需要在命令行使用chmod 777 文件名,赋予执行权限
cfg 配置文件
ssl 存放https证书文件
1)在ssl目录生成相关https证书
新建 ca-csr.json,具体内容如下:
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "HuBei",
"ST": "WuHan",
"O": "k8s",
"OU": "System"
}
]
}
新建ca-config.json,具体内容如下:
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"expiry": "876000h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
新建kube-proxy-csr.json,具体内容如下:
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "HuBei",
"ST": "WuHan",
"O": "k8s",
"OU": "System"
}
]
}
新建server-csr.json
{
"CN": "kubernetes",
"hosts": [
"10.0.0.1",
"127.0.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local",
"192.168.225.132",
"192.168.225.133",
"192.168.225.134"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "HuBei",
"ST": "WuHan",
"O": "k8s",
"OU": "System"
}
]
}
注:host中的最后几个IP为需要连接apiserver的IP,一般为master集群的所有IP,和负载均衡LB的所有IP和VIP,本文中的IP
"192.168.225.132", master部署机器ip
"192.168.225.133", 备用ip
"192.168.225.134". 备用ip
在ssl目录下运行如下3条命令,生成最终证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca –
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
执行 ll *.pem,会看到如下图红色框所表示的证书文件
2)建立相关组件的配置文件
在cfg目录陆续建立如下几个配置文件
建立api-server配置文件kube-apiserver.conf,具体内容如下:
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--log-dir=/root/k8scluster/data \
--etcd-servers=https://192.168.225.132:2379 \
--bind-address=192.168.225.132 \
--secure-port=6443 \
--advertise-address=192.168.225.132 \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/24 \ #服务ip网段
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--enable-bootstrap-token-auth \
--token-auth-file=/root/k8scluster/cfg/token.csv \
--service-node-port-range=30000-50000 \ #可使用端口范围
--kubelet-client-certificate=/root/k8scluster/ssl/server.pem \ #https证书路径
--kubelet-client-key=/root/k8scluster/ssl/server-key.pem \ #https证书路径
--tls-cert-file=/root/k8scluster/ssl/server.pem \
--tls-private-key-file=/root/k8scluster/ssl/server-key.pem \ #https证书路径
--client-ca-file=/root/k8scluster/ssl/ca.pem \ #https证书路径
--service-account-key-file=/root/k8scluster/ssl/ca-key.pem \ #https证书路径
--etcd-cafile=/root/k8s/ssl/etcd-ca.pem \ #etcd https证书路径
--etcd-certfile=/root/k8s/ssl/etcd-server.pem \ #etcd https证书路径
--etcd-keyfile=/root/k8s/ssl/etcd-server-key.pem \ #etcd https证书路径
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/root/k8scluster/data/k8s-audit.log"
上面配置中token.csv内容如下:
4218903d0f96c61ce3be55a8f61639c4,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
标红的token可以使用如下命令生成
head -c 16 /dev/urandom | od -An -t x | tr -d ' '
建立kube-controller-manager的配置文件kube-controller-manager.conf,具体内容如下:
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=true \
--v=4 \
--log-dir=/root/k8scluster/data \
--master=127.0.0.1:8080 \ #访问api-server地址,为本地不安全地址
--leader-elect=true \
--address=127.0.0.1 \
--allocate-node-cidrs=true \
--cluster-cidr=10.244.0.0/16 \ #Pod的IP地址段
--service-cluster-ip-range=10.0.0.0/24 \ # service clusterIP段,跟kube-apiserver.conf
--cluster-name=kubernetes \
--cluster-signing-cert-file=/root/k8scluster/ssl/ca.pem \
--cluster-signing-key-file=/root/k8scluster/ssl/ca-key.pem \
--root-ca-file=/root/k8scluster/ssl/ca.pem \
--service-account-private-key-file=/root/k8scluster/ssl/ca-key.pem \
--experimental-cluster-signing-duration=87600h0m0s"
建立kube-scheduler配置文件kube-scheduler.conf,具体内容如下:
KUBE_SCHEDULER_OPTS="--logtostderr=true \
--v=4 \
--log-dir=/root/k8scluster/data \
--leader-elect \
--master=127.0.0.1:8080 \
--address=127.0.0.1"
3)建立各组件的服务启动文件
kube-apiserve服务启动配置文件
vi /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/root/k8scluster/cfg/kube-apiserver.conf #配置文件所在路径
ExecStart=/root/k8scluster/bin/kube-apiserver $KUBE_APISERVER_OPTS #执行文件所在路径
Restart=on-failure
[Install]
WantedBy=multi-user.target
kube-controller-manager服务启动配置文件
vi /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/root/k8scluster/cfg/kube-controller-manager.conf #配置文件所在路径
ExecStart=/root/k8scluster/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS #执行文件所在路径
Restart=on-failure
[Install]
WantedBy=multi-user.target
kube-scheduler服务启动配置文件
vi /usr/lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/root/k8scluster/cfg/kube-scheduler.conf #配置文件所在路径
ExecStart=/root/k8scluster/bin/kube-scheduler $KUBE_SCHEDULER_OPTS #执行文件所在路径
Restart=on-failure
[Install]
WantedBy=multi-user.target
4)启动服务,运行如下命令
systemctl daemon-reload
systemctl start kube-apiserver
systemctl start kube-scheduler
systemctl start kube-controller-manager
如果一切正常,3个组件都会显示running状态
5)验证master组件安装情况
在/etc/profile末尾增加kubectl路径和相关环境变量
PATH=/root/k8s/bin:/root/k8scluster/bin:$PATH:$HOME
export KUBERNETES_MASTER="127.0.0.1:8080"
运行source /etc/profile使配置生效
最终/etc/profile末尾最后两行如下图红色框所示
在命令行运行kubectl get cs,最终结果如下图,表示master部署成功
1)生成node节点访问认证文件,在ssl目录编辑environment.sh脚步,具体内容如下:
# 创建kubelet bootstrapping kubeconfig
BOOTSTRAP_TOKEN=4218903d0f96c61ce3be55a8f61639c4 #token.csv中的token
KUBE_APISERVER=https://192.168.225.132:6443 #api-server访问地址
# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_TOKEN} \
--kubeconfig=bootstrap.kubeconfig
# 设置上下文参数
kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=bootstrap.kubeconfig
# 设置默认上下文
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
#----------------------
# 创建kube-proxy kubeconfig文件
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
--client-certificate=kube-proxy.pem \
--client-key=kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
运行脚本sh environment.sh,会生成3个新文件,分别是bootstrap.kubeconfig、kube-proxy.kubeconfig,为了方便将这2个文件复制到cfg目录
2)在cfg目录建立配置文件和配置模版
建立kubelet配置模版,文件名为kubelet.config,具体内容如下,标红ip为node ip地址
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 192.168.225.132
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDomain: cluster.local.
failSwapOn: false
authentication:
anonymous:
enabled: true
建立kubelet配置文件,文件名为kubelet,具体内容如下:
KUBELET_OPTS="--logtostderr=true \
--v=4 \
--hostname-override=192.168.225.132 \ #node节点ip
--kubeconfig=/root/k8scluster/cfg/kubelet.kubeconfig \ #接入认证文件路径
--bootstrap-kubeconfig=/root/k8scluster/cfg/bootstrap.kubeconfig \ #接入认证文件路径
--config=/root/k8scluster/cfg/kubelet.config \ #配置模版路径
--cert-dir=/root/k8scluster/ssl \ #证书存放路径
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
建立kube-proxy配置文件,文件名为kube-proxy,具体内容如下:
KUBE_PROXY_OPTS="--logtostderr=true \
--v=4 \
--hostname-override=192.168.225.132 \ #node节点ip
--cluster-cidr=10.0.0.0/24 \
--kubeconfig=/root/k8scluster/cfg/kube-proxy.kubeconfig" #接入认证文件路径
3)建立相关服务启动配置文件
kubelet服务配置文件
vi /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
After=docker.service
Requires=docker.service
[Service]
EnvironmentFile=/root/k8scluster/cfg/kubelet #配置文件所在路径
ExecStart=/root/k8scluster/bin/kubelet $KUBELET_OPTS #执行文件所在路径
Restart=on-failure
KillMode=process
[Install]
WantedBy=multi-user.target
kube-proxy服务配置文件
vi /usr/lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Proxy
After=network.target
[Service]
EnvironmentFile=/root/k8scluster/cfg/kube-proxy #配置文件所在路径
ExecStart=/root/k8scluster/bin/kube-proxy $KUBE_PROXY_OPTS #执行文件所在路径
Restart=on-failure
[Install]
WantedBy=multi-user.target
4)审批node接入请求
在master机器上,本文master和node是在同一台机器依次执行如下命令:
运行kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap
运行 kubectl get csr 会看到以node开头的请求要求
运行 kubectl certificate approve node-csr-*通过请求
再运行kubectl get csr,csr 状态变为 Approved,Issued 即可
5)标记节点
稍等片刻,运行 kubectl get node,看到新加入的节点为Ready状态,运行如下命令标记节点为master
kubectl label node 192.168.225.132 node-role.kubernetes.io/master='master'
6)部署验证,编辑一个nginx-deployment.yml文件,尝试部署nginx
yml具体内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
运行命令kubectl apply -f nginx-deployment.yml
运行kubectl get pod –all-namespaces,具体结果如下图,能看到nginx-deployment的pod,表示单机部署k8s成功
7)异常排除
kubectl logs nginx-dbddb74b8-ft88w
Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log nginx-dbddb74b8-ft88w)
解决办法:
在master上面绑定一个角色
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
提示如下:
clusterrolebinding.rbac.authorization.k8s.io/cluster-system-anonymous created
相当于把一个普通用户绑定到了管理员用户