Docker & K8S 实践

使用 marp 制作的用于内部分享的 docker && k8s 的文档。


marp: true
theme: uncover
paginate: false
header: ‘NXDev

Docker & K8S 实践

纳星科技 张巍


Docker

是新技术吗?
解决了什么问题 ?


是新技术吗?

linux 的Namespaces + Cgroup
配合一种被称为 Union file system 的文件系统
最后打成一个包。


解决了什么问题?

  1. 对开发来说,统一了开发的环境。开发环境不一致的问题不再是问题。
  2. 对运维来说,上线只需要一条命令。 把所有的代码装进盒子。

Docs : https://docs.docker.com

安装

架构

Docker Run Gin


Docker 如何安装

https://docs.docker.com/get-docker/

Linux

1
2
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh

先看看 怎么用的

gin-hello
mysql


Docker 架构

bg right:60% fit


镜像 (Image)
容器 (Container)
仓库 (Repository)


镜像(Image)

相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。

1
2
3
4
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 9cfcce23593a 5 weeks ago 448MB
redis 3.2-alpine 6e94a98d3442 21 months ago 22.9MB

容器(Container)

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

1
2
3
4
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3548302772b1 redis:3.2-alpine "docker-entrypoint.s…" 3 weeks ago Up 3 weeks 0.0.0.0:6379->6379/tcp redis_redis_1
37259a661f27 xxiu/mysql "docker-entrypoint.s…" 3 weeks ago Up 3 weeks 0.0.0.0:3306->3306/tcp, 33060/tcp mysql_mysql_1

仓库(Repository)

仓库可看成一个代码控制中心,用来保存镜像。

  • 自己搭: Harbor
  • 阿里云:

核心技术

bg right:60% fit

Namespaces

Cgroup

Union file systems

Container format


Namespaces & Cgroup

linux 内核做资源隔离的两个概念。

所以 docker 和虚拟机的区别在于:

  • 虚拟机虚拟了整套的操作系统,
  • docker 只是在linux 内核上做了资源隔离。

Namespaces

资源隔离

bg right:68% fit


cgroup

Cgroup:控制程序对资源的占用。

  • 对进程组使用的资源总额进行限制;

  • 通过分配CPU时间片数量/磁盘IO/带宽大小,实际上就是相当于控制子进程运行的优先级。

  • 统计系统资源使用量,比如CPU使用时间,内存使用量等

  • 进程控制,恢复执行进程


Union file systems

img

  • boots:
    boot loader + kernel ,用户不可修改 (共享主机的内核)

  • root file system : 包括典型的 linux 目录结构:
    /dev /proc /bin /etc /lib /usr /tmp 等配置文件,二进制文件,库文件


AUFS (Union FS) : 支持将不同的目录挂载到虚拟目录下。

img


bg fit

bg fit


Docker Run Gin

1
2
3
4
5
6
7
8
9
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run(":8080")
}
1
go build . -o main

Dockerfile

1
2
3
4
5
FROM scratch
WORKDIR /root/
COPY main /root/main
EXPOSE 8080
CMD ["/root/main"]
1
2
3
docker build  -t ginhello .
docker ps |grep ginhello
docker run -it ginhello

1
2
3
语法
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

  • OPTIONS:
    开放的端口/挂载的文件/传入的变量…
  • IMAGE:
    正常的镜像名:
    registry.cn-beijing.aliyuncs.com/nxops/gin-hello:v0.0.2
  • COMMAND && ARG…

例如:

1
docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

运行 docker 的命令又长 参数又多,怎么办?


docker-compose

还是来用一个文件来描述刚才我们的 run 命令

1
2
3
4
5
6
7
8
9
# docker-compose.yml
version: '3'
services:
gin-hello:
image: registry.cn-beijing.aliyuncs.com/nxops/gin-hello:v0.0.2
build: .
restart: always
ports:
- 8080:8080

mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
version: '3'

services:
mysql:
image: mysql
build: .
volumes:
- ./data:/var/lib/mysql
- ./conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf
environment:
- MYSQL_ROOT_PASSWORD=pprt123
- MYSQL_USER=pprt
- MYSQL_PASSWORD=pprt123
ports:
- 3306:3306
command: --lower-case-table-names=1 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
restart: always

接下来命令变得简单了
gin-hello

1
2
3
4
docker-compose build gin-hello
docker-compose push|pull gin-hello
docker-compose run gin-hello
docker-compose exec gin-hello bash

mysql

1
docker-compose run mysql 

K8S

K8s 是什么 ?

容器的调度和管理。


minikube

1
2
3
4
5
6
7
8
9
10
11
# 安装 kubectl
brew install kubectl

# 安装 minikube
# https://github.com/AliyunContainerService/minikube
# https://developer.aliyun.com/article/221687

curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.12.1/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

## 选择环境
kubectl config use-context minikube

example :gin-hello


架构

bg fit right:80%


  • etcd保存了整个集群的状态;
  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;

  • kube-dns负责为整个集群提供DNS服务
  • Ingress Controller为服务提供外网入口
  • Heapster提供资源监控
  • Dashboard提供GUI
  • Federation提供跨可用区的集群
  • Fluentd-elasticsearch提供集群日志采集、存储与查询

整体

bg fit right:75%


master

bg fit right:75%


Node

bg fit right:75%


kubernetes 它都管理了什么

资源


一切都是资源,根据需要去申请。
网络,存储,cpu,内存
有状态服务,无状态服务,任务,定时任务,配置
……

所有的资源都靠一行命令:

1
kubectl apply -f  <filename.yaml>

控制器

bg right:70% fit

应用控制

  • Deployment
  • DaemonSet
  • StatefulSet
  • Job/CronJob

应用配置

  • ConfigMap
  • Secret

访问方式

  • Service
  • Ingress

service

https://kubernetes.io/zh/docs/concepts/services-networking/service/#loadbalancer
service 的四种网络

  • ClusterIP 集群内部暴露ip,(默认)
  • NodeIP 通过每个 Node 上的 ip 和NodePort 暴露服务,NodePort 会路由到 ClusterIP
  • LoadBalancer 使用云提供商的均衡负载服务。 向外暴露服务
  • ExternalName 通过返回 CNAME 和它的值。

ingress

1
2
3
4
5
  internet
|
[ Ingress ]
--|-----|--
[ Services ]

ingress 被称为server 的 server。
被用来作为网络的七层代理
其实它就是做 Nginx 的事情


Ingress Controllers

在使用七层代理时,我们需要对代理做一些配置
比如 nginx 的 upstream proxy_pass

Ingress Controllers 通过 watch ingress,将它转化为数据平面的配置。

1
2
3
4
5
  internet
|
[ Ingress ] <-- [Ingress Controllers ] kubuctl
--|-----|-- | |
[ Services ] [etcd]<----------------

Ingress 选型

  1. Nginx Ingress
  2. Kong Ingress
  3. APISIX Ingress
  4. Traefik
  5. Haproxy

Kong

Kong = Openresty + config
Openresty = Nginx + lua


END

作者

张巍

发布于

2020-10-12

更新于

2022-04-22

许可协议

评论