上一节发布了一个容器到 K8S 中,但其实实际操做的是 Pod ,那么为何是 Pod,而不是容器。html
Pod 包装了一个或多个容器。
Pod 是 K8S 的最小执行单元。
Pod 是 K8S 中的一个进程。
Pod 可包装 Docker,也支持包装其余类型容器。
Pod 包含封装的容器、存储资源、网络资源、以及指导容器如何运行的配置。node
能够把容器理解为一个无挂钩的光秃秃的集装箱,K8S 这艘大船没法直接挂载它,经过给集装箱(容器)加装挂钩(IP地址)等造成一个 Pod,方便 K8S 来操做。python
也能够把 Pod 理解为传统的虚拟机,而容器是传统虚拟机中运行的程序,只不过虚拟机是一个实体,而 Pod 是一个逻辑概念。linux
K8S 经过编排 Pod 来调度容器,而不是直接操做容器,K8S 没法直接操纵容器。nginx
Pod 为其中运行的多容器提供共享的网络、存储资源、命名空间。shell
Pod 具备惟一 IP 地址,Pod 中的多个容器共享一个 IP 地址和网络端口等网络资源
Pod 中多容器可以使用 localhost 通讯
Pod 中容器和外部通讯时候,多容器须要协调网络端口
Pod 中的容器获取的系统主机名与为 Pod 配置的 name 相同api
Pod 可指定一组存储卷
Pod 中多容器都可以访问该存储卷,以便互相共享数据
Pod 中的共享卷能够持久保存,防止容器重启丢失数据安全
若是使用 kind: Pod 的 yaml 文件来建立 Pod,当前节点服务器出现问题后,Pod 不能被自动调度到其余可用服务器。bash
通常使用 kind: Deployment 的 yaml 来建立 Pod。服务器
Deployment 是一种控制器,能够用来建立、管理 Pod。如建立多副本 Pod,滚动更新 Pod。
当 Pod 所在节点出现问题,Deployment 控制器能够在集群中其余节点启动新 Pod。
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
不具体指定的状况下,imagePullPolicy 是 Always,即 kubelet 会尝试从指定的仓库拉取每一个镜像。
若是容器属性 imagePullPolicy 设置为 IfNotPresent , 则会优先使用本地镜像。
若是容器属性 imagePullPolicy 设置为 IfNotPresent Never, 则会必定使用本地镜像。
apiVersion: v1 kind: Pod metadata: name: private-image-test-1 spec: containers: - name: uses-private-image image: nginx imagePullPolicy: Always command: [ "echo", "SUCCESS" ]
功能:将 Pod 与 Node 绑定
apiVersion: v1 kind: Pod ... spec: nodeSelector: disktype: ssd
该 Pod 只能运行在携带了“disktype:ssd”标签(Label)的节点上,若是没有这种标签的节点,调度将失败。
该字段通常由调度器设置,但咱们测试时候能够手工设置该字段,让调度器认为该 Pod 已经被调度过了。
给 Pod 里各容器的 /etc/hosts 文件设置内容
apiVersion: v1 kind: Pod ...... spec: hostAliases: - ip: "10.20.20.20" hostnames: - "test1.com" - "test2.com"
进容器检查一下
[root@master01 ~]# kubectl exec -it nginx -- bash root@nginx:/# cat /etc/hosts ...... # Entries added by HostAliases. 10.20.20.20 test1.com test2.com
定义参数 shareProcessNamespace=true,那么该 Pod 中全部容器将共享 PID Namespace
建立一个包含两个容器的 Pod
[root@master01 ~]# cat nginx.yaml apiVersion: v1 kind: Pod metadata: name: nginx spec: shareProcessNamespace: true containers: - name: nginx image: nginx - name: shell image: busybox stdin: true tty: true
查看运行状况
[root@master01 ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 2/2 Running 0 117s 192.10.137.131 work03 <none> <none>
进入到 Pod nginx 中的名为 shell 的容器中
[root@master01 ~]# kubectl attach -it nginx -c shell If you don't see a command prompt, try pressing enter. / # ps aux PID USER TIME COMMAND 1 root 0:00 /pause 6 root 0:00 nginx: master process nginx -g daemon off; 33 101 0:00 nginx: worker process 34 root 0:00 sh 39 root 0:00 ps aux
能够看到,shell 容器中能够看到 nginx 容器的进程
咱们能够预先设置好一些通用的配置,当用户提交本身的个性化 Pod 配置时,PodPreset 就能够自动附加通用配置到对应的 Pod 上。PodPreset 里定义的内容,只会在 Pod API 对象被建立以前追加在这个对象自己 上,而不会影响任何 Pod 的控制器的定义。
好比,咱们如今提交的是一个 nginx-deployment,那么这个 Deployment 对象自己是永远不会被 PodPreset 改变的,被修改的只是这个 Deployment 建立出来的全部 Pod。
未启用 PodPreset 特性时
# kubectl get podpresets error: the server doesn't have a resource type "podpresets"
启用 PodPreset 特性
修改 [/etc/kubernetes/manifests/kube-apiserver.yaml] 中的 spec.containers.command: 修改原 - --runtime-config=api/all=true 为 - --runtime-config=api/all=true,settings.k8s.io/v1alpha1=true 新加一行 - --enable-admission-plugins=PodPreset 3台MASTER均执行重启 kubelet systemctl restart kubelet
预设值配置 preset.yaml
apiVersion: settings.k8s.io/v1alpha1 kind: PodPreset metadata: name: allow-tz-env spec: selector: matchLabels: env: - name: TZ value: Asia/Shanghai
Pod配置 nginx.yaml
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx
建立 PodPreset
# kubectl get podpreset No resources found in default namespace. # kubectl apply -f podpreset.yaml podpreset.settings.k8s.io/allow-tz-env created # kubectl get podpreset NAME CREATED AT allow-tz-env
建立 Pod
[root@master01 ~]# kubectl apply -f nginx.yaml pod/nginx created
查看该 Pod 是否被注入
# kubectl get pod nginx -o yaml ...省略 spec: containers: - env: - name: TZ value: Asia/Shanghai image: nginx imagePullPolicy: Always name: nginx resources: {} ...省略
能够看到 Pod 被注入了名为 TZ 的 env
建立 Pod 的 YAML 文件:
cat myapp.yaml
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
建立 mydb 和 myservice 两个 Service 的 YAML 文件:
cat myservice.yaml
kind: Service apiVersion: v1 metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- kind: Service apiVersion: v1 metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377
要启动这个 Pod,能够执行以下命令:
kubectl apply -f myapp.yaml pod/myapp-pod created
检查其状态:
kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 6m
使用下面命令查看更详细的信息:
kubectl describe -f myapp.yaml Name: myapp-pod Namespace: default [...] Labels: app=myapp Status: Pending [...] Init Containers: init-myservice: [...] State: Running [...] init-mydb: [...] State: Waiting Reason: PodInitializing Ready: False [...] Containers: myapp-container: [...] State: Waiting Reason: PodInitializing Ready: False [...]
查看Pod内 Init 容器的日志
$ kubectl logs myapp-pod -c init-myservice $ kubectl logs myapp-pod -c init-mydb
此时,Init 容器将会等待直到发现名称为mydb和myservice的 Service。
建立mydb和myservice的 service:
$ kubectl create -f services.yaml service "myservice" created service "mydb" created
能够看到这些 Init 容器执行完毕,随后my-app的Pod转移进入 Running 状态:
$ kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 1/1 Running 0 9m
只有咱们启动了 mydb 和 myservice 这两个 Service,Init 容器完成,myapp-pod 才能被建立。
若是 Pod 被终止,可经过以下命令查看缘由
kubectl describe pod pod名称 kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' pod名称
Pod 包装了容器,K8S 经过操做 Pod 来操做容器。
Pod 能够包含多个应用容器和多个 Init 容器。
人工直接建立的 Pod 在服务器节点故障时,没有自愈能力,须要使用控制器来解决这个问题。
微信公众号:zuolinux_com