k8s集群中的名词非常多,不过不用慌,我们会一个个依次学习到。上一节我们已经成功创建了一个集群,这一节我们先了解下k8s中对于这些名词的分类方式,并在上一节集群里面以创建一个pod为例来初窥k8s中yaml配置文件各个字段的用法。
我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。
k8s中的资源
k8s中所有的内容都是资源,资源实例化之后叫做对象。
名称空间级别
下面这些资源在创建的时候都是和名称空间绑定的,也就是在执行kubectl get xx
等操作的时候后面要加上-n xxx
的名称空间,例如系统容器所对应的kube-system
空间,或者是利用--all-namespaces
直接在所有命名空间中查找。不然会出现资源找不到的报错。
这一节主要是认识下pod,后面的这些在这里先有个简单印象,后面我们会一个个学习到。
工作负载型资源
- Pod
最小资源级别 - ReplicaSet
通过标签控制Pod - Deployment
通过控制RS去控制Pod - StatefulSet
- DaemonSet
- Job/CronJob
服务发现及负载均衡型资源
- Service
- Ingress
配置与存储型资源
- Volume
- CSI(Container Storage Interface)
用来扩充第三方volume
特殊类型的存储卷
- ConfigMap
存储一些配置文件,达到热更新的状态 - Secret
保存敏感数据 - DownwardAPI
把外部环境中的信息输出给容器
集群级别
下面这些资源是整个集群级别的。
- Namespace
- Node
- Role
- ClusterRole
- RoleBinding
- ClusterRoleBinding
元数据
下面这些数据规定了一些指标,同时对应着一些相应操作。
- HPA
- PortTemplate
- LimitRange
YAML
K8s里面的配置文件基本都是YAML格式的,类似于json是一种标记语言。这里不会对起语法规范做详细解释,如果有不熟悉的朋友可以先参考YAML教程进行了解。
想在k8s集群里面创建任何资源,都可以通过新建一个对应的yaml配置文件,直接通过kubectl去apply即可。下面我们就会用实例来感受到。
常用字段
下面看一下在定义一个资源的时候有哪些字段需要放在yaml文件中的。这里只是列出了一些常用的,全部的资源字段可以通过kubectl explain xx
来查看,例如kubectl explain pod
来查看Pod的所有字段,然后进一步通过kubectl explain pod.spec
之类的去层层递进地查看。
用docker-compose构建过容器的朋友应该会很熟悉。
字段名 | 字段类型 | 说明 |
---|---|---|
version | string | RESTFul API的版本,目前基本上是v1,可以通过kubectl api-versions命令去查询所有的API的version |
kind | string | 定义的资源类型和角色,例如Pod |
metadata | object | 元数据对象,固定值就写metadata |
metadata.name | string | 元数据对象的名字,例如Pod的名字 |
metadata.namespace | string | 元数据对象的命名空间,不指定则默认是default空间 |
spec | object | 详细定义对象,固定值就写Spec |
spec.containers[] | list | 容器列表 |
spec.containers[].name | string | 这里定义容器的名字 |
spec.containers[].image | string | 这里定义容器要用到的镜像名称 |
spec.containers[].imagePullPolicy | string | 镜像拉取策略,有Always/Never/IfNotPresent三个可选,默认是Always |
spec.containers[].command[] | list | 指定容器启动命令,不指定则使用镜像打包时的启动命令 |
spec.containers[].args[] | list | 指定容器启动命令参数,因为是数组所以可以指定多个 |
spec.containers[].workingDir | string | 指定容器的工作目录 |
spec.containers[].volumeMounts[] | list | 存储卷配置 |
spec.containers[].volumeMounts[].name | string | |
spec.containers[].volumeMounts[].mountPath | string | |
spec.containers[].volumeMounts[].readOnly | string | |
spec.containers[].ports[] | list | 容器需要的端口列表 |
spec.containers[].ports[].name | string | 端口名称 |
spec.containers[].ports[].containerPort | string | 容器需要监听的端口号 |
spec.containers[].ports[].hostPort | string | 主机需要监听的端口号,默认跟上面的containersPort一致,设置了以后不能在同一台宿主机上启动第二个副本 |
spec.containers[].ports[].protocol | string | 端口协议,TCP/UDP,默认是TCP |
spec.containers[].env[] | list | 环境变量 |
spec.containers[].env[].name | string | 环境变量名称 |
spec.containers[].env[].value | string | 环境变量值 |
spec.containers[].resources | object | 限制资源的使用上限,后面详细讲 |
spec.restartPolicy | string | Pod的重启策略,可选Always/OnFailure/Never,默认值为Always |
spec.nodeSelector | object | 定义Node的label过滤标签,键值对格式指定 |
spec.imagePullSecrets | object | 定义pull镜像时使用的密钥,键值对格式指定 |
spec.hostNetwork | Boolean | 定义是否使用主机网络。默认为false表示不使用宿主机网络,只用docker网桥。设置了true将无法在同一台宿主机上启动第二个副本 |
需要注意的是字段不写出来和写出来留空值是不一样得结果,前者是走默认值,后者是None。
创建自己的第一个Pod
说了这么多,下面开始实际操作了。
对照着上面的字段,在master上创建一个pod.yaml
文件如下
apiVersion: v1
kind: Pod
metadata:
name: hellok8s
namespace: default
labels:
app: myapp
version: v1
spec:
containers:
- name: mynginx
image: nginx
- name: myredis
image: redis
这里创建一个叫hellok8s的pod,其中包含两个容器,一个是nginx在80端口,一个是redis在6379端口。因为pod里面的容器共享网络栈所以端口不要重复。
注意这里的kind后面的Pod要大写P
然后跑下面的命令创建
kubectl apply -f pod.yaml
之后就看到pod成功启动了
[root@k8s-master k8s-test]# kubectl apply -f pod.yaml
pod/hellok8s created
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
curl-6bf6db5c4f-kljp4 1/1 Running 1 19h 10.244.1.2 k8s-node1 <none> <none>
hellok8s 2/2 Running 0 11s 10.244.1.6 k8s-node1 <none> <none>
可以看到pod成功起来了,直接根据pod的flannel网段的ip去访问80端口和6379端口都是通的
[root@k8s-master k8s-test]# curl 10.244.1.6
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@k8s-master k8s-test]# telnet 10.244.1.6 6379
Trying 10.244.1.6...
Connected to 10.244.1.6.
Escape character is '^]'.
不过假如你们的image用的和我不一样,可能会报错。出现报错也不用慌张,首先通过下面的命令查看pod的详细描述信息
kubectl describe pod hellok8s
结果如下
[root@k8s-master k8s-test]# kubectl describe pod hellok8s
Name: hellok8s
Namespace: default
Priority: 0
Node: k8s-node1/172.29.56.176
Start Time: Wed, 29 Apr 2020 11:46:56 +0800
Labels: app=myapp
version=v1
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"myapp","version":"v1"},"name":"hellok8s","namespace":"defaul...
Status: Running
IP: 10.244.1.6
Containers:
myredis:
Container ID: docker://5d685645bab41e9f76fc876d7ac63835ee2c3c41e9377af8ecfd49bfd37981dc
Image: redis
Image ID: docker-pullable://redis@sha256:157a95b41b0dca8c308a33489dfdb28019e033110320414b4b16fad7d28c0f9f
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 29 Apr 2020 11:47:02 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-hln8x (ro)
mynginx:
Container ID: docker://e4d96e6c6f320abbba7307e22b33be1b14c52449c06c089f2a42fbd90395225f
Image: nginx
Image ID: docker-pullable://nginx@sha256:86ae264c3f4acb99b2dee4d0098c40cb8c46dcf9e1148f05d3a51c4df6758c12
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 29 Apr 2020 11:47:06 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-hln8x (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-hln8x:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-hln8x
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events: <none>
这里除了可以看到pod的整体信息,还可以在Containers
下面看到每个容器的单独状态,如果有报错就可以看到到底是哪个容器有问题。同时在最下面的Events
还有一些异常的消息。
而想进一步获取单个容器的日志,可以跑下面的命令,例如查看nginx容器的日志
kubectl logs hellok8s mynginx
结果如下
[root@k8s-master k8s-test]# kubectl logs hellok8s mynginx
10.244.0.0 - - [29/Apr/2020:06:43:58 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
只有我们刚才curl的一条记录,没有别的异常消息。
最后如果想删除刚才创建的测试pod,可以跑下面的命令
kubectl delete pod hellok8s
总结
这一节我们通过yaml配置文件成功创建了自己的第一个pod。但是仅仅创建出pod只是服务部署的第一步,k8s如何确保不光容器起来了,而且可以正常对外提供服务?又或者容器内的进程持续可用而不是僵尸进程?如果容器不会自己异常退出什么时候该剔除这种容器?带着这些问题我们下一节来继续学习。