k8s安装部署以及部署过程中的那些坑!!!

此篇文章主要分享的是使用yum安装部署k8s的方式。有些小伙伴想使用kubeadm的方式安装部署,本人也亲自测试过,太麻烦了,后期的k8s配置先不说,但是各种k8s部署过程中所需要的镜像无法pull下来就够喝一壶的了,因为这些镜像大都在外网。

有些文章分享的部署方法完全没有说明部署环境,也没有说明k8s的版本和相应的docker版本,完全属于耍流氓。因为k8s版本和docker版本是存在兼容问题的,不兼容的版本是无法让k8s成功运行的。下面我会和大家分享一个方法,而无需自己去关心自己下载的k8s软件包和docker软件包是否兼容。

环境准备:

一、虚拟机初始配置

i、三台虚拟机的CPU核数必须要大于1,否则无法配置成功
ii、三台虚拟机的内存配置都必须大于等于2G

#修改主机名
1、hostnamectl set-hostname master
2、hostnamectl set-hostname node1
3、hostnamectl set-hostname node2

#修改主机映射(三台虚拟机都需要做)
vim /etc/hosts
  ...
  10.0.0.10   master
  10.0.0.11   node1
  10.0.0.12   node2

二、操作系统配置

#系统版本
我使用的CentOS 7.5版本,建议初学者也使用这个版本,否则很容易无法配置成功

#内核版本
将Linux的内核的版本升级到最新,不建议使用 "kernel-3.10.0"版本,这个版本有些bug。

如何升级操作操作系统版本和内核版本,可以参看这篇文章:CentOS 7 修改内核版本

三、关闭防火墙、selinux

#关闭三台虚拟机上的防火墙
systemctl stop firewalld
systemctl disable firewalld

#关闭selinux
vim /etc/selinux/config
  ...
  SELINUX=disabled

四、关闭Swap

#关闭swap
swapoff -a

#编辑/etc/fstab文件,将swap挂载的信息注释掉,这样虚拟机重启后swap便不会又自动打开了
vim /etc/fstab
  ...
  # /dev/mapper/centos-swap swap         swap    defaults        0 0

tip:到这里有小伙伴可能就有疑问了?问什么要关闭防火墙、selinux、swap

i、关于防火墙的原因(nftables后端兼容性问题,产生重复的防火墙规则)

#部署文档说明

Theiptablestooling can act as a compatibility layer, behaving like iptables but actually 
configuring nftables. This nftables backend is not compatible with the current kubeadm 
packages: it causes duplicated firewall rules and breakskube-proxy.

ii、关于selinux的原因(关闭selinux以允许容器访问宿主机的文件系统)

#部署文档说明

Setting SELinux in permissive mode by runningsetenforce 0andsed ...effectively disables it. 
This is required to allow containers to access the host filesystem, which is needed by pod 
networks for example. You have to do this until SELinux support is improved in the kubelet.

iii、关于swap关闭的原因

k8s的设计者们觉得允许Pod使用Swap,如何去衡量默认的Swap设置、以及调度器应该如何根据Swap来进行调度?
讨论一段时间后,发现支持Swap很复杂,而是k8s现实应用中也很少用到Swap,所以直接默认不用了

 五、修改 sysctl 配置

对于 RHEL/CentOS 7 系统,可以会由于 iptables 被绕过导致网络请求被错误的路由。所以还需执行如下命令保证 sysctl 配置中 net.bridge.bridge-nf-call-iptables 被设为1。

#所有节点都要操作

i、使用 vi 命令编辑相关文件:
   vi /etc/sysctl.conf
      ...
     net.bridge.bridge-nf-call-ip6tables = 1
     net.bridge.bridge-nf-call-iptables = 1
     net.ipv4.ip_forward = 1

ii、最后执行如下命令即可:
   sysctl -p

k8s安装部署

一、Master虚拟机上操作

i、下载etcd、kubernetes-master服务安装包
[root@master ~] # yum install -y etcd kubernetes-master

ii、编辑etcd服务的配置文件
[root@master ~] # vim /etc/etcd/etcd.conf
   ...
  ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"    
   ...
  ETCD_ADVERTISE_CLIENT_URLS="http://10.0.0.10:2379"     #指定etcd服务的地址和端口号  是ETCD_LISTEN_CLIENT_URLS参数指定的地址:端口的子集
iii、编辑k8s服务master端的配置文件:apiserver
[root@master ~] # vim /etc/kubernetes/apiserver
  ...
  KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"     #可以访问的api-server的地址   0.0.0.0表示任何内外部请求,都可以通过 insecure-port 端口任意操作k8s集群(这样的配置是非常危险的,相当于整个k8s集群在裸奔,需要一定的安全配置)
  KUBE_API_PORT="--port=8080"       #地址绑定到不安全服务端口,(将来会被remove)
  KUBELET_PORT="--kubelet-port=10250"                                                                                                                                         
  KUBE_ETCD_SERVERS="--etcd-servers=http://10.0.0.10:2379"
  KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"     #service的网段
  KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"  #去掉ServiceAccount参数,因为ServiceAccount验证证书在外网上,无法获取到

iv、编辑k8s服务master端的配置文件:config
[root@master ~] # vim /etc/kubernetes/config
  ...
  KUBE_MASTER="--master=http://10.0.0.10:8080"       #指定master的地址、端口

v、启动k8s的master端的服务
[root@master ~] # for SERVICE in etcd kube-apiserver kube-controller-manager kube-scheduler;do systemctl enable ${SERVICE};systemctl start ${SERVICE};done

vi、在etcd中定义flannel网络
[root@master ~] # etcdctl mk /atomic.io/network/config '{"Network":"172.17.0.0./16"}'  #为什么使用/atomic.io/network/config这个key,下面安装flannel插件时会说明

二、node虚拟机上操作

#以下操作node1、node2两个节点都要操作,我只演示了在node1上的操作
i、安装k8s node端的安装包
[root@node1 ~] # yum install -y kubernetes-node

ii、编辑k8s node端的配置文件:config
[root@node1 ~] # vim /etc/kubernetes/config
   ...
  KUBE_MASTER="--master=http://10.0.0.10:8080"
   ...

iii、编辑k8s node端的配置文件:kubelet
[root@node1 ~] # vim /etc/kubernetes/kubelet
   ...
   KUBELET_ADDRESS="--address=10.0.0.31"        #指定node1节点的地址
   KUBELET_HOSTNAME="--hostname-override=node1"      #指定node1节点的主机名
   KUBELET_API_SERVER="--api-servers=http://10.0.0.10:8080"     #告诉node1节点master中apiserver的地址、端口
   KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=10.0.0.10:5000/cxs/pod-infrastructure:latest"      #指定从自建的私有仓库中获取Pod的基础架构镜像
   --allow-privileged=true      #允许特权
   KUBELET_ARGS="--cluster-dns=10.0.0.10 --cluster-domain=playcrab-inc.com"    #配置k8s集群的dns

iv、开去node端所有k8s相关的服务
[root@node1 ~] # for SERVICE in kubelet kueb-proxy docker;do systemctl enable ${SERVICE};systemctl start ${SERVICE};done

1、KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=10.0.0.10:5000/cxs/pod-infrastructure:latest"

2、--allow-privileged=true

3、KUBELET_ARGS="--cluster-dns=10.0.0.10 --cluster-domain=playcrab-inc.com"

这三个参数要特别注意,很多坑和这三个参数有关!!!下面会细讲。

三、部署flannel网络插件

#flannel插件的作用,这里就不展开讲了,可以去我博客或者百度里查看一下。

以下操作在master、node节点上都要做,只演示在node1上的操作
i、下载flannel插件
[root@node1 ~] # yum install -y flannel

ii、编辑flannel配置文件
[root@node1 ~] # vim /etc/sysconfig/flanneld
   ...
  FLANNEL_ETCD_ENDPOINTS="http://10.0.0.10:2379"    #告诉flannel服务etcd服务的地址 
  FLANNEL_ETCD_PREFIX="/atomic.io/network"         #此参数随不需要配置,但是需要此参数的值和etcd建立关联

iii、启动flannel服务
[root@node1 ~] # systemctl enable flanneld
[root@node1 ~] # systemctl start flanneld


以下在master节点上操作
i、查看运行的node节点
[root@master ~] # kubectl get nodes
NAME      STATUS    AGE
node1     Ready     3m
node2     Ready     5m

#出现上面的结果,就表明k8s已经安装完成了

配置私有镜像仓库

在k8s中必须要配置私有镜像仓库,因为k8s集群一般管理的都是成千上万台容器,不建立镜像仓库,从其它镜像网站拉去镜像时就会非常慢。

配置本地私有镜像仓库要在master节点上操作

i、在master节点上启动docker,此时就会发现。master节点上并没有安装docker的软件。心细的小伙伴可能
会在node端安装kubernetes-node软件包时发现,安装kubernetes-node软件包时,会自动下载相应的docker版
本的软件包的,所以根据node端上docker软件包的版本,在master端上下载相同版本的docker软件包
[root@node1 ~] # rpm -qa | grep docker    #查看docker软件包的版本
    ...

[root@master ~] #  yum install -y xxx       #在master端下载相应版本的软件包


ii、编辑docker配置文件
[root@master ~] # vim /etc/sysconfig/docker    #master和node端时相同的配置
   ...
  OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false  --insecure-registry=10.0.0.10:5000'     #指定私有镜像仓库的地址

iii、启动docker服务    #master和node端都要启动
[root@master ~] # systemctl start docker

iv、使用 registry镜像 启动本地镜像仓库
[root@master ~] # docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry  registry
[root@master ~] # docker tag nginx 10.0.0.11:5000/oldguo/nginx:v1    #对本地的nginx镜像进行打标,若是镜像没有打标,则无法上传到私有镜像仓库中
[root@master ~] # docker push 10.0.0.11:5000/oldguo/nginx:v1       #将打标好的镜像上传到私有镜像中,这样node端就可以从私有镜像中拉取镜像了

tip:这里说一下"/etc/docker/daemon.json"和"/etc/sysconfig/docker"的区别:

有些小伙伴之前有了解过docker,就认为docker的配置文件不应该是"/etc/docker/daemon.json"嘛?关于docker启动时使用的是哪个配置文件,最好查看一下"docker.service"启动文件,"EnvironmentFile"参数会指定docker启动使用的配置文件。

PODS的创建

master端操作
i、编辑yml文件
[root@master ~] # mkdir /opt/yml
[root@master ~] # cd /opt/yml
[root@master yml] # vim k8s_pod.yml
  apiVersion: v1
  kind: Pod
  metadata:
    name: nginx      #pod的名称
    labels:
      app: web      # 标签名称    Kubernetes中的任意API对象都是通过Label进行标识
  spec:
    containers:
      - name: nginx
        image: 10.0.0.11:5000/oldguo/nginx:v1    #指定容器启动依赖的镜像文件
        ports:
          - containerPort: 80

ii、创建Pods
[root@master yml] # kubectl create -f k8s_pod.yml
[root@master yml] # kubectl get pod      #查询资源是否创建成功

Pod创建过程中容易出现的坑!!!

1、状态为 "Pending"

第一步:
[root@master ~] # kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
nginx     0/1       Pending   0          16s

第二步:
[root@master ~] # kubectl describe pod nginx      #查看nginx所在pod的详细信息
   ...
  No Events           #显示的是没有事件信息,也就无法得知哪里出错了

第三步:
[root@master ~] # kubectl describe node node1    #查看node端节点上的信息
   ...
  Events:       #定位到Events,来查看问题出在了那里
  FirstSeen	LastSeen	Count	From		SubObjectPath	Type		Reason			Message
  ---------	--------	-----	----		-------------	--------	------			-------
  12m		12m		1	{kubelet node2}			Normal		Starting		Starting kubelet.
  12m		12m		1	{kubelet node2}			Warning		ImageGCFailed		unable to find data for container / 
  12m		12m		2	{kubelet node2}			Normal		NodeHasSufficientDisk	Node node2 status is now: NodeHasSufficientDisk
  12m		12m		2	{kubelet node2}			Normal		NodeHasSufficientMemory	Node node2 status is now: NodeHasSufficientMemory
  12m		12m		2	{kubelet node2}			Normal		NodeHasNoDiskPressure	Node node2 status is now: NodeHasNoDiskPressure
  12m		12m		1	{kubelet node2}			Normal		NodeReady		Node node2 status is now: NodeReady

#有以上报错的时候,就说明你没有在kubelet配置文件中配置 "--allow-privileged=true"。配置成功后,重新启动kubelet服务。

2、状态为 "ContainerCreating"

第一步:
[root@master yml] # kubectl get pods
NAME      READY     STATUS              RESTARTS   AGE
nginx     0/1       ContainerCreating   0          6s

第二步:
[root@master yml] # kubectl describe pod nginx     #查看详细信息
   ...
  Events:     #定位到Events,查看报错情况
  FirstSeen	LastSeen	Count	From			SubObjectPath	Type	 Reason		Message
  ---------	--------	-----	----			-------------	-------- ------		-------
  27s		27s		1	{default-scheduler }			Normal	 Scheduled	Successfully assigned nginx to node1
  		2	{kubelet node1}				Warning	 FailedSync	Error syncing pod, skipping: failed to "StartContainer" for "POD" with ErrImagePull: "image pull failed for registry.access.redhat.com/rhel7/pod-infrastructure:latest, this may be because there are no credentials on this request.  details: (open /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt: no such file or directory)"      #pod-infrastructure:latest基础镜像找不到

********************************************************************************************************************
pod基础架构的镜像,每开启一个pod,都需要开启一个pod-infrastructure镜像容器。因为没有设置验证证书,所以无法进入外网,所以只能将别人从外网获取的镜像拿来使用。
所以我之前的配置中,将docker配置文件获取镜像的途径改为了自己搭建的私有镜像仓库,这样就可以把从外网获取到的镜像文件上传到私有镜像仓库中供k8s使用
********************************************************************************************************************

#修改之后重启docker服务,重新创建Pod就不会在出现这错误

3、报错为 "kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. Falling back to DNSDefault policy."

#在遇到这种情况时,有可能你的Pod已经创建成功了,但是查看Pod的详细信息时就会报上面的这个错误,这是因为没有设置集群的DNS所导致的
[root@node1 ~] # vim /etc/kubernetes/kubelet
   ...
  KUBELET_ARGS="--cluster-dns=10.0.0.10 --cluster-domain=playcrab-inc.com"  #在node端节点的kubelet配置文件中配置此参数即可


#配置完kubelet配置文件后,要重启kubelet服务

 

 

你可能感兴趣的:(k8s安装部署以及部署过程中的那些坑!!!)