体验 Kubernetes 最简单的方法是跑一个 nginx 容器,然后使用 kubectl 操作该容器。
创建pod
使用命令行
1
| kubectl run --image=nginx:alpine nginx-app --port=80
|
查看pods
1
2
3
| kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-app 1/1 Running 0 3s
|
等到容器变成 Running 后,就可以用 kubectl
命令来操作它了,比如
kubectl get
- 类似于 docker ps
,查询资源列表kubectl describe
- 类似于 docker inspect
,获取资源的详细信息kubectl logs
- 类似于 docker logs
,获取容器的日志kubectl exec
- 类似于 docker exec
,在容器内执行一个命令
查看pod详情
1
2
3
4
5
| kubectl describe pod nginx-app | grep IP
kubectl describe pod nginx | grep IP
IP: 172.17.0.3
IPs:
IP: 172.17.0.3
|
集群内测试,本地使用minikube创建单集群,进入minikube节点ssh
1
2
| minikube ssh
curl http://172.17.0.3
|
使用yaml文件
nginx.pod.yaml
1
2
3
4
5
6
7
8
9
10
11
12
| apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
|
1
| kubectl create -f nginx.pod.yaml
|
创建deployment
kubectl run
并不是直接创建一个 Pod,而是先创建一个 Deployment 资源(replicas=1),再由与 Deployment 关联的 ReplicaSet 来自动创建 Pod,这等价于这样一个配置nginx.nginx.deployment.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: nginx-app
name: nginx-app
namespace: default
spec:
replicas: 1
selector:
matchLabels:
run: nginx-app
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
run: nginx-app
spec:
containers:
- image: nginx
name: nginx-app
ports:
- containerPort: 80
protocol: TCP
dnsPolicy: ClusterFirst
restartPolicy: Always
|
这样kubectl create -f nginx.nginx.deployment.yaml
将会创建名为nginx-app的Deployment和随机名称关联的pod。
创建service
前面虽然创建了 Pod,但是在 kubernetes 中,Pod 的 IP 地址会随着 Pod 的重启而变化,并不建议直接拿 Pod 的 IP 来交互。那如何来访问这些 Pod 提供的服务呢?使用 Service。Service 为一组 Pod(通过 labels 来选择)提供一个统一的入口,并为它们提供负载均衡和自动服务发现。比如,可以为前面的 deploymentnginx-app
创建一个 service:
1
| kubectl expose deployment nginx-app --port=80 --target-port=80 --type=NodePort
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| kubectl describe service nginx-app
Name: nginx-app
Namespace: default
Labels: run=nginx-app
Annotations: <none>
Selector: run=nginx-app
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.105.166.236
IPs: 10.105.166.236
Port: <unset 80/TCP
TargetPort: 80/TCP
NodePort: <unset 32447/TCP
Endpoints: 172.17.0.7:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
|
这样,在 cluster 内部就可以通过 http://10.105.166.236
和 http://node-ip:32447
来访问 nginx-app。而在 cluster 外面,则只能通过 http://node-ip:32447
来访问。
使用 Volume
Pod 的生命周期通常比较短,只要出现了异常,就会创建一个新的 Pod 来代替它。那容器产生的数据呢?容器内的数据会随着 Pod 消亡而自动消失。Volume 就是为了持久化容器数据而生,比如可以为 redis 容器指定一个 hostPath 来存储 redis 数据(pod.redis.yaml):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-persistent-storage
mountPath: /data/redis
volumes:
- name: redis-persistent-storage
hostPath:
path: /data/
|
1
| kubectl create -f pod.redis.yaml
|
Kubernetes volume 支持非常多的插件,可以根据实际需要来选择:
- emptyDir
- hostPath
- gcePersistentDisk
- awsElasticBlockStore
- nfs
- iscsi
- flocker
- glusterfs
- rbd
- cephfs
- gitRepo
- secret
- persistentVolumeClaim
- downwardAPI
- azureFileVolume
- vsphereVolume
参见