创立、运行及共享容器镜像 P23
运行容器 P24
运行 P24
能够运行 Docker 客户端可执行文件来执行各种 Docker 命令。例如:能够试着从 Docker Hub 的公共镜像仓库拉取、运行镜像。Docker Hub 中有许多随时可用的常见镜像,其中就包含 busybox
,能够用来运行简略的命令,例如:echo "Hello world"
。P24
docker run busybox echo "Hello world"
原理 P25
执行 docker run
命令后:P25
- Docker 查看
busybox:lastest
镜像是否存在于本机。如果不存在,则会主动从 Docker 镜像核心拉取镜像 - Docker 基于
busybox:lastest
镜像创立一个容器并在容器中运行命令echo "Hello world"
运行镜像 P25
docker run <image>
docker run <image>:<tag>
Docker 反对同一镜像的多个版本,每个版本必须有惟一的 tag 名,当援用镜像没有显式地指定 tag 时,Docker 会默认指定 tag 为 latest
。P25
创立利用 P26
const http = require('http');
const os = require('os');
console.log("Kubia server starting...");
var handler = function(request, response) {console.log("Received request from" + request.connection.remoteAddress);
response.writeHead(200);
response.end("You've hit "+ os.hostname() +"\n");
};
var www = http.createServer(handler);
www.listen(8080);
这个利用会接管 HTTP 申请并响应利用运行的服务器实在主机名(非宿主机名),当其部署在 Kubernetes 上并进行伸缩时(程度伸缩,复制利用到多个节点),能够发现 HTTP 申请切换到了利用的不同实例上。P26
创立 Dockerfile P27
FROM node:7
ADD app.js /app.js
ENTRYPOINT ["node", "app.js"]
FROM
行定义了镜像的起始内容(构建所基于的根底镜像)P27
ADD
行把 app.js 文件从本地增加到镜像的根目录,并放弃文件名为 app.jsP27
ENTRYPOINT
行定义了当镜像被运行时须要执行的命令P27
构建容器镜像 P27
docker build -t kubia .
上述命令会基于当前目录下的 Dockerfile 文件中的指令创立一个名为 kubia
的镜像。P27
镜像是如何构建的 P28
构建过程不是由 Docker 客户端运行的,而是将整个目录的文件上传到 Docker 守护过程并在那里进行的。如果在一台非 Linux 操作系统中应用 Docker,客户端运行在宿主机操作系统上,而守护过程运行在一个虚拟机内。P28
提醒: 不要在构建目录中蕴含任何不须要的文件,这样会减慢构建的速度,尤其是 Docker 守护过程运行在一个远端机器的时候。P28
镜像分层 P28
镜像不是一个大的二进制块,而是由许多层组成的,不同镜像可能会共享分层,这样会让存储和传输变得更加高效。P28
构建镜像时,Dockerfile 中每一条独自的指令都会创立一个新层,最初一层会被标记为指定的镜像名。P29
能够通过 docker images
查看本地存储的镜像。
运行容器镜像 P30
docker run --name kubia-container -p 8080:8080 -d kubia
上述命令会基于 kubia 镜像创立一个叫 kubia-container 的新容器。-d
示意这个容器与命令行拆散,意味着在后盾运行。-p 8080:8080
示意本机上的 8080 端口会映射到容器内的 8080 端口,所以能够通过 localhost:8080
拜访这个利用。P30
列出所有运行中的容器 P30
docker ps
会打印出每一个容器的 ID 和名称、容器运行所应用的镜像、容器中执行代码命令、创立工夫、以及以后状态。P30
-a
: 查看所有容器,包含运行中的和已进行的
获取更多的容器信息 P30
docker inspect kubia-container
能够查看蕴含容器底层信息的长 JSON。P31
摸索运行容器的外部 P31
在已有的容器外部运行 shell P31
docker exec -ti kubia-container bash
上述命令会在已有的 kubia-container 容器外部运行 bash。bash 过程会和主容器过程领有雷同的命名空间,能够用于查看 Node.js 和利用是如何在容器里运行的。P31
-t
: 调配一个伪终端 (TTY),能够显示命令提示符-i
: 确保规范输出流放弃凋谢,能够在 shell 中输出命令
进入容器对于调试容器内运行的利用来说十分有用。出错时,须要做的第一件事是查看利用运行的零碎的实在状态。利用不仅领有独立的文件系统,还有过程、用户、主机名和网络接口。P32
进行和删除容器 P32
docker stop kubia-container
: 进行容器,容器进行后依然存在P32
docker rm kubia-container
: 删除容器,所有内容都会被删除并且无奈再次启动P32
向镜像仓库推送镜像 P33
应用附加标签标注镜像 P33
docker tag kubia idealism/kubia
上述命令不会重命名标签,而是给同一个镜像创立一个额定的标签。kubia
和 idealism/kubia
指向同一个镜像 ID,实际上是同一个镜像的两个标签。P33
推送镜像 P33
docker push idealism/kubia
能够将本地的镜像推送到 idealism
名下的 kubia
。
在不同机器上运行镜像 P33
推送实现之后,就能够通过 docker run --name kubia-container -p 8080:8080 -d kubia
在任何机器上运行同一个镜像了。
配置 Kubernetes 集群 P34
用 Minikube 运行一个本地三节点 Kubernetes 集群
Minikube 是一个构建单节点集群的工具,对于测试 Kubernetes 和本地开发利用都十分有用。P35
minikube start --nodes 4
: 启动一个四节点的 Kubernetes 集群,蕴含一个主节点和三个工作节点。kuibectl cluster-info
: 展现集群信息minikube ssh
: 登录到 Minikube VM 从外部拜访,能够查看在节点上运行的过程kubectl get nodes
: 列出集群的节点kubectl describe node minikube
: 查看指定节点的更多信息
应用 kubectl get nodes
查看以后集群的节点信息如下:
NAME STATUS ROLES AGE VERSION
minikube Ready master 56m v1.18.2
minikube-m02 Ready <none> 13m v1.18.2
minikube-m03 Ready <none> 11m v1.18.2
minikube-m04 Ready <none> 10m v1.18.2
能够发现有三个节点的角色是 <none>
,须要手动将它们的 ROLES
设置为 worker
,运行如下命令即可:
kubectl label node minikube-m02 node-role.kubernetes.io/worker=worker
kubectl label node minikube-m03 node-role.kubernetes.io/worker=worker
kubectl label node minikube-m04 node-role.kubernetes.io/worker=worker
在 Kubernetes 上运行第一个利用 P40
部署 Node.js 利用 P40
kubectl create deployment kubia --image=idealism/kubia
上述命令毋庸配置文件即可创立一个名为 kubia 的 development
(能够应用 kubectl get developments
查看),同时主动创立一个名称前缀为 kubia 的 pod
(能够应用 kubectl get pods
查看)。P40
介绍 pod P41
Kubernetes 不间接解决单个容器,它应用多个共存容器的理念,这组容器叫作 pod。P41
一个 pod 是一组严密相干的容器,它们总是一起运行在同一个工作节点上,以及同一个 Linux 命名空间中。每个 pod 就像一个独立的逻辑机器,领有本人的 IP、主机名、过程等,运行一个独立的应用程序。应用程序能够是单个过程,运行在单个容器中,也能够是一个主利用过程和其余反对过程,每个过程都在本人的容器中运行。一个 pod 的所有容器都运行在同一个逻辑机器上,而其余 pod 中的容器,即便运行在同一个工作节点上,也是运行在不同的逻辑机器上。P41
列出 pod P41
kubectl get pods
: 查看 pod 的重要信息:pod 名称、READY、状态、重启次数和 AGEkubectl describe pod <pod-name>
: 查看指定 pod 的详细信息
幕后产生的事件 P42
上图显示了在 Kubernetes 中运行容器镜像所必须的两个步骤:P42
- 构建镜像并将其推送到 Docker Hub
-
运行 kubectl 命令
- 命令向 Kubernetes API 服务器发送一个 REST HTTP 申请
- 创立一个新的 pod,调度器将其调度到一个工作节点上
- Kubelet 看到 pod 被调度到节点上,就告知 Docker 从镜像核心中拉取指定的镜像,因为本地没有该镜像
- 下载镜像后,Docker 创立并运行容器
调度 (scheduling): 将 pod 调配给一个节点。pod 会立刻执行,而不是将要执行。P43
拜访 Web 利用 P43
通过 kubectl describe pod <pod-name>
能够看到 pod 本人的 IP,不过这个地址只能从集群外部拜访。通过创立一个 LoadBalancer
类型的服务,能够创立一个内部的负载平衡,通过负载平衡的公共 IP 就能够拜访 pod。P43
创立一个服务对象 P43
kubectl expose deployment kubia --type=LoadBalancer --name kubia-http --port=8080
: 对外裸露之前创立的 Pod
P43
大多数资源都有缩写:P43
po
:pod
的缩写svc
:service
的缩写rc
:replicationcontroller
的缩写(目前已 不举荐应用该控制器)deploy
:deployment
的缩写rs
:replicaset
的缩写
因为咱们应用的是 minikube,所以没有集成 LoadBalancer
,运行完上述命令后,应用 kubectl get services
会失去如下后果:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 37m
kubia-http LoadBalancer 10.100.74.254 <pending> 8080:32342/TCP 5m52s
能够发现 LoadBalancer
的 EXTERNAL-IP
始终处于 <pending>
,咱们能够应用 minikube 自带的 minikube tunnel
命令能够实现裸露,运行完后,可得如下后果:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39m
kubia-http LoadBalancer 10.100.74.254 10.100.74.254 8080:32342/TCP 7m56s
列出服务 P44
expose
命令的输入是一个名为 kubia-http 的服务。服务是相似于 pod 和 node 的对象,因而能够通过 kubectl get services
命令查看新创建的服务对象。
应用内部 IP 拜访服务 P44
curl 10.100.74.254:8080
# 输入如下:# You've hit kubia-5b6b94f7f8-h6dbr
能够发现利用将 pod 名称作为它的主机名。P45
应用 minikube
为集群增加节点可能会导致新增的节点无法访问(在这里耗时几小时终于搞明确了,还是要多读文档),能够依照文档中进行设置;当然也有可能是期待的工夫不够,设置等操作还没有完结(依照后面的配置了后,还是无法访问,认为哪里操作有问题,各种操作程序都试了还是无法访问,最初期待了近 10 min 就主动好了。。。)
零碎的逻辑局部 P45
Deployment
、pod 和服务是合乎组合在一起的 P45
Kubernetes 的根本构建是 pod。然而,咱们后面并没有真的间接创立出任何 pod。通过运行 kubectl create deployment
命令,创立了一个 Deployment
控制器,它用于创立 pod 实例。为了使该 pod 可能从集群内部拜访,须要让 Kubernetes 将该 Deployment
治理的所有 pod 由一个服务对外裸露。P45
pod 和它的容器 P45
零碎中最重要的组件是 pod,一个 pod 中能够蕴含任意数量的容器。pod 有本人独立的公有 IP 地址和主机名。P46
Deployment
的角色 P46
Deployment
控制器确保始终存在一个运行中的 pod 实例。通常,Deployment
用于复制 pod(即创立 pod 的多个正本)并让它们放弃运行。如果 pod 因为任何起因隐没了,那么 Deployment
将创立一个新的 pod 来替换隐没的 pod。P46
为什么须要服务 P46
零碎的第三个组件是 kubia-http
服务。pod 的存在是短暂的,一个 pod 可能会在任何时候隐没(1. 所在节点产生故障;2. 有人删除了 pod;3. pod 被从一个衰弱的节点剔除了),此时隐没的 pod 将被 Deployment
替换为新的 pod。新旧 pod 具备不同的 IP 地址。所以须要一个服务来解决一直变动的 pod IP 地址的问题,以及在一个固定的 IP 和端口对上对外裸露多个 pod。P46
服务示意一组或多组提供雷同服务的 pod 的动态地址。达到服务 IP 和端口的申请将被转发到属于该服务的一个容器的 IP 和端口。P46
程度伸缩 P46
kubectl get deployments
# 输入如下:# NAME READY UP-TO-DATE AVAILABLE AGE
# kubia 1/1 1 1 49m
应用 kubectl get
能够查看所有类型的资源,上述命令查看所有的 Deployment
,目前仅有一个名为 kubia
的控制器,总共须要 1 个 pod,目前已有 1 个 pod 已筹备好,1 个 pod 已是最新版本,1 个 pod 可用。
减少冀望的正本数 P47
kubectl scale deployment kubia --replicas=3
# 输入如下:# deployment.apps/kubia scaled
上述命令通知 Kubernetes 须要确保 pod 始终有三个实例在运行。这是 Kubernetes 最根本的准则之一。不通知 Kubernetes 应该执行什么操作,而是申明性地扭转零碎的冀望状态,并让 Kubernetes 查看以后的状态是否与冀望的状态统一。P47
打到服务上到申请会打到所有到三个 pod 上 P47
curl 10.100.74.254:8080
# 因为存在三个 pod,所以有以下三种输入
# You've hit kubia-5b6b94f7f8-h6dbr
# You've hit kubia-5b6b94f7f8-wwbdh
# You've hit kubia-5b6b94f7f8-zzxks
当 pod 有多个实例时 Kubernetes 服务作为负载平衡挡在多个 pod 后面,申请随机地打到不同的 pod。P48
查看利用运行在哪个节点上 P49
kubectl get pods -o wide
# 输入如下:# NAME READY STATUS RESTARTS AGE IP NODE ...
# kubia-5b6b94f7f8-h6dbr 1/1 Running 0 12m 10.244.3.2 minikube-m04 ...
# kubia-5b6b94f7f8-wwbdh 1/1 Running 0 12m 10.244.2.2 minikube-m03 ...
# kubia-5b6b94f7f8-zzxks 1/1 Running 0 55m 10.244.1.2 minikube-m02 ...
-o wide
: 显示 pod 的 IP 和所运行的节点,以及其余局部信息。P49
介绍 Kubernetes dashboard P50
拜访 Minikube 的 dashboard P51
minikube dashboard
以上命令会启动 dashboard,并输入可拜访的网址供浏览器中关上。P51
实际操作时,发现这个命令会始终卡在 Verifying proxy health ...
这一行,随后会返回 503 谬误,目前 github 上已有相似的 issue。我依照探讨中的办法发现,kubernetes-dashboard
namespace 下的两个 pod 都胜利启动了,并且能够通过 kubectl port-forward -n kubernetes-dashboard pod/kubernetes-dashboard-696dbcc666-gbgwl 9090:9090
将端口映射到本地并能胜利拜访。
本文首发于公众号:满赋诸机(点击查看原文)开源在 GitHub:reading-notes/kubernetes-in-action