文章目录
- 前言
- 使用到的各种软件的版本
- VMware Workstation
- CentOS 7
- Docker
- k8s
- 实验流程
- 虚拟机的下载安装
- 使用xshell连接虚拟机
- 修改hostname
- 安装Docker(所有节点都要安装)(参考[CentOS搭建K8S环境教程](https://cloud.tencent.com/developer/article/1709491)即可)
- 配置k8s环境(所有节点都要配置)
- 安装k8s(所有节点)
- 初始化Master节点(只在Master上)
- 从节点加入集群
- Docker镜像打包,上传(Master节点)
- 部署到Kubernetes中
前言
我在做实验的时候还没有火炬,而且实验指导书过于粗糙(并且有的指令是错误的),在经历了相当痛苦的一段时间才将这个实验完成。于是就想将这里实验过程记录下来,让学弟学妹少走一些弯路。这份文档主要记录了我做实验的过程以及中间遇到的问题及解决办法。
本次实验建议使用CentOS 7,不建议使用Ubuntu。实验指导书上的教程是在CentOS下的教程,部署k8s时CentOS和Ubuntu有一些区别。刚开始大家都选择在比较熟悉的Ubuntu下做实验,但是很快便都换成了CentOS。所以,别浪费时间,直接用CentOS做吧。
我是使用两台虚拟机部署的网络,根据我多次推倒重做的经验,使用虚拟机和使用老师提供的服务器会遇到不一样的错误。如果要参考我的实验流程,建议使用虚拟机,同时虚拟机和k8s、docker就和我用一样的版本,不然可能会遇到各种各样的问题。此外要注意的是,CentOS 6和CentOS 7在一些指令上并不相同,如果实验过程中遇到问题上网找解决办法时注意网上给的是CentOS 6下的指令还是CentOS 7下的指令
本文主要参考了实验指导书以及CentOS搭建K8S环境教程
使用到的各种软件的版本
VMware Workstation
CentOS 7
在网站阿里云镜像链接下选择CentOS-7-x86_64-DVD-2009.iso即可
Docker
18.09.9
k8s
1.17.3
实验流程
虚拟机的下载安装
因为需要一个主节点和一个从节点,所以需要安装两台虚拟机,两台虚拟机均按照相同的办法安装即可。
iso文件并不需要下载两个,两个虚拟机可以使用同一个iso文件
在上文的链接中下载好虚拟机之后,可以按照如下流程进行安装。
在这里选择虚拟机的名称以及存储位置
这里我没记错的话,选择1*1的处理器配置k8s将无法正常工作,我选择的是2*2的
我在这里给每一台机器分配了4096MB的空间
我在这里选择了默认的大小20GB
点击如下位置的浏览选择自己下载的iso文件
之后点击完成即可。
之后点击开启虚拟机,用键盘选择Install CentOS7之后按enter即可
在页面内输入chinese选择中文,点击继续
可以选择“软件安装”安装其他软件包,例如安装GNome桌面,最小安装的有点是体积小安装快,但是他只能通过命令行操作。同时这个软件包不带有vim,实验过程中遇到vim指令时需要将vim换成vi
配置磁盘,进去之后点左上角的完成即可。
点击这里可以设置root密码,也就是以root模式运行时的密码。
之后点击重启即可
重启之后可以看到下面的画面,login的位置输入root即可,password即为上面设置过的密码。这样虚拟机就安装好了,这是一个只有命令行模式的虚拟机
使用xshell连接虚拟机
直接在虚拟机上进行实验不如使用xshell方便,可以参考下面的文章使用xshell连接虚拟机
shell连接本地虚拟机centos_kong___的博客-CSDN博客
修改hostname
虚拟机上hostname的值是默认的,这样在查看k8s的节点状态时将无法区分不同的节点,所以我们更改hostname。最好早一点更改hostname,配置好k8s之后再更改hostname会比较麻烦,还会有其他问题。
直接使用如下指令更改hostname即可
hostnamectl set-hostname name
安装Docker(所有节点都要安装)(参考CentOS搭建K8S环境教程即可)
# 安装docker所需的工具
yum install -y yum-utils device-mapper-persistent-data lvm2
# 配置阿里云的docker源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 指定安装这个版本的docker-ce
yum install -y docker-ce-18.09.9-3.el7
# 启动docker
systemctl enable docker && systemctl start docker
配置k8s环境(所有节点都要配置)
# 关闭防火墙
systemctl disable firewalld
systemctl stop firewalld# 关闭selinux
# 临时禁用selinux
setenforce 0
# 永久关闭 修改/etc/sysconfig/selinux文件设置
sed -i 's/SELINUX=permissive/SELINUX=disabled/' /etc/sysconfig/selinux
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config# 禁用交换分区
swapoff -a
# 永久禁用,打开/etc/fstab注释掉swap那一行。
sed -i 's/.*swap.*/#&/' /etc/fstab# 修改内核参数
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system# 安装 Kubernetes 和 docker
cat <<EOF > /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.gpghttp://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
安装k8s(所有节点)
实验指导书上的指令安装的是最新的k8s,但是最好选择1.23以及以下的k8s版本,否则会存在版本兼容问题,这里选择1.17.3
yum install -y kubectl-1.17.3-0 kubeadm-1.17.3-0 kubelet-1.17.3-0
systemctl enable kubelet && systemctl start kubelet
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --systemmkdir -p /etc/cni/net.d
初始化Master节点(只在Master上)
实验指导书上的指令为
kubeadm init --pod-network-cidr=192.168.0.0/16 --kubernetes-version=v1.17.3
--apiserver-advertise-address=192.168.56.101
注意在kubernetes-version
字段规定了k8s的版本,我们需要将其改成刚刚安装的版本,在这里也就是1.17.3。同时将apiserver-advertise-address
中的内容改成Master节点的IP地址。这里,我执行的指令如下所示,在指令中规定了使用阿里云的镜像,可以加快速度。--token-ttl 0
可以让我们生成的集群密钥变成永久密钥,否则其有效期默认只有一天
kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.17.3 --apiserver-advertise-address 192.168.179.132 --pod-network-cidr=192.168.0.0/16 --token-ttl 0
init成功之后我们可以得到如下指令
在Master节点中使用第一段指令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
从节点加入集群时可以使用第二段指令
kubeadm join 192.168.179.132:6443 --token y8r2c0.7vhn3111ewy9vav0 \--discovery-token-ca-cert-hash sha256:106ac3177ff1cc2532902677a798e1430406b841c3fa1d48f1247bdd8e7f61ce
从节点加入集群
在从节点中使用上面的join指令,在从节点中使用指令kubectl get nodes
,如下提示:
The connection to the server localhost:8080 was refused - did you specify the right host or port?
按照文章https://blog.csdn.net/tearofthemyth/article/details/113146166中的方法可以解决问题,注意如果没有配置IP映射的话需要将下面的master换成主节点的IP地址
之后在主节点或者从节点执行kubectl get nodes
,均可以看到下面的提示信息
在主节点和从节点中均使用kube-flannel.yml(已修改镜像下载数据源)中的方法(和指导书上的指令kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml是一个道理,有人用指导书上的指令一遍就跑通了,但是我这里不行,所以我使用了其他办法。使用上面文章中的方法可以解决一部分问题,但是其他地方仍然存在错误,所以之后可以看到节点状态仍然是NotReady),之后看到节点状态仍然是NotReady。使用指令kubectl get pods -n kube-system
定位是哪个组件出现了问题,可以看到是这两个
使用kubectl describe pod coredns-9d85f5447-22qn2
查看详细信息
在文章https://blog.csdn.net/baidu_38803985/article/details/105966464中看到可能是因为没有本地IP解析,所以尝试在/etc/hosts更改本地IP解析,添加如下的两行即可,注意hostname要换成自己的,使用hostname指令可以直接查看虚拟机的的hostname
在主从节点均设置完之后那两个pod仍然是pending状态。
之后使用如下指令查看日志
journalctl -f -u kubelet.service
可以看到如下错误信息
根据文章https://blog.csdn.net/qq_29385297/article/details/127682552中的方法可以解决问题,主节点和从节点都要进行这一步操作
之后查看node的状态,可以看到全部转变为ready了
Docker镜像打包,上传(Master节点)
按照指导书上的指示,创建一个文件夹hello_kube并且添加下面两个文件。
server.js:
var http = require('http');
console.log('Heeeee');
var handleRequest = function(request, response) {console.log('Received request for URL: ' + request.url);response.writeHead(200);response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);
console.log('Listening')
Dockerfile:
FROM node:6.14.2
EXPOSE 8080
COPY server.js .
CMD node server.js
接下来执行指令
docker build -t hello_world:v2 . #(别忘了这里有个点)
使用 docker images
可以查看镜像
同时按照指导书上的办法进行注册和push,这里由于我之前已经push过了便不再演示,如果失败的话极有可能是因为网络问题,我在服务器上进行实验的时候push很快就完成了,但是在虚拟机上变得特别慢,不知道是因为什么原因。注意要将下面的USERNAME换成自己的用户名,同时只能是小写,就算注册时使用了大写这里也要改成小写,我没有记错的话这里也不能使用邮箱,只能用用户名
部署到Kubernetes中
按照实验指导书,在 master 节点上,新建文件:注意将 image 修改为自己刚刚上传的。
这里有一个很坑的地方,yaml文件的缩进只能使用空格不能使用tab。并且yaml文件是根据缩进的格数来确定各个属性的,所以对缩进有着很严格的要求,但是如果直接从pdf上直接复制粘贴文件内容,文本将会失去之前的格式,建议直接用下面的配置文件即可,我已经调整好了格式,别忘了将image修改为自己刚刚上传的USERNAME/hello_world:v2
apiVersion: v1
kind: Service
metadata:name: hello-world
spec:type: NodePortports:- port: 80targetPort: 8080nodePort: 31611selector:app: hello-world
---
apiVersion: apps/v1
kind: Deployment
metadata:name: hello-world
spec:replicas: 3selector:matchLabels:app: hello-worldtemplate:metadata:labels:app: hello-worldspec:containers:- name: hello-worldimage: USERNAME/hello_world:v2ports:- containerPort: 8080
之后执行指令
kubectl create -f ./hello_world.yaml
使用kubectl get pods
查看pod情况
发现pod处于ContainerCreating状态,使用kubectl describe pod hello-world-7fc4b95f8f-dtm4z
指令查看具体状态
k8s中默认Master节点是不工作,只负责管理调动。我们刚刚在Master节点中完成的push和部署的,然而工作任务实际上要在从节点上执行,也就是说目前从节点一直在尝试从Docker的库中拉取镜像,得到镜像之后才可以进行工作。但是镜像所在的服务器,也就是你刚刚push到的地方在国外,因为一些不能明说的原因,pull变得非常非常慢而且还经常失败。所以我想到,我直接从Master节点上传一份image到从节点不久可以了吗?
按照https://haicoder.net/docker/docker-save.html中的方法使用docker save将Master中的image打包,之后使用scp指令(scp的使用方法可以参考https://blog.csdn.net/orangefly0214/article/details/81635124)或者xftp将文件传输到从节点中,在从节点中使用docker load指令即可加载镜像(docker load指令可以参考docker常用命令-docker load)。之后使用kubectl get pods
可以看到所有pod都正常运行。
可以在自己的Windows系统上直接访问192.168.179.133:31611,可以看到如下内容,如果是在服务器上完成的实验,可以使用wegt指令进行查看
之后在Master上使用指令kubectl scale Deployment hello-world --replicas=10
进行扩容即可,这一步应该不会遇到什么问题。
到这里实验3就完成了