pod 的创建和常用操作
Pod是Kubernetes中最基本的部署调度单元,可以包含container,逻辑上表示某种应用的一个实例。例如一个web站点应用由前端、后端及数据库构建而成,这三个组件将运行在各自的容器中,那么我们可以创建包含三个container的pod。
而pod的创建可以通过命令创建或者将pod资源定义为资源清单,再通过定义的清单创建。
1.POD 的创建流程
首先判断:pod.spec.Node == null?
若为null,表示这个Pod请求是新来的,需要创建;因此先进行调度计算,找到最“闲”的node。
然后将信息在etcd数据库中更新分配结果:pod.spec.Node = nodeA (设置一个具体的节点)
ps:同样上述操作的各种信息也要写到etcd数据库中中。
如果这条记录中的Node与自己的编号相同(即这个Pod由scheduler分配给自己了);
则调用node中的docker api,创建container。
2. 创建POD
命令行:
kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool]
kubectl run test --image=httpd --port=80 --replicas=2
通过资源配置清单的方式创建
Pod在kubernetes中也是一种资源,pod资源的定义也是通过”apiVersion”、”kind”、”meadata”、”spec”、”status”五个字段组成,除”status”字段中的信息为系统自动生成外,其余各字段都需要管理员定义。
1、pod中容器的管理
Pod中容器的定义主要是在spec字段下的containers字段下定义,containers字段是定义pod时其嵌套字段spec中的必选项,用于为pod指定要创建的容器列表。
(1)Containers中关于容器的字段中常用字段有:
1)name:必选字段,用于指定容器名称
2)image:为可选字段,定义容器运行时的镜像,但是自助式的pod不能省略此字段。
3)imagePullPolicy:用于指定镜像的获取策略,主要的值有:
Always:当镜像不存在时或不是最新镜像时则从指定的仓库中去拉去镜像
IfNotPresent:当需要运行的镜像在本地不存在时则从指定的仓库中下载镜像
Nerver:仅使用本地镜像,不去仓库中下载镜像
2)暴露pod中服务的端口
Containers字段中的ports字段用于暴露容器的端口,容器的ports字段的值是一个列表,由一到多个端口对象组成,常用的嵌套字段如下:
1)containerPort:为必选字段,指定在Pod对象的的ip地址上暴露的容器的端口。
2)name:当前端口端口名称,需在当前pod中唯一,此端口可被Serviece资源调用。
3)protocol:端口相关的协议,值为tcp或udp
Pod对象的ip地址仅可在当前集群内可达,集群外是无法访问,当集群外需要访问pod中的服务时,可定义node节点的IP地址及端口,将pod中服务端口映射到node上,外部通过node节点访问;一般都不建议这样做,常用的做法是通过service的NodePort模式访问pod内的服务。
4)hostPort:主机端口
5)hostIP:主机端口要绑定主机的ip
# 定义一个pod资源指定镜像以及端口 [root@master01 test01]# cat test03.yaml apiVersion: v1 kind: Pod metadata: name: test-nginx spec: containers: - name: nginx-test01 image: nginx:1.12 ports: - name: http containerPort: 80 protocol: TCP hostPort: 33333
(3)定义pod中容器的运行程序及指令
运行docker容器时运行的应用程序由Dockerfile中ENTRYPOINT指令定义,传递的参数则通过CMD指令指定,ENTRYPOINT不存在时,CMD可用于同时指定程序和参数。而kubernetes中containers字段中的command字段能够指定不同于镜像默认运行的应用程序,可通过args字段传参,并会覆盖镜像中的默认定义;如果只定义了command字段,则会覆盖镜像中的默认指定及参数,如果只定义了args字段,则会将参数传递到容器中。
(4)为pod中的容器定义环境变量
Docker中程序的配置文件可以通过配置环境变量或者将配置文件挂载到宿主机上实现一个容器在不同的场景下使用不同的配置文件。Kubernetes中也已通过配置环境变量为Pod中容器传递参数。Kubernetes中的环境变量由containers中得evn字段定义;环境变量通常由name和value字段构成。
# 创建一个运行mysql数据库的pod资源并通过环境变量设置密码 [root@master01 test01]# cat test05.yaml apiVersion: v1 kind: Pod metadata: name: test-env spec: containers: - name: mysql-env image: mysql env: - name: "MYSQL_ROOT_PASSWORD" value: "123456" # 创建pod [root@master01 test01]# kubectl apply -f test04.yaml pod/test-env created # 查看pod中容器的环境变量 [root@master01 test01]# kubectl exec -it test-env -- printenv PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=test-env TERM=xterm MYSQL_ROOT_PASSWORD=123456
(5)设置pod中容器共享节点网络名称空间
Kubernetes中有一些pod中的容器需要共享节点的名称空间,比如通过kubeadm部署的kubernetes集群中的kube-apiserver、kube-scheduler等需要共享节点的名称空间,执行系统及的管理任务。如果pod中的容器需要共享节点的网络名称空间只需设置spec.HostNetwork的属性为true即可。同时,还可通过设置”spec.hostPID”及”spec.hostIPC”共享工作节点的PID及IPC。
# 定义一个运行tomcat容器的pod资源,共享节点的网络名称空间 [root@master01 test01]# cat test06.yaml apiVersion: v1 kind: Pod metadata: name: tomcat-net spec: containers: - name: tomcat-hostnet image: tomcat hostNetwork: true # 创建pod [root@master01 test01]# kubectl apply -f test06.yaml # 查看node监听的端口 [root@node01 ~]# lsof -i :8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 29856 root 56u IPv6 2949386 0t0 TCP *:webcache (LISTEN)
(6)pod资源中安全设置
Pod对象的安全上下文定义在spec.securityContext字段中,容器的安全定义在spec.containers[].securityContest字段中,各字段的具体用法可通过”kubectl explain”命令查看。
# 创建一个pod资源并以非root用户运行容器中服务 [root@master01 test01]# cat test07.yaml apiVersion: v1 kind: Pod metadata: name: test-sec spec: containers: - name: busybox-sec image: busybox command: ["/bin/sh","-c","sleep 3600"] securityContext: runAsNonRoot: true runAsUser: 1000 allowPrivilegeEscalation: false [root@master01 test01]# kubectl exec -it test-sec -- ps PID USER TIME COMMAND 1 1000 0:00 sleep 3600