带你玩转kubernetes-k8s(第9篇:k8s-使用kubeadm安装,Kubectl命令补充)

释放双眼,带上耳机,听听看~!

大家好,我们又见面了,现在说明一下哈,每周更新5篇哦。 

kubeadm config

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

◎ 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:拉取镜像到本地。

获取默认初始化参数


1
2
3
1kubeadm config print init-dafaults > init.default.yaml
2
3

 

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。

 

基于CA签名的双向数字证书认证方式

     在一个安全的内网环境中,Kubernetes的各个组件与Master之间可以通过kube-apiserver的非安全端口http://<kube-apiserver-ip>:8080进行访问。但如果API Server需要对外提供服务,或者集群中的某些容器也需要访问API Server以获取集群中的某些信息,则更安全的做法是启用HTTPS安全机制。Kubernetes提供了基于CA签名的双向数字证书认证方式和简单的基于HTTP Base或Token的认证方式,其中CA证书方式的安全性最高。

     我们现在讲解如何以CA证书的方式配置k8s集群,要求Master上的kube-apiserver、kube-croller-manage、kube-scheduler进程进行CA签名双向数字证书安全设置。

基于CA签名的双向数字证书的生成过程如下。
(1)为kube-apiserver生成一个数字证书,并用CA证书签名。
(2)为kube-apiserver进程配置证书相关的启动参数,包括CA证书(用于验证客户端证书的签名真伪)、自己的经过CA签名后的证书及私钥。
(3)为每个访问Kubernetes API Server的客户端(如kube-controller-manager、kube-scheduler、kubelet、kube-proxy及调用API Server的客户端程序kubectl等)进程都生成自己的数字证书,也都用CA证书签名,在相关程序的启动参数里增加CA证书、自己的证书等相关参数。

1.设置kube-apiserver的CA证书相关的文件和启动参数

      使用OpenSSL工具在Master服务器上创建CA证书和私钥相关的文件:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
1[root@k8s-master1 home]# openssl genrsa -out ca.key 2048
2Generating RSA private key, 2048 bit long modulus
3................................................................................................................+++
4................................................+++
5e is 65537 (0x10001)
6[root@k8s-master1 home]# openssl req -x509 -new -nodes -key ca.key -subj &quot;/CN=k8s-master1&quot; -days 5000 -out ca.crt
7[root@k8s-master1 home]# openssl genrsa -out server.key 2048
8Generating RSA private key, 2048 bit long modulus
9...................................................................+++
10.+++
11e is 65537 (0x10001)
12[root@k8s-master1 home]#
13
14

注意:在生成ca.crt时,-subj参数中“/CN”的值为Master主机名。

准备master_ssl.cnf文件,该文件用于x509 v3版本的证书。在该文件中主要需要设置Master服务器的hostname(k8s-master1)、IP地址(x.x.x.x),以及Kubernetes Master Service的虚拟服务名称(kubernetes.default等)和该虚拟服务的ClusterIP地址(10.96.0.1)。

带你玩转kubernetes-k8s(第9篇:k8s-使用kubeadm安装,Kubectl命令补充)

master_ssl.cnf文件的实例如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1[root@k8s-master1 home]# cat master_ssl.cnf
2[req]
3req_extensions=v3_req
4distinguished_name=req_distinguished_name
5[req_distinguished_name]
6[ v3_req ]
7basicConstraints=CA:FALSE
8keyUsage=nonRepudiation,digitalSignature,keyEncipherment
9subjectAltName=@alt_names
10[alt_names]
11DNS.1=kubernetes
12DNS.2=kubernetes.default
13DNS.3=kubernetes.default.svc
14DNS.4=kubernetes.default.svc.cluster.local
15DNS.5=k8s-master1
16IP.1=10.96.0.1
17IP.2=20.0.40.51
18
19

基于master_ssl.cnf创建server.csr和server.crt文件。在生成server.csr时,-subj参数中“/CN”的值需为Master的主机名:


1
2
3
1openssl req -new -key server.key -subj &quot;/CN=k8s-master1&quot; -config master_ssl.cnf -out server.csr
2
3

1
2
3
4
5
6
1[root@k8s-master1 home]# openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 5000 -extensions v3_req -extfile master_ssl.cnf -out server.crt
2Signature ok
3subject=/CN=k8s-master1
4Getting CA Private Key
5
6

 

在全部执行完后会生成6个文件:ca.crt、ca.key、ca.srl、server.crt、server.csr、server.key。
将这些文件复制到一个目录下(例如/var/run/kubernetes/),然后设置kube-apiserver的三个启动参数“–client-ca-file”“–tls-cert-file”和“–tls-private-key-file”,分别代表CA根证书文件、服务端证书文件和服务端私钥文件:

带你玩转kubernetes-k8s(第9篇:k8s-使用kubeadm安装,Kubectl命令补充)

这一部分内容是二进制安装过程的步骤,我们使用的是kubeadm安装的k8s,在安装过程中k8s默认给我们生成了ca,并加入了启动项

带你玩转kubernetes-k8s(第9篇:k8s-使用kubeadm安装,Kubectl命令补充)

二进制的安装我们后面会带着大家来搭建一个生产环境。

 

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

    kubernetes Node(kubelet)的主要功能就是启动和停止容器的组件,我们称之为容器运行时(Container Runtime),其中最致命的就是Docker 了。
kubelet使用gRPC框架通过UNIX Socket与容器运行时(或CRI代理)进行通信。在这个过程中kubelet是客户端,CRI代理(shim)是服务端,

带你玩转kubernetes-k8s(第9篇:k8s-使用kubeadm安装,Kubectl命令补充)

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

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

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

 

Pod由一组应用容器组成,其中包含共有的环境和资源约束。在CRI里,这个环境被称为PodSandbox。Kubernetes有意为容器运行时留下一些发挥空间,它们可以根据自己的内部实现来解释PodSandbox。

 对于Hypervisor类的运行时,PodSandbox会具体化为一个虚拟机。其他例如Docker,会是一个Linux命名空间。在v1alpha1 API中,kubelet会创建Pod级别的cgroup传递给容器运行时,并以此运行所有进程来满足PodSandbox对Pod的资源保障。

在启动Pod之前,kubelet调用RuntimeService.RunPodSandbox来创建环境。这一过程包括为Pod设置网络资源(分配IP等操作)。PodSandbox被激活之后,就可以独立地创建、启动、停止和删除不同的容器了。kubelet会在停止和删除PodSandbox之前首先停止和删除其中的容器。

kubelet的职责在于通过RPC管理容器的生命周期,实现容器生命周期的钩子,存活和健康监测,以及执行Pod的重启策略等。

Kubernetes为用户提供了与Pod及其中的容器进行交互的功能(kubectl exec/attach/port- forward)。kubelet目前提供了两种方式来支持这些功能。
(1)调用容器的本地方法。
(2)使用Node上的工具(例如nsenter及socat)。

在设计CRI时,要让容器运行时能够跳过中间过程。容器运行时可以启动一个单独的流式服务来处理请求(还能对Pod的资源使用情况进行记录),并将服务地址返回给kubelet。这样kubelet就能反馈信息给API Server,使之可以直接连接到容器运行时提供的服务,并连接到客户端。

尝试使用新的Docker-CRI来创建容器


1
2
1kubectl run nginx --image=nginx
2

带你玩转kubernetes-k8s(第9篇:k8s-使用kubeadm安装,Kubectl命令补充)

带你玩转kubernetes-k8s(第9篇:k8s-使用kubeadm安装,Kubectl命令补充)

带你玩转kubernetes-k8s(第9篇:k8s-使用kubeadm安装,Kubectl命令补充)

kubectl命令工具用法详解

 

(1)显示Pod的更多信息:


1
2
1kubectl get pod &lt;pod-name&gt; -o wide
2

(2)以YAML格式显示Pod的详细信息:


1
2
1kubectl get pod&lt;pod-name&gt; -o yaml
2

(3)以自定义列名显示Pod的信息:


1
2
1kubectl get pod &lt;pod-name&gt; -o=custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion
2

(4)基于文件的自定义列名输出:


1
2
1kubectl get pods &lt;pod-name&gt; -o=custom-columns-file=template.txt
2

另外,可以将输出结果按某个字段排序,通过–sort-by参数以jsonpath表达式进行指定:
例如,按照名称进行排序:


1
2
1kubectl get pods --sort-by=.metadata.name
2

1.创建资源对象
根据YAML配置文件一次性创建Service和RC:


1
2
1kubectl create -f my-service.yaml 0f my-rc.yaml
2

根据<directory>目录下所有.yaml、.yml、.json文件的定义进行创建:


1
2
1kubectl create -f &lt;directory&gt;
2

2.查看资源对象
查看所有Pod列表:


1
2
1kubectl get pod --all-namespaces
2

查看RC和Service列表:


1
2
1kubectl get rc,service --all-namespaces
2

3.描述资源对象
显示Node的详细信息:


1
2
1kubectl describe nodes &lt;node-name&gt;
2

显示Pod的详细信息:


1
2
1kubectl describe pods/&lt;pod-name&gt;
2

显示由RC管理的Pod的信息:


1
2
1kubectl describe pods &lt;rc-name&gt;
2

4.删除资源对象
基于pod.yaml定义的名称删除Pod:


1
2
1kubectl  delete -f pod.yaml
2

删除所有包含某个Label的Pod和Service:


1
2
1kubecl delete pods,services -l name=&lt;label-name&gt;
2

删除所有Pod:


1
2
1kubectl delete pods --all
2

5.执行容器的命令
执行Pod的date命令,默认使用Pod中的第1个容器执行:


1
2
1kubectl exec &lt;pod-name&gt; date
2

指定Pod中的某个容器执行date命令:


1
2
1kubectl exec &lt;pod-name&gt; -c &lt;container-name&gt; date
2

通过bash获得Pod中某个容器的TTY,相当于登录容器:


1
2
1kubectl exec -ti &lt;pod-name&gt; -c &lt;container-name&gt; /bin/bash
2

6.查看容器的日志
查看容器输出到stdout的日志:


1
2
1kubectl logs &lt;pod-name&gt;
2

跟踪查看容器的日志,相当于tail -f命令的结果:


1
2
1kubectl logs -f &lt;pod-name&gt; -c &lt;container-name&gt;
2

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


1
2
1kubectl apply -f app.yaml
2

8.在线编辑运行中的资源对象
可以使用kubectl edit命令编辑运行中的资源对象,例如使用下面的命令编辑运行中的一个Deployment:


1
2
1kubectl edit deploy nginx
2

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

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

将集群上Pod的80端口映射到本地的8888端口,在浏览器http://127.0.0.1:8888中就能够访问到容器提供的服务了:


1
2
1kubectl port-forward --address 0.0.0.0 pod/&lt;pod-name&gt; 8888:80
2

10.在Pod和本地之间复制文件
把Pod上的/etc/fstab复制到本地的/tmp目录:


1
2
1kubectl cp &lt;pod-name&gt;:/etc/fstab /tmp
2

11.资源对象的标签设置
为default namespace设置testing=true标签:


1
2
1kubectl label namespaces default testing=true
2

12.检查可用的API资源类型列表
该命令经常用于检查特定类型的资源是否已经定义,列出所有资源对象类型:


1
2
1kubectl api-resources
2

13.使用命令行插件
为了扩展kubectl的功能,Kubernetes从1.8版本开始引入插件机制,在1.14版本时达到稳定版。
用户自定义插件的可执行文件名需要以“kubectl-”开头,复制到$PATH中的某个目录(如/usr/local/bin),然后就可以通过kubectl <plugin-name>运行自定义插件了。例如,实现一个名为hello的插件,其功能为在屏幕上输出字符串“hello world”:
新建名为kubectl-hello的可执行脚本文件,其内容为


1
2
1echo &quot;hello world&quot;
2

复制kubectl-hello文件到/usr/local/bin/目录下,就完成了安装插件的工作。
然后在kubectl命令后带上插件名称就能使用这个插件了:


1
2
1kubectl hello
2

使用kubectl plugin list命令可以查看当前系统中已安装的插件列表:


1
2
1kubectl plugin list
2

完整的插件开发示例可以从https://github.com/kubernetes/sample-cli-plugin找到。

 

 

小结:

        今天就说道这里了,今天讲解的有点乱,东补西补的,主要是为了补充前面缺失的内容,希望对大家有帮助。明天我们将深入讲解Pod。

         谢谢大家的支持!

 

 

 

 

 

 

给TA打赏
共{{data.count}}人
人已打赏
安全运维

故障复盘的简洁框架-黄金三问

2021-9-30 19:18:23

安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索