Kubernetes安装配置指南以及kubectl命令行示例——Kubernetes权威指南(第二章)

Kubernetes安装配置指南以及kubectl命令行示例

安装配置环境为CentOS7。使用Systemd系统完成对Kubernetes的配置。为了便于管理,常见的做法是将K8S服务程序配置为Linux系统开机自动启动的服务。Master和Node间会有大量通信,CentOS7又开启了firewalld,安全的做法是在防火墙上配置各组件需要相互通信的端口号。内网中可以关闭防火墙服务:

systemctl disable firewalld
systemctl stop firewalld
另外,建议在主机上禁用SELinux,让容器可以读取主机文件系统:
setenforece 0
或修改系统文件/etc/sysconfig/selinux,将SELINUX=enforcing修改成SELINUX=disabled,再重启即可。

Kubernetes需要容器运行时CRI(Container Runtime Interface,CRI)的支持,目前官方支持的CRI包括:Docker、Containerd、CRI-O和frakti。

使用kubeadm工具快速安装k8s

最简单的方法是yum install kubernetes命令安装K8S集群,但仍需修改各组件的启动参数,才能完成对K8S集群的配置,整个过程比较复杂。后来v1.4后引入kubeadm。

安装 kubeadm和相关工具
vim /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes Repository
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0

然后运行yum install 命令安装kubeadm和相关工具:

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

再启动Docker服务(如果已安装docker,则无须再次启动)和kubelet服务,并设置为开机自动启动:

systemctl enable docker && systemctl start docker
systemctl enable kubelet && systemctl start kubelet
kubeadm config

kubeadm已经进入GA阶段,其控制面初始化和加入节点步骤都支持大量的可定制内容。kubeadm将配置文件以ConfigMap的形式保存到集群之中,便于后续的查询和升级工作。kubeconfig 子命令提供了对这一组功能的支持:

  • kubeadm config upload from-file:由配置文件上传到集群中生成ConfigMap;
  • kubeadm config upload from-flags:由配置参数生成ConfigMap
  • kubeadm config view:查看当前集群中的配置值
  • kubeadm config print init-defaults:输出kubeadm init默认参数文件的内容
  • kubeadm config print join-defaults:输出kubeadm join默认参数文件的内容
  • kubeadm config migrate:在新旧版本之间进行配置转换
  • kubeadm config images list:列出所需的镜像列表
  • kubeadm config images pull:拉取镜像到本地

获得初始化参数文件:

kubeadm config print init-defaults > init.default.yaml

对生成的文件进行编辑,可以按需生成合适的配置。例如,若需要定制镜像仓库的地址,以及Pod的地址范围,则可以使用如下配置:

apiVersion:kubeadm.k8s.io/v1beta1
kind:ClusterConfiguration
imageRepository:docker.io/dustise
kubernetesVersion:v1.14.0
networking:
	podSubnet:"192.168.0.0/16"
下载K8S的相关镜像

修改Docker的镜像托管站点加速,增加Registry Mirror参数,将镜像配置写入配置参数中。然后重启Docker服务。

下载所需的镜像
kubeadm config images pull --config=init-config.yaml
运行kubeadm init命令安装Master

则到此准备工作完成,执行kubeadm init命令即可一键安装Kubernetes的Master。

注意,kubeadm的安装过程不涉及网络插件(CNI)的初始化,因此kubeadm初步安装完成的集群不具备网络功能,任何Pod包括自带的CoreDNS都无法正常工作。

网络插件的安装往往对kubeadm init命令的参数有一定的要求。例如,安装Calico插件时需要指定–pod-network-cidr=192.168.0.0/16,详情可以参考https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network

接下来使用kubeadm init命令,使用前面的配置文件:

kubeadm init --config=init-config.yaml
按照提示信息完成余下步骤:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

这样就在Master上安装了k8s,但在集群内还是没有可用的工作Node,并缺少对容器网络的配置。需要上面的信息的kubeadm join和所需的Token让Node加入。

可以使用kubectl验证cofigmap:

kubectl get -n kube-system configmap
可以看到生成了名为kubeadm-config的configmap对象。
安装Node,加入集群

系统准备和K8S yum镜像源配置过程和Master相同

(1)安装kubeadm和相关工具

 yum install kubelet kubeadm --disableexcludes=kubernetes(不使能除了kubernetes的镜像源)
运行Dokcer和kubelet,并设置为开机启动:
systemctl enable docker && systemctl start docker
systemctl enable kubelet && systemctl start kubelet

(2)为kubeadm命令生成配置文件。创建文件join-config.yaml,内容如下:

apiVersion:kubeadm.k8s.io/v1beta1
kind:JoinConfiguration
discovery:
	bootstrapToken:
	apiServerEndpoint:10.211.55.30:6443  (Master的地址)
	token:ah9koe.nvuvz2v60iam0e0d
	unsafeSkipCAVerification:true
  tlsBootstrapToken:ah9koe.nvuvz2v60iam0e0d (这里是上面master安装成功后的最下面的信息)

(3)执行kubeadm join,将本Node加入集群:

kube join --config=join-config.yaml
也可以直接复制master最后一行加入(方便)

kubeadm在master上也安装了kubelet,在默认情况下并不参数工作负载。如果希望安装一个单机ALL-IN-ONE的K8S环境,则可以执行下面的命令(删除Node的Label“node-role.kubernetes.io/master”),让Master成为一个Node:
kubectl taint nodes -all node-role.kubernetes.io/master-

安装网络插件

执行kubectl get nodes命令,发现k8s提示master为NotReady状态,这是因为还没有安装CNI网络插件。下面根据kubeadm的提示安装CNI网络插件,可以参考https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network的说明进行选择安装。

例如,选择weave插件,但现在一般使用ipvs:

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
验证K8S集群是否安装完成

kubectl get pods --all-namespaces验证k8s集群的相关pod是否正常创建和工作。

如果发现又状态错误的Pod,可以执行

kubectl --namespace=kube-system describe pod 查看错误原因。

如果安装失败,可以执行kubeadm reset命令将主机恢复原状,重新执行kubeadm init命令,再次安装。

以二进制文件方式安装k8s集群

从k8s发布官网[github.com/kubernetes/kubernetes/releases]找到对应的版本号,单机CHANGELOG,找到已编译好的二进制文件的下载页面。在压缩包kubernetes.tar.gz内包含了kubernetes的服务程序文件、文档和示例;在压缩包kubernetes-src.tar.gz内则包含了全部源代码。也可以直接下载Server Binaries中kubernetes-server-linux-amd64.tar.gz文件,其中包含了kubernetes需要运行的全部服务程序文件。

k8s的主要服务程序都可以通过直接运行二进制文件加上启动参数完成运行。在k8s的master上需要部署etcd、kube-apiserver、kube-contrller-manager,kube-scheduler服务进程,在Node上部署docker、kubelet和kube-proxy服务进程。

将K8S的二进制可执行文件复制到/usr/bin目录下,然后再/usr/lib/system/system目录下为各服务创建systemd服务配置文件,这样就完成了软件的安装。要使k8s正常工作,需要详细配置各个服务的启动参数。

暂时先略过
Kubernetes集群的网络配置

除了谷歌公有云GCE平台提供的网络配置,一些开源的工具包括Flannel、Open vSwitch,Weave,Calico等都都能够实现跨主机的容器间网络互通。随着CNI网络模型的逐渐成熟,k8s将优先使用CNI网络插件打通跨主机的容器网络。

内网中的kubernetes相关配置

外网:docker.io和gcr.io提供大量docker镜像;另一方面,GCE,AWS提供的云平台已经成熟,用户通过租用一定的空间来部署K8S集群也很简单。

但,由于安全原因无法访问internet,需要创建一个内部的私有docker registry,并修改一些k8s的配置,来启动内网中的k8s集群。

Docker Private Registry(私有Docker镜像库)

使用Docker提供的Registry镜像创建一个私有镜像仓库。

详细的安装步骤参考Dokcer的官方文档:docs.docker.com/registry/deploying/

kubelet配置

在kubelet创建Pod时,还通过启动一个名为k8s.gcr.io/pause:3.1的镜像来实现Pod的概念。

该镜像存在于谷歌镜像库k8s.gcr.io中,需要通过一台能够脸上网络的服务器将其下载,导出文件,再push到私有Docker Registry中。

之后,可以给每个Node的kubelet服务都加上启动参数–pod-infra-container-image,指定为私有docker registry中pause镜像的地址。例如:

cat /etc/kubernetes/kubelet
KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig
--hostname-override=192.168.18.3 --log-dir=/var/log/kubernetes --v=0
--pod-infra-container-image=myregistry/pause:3.1"
然后重启kubelet服务:
systemctl restart kubelet
通过以上设置就再内网环境中搭建了一个企业内部的私有容器云平台。

Kubernetes的版本升级

二进制升级

为使得docker不受影响,应对集群中的各个Node逐个进行隔离,然后等待在其上运行的容器全部执行完成,再更新该Node上的kubelet和kube-proxy服务,将全部Node更新完成后,再更新Master的服务。

使用kubeadm进行集群升级

kubeadm提供了upgrade命令用于升级。

开始之前需要注意:

  • 虽然kubeadm的升级不会触及工作负载,但还是要在升级之前做好备份。
  • 升级过程可能会因为Pod的变化而造成容器的重启。

首先升级kubeadm:
yum install -y kubeadm-1.14.0 --disableexcludes=kubernetes
查看kubeadm的版本:
kubeadm version
接下来查看kubeadm的升级计划:
kubeadm upgrade plan
按照任务指引进行升级:
kubeadm upgrade apply 1.14.0
运行完成后,再次查询版本:
kubectl version
虽然kubectl还是老版本,但服务端的控制平面已经升级到了新版本。查看Node版本还是老版本:
kubectl get nodes
然后可以对节点配置进行升级:
kubeadm upgrade node config --kubelet-version 1.14.0
接下来,按照和二进制升级一样的步骤将kubectl升级,这样就完成了集群的整体升级:
kubectl get nodes

CRI(容器运行时接口)详解

kubelet主要功能就是启动和停止容器的组件,为了更具扩展性,k8s从1.5版本开始就加入了容器运行时插件API,即CRI。

CRI 概述

k8是从1.5版本开始引入了CRI接口规范,通过插件接口模式,k8s无须重新编译就可以使用更多的容器运行时。

CRI包含Protocol Buffers、gRPC API、运行库支持及开发中的标准规范和工具。

CRI的主要组件

kubelet使用gRPC框架通过UNIX Socket与容器运行时(或CRI代理)进行通信。在这个过程中kubelet是客户端,CRI代理(shim)是服务端。

Protocol Buffers API包含两个gRPC服务:ImageService和RuntimeService

ImageService提供了从仓库拉去镜像、查看和移除镜像的功能。

RuntimeServcie负责Pod和容器的生命周期管理,以及与容器的交互(exec/attach/port-forward)。rkt和Docker这样的容器运行时可以使用一个Socket同时提供两个服务,在kubelet中可以使用–container-runtime-endpoint和–image-service-endponit参数设置这个Socket。

Pod和容器的生命周期管理

Pod由一组应用容器组成,其中包含共有的环境和资源约束。在CRI里,这个环境被称为PodSandbox。K8S有意为容器运行时留下一些发挥空间,它们可以根据自己的内部实现解释PodSandbox。对于Hypervisor类的运行时,PodSandbox会具体化为一个虚拟机。其他例如Docker,会是一个Linux命名空间。。在v1alphal API中,kubelet会创建Pod级别的cgroup传递给容器运行时,并以此运行所有的进程来满足PodSandbox对Pod的资源保障。

在启动Pod之前,kubelet会启动RuntimeService.RunPodSandbox来创建环境。这一过程包括为Pod设置网络资源(分配IP等操作)。kubelet在停止和删除PodSandbox之前首先停止和删除其中的容器。

kubelet的职责在于通过RPC管理容器的生命周期。

省略了一些

kubectl命令行工具

kubectl [command] [TYPE] [NAME] [flags]
(1)command:子命令,用于操作k8s集群资源对象的命令,例如create、delete、describe、get、apply等。
(2)TYPE:资源对象的类型,区分大小写,但能以单数、复数或者简写形式表示。例如以下3种TYPE是等价的。
kubectl get pod pod1
kubectl get pods pod1
kubectl get po pod1
(3)NAME:资源对象的名称,区分大小写。如果不指定名称,则返回属于TYPE的全部对象的列表。
(4)flags:kubectl子命令的可选参数,例如使用“-s”指定API Server的URL地址而不使用默认值。

书本P138页给出了kubectl可操作的资源对象类型及缩写


获取多种对象:
kubectl get pod/pod1 rc/rc1
同时应用多个YAML文件,以多个-f file参数表示:
kubectl get pod -f pod1.yaml -f pod2.yaml
kubectl create -f pod1.yaml -f rc1.yaml -f service1.yaml

kubectl命令可以用多种格式对结果进行显示,输出格式通过-o参数指定:
kubectl [command] [TYPE] [NAME] [flags] -o=

显示Pod的更多信息:
kubectl get pod pod_name -o wide
以yaml格式显示Pod的详细信息:
kubectl get pod pod_name -o yaml
以自定义列名显示Pod的信息:
kubectl get pod pod_name -o=custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion
基于文件的自定义列名输出:
kubectl get pods pod_name -o=custom-columns-file=template.txt
template.txt文件的内容:
NAME				RSRC
metadata.name 		metadata.resourceVersion
按某个字段顺序,通过--sort-by参数以jsonpath表达式进行指定:
kubectl [command] [TYPE][NAME] --sort-by=
kubectl get pods --sort-by=.metadata.name

kubectl操作实例

1.创建资源对象

根据YAML配置文件一次性创建Service和RC:
kubectl create -f my-service.yaml -f my-rc.yaml
根据directory目录下所有.yaml,.yml,.json文件的定义进行创建:
kubectl create -f 

2.查看资源对象

查看所有Pod列表:
kubectl get pods
查看RC,Service列表:
kubectl get rc,service

3.描述资源对象

显示Node的详细信息:
kubectl describe nodes node_name
显示Pod的详细信息:
kuebctl describe pods pod_name
显示由RC管理的pod信息:
kubectl describe pods rc_name

4.删除资源对象

基于pod.yaml定义的名称删除Pod:
kubectl delete -f pod.yaml
删除所有包含某个Label的Pod和Service:
kubectl delete pods,services -l name=label_name
删除所有Pod:
kubectl delete pods --all

5.执行容器的命令

执行Pod的date命令,默认使用Pod中的第1个容器执行:
kubectl exec pod_name date
指定Pod中的某个容器执行date命令:
kubectl exec pod_name -c containner-name date
通过bash获得Pod中某个容器的TTY,相当于登录容器:
kubectl exec -ti pod_name -c container-name /bin/bash

6.查看容器的日志

查看容器输出到stdout的日志:
kubectl logs pod_name
跟踪查看容器的日志,相当于tail -f命令的结果:
kubectl logs -f pod_name -c container_name

7.创建或更新资源对象

用法和kubectl create类似,,逻辑稍有差异:如果目标资源对象不存在,则进行创建;否则进行更新
kubectl apply -f app.yaml

8.在线编辑运行中的资源对象

kubectl edit deploy nginx
在命令执行后,会通过YAML格式展示该对象的定义和状态,用户可以对代码进行编辑和保存,从而完成对在线资源的直接修改。

9.将Pod的开放端口映射到本地

将集群上Pod的80端口映射到本地的8888端口,在浏览器127.0.0.1:8888中就能够访问到容器提供的服务了:
kubectl port-forward --address 0.0.0.0 \
pod/nginx-xxxx 8888:80

10.在Pod和本地之间复制文件

把Pod上的/etc/fstab复制到本地的/tmp目录:
kubectl cp nginx-xxxx:/etc/fstab   /tmp

11.资源对象的标签设置

为default namespace设置testing=true标签:
kubectl label namespaces default testing=true

12.检查可用的API资源类型列表

该命令经常用于检查特定类型的资源是否已经定义,列出所有资源对象类型:
kubectl api-resources

13.使用命令行插件

用户自定义插件的可执行文件名需要以“kubectl-”开头,复制到$PATH中的某个目录(如/usr/local/bin),
然后就可以通过kubectl 运行自定义插件了。
例如,实现一个名为hello的插件,其功能是在屏幕上输出“hello”
新建名谓kubectl-hello的可执行脚本文件,内容为
echo "hello world"
复制到/usr/local/bin/目录下,就完成了安装插件的工作。
然后在kubectl命令后带上插件名称就能使用这个插件了:
kubectl hello
hello

kubectl plugin list
可以查看当前系统中已经安装的插件列表
更完整的插件开发示例可以从github.com/kubernetes/sample-cli-plugin找到。

你可能感兴趣的:(Kubernetes安装配置指南以及kubectl命令行示例——Kubernetes权威指南(第二章))