目录
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元; Pod 中会启动一个或一组紧密相关的业务容器, 各个业务容器相当于Pod 中的各个进程, 此时就可以将Pod 作为虚拟机看待; 在创建 Pod 时会启动一个init容器, 用来初始化存储和网络, 其余的业务容器都将在init容器启动后启动, 业务容器共享init容器的存储和网络; Pod 只是一个逻辑单元, 并不是真实存在的“主机”, 这种类比主机的概念可以更好的符合现有互联网中几乎所有的虚拟化设计; 像之前运行在虚拟机中的 nginx、mysql、php均可以使用对应的镜像运行出对应的容器在Pod中, 来类比虚拟机中运行这三者;
对于 Pod 而言, 在运行的过程中, k8s为了控制其生命周期的状态, 增加了容器探测指针、资源限额、期望状态保持、多容器结合、安全策略设定、控制器受管、故障处理策略 等; Pod在平时是不能够被单独创建的, 而是需要使用控制器对其创建, 这样可以时刻保持Pod的期望状态;
在Kubernetes中所有的资源均可通过命令行参数或者资源清单[yaml/json]的方式进行创建和修改, 但由于Kubernetes属于声明式资源控制集群, 故大多管理Kubernetes集群的方式采用资源配置清单; 资源配置清单可以很好的追溯资源的原型和详细的配置, 且配合版本控制能够完成更好的溯源、回滚、发布等操作; 所以课程中所有的资源创建和修改都会采用资源配置清单的方式, 除部分命令行操作以外;
1.1 创建一个pod
$ vim nginx.yaml apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx:1.16.1 ports: - containerPort: 80 $ kubectl apply -f nginx.yaml
1.2 pod是如何被创建的
step1: kubectl 向 k8s api server 发起一个create pod 请求
step2: k8s api server接收到pod创建请求后,不会去直接创建pod;而是生成一个包含创建信息的yaml。
step3: apiserver 将刚才的yaml信息写入etcd数据库。
step4: scheduler 查看 k8s api,判断:pod.spec.Node == null,若为null,表示这个Pod请求是新来的,需要创建;因此先进行调度计算,找到最适合的node。并更新数据库
step5: node节点上的Kubelet通过监听数据库更新,发现有新的任务与自己的node编号匹配,则进行任务创建
1.3 创建一个单容器pod
$ vim mysql.yaml apiVersion: v1 kind: Pod metadata: name: mysql labels: name: mysql spec: restartPolicy: OnFailure containers: - name: mysql image: mysql:5.7 imagePullPolicy: IfNotPresent env: - name: MYSQL_ROOT_PASSWORD value: "123456" resources: limits: memory: "1024Mi" cpu: "1000m" ports: - containerPort: 3306 nodeSelector: kubernetes.io/hostname: kub-k8s-node2 # nodeName: kub-k8s-node2 $ kubectl apply -f mysql.yaml # 字段解析 restartPolicy: pod 重启策略,可选参数有: 1、Always:Pod中的容器无论如何停止都会自动重启 2、OnFailure: Pod中的容器非正常停止会自动重启 3、Never: Pod中的容器无论怎样都不会自动重启 imagePullPolicy: 镜像拉取策略,可选参数有: 1、Always:总是重新拉取 2、IfNotPresent:默认,如果本地有,则不拉取 3、Never:只是用本地镜像,从不拉取 nodeSelector: 节点选择器:可以指定node的标签,查看标签指令: nodeName: 节点名称: 可以指定node的名称进行调度 $ kubectl get node --show-labels
1.4 创建一个多容器pod
#vim lnmp.yaml --- apiVersion: v1 kind: Pod metadata: name: nginx-many namespace: default labels: app: nginx spec: restartPolicy: OnFailure containers: - name: nginx image: nginx:1.16.1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 - name: php-fpm image: php:8.0-fpm-alpine imagePullPolicy: IfNotPresent ports: - containerPort: 9000 $ kubectl apply -f lnmp.yaml # 字段解析 nodeSelector: 节点选择器:可以指定node的标签,查看标签指令: $ kubectl get node --show-labels
1.4.1 配置节点标签
添加标签· kubectl label nodes node3 name=value 删除标签 kubectl label nodes node3 name-
1.5 Pod容器的交互
1.5.1 创建pod,并做本地解析
vim host-alias.yaml --- apiVersion: v1 kind: Pod metadata: name: centos labels: name: centos spec: containers: - name: centos image: centos:7 command: - "tail" - "-f" - "/dev/null" hostAliases: - ip: "192.168.100.128" hostnames: - "master" - "k8s-master" - "apiserver" # 字段解析 command: 启动容器时执行的指令,类似于docker run -it 镜像 tail -f /dev/null hostAliases: 在容器中的/etc/hosts文件中配置本地解析
1.5.2 pod共享进程
[root@kub-k8s-master prome]# kubectl delete -f pod.yml pod "website" deleted [root@kub-k8s-master prome]# vim pod.yml #修改如下。最好是提前将镜像pull下来。 --- apiVersion: v1 kind: Pod metadata: name: website labels: app: website spec: shareProcessNamespace: true #共享进程名称空间 containers: - name: test-web image: daocloud.io/library/nginx ports: - containerPort: 80 - name: busybox image: daocloud.io/library/busybox stdin: true tty: true
创建[root@kub-k8s-master prome]# kubectl apply -f pod.yml pod/website created
1. 定义了 shareProcessNamespace=true 表示这个 Pod 里的容器要共享进程(PID Namespace)如果是false则为不共享。 2. 定义了两个容器: 一个 nginx 容器 一个开启了 tty 和 stdin 的 busybos 容器 在 Pod 的 YAML 文件里声明开启它们俩,等同于设置了 docker run 里的 -it(-i 即 stdin,-t 即 tty)参数。此 Pod 被创建后,就可以使用 shell 容器的 tty 跟这个容器进行交互了。我们通过kubectl可以查看到 # kubectl exec -it website -c busybox -- ps aux PID USER TIME COMMAND 1 root 0:00 /pause 7 root 0:00 nginx: master process nginx -g daemon off; 35 101 0:00 nginx: worker process 36 root 0:00 sh 66 root 0:00 ps aux 在busybox中可以查看到nginx的进程
1.5.2 pod共用宿主机namespace
刚才的都是pod里面容器的Namespace,并没有和本机的Namespace做共享,接下来我们可以做与本机的Namespace共享,可以在容器里面看到本机的进程。 [root@kub-k8s-master prome]# kubectl delete -f pod.yml pod "website" deleted [root@kub-k8s-master prome]# vim pod.yml #修改如下 --- apiVersion: v1 kind: Pod metadata: name: website labels: app: website spec: hostNetwork: true #共享宿主机网络 hostIPC: true #共享ipc通信 hostPID: true #共享宿主机的pid containers: - name: test-web image: daocloud.io/library/nginx ports: - containerPort: 80 - name: busybos image: daocloud.io/library/busybox stdin: true tty: true
创建pod[root@kub-k8s-master prome]# kubectl apply -f pod.yml pod/website created
定义了共享宿主机的 Network、IPC 和 PID Namespace。这样,此 Pod 里的所有容器,会直接使用宿主机的网络、直接与宿主机进行 IPC 通信、看到宿主机里正在运行的所有进程。