1. 命令集
1.1. docker相关
1.1.1. 查看所用容器状态 docker ps -a
1.1.2. 删除所有不再使用的容器 docker container prune
1.1.3. build镜像 docker build -t kubia . # 当前目录下寻找dockerfile并构建镜像
1.1.4. 进入容器内部 docker exec -it <ContainerName/ContainerID> bash # 这里-i 确保输入流开放.可以在shell中输入命令,-t分配一个伪终端.
1.1.5. 停止一个容器 docker stop <ContainerName/ContainerID>
1.1.6. 删除一个容器 docker rm <ContainerName/ContainerID>
1.1.7. 给一个镜像添加标签 docker tag
1.1.8. 运行一个镜像 docker run -p : -d # 后台运行镜像并把容器内的IPA端口暴露在宿主机的IPB端口
1.1.9. 当自己执行docker命令没有权限,newgrp docker
1.1.10. 给镜像打tag docker tag <原镜像名> <tag名>
1.1.11. 多线程save镜像 docker save :latest | pigz --best -p 32 > .tar.gz
1.2. K8S相关
1.2.1. 获取pod信息 k get pod
1.2.2. 删除一个ReplicationControllers以及他的pods k delete replicationcontroller
1.2.3. 强行删除所有pod k delete cm,deploy,svc,sts --all
1.2.4. 查看一个pod当前用的yaml k get pod -o yaml
1.2.5. k8s运行一个镜像,镜像内的应用监听PORT端口,最后指的是生成一个RC k run --image= --port= --generator=run/vl
1.2.6. kubectl 的 config地址: /etc/kubernetes/kubelet.conf
1.2.7. 调整一个ns的资源限制 kubectl edit resourcequota
1.2.8. 删除所有被驱逐的节点 kubectl get pods | grep Evicted | awk '{print $1}' | xargs kubectl delete pod
1.2.9. 开端口
# 打开hostnetwork,并添加一个tcp转发规则,将9000端口(任意一个集群内节点的外网ip)转发到default空间下的nginx-service:80上,根据需求改为实际值
helm upgrade --``set controller.hostNetwork=``true``,tcp.9000=default``/nginx-service``:80 ingress stable``/nginx-ingress
# 重启所有nginx-ingress pod
kubectl -n ingress get pod | ``awk '{print $1}'``|``grep ingress| ``xargs kubectl -n ingress delete pod
\
2. docker相关
2.1. 为什么要容器?
在同一机器上运行的不同组件可能会遇到各种问题,比如需要不同的库依赖,或者其他不同的环境需求.
当一个产品所需组件少的时候,可以通过给每个组件提供一个单独的操作系统来隔离他们的环境.
但是当组件变小而且总数变多时,这种方法就会造成很多资源浪费.这时候我们就需要用容器技术,容器允许在同一台机器上运行多个服务,不仅提供不同的环境给每个服务,而且将他们隔离.容器类似虚拟机,但是开销小很多.
容器中运行的进程实际上运行在宿主机的操作系统上.但是容器内的进程是和其他进程隔离的.
首先虚拟机需要运行自己的一组系统进程,这消耗了很多额外的计算资源.一个容器仅仅是宿主机上被隔离的单个进程,不会有其他进程的开销.
\
2.2. docker与宿主机的关系
docker内的进程实际上是跑在宿主机上的,可以再宿主机上通过ps -a获取到.但是容器内部会有一套独立的PID分配,完全独立于宿主机的进程树.
容器内部的文件系统,进程,用户,主机名,网络接口都是独立的.
让每个进程运行于自己的容器中,这是docker和k8s所期望的方式.
一个pod中的容器共享相同的IP地址和端口空间.
\
3. K8S相关
3.1. 开发者角度
开发者能指定一些容器必须一起运行,k8s将会在一个工作节点上部署他们.
开发者不应该过度考虑服务发现,扩容,负载均衡,自恢复,甚至领导者的选举.
k8s最小单位是pod,而不是容器.不能单独扩缩容器,只能单独扩缩pod
3.2. k8s集群架构
\
控制面板(master)
工作节点
API服务器
etcd
Scheduler
Controller
Manager
Kubelet
kube-proxy
容器运行时
3.3. k8s运行镜像幕后发生的事情
当运行kubectl命令时,它通过向Kubernetes API服务器发送一个REST HTTP请求,在集群中创建一个新的RC对象.然后,RC创建了一个新的pod,
调度器将其调度到一个工作节点上.kubectl看到pod被调度到节点上,就告知Docker从镜像中心拉取指定的镜像,如果本地没有镜像,则会从远端拉取,
最后Docker拉去镜像并创建运行容器.
3.4. ReplicationController角色
通常,ReplicationController(以下简称RC)用于复制pod,并让他们保持运行.如果你的pod因为任何原因消失了,那么RC将创建一个新的pod来替换消失的pod.
3.5. 为什么需要服务
pod的存在是短暂的,是有可能在任何时候消失的,当发生特殊情况pod消失的时候,RC将拉起pod,新的pod与之前的pod具有不同的IP地址,这就是需要服务的地方,解决不断变化的IP地址的问题,以及在一个固定IP和端口上对外暴露多个pod.
当一个服务被创建时,他会得到一个静态的IP,在服务的生命周期中这个IP不会发生改变.客户端应该通过固定IP地址连接到服务,而不是直接连接pod.服务会确保其中一个pod接收链接,而不关心pod运行在哪里以及他的IP是什么.
服务表示一组或多组提供相同服务的pod的静态地址.
3.6. 关于namespace
默认情况下我们所在的namespace都是default,所起的资源也都在默认的namespace下,naespace能使我们将不属于一组的资源分到不重叠的组中.
如果有多个用户或者用户组正在使用同一个集群,他们就应该使用各自的命名空间.命名空间为资源名称提供了一个作用域.除了隔离资源,namespace可用于
仅允许某些用户访问某些特定资源,还可以限制单个用户可用的计算资源数量.
3.7. 关于dns解析
首先k8s 有一个组件叫coredns,这个组件提供整个集群做内部域名解析的服务.
在k8s中,比如服务a访问服务b,对于同一个namespace下的服务,可以直接在pod中curl b来访问,对于跨namespace的情况,服务名后面对应上namespace即可.
比如我们想访问 default命名空间下的mysql服务, 那么可以通过 curl mysql.default来访问.
首先dns解析依赖容器内的resolv文件:
nameserver 10.96.0.10``search default.svc.cluster.local svc.cluster.local cluster.local yitu-inc.intra``options ndots``:``5 |
|---|
这里会对dns server进行配置,而且还有一些可选配置项,
nameserver: 填写dns server的IP,这里填写k8s coredns的虚拟ip就可以.
search: 代表dns解析的search域.
ndots: 如果查询的域名包含的点“.”,不到5个,那么进行DNS查找,将使用非完全限定名称(或者叫绝对域名),如果你查询的域名包含点数大于等于5,那么DNS查询,默认会使用绝对域名进行查询。(感兴趣的可以去学习一下,也可以用这个来减少dns解析浪费.)
当 我们执行一次 curl mysql 时,经过了哪些步骤呢?
首先一定要有一个service的名称为b,这是前提.
之后在容器内会根据 /etc/resolve.conf文件进行解析流程,
首先选择10.96.0.10 进行解析,然后用字符串"mysql"依次带入 search域进行dns查询.
依次执行:
if ( ``find mysql.default.svc.cluster.``local )`` ``解析完成``else if (``find mysql.svc.cluster.``local``)`` ``解析完成``else if (``find mysql.cluster.``local``)`` ``解析完成``else if (``find mysql.yitu-inc.intra)`` ``解析完成``else`` ``解析失败 |
|---|
这也就解释了为什么用mysql或者mysql.default都可以解析成功,但是很显然用mysql进行dns查询效率更高,因为用mysql.default会多进行一次dns解析.
在做域名解析的过程中,会同时发送A记录解析的包和AAAA记录解析的包给dns server,k8s会分配一个dns实例 进行dns解析,解析之后会返回一个包给client端,解析结束
4. 各种资源的yml写法
4.1. pod.yml 的 写法
apiVersion: v1 ``#Kubernetes API 版本``kind: Pod ``#K8s 对象/资源 类型``metadata: # pod 元数据(名称,标签,注解等)`` ``annotations:`` ``creationTimestamp:`` ``labels:`` ``run: kubia ``# 标签在opod中经常使用``spec: # pod 规格/内容 (pod的容器列表,volume等)`` ``containers:`` ``- image``: # 容器所用的镜像`` ``imagePullPolicy: # 拉镜像的原则,默认的镜像拉取策略是 IfNotPresent,也就是不存在的时候去hub拉取,但是可以手动改成always,这样就可以每次都从远端拉镜像. `` ``name: #容器名`` ``ports:`` ``- containerPort``: 8080 ``#应用监听的端口`` ``protocol: TCP`` ``resources:`` ``requests:`` ``cpu: 100m``status: # pod及其内部容的详细状态 |
|---|
\
pod定义的主要部分
metadata: 名称、命名空间、标签
spec: pod的容器,卷和其他数据
statu: 运行中pod的当前信息,每个容器的描述和状态
5. FAQ
\
5.1. docker需要权限
newgrp docker |
|---|
5.2. 如何安装minikube
k8smeetup.github.io/docs/tasks/…
(1) 安装VirtualBox
(2) 安装kubectl
(3) 安装minikube
(4) minikube start
过程中可能需要一些google.
5.3. 如何构建并使用本地仓库
(1) 使用registry搭建本地仓库
docker pull registry``docker run -d -p 5000:5000 --restart=always --name registry -``v /mnt/docker_imgs``:``/var/lib/registry registry |
|---|
(2) docker ps 查看registry容器是否在运行
(3) 给要push的镜像打上tag
docker tag <imageName> <localhost:5000``/imageName``> |
|---|
(4) push镜像
docker push <localhost:5000``/imageName``> |
|---|
(5) pull镜像
docker pull <localhost:5000``/imageName``> |
|---|
5.4. 执行kubectl出现 bash: /usr/local/bin/kubectl: cannot execute binary file: Exec format error
大概率是kubectl下载成mac系统的了,下载linux重装即可.
5.5. kubectl permission denied
(1) sudo chmod +x /usr/local/bin/kubectl
(2) 把自己加入root用户组
5.6. kubectl get pod 报错 (Error from server (NotAcceptable): unknown (get nodes))
(1) 原因是server端和client端的kubectl版本不匹配.
(2) 首先kubectl version 获取server版本和client版本.
(3) 把下面的v1.8.7替换为对应的server版本即可.
$ curl -LO https:``//storage``.googleapis.com``/kubernetes-release/release/v1``.8.7``/bin/linux/amd64/kubectl``$ ``chmod +x .``/kubectl``$ ``sudo mv .``/kubectl /usr/local/bin/kubectl |
|---|
5.7. dockerfile中CP出现报错
首先源文件需要在dockerfile目录中,其次不能是软链接.
5.8. 如何在pod内gdb调试
\