体验 Kubernetes 最简单的方法是跑一个 nginx 容器,然后使用 kubectl 操作该容器。Kubernetes 提供了一个类似于 docker run
的命令 kubectl run
,可以方便的创建一个容器(实际上创建的是一个由 deployment 来管理的 Pod):
$ kubectl run --image=nginx:alpine nginx-app --port=80deployment "nginx-app" created$ kubectl get podsNAME READY STATUS RESTARTS AGEnginx-app-4028413181-cnt1i 1/1 Running 0 52s
等到容器变成 Running 后,就可以用 kubectl
命令来操作它了,比如
kubectl get
- 类似于 docker ps
,查询资源列表
kubectl describe
- 类似于 docker inspect
,获取资源的详细信息
kubectl logs
- 类似于 docker logs
,获取容器的日志
kubectl exec
- 类似于 docker exec
,在容器内执行一个命令
$ kubectl get podsNAME READY STATUS RESTARTS AGEnginx-app-4028413181-cnt1i 1/1 Running 0 6m$ kubectl exec nginx-app-4028413181-cnt1i ps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 1 0.0 0.5 31736 5108 ? Ss 00:19 0:00 nginx: master process nginx -g daemon off;nginx 5 0.0 0.2 32124 2844 ? S 00:19 0:00 nginx: worker processroot 18 0.0 0.2 17500 2112 ? Rs 00:25 0:00 ps aux$ kubectl describe pod nginx-app-4028413181-cnt1iName: nginx-app-4028413181-cnt1iNamespace: defaultNode: boot2docker/192.168.64.12Start Time: Tue, 06 Sep 2016 08:18:41 +0800Labels: pod-template-hash=4028413181run=nginx-appStatus: RunningIP: 172.17.0.3Controllers: ReplicaSet/nginx-app-4028413181Containers:nginx-app:Container ID: docker://4ef989b57d0a7638ad9c5bbc22e16d5ea5b459281c77074fc982eba50973107fImage: nginxImage ID: docker://sha256:4efb2fcdb1ab05fb03c9435234343c1cc65289eeb016be86193e88d3a5d84f6bPort: 80/TCPState: RunningStarted: Tue, 06 Sep 2016 08:19:30 +0800Ready: TrueRestart Count: 0Environment Variables: <none>Conditions:Type StatusInitialized TrueReady TruePodScheduled TrueVolumes:default-token-9o8ks:Type: Secret (a volume populated by a Secret)SecretName: default-token-9o8ksQoS Tier: BestEffortEvents:FirstSeen LastSeen Count From SubobjectPath Type Reason Message--------- -------- ----- ---- ------------- -------- ------ -------8m 8m 1 {default-scheduler} Normal Scheduled Successfully assigned nginx-app-4028413181-cnt1i to boot2docker8m 8m 1 {kubelet boot2docker} spec.containers{nginx-app} Normal Pulling pulling image "nginx"7m 7m 1 {kubelet boot2docker} spec.containers{nginx-app} Normal Pulled Successfully pulled image "nginx"7m 7m 1 {kubelet boot2docker} spec.containers{nginx-app} Normal Created Created container with docker id 4ef989b57d0a7m 7m 1 {kubelet boot2docker} spec.containers{nginx-app} Normal Started Started container with docker id 4ef989b57d0a$ curl http://172.17.0.3<!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 andworking. 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>$ kubectl logs nginx-app-4028413181-cnt1i127.0.0.1 - - [06/Sep/2016:00:27:13 +0000] "GET / HTTP/1.0" 200 612 "-" "-" "-"
上面是通过 kubectl run
来启动了第一个 Pod,但是 kubectl run
并不支持所有的功能。在 Kubernetes 中,更经常使用 yaml 文件来定义资源,并通过 kubectl create -f file.yaml
来创建资源。比如,一个简单的 nginx Pod 可以定义为:
apiVersion: v1kind: Podmetadata:name: nginxlabels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80
前面提到,kubectl run
并不是直接创建一个 Pod,而是先创建一个 Deployment 资源(replicas=1),再由与 Deployment 关联的 ReplicaSet 来自动创建 Pod,这等价于这样一个配置:
apiVersion: extensions/v1beta1kind: Deploymentmetadata:labels:run: nginx-appname: nginx-appnamespace: defaultspec:replicas: 1selector:matchLabels:run: nginx-appstrategy:rollingUpdate:maxSurge: 1maxUnavailable: 1type: RollingUpdatetemplate:metadata:labels:run: nginx-appspec:containers:- image: nginxname: nginx-appports:- containerPort: 80protocol: TCPdnsPolicy: ClusterFirstrestartPolicy: Always
Pod 的生命周期通常比较短,只要出现了异常,就会创建一个新的 Pod 来代替它。那容器产生的数据呢?容器内的数据会随着 Pod 消亡而自动消失。Volume 就是为了持久化容器数据而生,比如可以为 redis 容器指定一个 hostPath 来存储 redis 数据:
apiVersion: v1kind: Podmetadata:name: redisspec:containers:- name: redisimage: redisvolumeMounts:- name: redis-persistent-storagemountPath: /data/redisvolumes:- name: redis-persistent-storagehostPath:path: /data/
Kubernetes volume 支持非常多的插件,可以根据实际需要来选择:
emptyDir
hostPath
gcePersistentDisk
awsElasticBlockStore
nfs
iscsi
flocker
glusterfs
rbd
cephfs
gitRepo
secret
persistentVolumeClaim
downwardAPI
azureFileVolume
vsphereVolume
前面虽然创建了 Pod,但是在 kubernetes 中,Pod 的 IP 地址会随着 Pod 的重启而变化,并不建议直接拿 Pod 的 IP 来交互。那如何来访问这些 Pod 提供的服务呢?使用 Service。Service 为一组 Pod(通过 labels 来选择)提供一个统一的入口,并为它们提供负载均衡和自动服务发现。比如,可以为前面的 nginx-app
创建一个 service:
$ kubectl expose deployment nginx-app --port=80 --target-port=80 --type=NodePortservice "nginx-app" exposed$ kubectl describe service nginx-appName: nginx-appNamespace: defaultLabels: run=nginx-appSelector: run=nginx-appType: ClusterIPIP: 10.0.0.66Port: <unset> 80/TCPNodePort: <unset> 30772/TCPEndpoints: 172.17.0.3:80Session Affinity: NoneNo events.
这样,在 cluster 内部就可以通过 http://10.0.0.66
和 http://node-ip:30772
来访问 nginx-app。而在 cluster 外面,则只能通过 http://node-ip:30772
来访问。