K8s的基础操作

环境说明

kubenetes:阿里云服务,版本v1.10.4,三个master,一个node,我也不知道为啥阿里云设定master最少是3个,而node最少可以是1个…
服务器:阿里云Centos 7.4

部署服务

首先,我们先部署一个以dockhub最新nginx镜像为底的nginx。命令如下:kubectl run nginx-test --image=nginx:latest --port=80。同理,再部署一个最新版redis的话,就是找葫芦画瓢:kubectl run redis-test --image=redis:latest --port=6379

两个命令敲完,这就给k8s下达了一个deployment(部署任务),可用kubectl get deploymentskubectl get pods命令查看:
paradin

可以看到现在已经生成了对应的pod,而pod里就是容器了,容器里就是对应的服务。如果想爬进这个容器看一下里面的文件等情况,命令是:kubectl exec -it nginx-test-bb95c4645-7qpbj bash

这里插播一下kubectl get deployment里各参数的含义:

1
2
3
4
DESIRED:对应.spec.replicas,用户设定的期望副本数
CURRENT:对应.status.replicas,目前运行的副本数
UP-TO-DATE:对应.status.updatedReplicas,包含最新的pod template的副本数
AVAILABLE:对应.status.availableReplicas,进入正常状态的副本数

但是现在这个服务是外网无法访问的,因为宿主机还没有一个端口与这个nginx容器的80端口相对应。所以要暴露一个端口给外部用于访问。命令是:kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 80,然后用kubectl get services查看一下效果:
paradin

然后在对应的master和node里就看到宿主机随机分配的那个30497端口已经启动了,如图:
paradin

在浏览器上访问一下30497端口,果然可以访问到nginx服务:
paradin

扩容服务

服务嘛,总有高峰低谷。比如微博,突然爆出来哪个娱乐明星的新闻,肯定就会有大量的流量涌入,此时就需要扩容,那么k8s的扩容很简单,就是pod的复制,如果要把上面那个nginx-test的部署任务进行扩展,命令就是kubectl scale deployments/nginx-test --replicas=4,如图:
paradin

可见nginx-test又生成了三个pod,与原来的组成了4个pod,而另一个redis的部署任务是没有变化的。

kubectl get pods -o wide可见,每一个pod分配到了不同的虚拟IP上,而且node都是阿里云的那台node服务器。
paradin

在阿里云控制台也能看到里面的情况:
paradin

此时进入到node节点,docker ps -a就会看到新的nginx景象生成,同时也生成了三个/pause的容器:
paradin

kubernetes中的pause容器主要为每个业务容器提供以下功能:

  1. 在pod中担任Linux命名空间共享的基础;
  2. 启用pid命名空间,开启init进程。

注意!目前kubernetes似乎仅仅支持共享网络,还不支持进程体系、文件系统之间的共享。如果此时在访问,就会看到访问会相对均匀的落到这四个pod中的每一个,起到一个负载均衡的作用。如果高峰期过了,不需要那么多pod了,就kubectl scale deployments/nginx-test --replicas=1,pod就会恢复成1个,据我几次试验,每次都是保留最老的那一个pod。

yaml文件创建一个pod

K8s的yaml文件的文法和规矩,官方社区就有教程:https://www.kubernetes.org.cn/1414.html 。但是如果要搭配阿里云的私有镜像,需要先参考一下阿里云文档:https://help.aliyun.com/document_detail/86562.html注意,这个方法不能在命令行里使用,只能在yaml或者json里用。这里先写一个简单的nginx配置文件pod-nginx.yaml做例子,全文如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
---
apiVersion: v1
kind: Pod
metadata:
name: aliyun-nginx
labels:
app: web
spec:
restartPolicy: Always #表明该容器一直运行,默认k8s的策略,在此容器退出后,会立即创建一个相同的容器
nodeSelector:
zone: node1 #节点选择
containers:
- name: aliyun-test-nginx
image: registry-vpc.cn-hangzhou.aliyuncs.com/lechangetest/chentest:1.1
imagePullPolicy: IfNotPresent #可选择Always、Never、IfNotPresent,即每次启动时检查和更新images的策略,IfNotPresent是节点上没有此nginx镜像时才执行pull操作
ports:
- containerPort: 80 #容器开发对外的端口
hostPort: 33664 #映射到主机的端口/对外映射的端口(一般可以不写)
imagePullSecrets:
- name: regsecret #这句话为了通过阿里云似有仓库的鉴权

保存退出,再kubectl create -f pod-redis.yaml把这个文件执行一下。然后kubectl get pod看一下效果:
paradin

发现我们创建那个redis-pod状态是Pending(等待中),那就是不成功啊。于是就kubectl describe pod/pod-redis查看一下原因,反馈如下:
paradin

这个错误的意思是“如果指定的label在所有node上都无法匹配,则创建Pod失败”。原来是我没有配置kubectl label nodes,那先把pod-redis删除,再把nodeSelector那一段去掉,改成nodeName: cn-hangzhou.i-bp1978gmunq3oalfcqlx,去掉再重新create一下。kubectl get pod检查:
paradin

然后就是给这个pod增加一个对外的端口。kubectl expose pod/aliyun-nginx --type="NodePort" --port 80,效果如下:
paradin

再去浏览器里,输入node的外网网址:31829看看效果:
paradin

配置成功,当然这整个过程也可以在阿里云的控制台操作,更简单更直观,而且阿里云还会自动把对外端口配置到SLB里,具体步骤可以看阿里云的官方文档。

升级与回滚

假设我们把nginx-test这个deployment的镜像升级成阿里云私有仓库的1.1版本,那么命令是:

1
kubectl set image deployments/nginx-test nginx-test=registry.cn-hangzhou.aliyuncs.com/lechangetest/chentest:1.1

升级之后,kubectl get pod发现有几个节点不正常,如图:
paradin

那么这种情况下需要紧急回滚,回滚命令:

1
kubectl rollout undo deployment/nginx-test

一会就看到回滚成功了。如图:
paradin

参考资料

https://jimmysong.io/posts/what-is-a-pause-container/
https://blog.csdn.net/mailjoin/article/details/79686937
http://pipul.org/2016/05/why-we-need-the-pod-and-service-of-kubernetes/
https://www.imooc.com/article/30473

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------