提交 d8fbc132 编写于 作者: 阳明的博客's avatar 阳明的博客

add pod article

上级 2d84f225
.vscode/
\ No newline at end of file
.vscode/
node_modules/
book.json
SUMMARY.md
_book/*
# kubernetes learning —— 从Docker到Kubernetes进阶
# 从Docker到Kubernetes进阶
从 Docker 入门一步步迁移到 Kubernetes 的进阶课程
## 介绍
......@@ -40,7 +41,3 @@ GitHub地址:[https://github.com/cnych/kubernetes-learning/tree/master/docs](h
![优点知识服务号](./docs/images/ydzs-qrcode.png)
![优点知识小程序](./docs/images/ydzs-xcx.png)
## 目录
TODO,整理中,部分可以通过[docs](https://github.com/cnych/kubernetes-learning/tree/master/docs)目录查看
# 18. YAML 文件
在前面的课程中,我们在安装 kubernetes 集群的时候使用了一些 YAML 文件来创建相关的资源,但是很多同学对 YAML 文件还是非常陌生。所以我们先来简单看一看 YAML 文件是如何工作的,并使用 YAML 文件来定义一个 kubernetes pod,然后再来定义一个 kubernetes deployment吧。
## YAML 基础
它的基本语法规则如下:
* 大小写敏感
* 使用缩进表示层级关系
* 缩进时不允许使用Tab键,只允许使用空格。
* 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
* `#` 表示注释,从这个字符一直到行尾,都会被解析器忽略。
在我们的 kubernetes 中,你只需要两种结构类型就行了:
* Lists
* Maps
也就是说,你可能会遇到 Lists 的 Maps 和 Maps 的 Lists,等等。不过不用担心,你只要掌握了这两种结构也就可以了,其他更加复杂的我们暂不讨论。
### Maps
首先我们来看看 Maps,我们都知道 Map 是字典,就是一个`key:value`的键值对,Maps 可以让我们更加方便的去书写配置信息,例如:
```yaml
---
apiVersion: v1
kind: Pod
```
第一行的`---`是分隔符,是可选的,在单一文件中,可用连续三个连字号`---`区分多个文件。这里我们可以看到,我们有两个键:`kind` 和 `apiVersion`,他们对应的值分别是:v1 和Pod。上面的 YAML 文件转换成 JSON 格式的话,你肯定就容易明白了:
```json
{
"apiVersion": "v1",
"kind": "pod"
}
```
我们在创建一个相对复杂一点的 YAML 文件,创建一个 KEY 对应的值不是字符串而是一个 Maps:
```yaml
---
apiVersion: v1
kind: Pod
metadata:
name: kube100-site
labels:
app: web
```
上面的 YAML 文件,metadata 这个 KEY 对应的值就是一个 Maps 了,而且嵌套的 labels 这个 KEY 的值又是一个 Map,你可以根据你自己的情况进行多层嵌套。
上面我们也提到了 YAML 文件的语法规则,YAML 处理器是根据行缩进来知道内容之间的嗯关联性的。比如我们上面的 YAML 文件,**我用了两个空格作为缩进,空格的数量并不重要,但是你得保持一致,并且至少要求一个空格**(什么意思?就是你别一会缩进两个空格,一会缩进4个空格)。
我们可以看到 name 和 labels 是相同级别的缩进,所以 YAML 处理器就知道了他们属于同一个 MAP,而 app 是 labels 的值是因为 app 的缩进更大。
> 注意:在 YAML 文件中绝对不要使用 tab 键。
样的,我们可以将上面的 YAML 文件转换成 JSON 文件:
```json
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "kube100-site",
"labels": {
"app": "web"
}
}
}
```
许你对上面的 JSON 文件更熟悉,但是你不得不承认 YAML 文件的语义化程度更高吧?
### Lists
Lists 就是列表,说白了就是数组,在 YAML 文件中我们可以这样定义:
```yaml
args
- Cat
- Dog
- Fish
```
可以有任何数量的项在列表中,每个项的定义以破折号(-)开头的,与父元素直接可以缩进一个空格。对应的 JSON 格式如下:
```json
{
"args": [ 'Cat', 'Dog', 'Fish' ]
}
```
然,list 的子项也可以是 Maps,Maps 的子项也可以是list如下所示:
```yaml
---
apiVersion: v1
kind: Pod
metadata:
name: kube100-site
labels:
app: web
spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
- name: flaskapp-demo
image: jcdemo/flaskapp
ports:
- containerPort: 5000
```
比如这个 YAML 文件,我们定义了一个叫 containers 的 List 对象,每个子项都由 name、image、ports 组成,每个 ports 都有一个 key 为 containerPort 的 Map 组成,同样的,我们可以转成如下 JSON 格式文件:
```json
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "kube100-site",
"labels": {
"app": web"
}
},
"spec": {
"containers": [{
"name": "front-end",
"image": "nginx",
"ports": [{
"containerPort": "80"
}]
}, {
"name": "flaskapp-demo",
"image": "jcdemo/flaskapp",
"ports": [{
"containerPort": "5000"
}]
}]
}
}
```
是不是觉得用 JSON 格式的话文件明显比 YAML 文件更复杂了呢?
### 使用 YAML 创建 Pod
现在我们已经对 YAML 文件有了大概的了解了,我相信你应该没有之前那么懵逼了吧?我们还是来使用 YAML 文件来创建一个 Deployment 吧。
API 说明: [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/)
#### 创建 Pod
```yaml
---
apiVersion: v1
kind: Pod
metadata:
name: kube100-site
labels:
app: web
spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
- name: flaskapp-demo
image: jcdemo/flaskapp
ports:
- containerPort: 5000
```
这是我们上面定义的一个普通的 POD 文件,我们先来简单分析下文件内容:
* apiVersion,这里它的值是 v1,这个版本号需要根据我们安装的 kubernetes 版本和资源类型进行变化的,记住不是写死的
* kind,这里我们创建的是一个 Pod,当然根据你的实际情况,这里资源类型可以是 Deployment、Job、Ingress、Service 等待。
* metadata:包含了我们定义的 Pod 的一些 meta 信息,比如名称、namespace、标签等等信息。
* spec:包括一些 containers,storage,volumes,或者其他 Kubernetes 需要知道的参数,以及诸如是否在容器失败时重新启动容器的属性。你可以在特定 Kubernetes API 找到完整的 Kubernetes Pod 的属性。
让我们来看一个典型的容器的定义:
```yaml
…spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
```
在这个例子中,这是一个简单的最小定义:一个名字(front-end),基于 nginx 的镜像,以及容器 将会监听的一个端口(80)。在这些当中,只有名字是非常需要的,你也可以指定一个更加复杂的属性,例如在容器启动时运行的命令,应使用的参数,工作目录,或每次实例化时是否拉取映像的新副本。以下是一些容器可选的设置属性:
* name
* image
* command
* args
* workingDir
* ports
* env
* resources
* volumeMounts
* livenessProbe
* readinessProbe
* livecycle
* terminationMessagePath
* imagePullPolicy
* securityContext
* stdin
* stdinOnce
* tty
明白了 POD 的定义后,我们将上面创建 POD 的 YAML 文件保存成 pod.yaml,然后使用`kubectl`创建 POD:
```shell
$ kubectl create -f pod.yaml
pod "kube100-site" created
```
然后我们就可以使用我们前面比较熟悉的 kubectl 命令来查看 POD 的状态了:
```shell
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kube100-site 2/2 Running 0 1m
```
到这里我们的 POD 就创建成功了,如果你在创建过程中有任何问题,我们同样可以使用前面的kubectl describe 进行排查。我们先删除上面创建的 POD:
```
$ kubectl delete -f pod.yaml
pod "kube100-site" deleted
```
#### 创建 Deployment
现在我们可以来创建一个真正的 Deployment。在上面的例子中,我们只是单纯的创建了一个 POD 实例,但是如果这个 POD 出现了故障的话,我们的服务也就挂掉了,所以 kubernetes 提供了一个`Deployment`的概念,可以让 kubernetes 去管理一组 POD 的副本,也就是副本集,这样就可以保证一定数量的副本一直可用的,不会因为一个 POD 挂掉导致整个服务挂掉。我们可以这样定义一个 Deployment:
```yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kube100-site
spec:
replicas: 2
```
注意这里的`apiVersion`对应的值是`extensions/v1beta1`,当然 kind 要指定为 Deployment,因为这就是我们需要的,然后我们可以指定一些 meta 信息,比如名字,或者标签之类的。最后,最重要的是`spec`配置选项,这里我们定义需要两个副本,当然还有很多可以设置的属性,比如一个 Pod 在没有任何错误变成准备的情况下必须达到的最小秒数。
我们可以在[Kubernetes v1beta1 API](https://kubernetes.io/docs/api-reference/extensions/v1beta1/definitions/#_v1beta1_deployment)参考中找到一个完整的 Depolyment 可指定的参数列表。
现在我们来定义一个完整的 Deployment 的 YAML 文件:
```yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kube100-site
spec:
replicas: 2
template:
metadata:
labels:
app: web
spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
- name: flaskapp-demo
image: jcdemo/flaskapp
ports:
- containerPort: 5000
```
看起来是不是和我们上面的 pod.yaml 很类似啊,注意其中的 template,其实就是对 POD 对象的定义。将上面的 YAML 文件保存为 deployment.yaml,然后创建 Deployment:
```shell
$ kubectl create -f deployment.yaml
deployment "kube100-site" created
```
同样的,想要查看它的状态,我们可以检查 Deployment的列表:
```shell
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kube100-site 2 2 2 2 2m
```
我们可以看到所有的 Pods 都已经正常运行了。
到这里我们就完成了使用 YAML 文件创建 Kubernetes Deployment 的过程,在了解了 YAML 文件的基础后,定义 YAML 文件其实已经很简单了,最主要的是要根据实际情况去定义 YAML 文件,所以查阅 Kubernetes 文档很重要。
> 可以使用[http://www.yamllint.com/](http://www.yamllint.com/)去检验 YAML 文件的合法性。
# 静态 Pod
我们上节课给大家讲解了 YAML 文件的使用,也手动的创建了一个简单的 Pod,这节课开始我们就来深入的学习下我们的 Pod。在Kubernetes集群中除了我们经常使用到的普通的 Pod 外,还有一种特殊的 Pod,叫做`Static Pod`,就是我们说的静态 Pod,静态 Pod 有什么特殊的地方呢?
静态 Pod 直接由特定节点上的`kubelet`进程来管理,不通过 master 节点上的`apiserver`。无法与我们常用的控制器`Deployment`或者`DaemonSet`进行关联,它由`kubelet`进程自己来监控,当`pod`崩溃时重启该`pod``kubelete`也无法对他们进行健康检查。静态 pod 始终绑定在某一个`kubelet`,并且始终运行在同一个节点上。
`kubelet`会自动为每一个静态 pod 在 Kubernetes 的 apiserver 上创建一个镜像 Pod(Mirror Pod),因此我们可以在 apiserver 中查询到该 pod,但是不能通过 apiserver 进行控制(例如不能删除)。
创建静态 Pod 有两种方式:配置文件和 HTTP 两种方式
### 配置文件
配置文件就是放在特定目录下的标准的 JSON 或 YAML 格式的 pod 定义文件。用`kubelet --pod-manifest-path=<the directory>`来启动`kubelet`进程,kubelet 定期的去扫描这个目录,根据这个目录下出现或消失的 YAML/JSON 文件来创建或删除静态 pod。
比如我们在 node01 这个节点上用静态 pod 的方式来启动一个 nginx 的服务。我们登录到node01节点上面,可以通过下面命令找到kubelet对应的启动配置文件
```shell
$ systemctl status kubelet
```
配置文件路径为:
```shell
$ /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
```
打开这个文件我们可以看到其中有一条如下的环境变量配置:
`Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true"`
所以如果我们通过`kubeadm`的方式来安装的集群环境,对应的`kubelet`已经配置了我们的静态 Pod 文件的路径,那就是`/etc/kubernetes/manifests`,所以我们只需要在该目录下面创建一个标准的 Pod 的 JSON 或者 YAML 文件即可:
如果你的 kubelet 启动参数中没有配置上面的`--pod-manifest-path`参数的话,那么添加上这个参数然后重启 kubelet 即可。
```yaml
[root@ node01 ~] $ cat <<EOF >/etc/kubernetes/manifest/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
app: static
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
EOF
```
### 通过 HTTP 创建静态 Pods
kubelet 周期地从`–manifest-url=`参数指定的地址下载文件,并且把它翻译成 JSON/YAML 格式的 pod 定义。此后的操作方式与`–pod-manifest-path=`相同,kubelet 会不时地重新下载该文件,当文件变化时对应地终止或启动静态 pod。
### 静态pods的动作行为
kubelet 启动时,由`--pod-manifest-path= or --manifest-url=`参数指定的目录下定义的所有 pod 都会自动创建,例如,我们示例中的 static-web。(可能要花些时间拉取nginx 镜像,耐心等待…)
```shell
[root@node01 ~] $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f6d05272b57e nginx:latest "nginx" 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c
```
现在我们通过`kubectl`工具可以看到这里创建了一个新的镜像 Pod:
```shell
[root@node01 ~] $ kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web-my-node01 1/1 Running 0 2m
```
静态 pod 的标签会传递给镜像 Pod,可以用来过滤或筛选。
需要注意的是,我们不能通过 API 服务器来删除静态 pod(例如,通过[kubectl](https://kubernetes.io/docs/user-guide/kubectl/)命令),kebelet 不会删除它。
```shell
[root@node01 ~] $ kubectl delete pod static-web-my-node01
[root@node01 ~] $ kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web-my-node01 1/1 Running 0 12s
```
我们尝试手动终止容器,可以看到kubelet很快就会自动重启容器。
```shell
[root@node01 ~] $ docker ps
CONTAINER ID IMAGE COMMAND CREATED ...
5b920cbaf8b1 nginx:latest "nginx -g 'daemon of 2 seconds ago ...
```
### 静态pods的动态增加和删除
运行中的kubelet周期扫描配置的目录(我们这个例子中就是/etc/kubernetes/manifests)下文件的变化,当这个目录中有文件出现或消失时创建或删除pods。
```shell
[root@node01 ~] $ mv /etc/kubernetes/manifests/static-web.yaml /tmp
[root@node01 ~] $ sleep 20
[root@node01 ~] $ docker ps
// no nginx container is running
[root@node01 ~] $ mv /tmp/static-web.yaml /etc/kubernetes/manifests
[root@node01 ~] $ sleep 20
[root@node01 ~] $ docker ps
CONTAINER ID IMAGE COMMAND CREATED ...
e7a62e3427f1 nginx:latest "nginx -g 'daemon of 27 seconds ago
```
其实我们用 kubeadm 安装的集群,master 节点上面的几个重要组件都是用静态 Pod 的方式运行的,我们登录到 master 节点上查看`/etc/kubernetes/manifests`目录:
```shell
[root@master ~]# ls /etc/kubernetes/manifests/
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
```
现在明白了吧,这种方式也为我们将集群的一些组件容器化提供了可能,因为这些 Pod 都不会受到 apiserver 的控制,不然我们这里`kube-apiserver`怎么自己去控制自己呢?万一不小心把这个 Pod 删掉了呢?所以只能有`kubelet`自己来进行控制,这就是我们所说的静态 Pod。
# Pod Hook
我们知道`Pod``Kubernetes`集群中的最小单元,而 Pod 是有容器组组成的,所以在讨论 Pod 的生命周期的时候我们可以先来讨论下容器的生命周期。
实际上 Kubernetes 为我们的容器提供了生命周期钩子的,就是我们说的`Pod Hook`,Pod Hook 是由 kubelet 发起的,当容器中的进程启动前或者容器中的进程终止之前运行,这是包含在容器的生命周期之中。我们可以同时为 Pod 中的所有容器都配置 hook。
Kubernetes 为我们提供了两种钩子函数:
* PostStart:这个钩子在容器创建后立即执行。但是,并不能保证钩子将在容器`ENTRYPOINT`之前运行,因为没有参数传递给处理程序。主要用于资源部署、环境准备等。不过需要注意的是如果钩子花费太长时间以至于不能运行或者挂起, 容器将不能达到`running`状态。
* PreStop:这个钩子在容器终止之前立即被调用。它是阻塞的,意味着它是同步的, 所以它必须在删除容器的调用发出之前完成。主要用于优雅关闭应用程序、通知其他系统等。如果钩子在执行期间挂起, Pod阶段将停留在`running`状态并且永不会达到`failed`状态。
如果`PostStart`或者`PreStop`钩子失败, 它会杀死容器。所以我们应该让钩子函数尽可能的轻量。当然有些情况下,长时间运行命令是合理的, 比如在停止容器之前预先保存状态。
另外我们有两种方式来实现上面的钩子函数:
* Exec - 用于执行一段特定的命令,不过要注意的是该命令消耗的资源会被计入容器。
* HTTP - 对容器上的特定的端点执行`HTTP`请求。
### 示例1 环境准备
以下示例中,定义了一个Nginx Pod,其中设置了`PostStart`钩子函数,即在容器创建成功后,写入一句话到`/usr/share/message`文件中。
```yaml
apiVersion: v1
kind: Pod
metadata:
name: hook-demo1
spec:
containers:
- name: hook-demo1
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
```
### 示例2 优雅删除资源对象
当用户请求删除含有 pod 的资源对象时(如Deployment等),K8S 为了让应用程序优雅关闭(即让应用程序完成正在处理的请求后,再关闭软件),K8S提供两种信息通知:
* 默认:K8S 通知 node 执行`docker stop`命令,docker 会先向容器中`PID`为1的进程发送系统信号`SIGTERM`,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认超时时间(30s),会继续发送`SIGKILL`的系统信号强行 kill 掉进程。
* 使用 pod 生命周期(利用`PreStop`回调函数),它执行在发送终止信号之前。
默认所有的优雅退出时间都在30秒内。kubectl delete 命令支持 `--grace-period=<seconds>`选项,这个选项允许用户用他们自己指定的值覆盖默认值。值'0'代表 强制删除 pod. 在 kubectl 1.5 及以上的版本里,执行强制删除时必须同时指定 `--force --grace-period=0`
强制删除一个 pod 是从集群状态还有 etcd 里立刻删除这个 pod。 当 Pod 被强制删除时, api 服务器不会等待来自 Pod 所在节点上的 kubelet 的确认信息:pod 已经被终止。在 API 里 pod 会被立刻删除,在节点上, pods 被设置成立刻终止后,在强行杀掉前还会有一个很小的宽限期。
以下示例中,定义了一个Nginx Pod,其中设置了`PreStop`钩子函数,即在容器退出之前,优雅的关闭 Nginx:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: hook-demo2
spec:
containers:
- name: hook-demo2
image: nginx
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
---
apiVersion: v1
kind: Pod
metadata:
name: hook-demo2
labels:
app: hook
spec:
containers:
- name: hook-demo2
image: nginx
ports:
- name: webport
containerPort: 80
volumeMounts:
- name: message
mountPath: /usr/share/
lifecycle:
preStop:
exec:
command: ['/bin/sh', '-c', 'echo Hello from the preStop Handler > /usr/share/message']
volumes:
- name: message
hostPath:
path: /tmp
```
另外`Hook`调用的日志没有暴露个给 Pod 的 event,所以只能通过`describe`命令来获取,如果有错误将可以看到`FailedPostStartHook``FailedPreStopHook`这样的 event。
## 21. 健康检查
上节课我们和大家一起学习了`Pod`中容器的生命周期的两个钩子函数,`PostStart``PreStop`,其中`PostStart`是在容器创建后立即执行的,而`PreStop`这个钩子函数则是在容器终止之前执行的。除了上面这两个钩子函数以外,还有一项配置会影响到容器的生命周期的,那就是健康检查的探针。
......@@ -85,7 +86,7 @@ spec:
通常来说,任何大于200小于400的返回码都会认定是成功的返回码。其他返回码都会被认为是失败的返回码。
我们可以来查看下上面的`healthz`的实现:
```golang
```go
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
duration := time.Now().Sub(started)
if duration.Seconds() > 10 {
......@@ -143,7 +144,7 @@ spec:
另外除了上面的`initialDelaySeconds``periodSeconds`属性外,探针还可以配置如下几个参数:
* timeoutSeconds:探测超时时间,默认1秒,最小1秒。
* successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1,但是如果是`liveness`则必须是 1。最小值是 1。
* failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3,最小值是 1。
......
......@@ -169,7 +169,7 @@ data:
| widget.com | 上游 DNS (8.8.8.8, 8.8.4.4,其中之一) |
另外我们还可以为每个 Pod 设置 DNS 策略。 当前 Kubernetes 支持两种 Pod 特定的 DNS 策略:“Default” 和 “ClusterFirst”。 可以通过 dnsPolicy 标志来指定这些策略。
另外我们还可以为每个 Pod 设置 DNS 策略。 当前 Kubernetes 支持两种 Pod 特定的 DNS 策略:“Default” 和 “ClusterFirst”。 可以通过 dnsPolicy 标志来指定这些策略。
> 注意:**Default** 不是默认的 DNS 策略。如果没有显式地指定**dnsPolicy**,将会使用 **ClusterFirst**
......
......@@ -198,6 +198,7 @@ ingress.extensions "traefik-web-ui" created
![traefik health](./images/ingress-config3.png)
* 第三步,上面我们可以通过自定义域名加上端口可以访问我们的服务了,但是我们平时服务别人的服务是不是都是直接用的域名啊,http 或者 https 的,几乎很少有在域名后面加上端口访问的吧?为什么?太麻烦啊,端口也记不住,要解决这个问题,怎么办,我们只需要把我们上面的 traefik 的核心应用的端口隐射到 master 节点上的 80 端口,是不是就可以了,因为 http 默认就是访问 80 端口,但是我们在 Service 里面是添加的一个 NodePort 类型的服务,没办法隐射 80 端口,怎么办?这里就可以直接在 Pod 中指定一个 hostPort 即可,更改上面的 traefik.yaml 文件中的容器端口:
```yaml
containers:
- image: traefik
......@@ -209,10 +210,12 @@ ports:
- name: admin
containerPort: 8080
```
添加以后`hostPort: 80`,然后更新应用:
```shell
$ kubectl apply -f traefik.yaml
```
更新完成后,这个时候我们在浏览器中直接使用域名方法测试下:
![traefik dashboard](./images/ingress-config4.png)
......
# 从Docker到Kubernetes进阶
## 介绍
[Kubernetes](http://kubernetes.io/)是Google基于Borg开源的容器编排调度引擎,作为[CNCF](http://cncf.io/)(Cloud Native Computing Foundation)最重要的组件之一,它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,`Kubernetes` 可以帮你将系统自动地达到和维持在这个状态。`Kubernetes` 作为云原生应用的基石,相当于一个云操作系统,其重要性不言而喻。
![从Docker到Kubernetes进阶](http://sdn.haimaxy.com/covers/2018/4/21/c4082e0f09c746aa848279a2567cffed.png)
之前一直有同学跟我说我 `Docker` 掌握得还可以,但是不知道怎么使用 `Kubernetes`,网上的其他关于 `Kubernetes` 的课程费用又太高,本书就是为你们准备的,当然如果你不了解 `Docker`,不了解 `Kubernetes`,都没有关系,我们会从 `Docker` 入门一步步深入,到 `Kubernetes` 的进阶使用的。所以大家完全没必要担心。
学完本课程以后,你将会对 `Docker``Kubernetes` 有一个更加深入的认识,我们会讲到:
* `Docker` 的一些常用方法,当然我们的重点会在 Kubernetes 上面
* 会用 `kubeadm` 来搭建一套 `Kubernetes` 的集群
* 理解 `Kubernetes` 集群的运行原理
* 常用的一些控制器使用方法
* 还有 `Kubernetes` 的一些调度策略
* `Kubernetes`的运维
* 包管理工具 `Helm` 的使用
* 最后我们会实现基于 Kubernetes 的 CI/CD
GitHub地址:[https://github.com/cnych/kubernetes-learning/tree/master/docs](https://github.com/cnych/kubernetes-learning/)
视频课程在线地址:[https://www.haimaxy.com/course/6n8xd6/](https://www.haimaxy.com/course/6n8xd6/)
## 社区&读者交流
* 博客:[阳明的博客](https://blog.qikqiak.com/)
* 微信群:`k8s`技术圈,扫描我的微信二维码,[阳明](https://blog.qikqiak.com/page/about/),或直接搜索微信号**iEverything**后拉您入群,请增加备注(k8s或kubernetes)
* 知乎专栏:[k8s技术圈](https://zhuanlan.zhihu.com/kube100)
* 开发者头条:[k8s技术圈](https://toutiao.io/subjects/268333)
* 微信公众号:扫描下面的二维码关注微信公众号`k8s技术圈`
![k8s公众帐号](./images/k8s-qrcode.png)
* 优点知识:[优点知识](https://www.haimaxy.com/)是一个综合的技术学习平台,本书配套的视频教程将会发布在该平台上面,感兴趣的朋友可以扫描下发的二维码关注自己感兴趣的课程。
![优点知识服务号](./images/ydzs-qrcode.png)
![优点知识小程序](./images/ydzs-xcx.png)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册