[工具与库]docker & k8s

一、docker

# 列一下当前机器有哪些image
docker image ls

# 查看image信息,参数是image id
docker image inspect bbc784a6bbbd

# 删除docker镜像
docker image rm -f 2c29d04b7cdd 003e8010223b 32ede99351f8 15b5afd66110

# 停止容器
docker ps -a找到container hash
docker stop $hash

# 删除容器
docker rm $hash

# 进入一个已经启动的容器
docker attch $hash

# 拉镜像
docker login -u xiaoguang.li it-artifactory.xx.com
docker pull it-artifactory.xx.com/docker/yy:mytag

# 进入docker
docker run -it yy:mytag /bin/bash
docker run -it \
--gpus all \
-v /mnt:/mnt \
it-artifactory.xx.com/docker/yy:mytag /bin/bash

# 清理所有已经停止的容器
docker system prune

# 清理所有容器,慎重
docker system prune -a -f

# 拷贝文件,yyy不能用通配符
docker cp xxx $hash:yyy
docker cp $hash:yyy xxx

# 查看镜像信息,包括层数
docker image inspect $hash

# 镜像保存成文件,并load出来
docker save golang:alpine3.7 -o ./my-image.tar
docker load < my-image.tar

​# 构建镜像,-f指定Dockerfile
docker build -t sgx_test_v0.1 .
docker build -t sgx_network_simulation:latest -f experiments/sgx_network_simulation/Dockerfile .

二、k8s

1、50天学习

Kubernetes Learning Path_Version 2.0.pdf

Kubernetes basics video series

https://www.youtube.com/playlist?list=PLLasX02E8BPCrIhFrc_ZiINhbRkYMKdPT

2、基本概念

资源存储在etcd里,所有资源通过yaml或者json来描述。

(1)Master

集群控制节点,命令都是在master上执行,占据一个或多个独立的服务器,关键进程有kube-apiserver、kube-controller-manager、kube-scheduler。

(2)Node

除了master,k8s集群中其他机器称为node,跟master一样可以是物理主机也可以是虚拟机;关键进程有kubelet、kube-proxy、docker engine,kubelet进程会定期向master汇报,超时的话会被判定为不可用,用 kubectl get nodes 可以查询node,用 kubectl describe node  可以查看详细信息。

(3)Pod

每个pod有一个“根容器”Pause容器,一个或多个用户业务容器;Pause容器的状态代表了pod的状态,其他容器共享Pause容器的IP(称作pod IP)和volume;k8s里pod之间可以直接通信,pod ID + 容器端口组成endpoint,代表一个服务对外的通信地址,比如tomcat有管理端口和服务端口,加上pod IP组成两个endpoint,通过 kubectl describe pod 可以查看pod信息;计算资源参数有requests和limits,前者是启动pod时检查的最小资源,后者是运行过程中定时监控的最大资源,超过被杀掉,cpu单位是千分之一核如“1000m”,memory单位是 Gi 或者 Mi。

(4)Label

key-value对,由用户指定,附加到各种资源对象上,在不同资源上含义也不一样;可以在创建后动态添加或删除;通过Label Selector实现类似SQL的对象查询机制,使得被管理的对象能够被精细地分组管理,实现整个集群的高可用性。

(5)Replication Controller

定义了一个期望的场景,声明某种pod的数量在任意时刻符合某个预期;RC包含了期望的pod的数量、用于筛选目标的Label Selector、创建pod的模板;当我们定义一个RC并提交给k8s后,master上的controller manager会接收此RC定义并定期巡检系统中的pod数量,实现高可用;运行时可通过 kubectl scale rc redis-slave --replicas=3 来实现动态调整;后来升级到了replica set,支持基于集合的Label Selector,我们很少单独用因为被deployment接管了。

(6)Deployment

在1.2版本引入,可以看做RC的一次升级,可以看到各pod的状态,支持更新、暂停、回滚;创建命令是 kubectl create -f tomcat- deployment.yaml ,查询命令是 kubectl get deployments ,查看对应的 replica set命令是 kubectl get rs ,可以看到rs的名字是deployment的名字拼上后缀,查看详情是 kubectl describe deployments

可以用命令进行升级,kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

可以看到Pod数从给定的3个变成4个(replica仍为3),用来滚动升级,其实是起了一个ReplicaSet,replica设为1,起来后原来的降到2,新的升到2,直到新3、旧0。kubectl get rs能看到两个ReplicaSet的状态,一个3、一个0。升级策略可以改,默认是滚动升级RollingUpdate,可以改成Recreate。

另一个方法是edit,kubectl edit deployment/nginx-deployment,会vim打开一个yaml文件,编辑完保存后自动更新,看到第四个滚动pod被拉起。

查看当前滚动升级状态是,kubectl rollout status deployment/nginx-deployment

查看滚动升级历史记录(Event)是describe。

不建议改Deployment的label selector,因为这会使原来的ReplicaSet和Pod处于孤立状态,需要手动删除。

# 查看滚动升级信息
kubectl rollout history deployment/nginx-deployment
# 查看某次滚动升级信息
kubectl rollout history deployment/nginx-deployment --revision=3
# 回滚到上次
kubectl rollout undo deployment/nginx-deployment
# 回滚到某次
kubectl rollout undo deployment/nginx-deployment --to-revision=3
# 暂停自动检测配置变更引起的部署,此时再set是不会触发滚动升级的
kubectl rollout pause deployment/nginx-deployment
# 暂停恢复,一次性升级完
kubectl rollout resume deploy nginx-deployment
# DaemonSet和StatefulSet也能进行类似的滚动升级。

 扩缩容命令

# 手动扩容缩容都是这句命令
kubectl scale deployment nginx-deployment --replicas 5
# 自动扩缩容通过HPA实现

(7)Horizontal Pod Autoscaler

在1.1版本引入,HPA实现自动化pod扩缩容,省去手动敲 kubectl scale 命令;有两种方式作为pod负载的度量指标,CPUUtilizationPercentage、每秒请求数TPS或QPS;CPU是按requests算的使用率百分比(确定不是limits吗?查了下官网确实是requests),比如申请400m,系统剩余超过400m时才会创建,实际用了200m,则百分比是50%;使用命令是 kubectl autoscale deployment php-apache --cpu-percent=90 --min=1 --max=10

(8)StatefulSet

管理有状态的pod,比如MySQL、MongoDB、Akka、ZooKeeper,有以下共同点,每个节点都有固定的身份id、集群规模比较固定不能随意变动、每个节点都是有状态的会持久化数据、磁盘损坏时则无法正常运行;1.4版本引入PetSet,1.5版本改名叫StatefulSet。

(9)Service

一个微服务,有外部可访问的固定的IP(称为cluster IP)和服务端口;查看endpoints列表 kubectl get endpoints ;查看服务信息 kubectl get svc tomcat-service -o yaml ,能看到cluster IP。

为某个deployment快速创建service是 kubectl expose deployment webapp。查看service,kubectl get svc

(10)Job

在1.2版本引入,批处理任务。Job生成的pod是临时的,重启策略为never。有四种处理模式:Job Template Expansion,每个work item配一个Job,适合work item数量少但重的场景;Queue with Pod per work,队列存储work item,一个Job处理队列,每个work item起一个Pod;Queue with variable Pod count,相比前一种,一个Pod可以处理多个work item;Single Job with static work assignment,跟2、3一样是一个Job,但不是队列而是静态分配好的。

四种处理模式可以总结出三种Job:Non-parallel Jobs,一个Job只启动一个Pod,Pod结束时Job结束;Parallel Jobs with a fixed completion count,Job会启动多个Pod,N个Pod正常结束后Job结束,Job的.spec.completions控制N,Job的.spec.parallelism控制并行度,N可以不等于并行数;Parallel Jobs with a work queue,此时work item提交到一个队列中,不需要设置completions,Pod自行判断队列中是否还有work item。

kubectl get jobs -l jobgroup=jobexample

(11)Volume

存储卷,生命周期与pod相同,与其中的容器不相关;支持GlusterFS、Ceph等;使用方式是pod yaml里加一个volumes,类别有emptyDir、hostPath、nfs、secret等。

(12)PersistentVolume

volume是定义在pod上的,是计算资源的一部分,实际上存储资源可以独立于计算资源。PV和volume的区别是,PV不属于任何node,在node之外定义,每个node都能访问。accessModes支持ReadWriteOnce、ReadOnlyMany、ReadWriteMany,once和many是指一个node还是多个node。如果pod想用PV,先定义一个PVC对象,PVC是Persistent Volume Claim,PVC中指定PV的name,再在pod的volumes中加上persistentVolumeClaim,claimName为PVC的name。

(13)Namespace

用于多租户的资源隔离。查看所有租户是 kubectl get namespaces。默认创建的是default,如果不指定,所有pod、RC、service等资源都会创建到default名下。创建新的namespace时,先定义一个kind: Namespace资源,metadata里就一个name,然后在pod的metadata中加一个namespace。kubectl命令只会显示当前namespace下的资源,加--namespace=xxx,可以看别的租户的资源。

(14)Annotation

与label类似,用key-value进行定义。不同的是label有严格的命名规则,用于label selector,annotation是用户任意定义的附加信息,以便外部查找。

(15)ConfigMap

这个概念来源于docker。docker把所有程序、依赖库、数据、配置打包到镜像中,会带来在运行中如何修改配置的问题,docker为了解决这个问题提出ConfigMap的概念,把容器外的配置文件映射到容器内,这样就能通过外部进行修改了。这种方法需要先在外部创建配置文件,在分布式情况下变得麻烦,需要管理好多服务器上的ConfigMap,所以k8s提出了它自己的ConfigMap资源对象。查询命令,kubectl get configmap

一个简单的config map定义,get时能看到有两个data。

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appvars
data:
  apploglevel: info
  appdatadir: /var/data

(16)downward API

pod的概念在容器之上,downward API是将pod的信息注入到容器的环境变量中。

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
  restartPolicy: Never

valueFrom就是downward API的语法。看日志能看到这几个环境变量。

(17)DaemonSet

1.2版本新增,用于管理每个node上仅运行一份Pod的副本实例,比如ceph、log Fluentd、monitor Prometheus(k8s中的单例模式?)。创建DaemonSet后,会自动在每个node上创建一个pod。但实际上我在一个13个node的集群上起如下DaemonSet,只起来10个node上的pod,不知道为什么。

kubectl get daemonset

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-cloud-logging
  labels:
    k8s-app: fluentd-cloud-logging
spec:
  selector:
    matchLabels:
      k8s-app: fluentd-cloud-logging
  template:
    metadata:
      labels:
        k8s-app: fluentd-cloud-logging
    spec:
      containers:
      - name: fluentd-cloud-logging
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
        env:
        - name: FLUENTD_ARGS
          value: -q
        volumeMounts:
        - name: varlog
          mountPath: /var/log
          readOnly: false
        - name: containers
          mountPath: /var/lib/docker/containers
          readOnly: false
      volumes:
      - name: containers
        hostPath:
          path: /var/lib/docker/containers
      - name: varlog
        hostPath:
          path: /var/log

(18)CronJob

定时任务,定时表达式参考了Linux Cron的表达式,格式是

5段
Minutes Hours DayofMonth Month DayofWeek
* 是任意值,如果minutes使用*,表示每分钟都会触发
/ 是从起始时间开始触发,如果minutes使用5/20,表示5min时第一次,此后每20分钟触发一次
每隔一分钟执行一次任务
*/1 * * * *

查看当前job运行情况,kubectl get jobs --watch。可以看到起了很多pod,每隔一分钟起一个hello。很快进入completed状态。删掉它们的命令是 kubectl get delete cronjob hello,注意这里删的是pod,不是cronjob本身,删cronjob用delete -f cron.yaml。

(19)Init Container

初始化容器,定义在Pod yaml里,在应用容器启动前运行,跑一遍,成功后再起应用容器,有多个时挨个跑一遍。常用于生成配置文件、注册数据库、下载依赖包等。yaml中initContainers跟containers同级。

(20)CRD

Kubernetes CRD - 知乎

(21)DevicePlugin

k8s 1.8开始支持,以DaemonSet的方式启动一个DevicePlugin容器,供kubelet调用。

image: nvidia/k8s-device-plugin:1.11

1.8和1.9版本需要在worker node上为kubelet手动启用DevicePlugin,1.10+自动启用了。

然后就能在别的容器里claim gpu资源了,位置是resources里的limits,跟cpu、memory一样,requests可以不写,默认跟limits一样,不能只放在requests。不能跨容器share。

nvidia.com/gpu: 1

(22)CoreDNS

k8s DNS经历了三个阶段,1.2版本起是SkyDNS,1.4版本起是KubeDNS,1.11版本起是CoreDNS。coredns在一个pod的一个容器内就能完成前几代多个容器才能完成的功能。kubectl看一下pod、cm、svc、deployment能找到各有一个叫coredns的资源(pod可能是多个),namespace是kube-system。node支持本地的DNS缓存,防止dns相关资源的负载过大,需要额外部署。

Pod的dnsPolicy有四种,Default是继承宿主机DNS,ClusterFirst是优先用coredns,ClusterFirstWithHostNet适用于以hostNetwork模式运行的Pod(同级的hostNetwork置为true),None是忽略coredns需要手动配置dnsConfig。

(23)Ingress

Service实现的是四层转发,ClusterIP + Port,Ingress实现的是七层转发,由URL决定往哪个pod转,入口流量由IngressController决定到哪个Service对应的endpoint,HTTP URL匹配到一个Ingress上,Ingress对应了一个Service,Service对应了一个后端Pod。Ingress支持HTTP和HTTPS。

1.18版本开始支持rule中设置通配符,仅支持一层,即*.foo.com可以是bar.foo.com,但不能是baz.bar.foo.com,也不能是foo.com。

3、常用命令

参考文档:kubectl 备忘单 | Kubernetes

# 查看k8s版本
kubectl version
# 查看api version
kubectl api-versions
# 查询已经创建的资源的yaml
kubectl get deployment fedlearner-web-console-v2 -o yaml
# 创建资源,比如从yaml里创建pod。可以指定文件夹,依次创建文件夹下所有yaml
kubectl create -f cm-test-pod.yaml
kubectl create -f jobs
# 查看日志
kubectl logs cm-test-pod
# 删除资源,可以根据创建时的yaml来删除
kubectl delete daemonset/netshoot
kubectl delete -f cm-appvars.yaml
# 连接pod,先 kubectl get pods 查名字,再执行以下,-c是指定容器的,只有一个容器时不用加
kubectl exec -it  bash
kubectl exec -it fl-sgx-simulation-server -c main-app bash
# 从pod复制文件,反之亦然。如果想从node上复制,先开一个node shell,就有对应的pod可以用来复制
kubectl cp ${pod_name}:/{file_path} ./
kubectl cp sgx-test-pod-1:CI-Examples/wide_n_deep/data ./data
# 查询ingress
kubectl get ing.networking.k8s.io
# 查看所有namespace下的资源,加-A,例如查看service
kubectl get svc -A
# 带namespace的edit
kubectl edit svc/web-gateway-proxy --namespace=vke-system
# 允许master部署pod(默认不允许)
kubectl taint nodes n137-025-197 node-role.kubernetes.io/master-
kubectl taint nodes --all node-role.kubernetes.io/master-
# 不允许master部署pod
kubectl taint nodes n137-025-197 node-role.kubernetes.io/master=true:NoSchedule
# 取消taint,末尾加个-
kubectl taint nodes n137-025-195 node.kubernetes.io/unreachable:NoSchedule-
# 强制删pod
kubectl delete -nkube-system pods calico-node-wt2l9 --grace-period=0 --force
# port forward
kubectl port-forward --address 0.0.0.0 pod/fedlearner-stack-kibana-86569fb458-kmf59 5601:5601

4、官方参考文档

容期间通信

Communicate Between Containers in the Same Pod Using a Shared Volume | Kubernetes

你可能感兴趣的:(docker,k8s)