🐳Docker学习总结
🐋DockeFile编写规则
From #基础镜像,一切从这里开始,去官网上找到镜像名和版本(比如tomcat镜像,nignx镜像)
MAINTAINER #镜像是谁写的
RUN #镜像构建需要运行的命令
ADD #步骤,添加内容,从本地添加本地内容到容器里,会自动解压,可以添加链接自动下载
WORKDIR #镜像工作目录,进入镜像的默认路径
VOLUME #设置容器卷
EXPOSE #指定暴露端口,指定容器允许暴露的端口
CMD # 指定容器启动的时候运行的命令,只有最后一个会生效,当容器run的时候的命令会替换掉cmd的命令可被替换
ENTRYPOINT # 指定这个容器启动时要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承Dockerfile,就会运行这个指令
COPY # 类似add 将文件文件拷贝到文件里
ENV # 构建的时候设置环境变量
🐋docker Run和Exec
docker run/exec
image
–name
–d(后台运行)
-it(交互方式运行)
-p(指定端口(主机端口:容器端口))
-P(随机指定端口 )
容器名id
/bin/bash(使用bash控制台)
–volumes-from 容器id(使用别的容器的数据卷)
-v 数据卷
–gpus all 使用所有的GPU
–gpus ‘“device=1,2”’ 使用指定的GPU
run和exec的区别就是run是针对镜像的exec是针对容器的。
- run启动一个容器
- exec对以启动的容器执行相关的命令行操作,shell之类的操作,或者进入命令行
🐋Docker容器打包为镜像,然后推送到dockerhub
docker commit [-m="提交的描述信息"] [-a="创建者"] 容器名称|容器ID 生成的镜像名[:标签名]
打包为镜像之后需要重命名镜像为 用户名/镜像名:版本标签的格式
docker tag 镜像名:标签 公共仓库名/镜像名:新标签
然后再push 公共仓库名/镜像名:新标签
Docker容器里添加文件
docker cp 你的文件路径 容器长ID:docker容器路径
🐋Docker Network
DockerNetwork有四种模式
Docker网络模式 | 配置 | 说明 |
---|---|---|
host模式 | –net=host | 容器和宿主机共享Network namespace。 |
container模式 | –net=container:NAME_or_ID | 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。 |
none模式 | –net=none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。 |
bridge模式 | –net=bridge | (默认为该模式) |
DockerNetwork的容器自动配置的IP地址是自动变化的,为了解决这个问题就要手动配置网络network 参考连接,
这样容器名就是服务名,可以直接ping容器名
docker0是默认的一个交换机网桥,所有连接到这个交换机的容器都在同一个局域网内。
🐋Docker Compose
DockerCompose进行服务编排的,可以在里面定义多个服务,并且指定相关的依赖,然后一次启动所有服务和依赖,适合中小型项目的服务编排,
适合单机部署微服务或者SOA服务的
yaml模板
serverces是一级目录,下面可以设置多个子服务。服务之间可以相互依赖,但是不要循环依赖奥!
version: "3.9"
services:
frontend:
image: awesome/webapp
ports:
- "443:8043"
networks:
- front-tier
- back-tier
configs:
- httpd-config
secrets:
- server-certificate
backend:
image: awesome/database
volumes:
- db-data:/etc/data
networks:
- back-tier
volumes:
db-data:
driver: flocker
driver_opts:
size: "10GiB"
configs:
httpd-config:
external: true
secrets:
server-certificate:
external: true
networks:
# The presence of these objects is sufficient to define them
front-tier: {}
🐋Docker监控
Cadviser+InfluxDB_Granfana
🐋DockerSwarm和K8S集群化部署,多个主机
🛞DockerSwarm
DockerSwarm的使用
- 初始化一个主节点master,并绑定对应的io,会生成一个token
- 在其他主机上初始化worker,然后使用token加入到master
- 可以配置多主节多从的集群。
DockerSwarm将不同主机的Docker进行了连接
manager节点负责进行服务注册和发现,以及调度请求的,也就是注册中心,你配置了多个服务,最后都会注册到manger,它会帮你发现负责和负载均衡,所以,所有服务可以指定同一个名字,不用担心重复,swarm集群帮你完成了自动的配置和注册
docker swarm配置docker stack进行服务编排
- 编写stack.yaml和compose.yaml类似,只是stack.yaml可以指定服务的重复数量,容器会自动选择节点进行重复部署。另外stack 是一组相互关联的服务,它是服务的上一层,
这些服务共享依赖关系
,docker service
- 控制具体的服务进行扩缩容或者修改容器
🛞K8s
k8s适合
上百台服务器的服务器集群的配置和使用
,组织结构和docker swarm是相同的master+worker。但是k8s的关键是Pod,Pod里面放置运行了容器,这个容器可以是docker的也可以是其他虚拟的容器,所以k8s是针对容器编排的一个框架,底层可以适配不同的虚拟化容器。
k8s的关键是pod,pod是容器管理的最新单元,pod内部可以运行一个或者多个容器,
具体容器的负载内容通过deployment,StatefulSet等方式具体说明,然后和pod绑定。
pod和servercie进行绑定,完成容器的服务化开发,每个pod都是一个服务,可以通过服务名直接访问
k8s提供丰富api易于扩展。
k8s还提供了其他的易于进行服务配置和扩展的操作,为微服务部署做了充分配置
- k8s的服务运行和swarm也是类似的,通过配置文件启动,只是k8s有更多其他的可选配置。
🛞 K8s学习记录
安装
🛎Minikube单机测试
🛎kubeadm
🛎k8s包管理工具Helm
🛎 具体命令行工具
平时主要使用了kubectl命令来部署操作各种服务
- 主要的功能和docker的对比图如下:
- pod涉及应用容器的相关操作
- 一些其他的组件完成服务的访问,部署,网络连接等
常用命令
# 部署应用
kubectl apply -f app.yaml
# 查看 deployment
kubectl get deployment
# 查看 pod
kubectl get pod -o wide
# 查看 pod 详情
kubectl describe pod pod-name
# 查看 log
kubectl logs pod-name
# 进入 Pod 容器终端, -c container-name 可以指定进入哪个容器。
kubectl exec -it pod-name -- bash
# 伸缩扩展副本
kubectl scale deployment test-k8s --replicas=5
# 把集群内端口映射到节点
kubectl port-forward pod-name 8090:8080
# 查看历史
kubectl rollout history deployment test-k8s
# 回到上个版本
kubectl rollout undo deployment test-k8s
# 回到指定版本
kubectl rollout undo deployment test-k8s --to-revision=2
# 删除部署
kubectl delete deployment test-k8s
应用部署
kubectl命令
命令行运行一个镜像(不怎么推荐使用吧)
kubectl run testapp --image=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1
配置文件运行一个服务镜像
配置文件运行一个镜像服务
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
# 定义容器,可以多个
containers:
- name: test-k8s # 容器名字
image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
kubectl apply -f .\pod.yaml
配置文件进行批量的部署
apiVersion: apps/v1
kind: Deployment
metadata:
# 部署名字
name: test-k8s
spec:
replicas: 2
# 用来查找关联的 Pod,所有标签都匹配才行
selector:
matchLabels:
app: test-k8s
# 定义 Pod 相关数据
template:
metadata:
labels:
app: test-k8s
spec:
# 定义容器,可以多个
containers:
- name: test-k8s # 容器名字
image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
kubectl apply -f .\app.yaml
应用访问
构建一个service服务,实现端口集中的转发管理
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
# 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
kubectl apply -f service.yaml
查看服务
kubectl get svc
应用数据
Stateful类型应用
创建持久层
- 方式一,和docker类似直接挂载目录(不推荐)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
serviceName: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data/db # 容器里面的挂载路径
name: mongo-data # 卷名字,必须跟下面定义的名字一致
volumes:
- name: mongo-data # 卷名字
hostPath:
path: /data/mongo-data # 节点上的路径
type: DirectoryOrCreate # 指向一个目录,不存在时自动创建
- 方式二:提交申请单
提交申请单pvc后,云服务商会自动匹配相关的pv,和sc,本地提前建好pv即可
创建后pvc后,绑定pvc
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
image: mongo:5.0
imagePullPolicy: IfNotPresent
name: mongo
volumeMounts:
- mountPath: /data/db
name: mongo-data
volumes:
- name: mongo-data
persistentVolumeClaim:
claimName: mongodata
应用配置
- 步骤1:
声明yaml配置文件
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
# Opaque 用户定义的任意数据,更多类型介绍 https://kubernetes.io/zh/docs/concepts/configuration/secret/#secret-types
type: Opaque
data:
# 数据要 base64。https://tools.fun/base64.html
mongo-username: bW9uZ291c2Vy
mongo-password: bW9uZ29wYXNz
# 应用
kubectl apply -f secret.yaml
# 查看
kubectl get secret mongo-secret -o yaml
- 步骤2:
作为环境变量使用
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
# Secret 的所有数据定义为容器的环境变量,Secret 中的键名称为 Pod 中的环境变量名称
# envFrom:
# - secretRef:
# name: mongo-secret
挂载为文件
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
Ingress服务访问
k8s中的ingress是一个标准规范,是定义外部流量进入集群内部的规则描述,ingress-nginx是一个具体的K8s ingress控制器提供者之一,通俗说就是一个k8s ingress的具体实现。同时也存在其他很多的实现,例如istio、kong等。
helm包管理工具
# 安装
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-mongo bitnami/mongodb
# 指定密码和架构
helm install my-mongo bitnami/mongodb --set architecture="replicaset",auth.rootPassword="mongopass"
# 删除
helm ls
helm delete my-mongo
# 查看密码
kubectl get secret my-mongo-mongodb -o json
kubectl get secret my-mongo-mongodb -o yaml > secret.yaml
# 临时运行一个包含 mongo client 的 debian 系统
kubectl run mongodb-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash
# 进去 mongodb
mongo --host "my-mongo-mongodb" -u root -p mongopass
# 也可以转发集群里的端口到宿主机访问 mongodb
kubectl port-forward svc/my-mongo-mongodb 27017:27018
命名空间管理
# 创建命名空间
kubectl create namespace testapp
# 部署应用到指定的命名空间
kubectl apply -f app.yml --namespace testapp
# 查询
kubectl get pod --namespace kube-system
# 切换命名空间
kubens kube-system
# 回到上个命名空间
kubens -
# 切换集群
kubectx minikube
🐋docker 私有镜像
- 第三方提供的私有镜像,比如官方,阿里云,腾讯云,华为云等云
- 自己搭建