k8s集群搭建教程
以下命令都是在root权限下进行操作的,也就是说,需要使用sudo+指令进行操作。执行如果不成功,提示Permission denied,一般都是权限不够,使用sudo用root权限进行操作即可。
1.更新系统源
如果使用Ubuntu自身带的镜像地址,服务器在国外,下载速度会很慢,可以打开/etc/apt/sources.list
替换为国内镜像。
执行
apt upgrade
2.更新软件包
将系统的软件组件更新至最新稳定版本。
apt update
3.安装docker
apt-get install docker.io
如果要配置Docker镜像加速,打开/etc/docker/daemon.json文件(这个时候一般没有这个文件,需要使用vim新建),registry-mirrors 增加或修改,加入https://registry.docker-cn.com 这个地址,也可以填写阿里云腾讯云等镜像加速地址,或者填入以下镜像:Docker:docker国内镜像加速。 重启docker,使配置生效。
sudo systemctl daemon-reload
sudo systemctl restart docker
4.安装k8s
4.1添加k8s的镜像源
打开 /etc/apt/sources.list 文件(对,没错,就是之前那个文件),添加一行
deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
4.2添加public key
这一步需要使用curl工具,没有的话使用apt-get install curl
下载工具即可,下载后执行
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add
4.3安装k8s组件
可以使用如下指令安装kubelet、kubeadm、kubectl,这样安装的是最新版本的k8s
apt-get install -y kubelet kubeadm kubectl --allow-unauthenticated
也可以指定版本进行安装,这里使用的1.18版本是可以正常搭建集群的。
apt-get install -y kubelet=1.18.0-00 kubeadm=1.18.0-00 kubectl=1.18.0-00
5.k8s初始化
5.1关闭swap
如果不关闭,kubernetes运行会出现错误, 即使安装成功了,node重启后也会出现kubernetes server运行错误。
#暂时关闭,
sudo swapoff -a
# 永久关闭
sudo vim /etc/fstab
注释掉swap那一行就行
虚拟机最好把内存分配调整到2G以上,否则关掉swap会导致图形界面难以进入。
5.2查看版本号
kubeadm version
初始化过程配置master节点,会自动从网络中下载需要的Docker镜像。但是google被墙,需要单独从别的源下载镜像。以阿里云为例,根据下面内容创建.sh脚本文件,并运行该脚本(最好使用bash运行该命令,而不要只使用sh ***.sh,这样默认的不是bash模式)。其中,kubeadm config images list
指令是用来获取k8s所需要的镜像。
for i in `kubeadm config images list`; do
imageName=${i#k8s.gcr.io/}
docker pull registry.aliyuncs.com/google_containers/$imageName
docker tag registry.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.aliyuncs.com/google_containers/$imageName
done;
执行脚本时如果报错“Error: No such image…“,那么表明拉取这个镜像失败,需要寻找别的源进行拉取。比如coredns镜像出错,可以从dockerhub上搜索该镜像。注意!自己pull的源需要将其名称进行更改成kubeadm config images list
中要求的一样。
比如pull下来的coredns,docker 显示的名称是coredns/coredns, 版本号是1.6.5
但是kubeadm config images list
中要求的形式是:k8s.gcr.io/coredns,版本号是v1.8.0,那么你需要使用如下命令进行更改
docker tag coredns/coredns:1.6.5 k8s.gcr.io/coredns:v1.8.0
这时你可以删除原来的镜像引用coredns/coredns:1.6.5,保留新的即可。
docker rmi coredns/coredns:1.6.5
5.3检查docker镜像
检查docker镜像是否pull成功,并与kubeadm config images list
进行比较
docker images
输入如下,对比版本是否正确
REPOSITORY TAG IMAGE ID CREATED SIZE
k8s.gcr.io/kube-proxy v1.17.2 cba2a99699bd 2 weeks ago 116MB
k8s.gcr.io/kube-apiserver v1.17.2 41ef50a5f06a 2 weeks ago 171MB
k8s.gcr.io/kube-controller-manager v1.17.2 da5fd66c4068 2 weeks ago 161MB
k8s.gcr.io/kube-scheduler v1.17.2 f52d4c527ef2 2 weeks ago 94.4MB
k8s.gcr.io/coredns 1.6.5 70f311871ae1 3 months ago 41.6MB
k8s.gcr.io/etcd 3.4.3-0 303ce5db0e90 3 months ago 288MB
k8s.gcr.io/pause 3.1 da86e6ba6ca1 2 years ago 742kB
5.3 master节点初始化
如果安装flannel,参数为–pod-network-cidr=10.244.0.0/16,安装calico,参数为‘–pod-network-cidr=192.168.0.0/16’,这里我们使用flannel。
在上一步成功获取所有镜像的情况下,我们使用如下命令对master节点进行初始化:
kubeadm init --pod-network-cidr=10.244.0.0/16
init成功以后,终端还会输出将node节点介入集群的命令。可以保存这条命令,便于将node节点加入,命令类似:(如果你忘记保存了,也别急,往下看就行)
kubeadm join 192.168.189.132:6443 --token u1ey5v.ivnftjikj1d7ud76 --discovery-token-ca-cert-hash sha256:c8e0a51bb5e634d675774eea98f0b759c84bd6b2b9733424257a6afa5a99814d
5.4配置授权信息
所需的命令在init成功后也会有提示,主要是为了保存相关的配置信息在用户目录下,这样不用每次都输入相关的认证信息。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
5.5查看安装情况
kubectl get pods --all-namespaces
5.6安装网络插件
这时我们发现所有的coredns pod都处于Pending状态,这是因为我们还需要安装Pod Network插件,这里我们使用flannel网络。
如果能访问到外网,可以直接执行以下命令安装网络插件:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml
如果不能访问的话,也可以自己编写一个yml文件,比如kube-flannel.yml(需要找到对应版本的网络插件,如果使用1.18版本的k8s,在文章末尾提供了对应的flannel.yml的文件内容)。
然后执行如下命令,也可以达到效果。
kubectl apply -f kube-flannel.yml
再查看所有pod的状态,等待所有的pod都变为Running状态时(这可能会需要一些时间),表明主节点初始化成功。
5.7查看节点信息
kubectl get nodes -o wide
输出如下:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
zml Ready master 32m v1.16.2 192.0.4.138 <none> Ubuntu 18.04.3 LTS 4.15.0-65-generic docker://19.3.3
6.将node节点加入集群
执行1-5.3步后,即可将该node节点加入集群
使用之前得到的语句即可:
kubeadm join 192.168.189.132:6443 --token u1ey5v.ivnftjikj1d7ud76 --discovery-token-ca-cert-hash sha256:c8e0a51bb5e634d675774eea98f0b759c84bd6b2b9733424257a6afa5a99814d
如果之前没有保存,那么可以在master主节点上执行以下命令重新获取join命令:
kubeadm token create --print-join-command
加入成功后,可以在master节点上查看所有node的信息
kubectl get nodes -o wide
等待node进入Ready状态即加入集群成功。
7.使外部能够访问
如果需要本机浏览器能够使用node的内网ip地址访问httpd提供的web服务器主页。
步骤如下:
(1)安装https
apt-get update && apt-get install -y apt-transport-https curl
(2)应用http的Deployment
(3)应用Service
这一步可以使得外部进行访问。
具体可以参考:利用k8s yaml配置文件起一个http能够让外部访问
8.其他
81.设置master节点也可以运行pod
kubectl taint nodes --all node-role.kubernetes.io/master-
此处如果有错误“at least one updat“之类,可以忽略 检查节点。
8.2重置k8s主节点
首先执行
kubeadm reset
然后系统提示需要删除$HOME/.kube/config文件,因此还需要执行
rm $HOME/.kube/config
8.3设置主机名以及后续的修改
在第4步以前,可以使用如下命令对主机名称进行修改
hostnamectl set-hostname k8smaster
然后使用如下命令查看主机名
cat /etc/hostname
最后再使用如下命令检查127.0.0.1对应的hostname是否正确,如果没改过来可以自行修改
vi /etc/hosts
如果在节点能够Init,但是后续有pod一直不能running,检查状态发现node “k8smaster” not found, 查看/etc/hosts中对应名称是否与当前主机名一致,不一致的话修改/etc/hosts中的主机名为当前主机名即可。
9.参考资料
主要参考文章:
在搭建k8s集群时自己遇到的问题及参考的解决方法:
k8s重启报错 :The connection to the server 192.168.102.149:6443 was refused
使用docker pull一个镜像时,出现Error response from daemon:…latest not found解决办法
kubernetes 使用中报错kubectl get pods The connection to the server was refused - did you specify the rig
其他问题参考:
10.kube-flannel.yml文件内容
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: psp.flannel.unprivileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
privileged: false
volumes:
- configMap
- secret
- emptyDir
- hostPath
allowedHostPaths:
- pathPrefix: "/etc/cni/net.d"
- pathPrefix: "/etc/kube-flannel"
- pathPrefix: "/run/flannel"
readOnlyRootFilesystem: false
# Users and groups
runAsUser:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
fsGroup:
rule: RunAsAny
# Privilege Escalation
allowPrivilegeEscalation: false
defaultAllowPrivilegeEscalation: false
# Capabilities
allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
defaultAddCapabilities: []
requiredDropCapabilities: []
# Host namespaces
hostPID: false
hostIPC: false
hostNetwork: true
hostPorts:
- min: 0
max: 65535
# SELinux
seLinux:
# SELinux is unused in CaaSP
rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
rules:
- apiGroups: ['extensions']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames: ['psp.flannel.unprivileged']
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-system
labels:
tier: node
app: flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
hostNetwork: true
priorityClassName: system-node-critical
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay.io/coreos/flannel:v0.14.0-rc1
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.14.0-rc1
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN", "NET_RAW"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg