本文教程来源:https://kuboard.cn/install/install-k8s.html
一、配置要求:centos7.6+
## 1、系统版本查看:
在 master 节点和 worker 节点都要执行
cat/etc/redhat-release
修改 hostname
hostnamectl set-hostname your-new-host-name
查看修改结果
hostnamectl status
设置 hostname 解析
echo"127.0.0.1 $(hostname)">> /etc/hosts
## 2、请使用 lscpu 命令,核对 CPU 信息查看;k8s集群机器最低要求:2核4G以上
lscpu
二、检查网络
[root@demo-master-a-1 ~]$ iproute show
default via172.21.0.1 dev eth0
169.254.0.0/16 dev eth0 scope link metric1002
172.21.0.0/20 dev eth0 proto kernel scope link src172.21.0.12
[root@demo-master-a-1 ~]$ ipaddress
1: lo: mtu65536qdisc noqueue state UNKNOWN group default qlen1000
link/loopback00:00:00:00:00:00 brd00:00:00:00:00:00
inet127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: mtu1500qdisc pfifo_fast state UP group default qlen1000
link/ether00:16:3e:12:a4:1b brd ff:ff:ff:ff:ff:ff
inet172.17.216.80/20 brd172.17.223.255 scope global dynamic eth0
valid_lft 305741654sec preferred_lft 305741654sec
kubelet使用的IP地址
ip route show 命令中,可以知道机器的默认网卡,通常是 eth0,如 default via172.21.0.23 dev eth0
ip address 命令中,可显示默认网卡的 IP 地址,Kubernetes 将使用此 IP 地址与集群内的其他节点通信,如172.17.216.80
所有节点上 Kubernetes 所使用的 IP 地址必须可以互通(无需 NAT 映射、无安全组或防火墙隔离)
三、安装docker及kubelet
# 卸载旧版本
yum remove-ydocker \
docker-client \
docker-client-latest \
docker-ce-cli \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
# 设置 yum repository
yum install-yyum-utils \
device-mapper-persistent-data \
lvm2
yum-config-manager--add-repohttp://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装并启动 docker
yum install-ydocker-ce-19.03.8 docker-ce-cli-19.03.8 containerd.io
systemctl enable docker
systemctlstartdocker
# 安装 nfs-utils
# 必须先安装 nfs-utils 才能挂载 nfs 网络存储
yum install-ynfs-utils
yum install-ywget
# 关闭 防火墙
systemctlstopfirewalld
systemctl disable firewalld
# 关闭 SeLinux
setenforce0
sed-i"s/SELINUX=enforcing/SELINUX=disabled/g"/etc/selinux/config
# 关闭 swap
swapoff-a
yes|cp/etc/fstab /etc/fstab_bak
cat/etc/fstab_bak |grep-vswap > /etc/fstab
# 修改 /etc/sysctl.conf
# 如果有配置,则修改
sed-i"s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g"/etc/sysctl.conf
sed-i"s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g"/etc/sysctl.conf
sed-i"s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g"/etc/sysctl.conf
sed-i"s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g"/etc/sysctl.conf
sed-i"s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g"/etc/sysctl.conf
sed-i"s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g"/etc/sysctl.conf
sed-i"s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g"/etc/sysctl.conf
# 可能没有,追加
echo"net.ipv4.ip_forward = 1">> /etc/sysctl.conf
echo"net.bridge.bridge-nf-call-ip6tables = 1">> /etc/sysctl.conf
echo"net.bridge.bridge-nf-call-iptables = 1">> /etc/sysctl.conf
echo"net.ipv6.conf.all.disable_ipv6 = 1">> /etc/sysctl.conf
echo"net.ipv6.conf.default.disable_ipv6 = 1">> /etc/sysctl.conf
echo"net.ipv6.conf.lo.disable_ipv6 = 1">> /etc/sysctl.conf
echo"net.ipv6.conf.all.forwarding = 1">> /etc/sysctl.conf
# 执行命令以应用
sysctl-p
# 配置K8S的yum源
cat< /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 卸载旧版本
yum remove-ykubelet kubeadm kubectl
# 安装kubelet、kubeadm、kubectl
# 将 ${1} 替换为 kubernetes 版本号,例如 1.17.2
yum install-ykubelet-${1}kubeadm-${1}kubectl-${1}
# 修改docker Cgroup Driver为systemd
# # 将/usr/lib/systemd/system/docker.service文件中的这一行 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# # 修改为 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd
# 如果不修改,在添加 worker 节点时可能会碰到如下错误
# [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd".
# Please follow the guide at https://kubernetes.io/docs/setup/cri/
sed-i"s#^ExecStart=/usr/bin/dockerd.*#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd#g"/usr/lib/systemd/system/docker.service
# 重启 docker,并启动 kubelet
systemctl daemon-reload
systemctlrestartdocker
systemctl enable kubelet && systemctlstartkubelet
docker version
三、初始化 master 节点
# 只在 master 节点执行
# 替换 x.x.x.x 为 master 节点的内网IP
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
exportMASTER_IP=x.x.x.x
# 替换 apiserver.demo 为 您想要的 dnsName
exportAPISERVER_NAME=apiserver.demo
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
exportPOD_SUBNET=10.100.0.1/16
echo"${MASTER_IP} ${APISERVER_NAME}">> /etc/hosts
curl-sSL./init_master.sh |sh-s1.18.3
init_master.sh
#!/bin/bash
# 只在 master 节点执行
# 脚本出错时终止执行
set-e
if[${#POD_SUBNET}-eq0] || [${#APISERVER_NAME}-eq0];then
echo-e"\033[31;1m请确保您已经设置了环境变量 POD_SUBNET 和 APISERVER_NAME \033[0m"
echo当前POD_SUBNET=$POD_SUBNET
echo当前APISERVER_NAME=$APISERVER_NAME
exit1
fi
# 查看完整配置选项 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
rm-f./kubeadm-config.yaml
cat< ./kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v${1}
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
controlPlaneEndpoint:"${APISERVER_NAME}:6443"
networking:
serviceSubnet:"10.96.0.0/16"
podSubnet:"${POD_SUBNET}"
dnsDomain:"cluster.local"
EOF
# kubeadm init
# 根据您服务器网速的情况,您需要等候 3 - 10 分钟
kubeadm init--config=kubeadm-config.yaml--upload-certs
# 配置 kubectl
rm-rf/root/.kube/
mkdir/root/.kube/
cp-i/etc/kubernetes/admin.conf /root/.kube/config
# 安装 calico 网络插件
# 参考文档 https://docs.projectcalico.org/v3.13/getting-started/kubernetes/self-managed-onprem/onpremises
echo"安装calico-3.13.1"
rm-fcalico-3.13.1.yaml
wgethttps://kuboard.cn/install-script/calico/calico-3.13.1.yaml
kubectl apply-fcalico-3.13.1.yaml
检查 master 初始化结果
# 只在 master 节点执行
# 执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态
watch kubectlgetpod-nkube-system-owide
# 查看 master 节点初始化结果
kubectlgetnodes-owide
# 只在 master 节点执行
kubeadm token create--print-join-command
# 可获取kubeadm join 命令及参数,如下所示
# kubeadm token create 命令的输出
kubeadm join apiserver.demo:6443--tokenmpfjma.4vjjg8flqihor4vt--discovery-token-ca-cert-hashsha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
五、初始化 worker节点
# 只在 worker 节点执行
# 替换 x.x.x.x 为 master 节点的内网 IP
exportMASTER_IP=x.x.x.x
# 替换 apiserver.demo 为初始化 master 节点时所使用的 APISERVER_NAME
exportAPISERVER_NAME=apiserver.demo
echo"${MASTER_IP} ${APISERVER_NAME}">> /etc/hosts
# 替换为 master 节点上 kubeadm token create 命令的输出
kubeadm join apiserver.demo:6443--tokenmpfjma.4vjjg8flqihor4vt--discovery-token-ca-cert-hashsha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
六、检查初始化结果
# 只在 master 节点执行 所有节点状态为ready状态时说明安装成功
kubectlgetnodes-owide
七、安装 Ingress Controller
# 只在 master 节点执行
kubectl apply-f./nginx-ingress.yaml
# 卸载 Ingress Controller
# 只在 master 节点执行
kubectl delete-f./nginx-ingress.yaml
nginx-ingress.yaml
# 如果打算用于生产环境,请参考 https://github.com/nginxinc/kubernetes-ingress/blob/v1.5.5/docs/installation.md 并根据您自己的情况做进一步定制
apiVersion: v1
kind: Namespace
metadata:
name: nginx-ingress
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress
namespace: nginx-ingress
---
apiVersion: v1
kind: Secret
metadata:
name: default-server-secret
namespace: nginx-ingress
type: Opaque
data:
tls.crt:LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN2akNDQWFZQ0NRREFPRjl0THNhWFhEQU5CZ2txaGtpRzl3MEJBUXNGQURBaE1SOHdIUVlEVlFRRERCWk8KUjBsT1dFbHVaM0psYzNORGIyNTBjbTlzYkdWeU1CNFhEVEU0TURreE1qRTRNRE16TlZvWERUSXpNRGt4TVRFNApNRE16TlZvd0lURWZNQjBHQTFVRUF3d1dUa2RKVGxoSmJtZHlaWE56UTI5dWRISnZiR3hsY2pDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUwvN2hIUEtFWGRMdjNyaUM3QlBrMTNpWkt5eTlyQ08KR2xZUXYyK2EzUDF0azIrS3YwVGF5aGRCbDRrcnNUcTZzZm8vWUk1Y2Vhbkw4WGM3U1pyQkVRYm9EN2REbWs1Qgo4eDZLS2xHWU5IWlg0Rm5UZ0VPaStlM2ptTFFxRlBSY1kzVnNPazFFeUZBL0JnWlJVbkNHZUtGeERSN0tQdGhyCmtqSXVuektURXUyaDU4Tlp0S21ScUJHdDEwcTNRYzhZT3ExM2FnbmovUWRjc0ZYYTJnMjB1K1lYZDdoZ3krZksKWk4vVUkxQUQ0YzZyM1lma1ZWUmVHd1lxQVp1WXN2V0RKbW1GNWRwdEMzN011cDBPRUxVTExSakZJOTZXNXIwSAo1TmdPc25NWFJNV1hYVlpiNWRxT3R0SmRtS3FhZ25TZ1JQQVpQN2MwQjFQU2FqYzZjNGZRVXpNQ0F3RUFBVEFOCkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWpLb2tRdGRPcEsrTzhibWVPc3lySmdJSXJycVFVY2ZOUitjb0hZVUoKdGhrYnhITFMzR3VBTWI5dm15VExPY2xxeC9aYzJPblEwMEJCLzlTb0swcitFZ1U2UlVrRWtWcitTTFA3NTdUWgozZWI4dmdPdEduMS9ienM3bzNBaS9kclkrcUI5Q2k1S3lPc3FHTG1US2xFaUtOYkcyR1ZyTWxjS0ZYQU80YTY3Cklnc1hzYktNbTQwV1U3cG9mcGltU1ZmaXFSdkV5YmN3N0NYODF6cFErUyt1eHRYK2VBZ3V0NHh3VlI5d2IyVXYKelhuZk9HbWhWNThDd1dIQnNKa0kxNXhaa2VUWXdSN0diaEFMSkZUUkk3dkhvQXprTWIzbjAxQjQyWjNrN3RXNQpJUDFmTlpIOFUvOWxiUHNoT21FRFZkdjF5ZytVRVJxbStGSis2R0oxeFJGcGZnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
tls.key:LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBdi91RWM4b1JkMHUvZXVJTHNFK1RYZUprckxMMnNJNGFWaEMvYjVyYy9XMlRiNHEvClJOcktGMEdYaVN1eE9ycXgrajlnamx4NXFjdnhkenRKbXNFUkJ1Z1B0ME9hVGtIekhvb3FVWmcwZGxmZ1dkT0EKUTZMNTdlT1l0Q29VOUZ4amRXdzZUVVRJVUQ4R0JsRlNjSVo0b1hFTkhzbysyR3VTTWk2Zk1wTVM3YUhudzFtMApxWkdvRWEzWFNyZEJ6eGc2clhkcUNlUDlCMXl3VmRyYURiUzc1aGQzdUdETDU4cGszOVFqVUFQaHpxdmRoK1JWClZGNGJCaW9CbTVpeTlZTW1hWVhsMm0wTGZzeTZuUTRRdFFzdEdNVWozcGJtdlFmazJBNnljeGRFeFpkZFZsdmwKMm82MjBsMllxcHFDZEtCRThCay90elFIVTlKcU56cHpoOUJUTXdJREFRQUJBb0lCQVFDZklHbXowOHhRVmorNwpLZnZJUXQwQ0YzR2MxNld6eDhVNml4MHg4Mm15d1kxUUNlL3BzWE9LZlRxT1h1SENyUlp5TnUvZ2IvUUQ4bUFOCmxOMjRZTWl0TWRJODg5TEZoTkp3QU5OODJDeTczckM5bzVvUDlkazAvYzRIbjAzSkVYNzZ5QjgzQm9rR1FvYksKMjhMNk0rdHUzUmFqNjd6Vmc2d2szaEhrU0pXSzBwV1YrSjdrUkRWYmhDYUZhNk5nMUZNRWxhTlozVDhhUUtyQgpDUDNDeEFTdjYxWTk5TEI4KzNXWVFIK3NYaTVGM01pYVNBZ1BkQUk3WEh1dXFET1lvMU5PL0JoSGt1aVg2QnRtCnorNTZud2pZMy8yUytSRmNBc3JMTnIwMDJZZi9oY0IraVlDNzVWYmcydVd6WTY3TWdOTGQ5VW9RU3BDRkYrVm4KM0cyUnhybnhBb0dCQU40U3M0ZVlPU2huMVpQQjdhTUZsY0k2RHR2S2ErTGZTTXFyY2pOZjJlSEpZNnhubmxKdgpGenpGL2RiVWVTbWxSekR0WkdlcXZXaHFISy9iTjIyeWJhOU1WMDlRQ0JFTk5jNmtWajJTVHpUWkJVbEx4QzYrCk93Z0wyZHhKendWelU0VC84ajdHalRUN05BZVpFS2FvRHFyRG5BYWkyaW5oZU1JVWZHRXFGKzJyQW9HQkFOMVAKK0tZL0lsS3RWRzRKSklQNzBjUis3RmpyeXJpY05iWCtQVzUvOXFHaWxnY2grZ3l4b25BWlBpd2NpeDN3QVpGdwpaZC96ZFB2aTBkWEppc1BSZjRMazg5b2pCUmpiRmRmc2l5UmJYbyt3TFU4NUhRU2NGMnN5aUFPaTVBRHdVU0FkCm45YWFweUNweEFkREtERHdObit3ZFhtaTZ0OHRpSFRkK3RoVDhkaVpBb0dCQUt6Wis1bG9OOTBtYlF4VVh5YUwKMjFSUm9tMGJjcndsTmVCaWNFSmlzaEhYa2xpSVVxZ3hSZklNM2hhUVRUcklKZENFaHFsV01aV0xPb2I2NTNyZgo3aFlMSXM1ZUtka3o0aFRVdnpldm9TMHVXcm9CV2xOVHlGanIrSWhKZnZUc0hpOGdsU3FkbXgySkJhZUFVWUNXCndNdlQ4NmNLclNyNkQrZG8wS05FZzFsL0FvR0FlMkFVdHVFbFNqLzBmRzgrV3hHc1RFV1JqclRNUzRSUjhRWXQKeXdjdFA4aDZxTGxKUTRCWGxQU05rMXZLTmtOUkxIb2pZT2pCQTViYjhibXNVU1BlV09NNENoaFJ4QnlHbmR2eAphYkJDRkFwY0IvbEg4d1R0alVZYlN5T294ZGt5OEp0ek90ajJhS0FiZHd6NlArWDZDODhjZmxYVFo5MWpYL3RMCjF3TmRKS2tDZ1lCbyt0UzB5TzJ2SWFmK2UwSkN5TGhzVDQ5cTN3Zis2QWVqWGx2WDJ1VnRYejN5QTZnbXo5aCsKcDNlK2JMRUxwb3B0WFhNdUFRR0xhUkcrYlNNcjR5dERYbE5ZSndUeThXczNKY3dlSTdqZVp2b0ZpbmNvVlVIMwphdmxoTUVCRGYxSjltSDB5cDBwWUNaS2ROdHNvZEZtQktzVEtQMjJhTmtsVVhCS3gyZzR6cFE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
namespace: nginx-ingress
data:
server-names-hash-bucket-size:"1024"
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: nginx-ingress
rules:
-apiGroups:
-""
resources:
-services
-endpoints
verbs:
-get
-list
-watch
-apiGroups:
-""
resources:
-secrets
verbs:
-get
-list
-watch
-apiGroups:
-""
resources:
-configmaps
verbs:
-get
-list
-watch
-update
-create
-apiGroups:
-""
resources:
-pods
verbs:
-list
-apiGroups:
-""
resources:
-events
verbs:
-create
-patch
-apiGroups:
-extensions
resources:
-ingresses
verbs:
-list
-watch
-get
-apiGroups:
-"extensions"
resources:
-ingresses/status
verbs:
-update
-apiGroups:
-k8s.nginx.org
resources:
-virtualservers
-virtualserverroutes
verbs:
-list
-watch
-get
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: nginx-ingress
subjects:
-kind: ServiceAccount
name: nginx-ingress
namespace: nginx-ingress
roleRef:
kind: ClusterRole
name: nginx-ingress
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-ingress
namespace: nginx-ingress
annotations:
prometheus.io/scrape:"true"
prometheus.io/port:"9113"
spec:
selector:
matchLabels:
app: nginx-ingress
template:
metadata:
labels:
app: nginx-ingress
spec:
serviceAccountName: nginx-ingress
containers:
-image: nginx/nginx-ingress:1.5.5
name: nginx-ingress
ports:
-name: http
containerPort:80
hostPort:80
-name: https
containerPort:443
hostPort:443
-name: prometheus
containerPort:9113
env:
-name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
-name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
args:
--nginx-configmaps=$(POD_NAMESPACE)/nginx-config
--default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
--enable-prometheus-metrics
docker镜像加速配置
mkdir-p/etc/docker
tee/etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://osscyeho.mirror.aliyuncs.com"]
}
EOF
# 重启docker、kubelet
systemctl daemon-reload
systemctlrestartdocker
systemctlstartkubelet# 假设您安装了 kubenetes