Docker基本使用
在虚拟机上安装docker并启动
[root@node1 ~]# yum install -y docker
[root@node1 ~] systemctl restart docker
传统虚拟机技术
- 虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便
Docker重要概念
- 镜像(Image)、容器(Container)、仓库(Repository)
- 镜像:采用了AUFS(联合文件系统),采用了分层结构,镜像是只读的,基础镜像一旦构建完成就不能再改了,但是可以在它上面封装一个层次,把改动的内容放到高层中
- 容器:相当于是镜像的一次执行,容器也相当于是镜像可读写副本
- 容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间
- 不要假定容器会永远运行,而应该假定容器随时可能出现故障,出现故障后,也不会再去修复它
- 数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡
- 仓库:一个Docker Registry中可以包含多个仓库(Repository)。每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。我们可以通过<仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签
容器、镜像的使用
[root@node1 ~]# docker run busybox echo 'Hello World'
# 如果本机没有busybox:latest,将会到仓库中下载,然后启动容器,
# 容器运行echo命令后,退出
# 因为容器只是宿主机上的一个进程,echo是个临时进程,运行后就退出,所以容器也就结束了
# 因为容器只是个进程,不是一个完整的系统,所以如果希望它一直处于运行状态,就必须
# 使容器内的进程在前台运行,不要让前台程序退出
[root@node1 ~]# docker run -it centos bash
如果执行exit退出,容器又停止运行了,如果希望退回到宿主机的shell但不要停掉容器,
可以按ctrl+p+q
进入容器的方法:
- 不启动新进程
[root@node1 ~]# docker attach 831b
- 启用新进程
[root@node1 ~]# docker exec -it 831b bash
创建镜像的方法:
1、基于原始镜像启动容器,修改容器,完毕后commit成新镜像。不推荐
2、使用dockerfile
1. 每个dockerfile的指令都会增加一层,所以要注意书写,不要出现太多层次
[root@node1 ~]# mkdir cent1
[root@node1 ~]# cd cent1/
[root@node1 cent1]# vim dockerfile
FROM centos
RUN echo 'hello' > /tmp/hi.txt
RUN echo 'workd' > /tmp/abc.txt
[root@node1 cent1]# docker build -t centos:v1 .
[root@node1 cent1]# docker history centos:v1 # 新镜像增加了两层
上面dockerfile应该改为以下样式:
FROM centos
RUN echo 'hello' > /tmp/hi.txt \
&& echo 'workd' > /tmp/abc.txt
[root@node1 cent1]# docker build -t centos:v2 .
- 构建上下文默认情况下,构建镜像时,docker会将当前目录所有内容拷贝到context上下文环境中,在dockerfile中的当前目录(.)实际上指的是context中的当前目录。
- 构建时,应该创建一个空目录,将所需文件拷贝到空目录中,然后构建。
- 常用指令FROM / COPY / CMD / ENTRYPOINT / RUN / EXPOSE
指定容器的name和主机名
[root@node1 ~]# docker run -it --name centos1 -h mycent centos bash
在虚拟机上搭建私有仓库
将kubernetes目录中的images导入到私有仓库
[root@node1 ~]# unzip docker_images.zip
[root@node1 ~]# tar xf images.tar.gz
[root@node1 ~]# cd images/
[root@node1 docker_images]# docker load < registry.tar
[root@node1 ~]# vim /etc/docker/daemon.json
{
"insecure-registries" : ["192.168.3.1:5000"]
}
[root@node1 ~]# systemctl restart docker
[root@node1 ~]# docker run -d -p 5000:5000 registry
[root@node1 kubernetes]# tar xf images.tar.gz
[root@node1 kubernetes]# cd images/
[root@node1 images]# for i in *
> do
> docker load < $i
> done
[root@node1 ~]# docker tag mysql 192.168.3.1:5000/mysql
[root@node1 ~]# docker tag kubeguide/guestbook-php-frontend 192.168.3.1:5000/guestbook-php-frontend
[root@node1 ~]# docker tag kubeguide/tomcat-app:v1 192.168.3.1:5000/tomcat-app
[root@node1 ~]# docker tag kubeguide/redis-master 192.168.3.1:5000/redis-master
[root@node1 ~]# docker tag kubeguide/guestbook-redis-slave 192.168.3.1:5000/guestbook-redis-slave
[root@node1 ~]# docker images > xxx
[root@node1 ~]# vim xxx // 修改为以下模样
192.168.3.1:5000/mysql
192.168.3.1:5000/pod-infrastructure
192.168.3.1:5000/guestbook-php-frontend
192.168.3.1:5000/tomcat-app
192.168.3.1:5000/redis-master
192.168.3.1:5000/guestbook-redis-slave
[root@node1 ~]# for i in `cat xxx`
> do
> docker push $i
> done
查看
[root@node1 ~]# curl 127.0.0.1:5000/v2/_catalog
{"repositories":["guestbook-php-frontend","guestbook-redis-slave","mysql","pod-infrastructure","redis-master","tomcat-app"]}
kubernets概述
k8s概述
- 它是一个全新的基于容器技术的分式架构领先方案
- 谷歌10几年以来大规模应用容器技术的重要成果
- Borg的一个开源版本
- 不限于任何语言,可以通过任何语言编写服务
master的进程
- Kubernetes API server
- 所有资源增删改查的唯一入口
- Kubernetes Controller Manager
- 所有资源对象的自动化控制中心
- Kubernetes Scheduler
- 负责资源调度
node的进程
- Kubelet
- 负责pod对应容器的创建、启停等
- Kube-proxy
- 实现Kubernetes service的通信与负载均衡机制的重要组件
- Docker Engine
- Docker进程,负责本机容器的创建与管理
pod
- 由若干容器组成的一个容器组
- 同个组内的容器共享一个存储卷(volume)
- 每个Pod被分配到节点上运行直至运行结束或被删除
- • 同个Pod下的容器使用相同的网络命名空间、IP地址和端口区间,相互之间能通过localhost来发现和通信
service
- Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —— 通常称为微服务
- 这一组 Pod 能够被 Service 访问到对非 Kubernetes 集群中的应用,Kubernetes 提供了基于 VIP 的网桥的方式访问 Service,再由 Service 重定向到 backend Pod
- 在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。kube-proxy 负责为 Service实现了一种 VIP(虚拟 IP)的形式
标签和选择器
- 为了建立service和pod间的关联,k8s先给每个pod打上一个标签(Label)。如给mysql的pod打上name=mysql标签
- 然后再给相应的service定义标签选择器(LabelSelector),如mysql service标签选择器的选择条件为name=mysql
RC/RS/Deployment
- RC: Replication Controller,它定义了一个期望的场景,即声明某种pod的副本数量在任意时刻都符合某个预期值,包括以下几个部分:
- 期待的pod副本数
- 用于筛选目标pod的Label Selector
- 副本数不足时,用于创建新pod的pod模板
- RS和Deployment逐步替换了rc的作用,在功能上做了进一步的升级
kubernetes环境的搭建
准备一台虚拟机用作k8s服务器,内存4G以上
1、node3
- 主机名 node3
- IP地址 192.168.3.3/24
- 网关 192.168.3.254 (必须配置网关,否则服务无法启动)
2、把k8s的软件压缩包和mykube目录拷贝到node3
[root@Ardee kubernetes]# scp -r k8s_pkgs.tar.gz mykube/ 192.168.3.3:~
[root@node3 ~]# tar xf k8s_pkgs.tar.gz
[root@node3 k8s_pkgs]# yum -y install *.rpm
3、安装
[root@node3 k8s_pkgs]# cp /etc/rhsm/ca/redhat-uep.pem ~ // 如果没有的报错的可以忽略,这两步
[root@node3 k8s_pkgs]# yum remove python-rhsm
[root@node3 ~]# cd k8s_pkgs/
[root@node3 k8s_pkgs]# yum install -y *rpm
4、k8s的组成
- master:一般是物理服务器,用于对容器进行控制、调度
- node:可以是物理服务器,也可以是云主机
5、修改docker配置文件,使之可以使用私有仓库
[root@node3 k8s_pkgs]# vim /etc/sysconfig/docker
OPTIONS='--selinux-enabled=false --log-driver=journald --signature-verification=false'
[root@node3 ~]# cat /etc/docker/daemon.json
{
"insecure-registries" : ["192.168.3.1:5000"] # 这是在192.168.3.1搭建过的私有仓库
}
[root@node3 k8s_pkgs]# systemctl start docker
[root@node3 k8s_pkgs]# systemctl enable docker
6、启动相关服务
- master:一般是物理主机,用于对容器进行控制、调度
- etcd: 是一个数据库,各组件信息将会写到etcd中
- kube-apiserver: 负责执行指令
- kube-controller-manager: 控制管理器
- kube-scheduler: 调度
- node: 可以是物理服务器,也可以是云主机
- kubelet: node节点接收指令,k8s客户端
- kube-proxy: 代理节点
- docker: 真正的容器服务
[root@node3 k8s_pkgs]# systemctl start etcd
[root@node3 k8s_pkgs]# systemctl enable etcd
[root@node3 k8s_pkgs]# systemctl start kube-apiserver.service
[root@node3 k8s_pkgs]# systemctl enable kube-apiserver.service
[root@node3 k8s_pkgs]# systemctl start kube-controller-manager.service
[root@node3 k8s_pkgs]# systemctl enable kube-controller-manager.service
[root@node3 k8s_pkgs]# systemctl start kube-scheduler.service
[root@node3 k8s_pkgs]# systemctl enable kube-scheduler.service
[root@node3 k8s_pkgs]# systemctl start kubelet.service
[root@node3 k8s_pkgs]# systemctl enable kubelet.service
[root@node3 k8s_pkgs]# systemctl start kube-proxy.service
[root@node3 k8s_pkgs]# systemctl enable kube-proxy.service
7、配置文件
- /etc/kubernetes/apiserver
[root@node3 k8s_pkgs]# vim /etc/kubernetes/apiserver
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
// 把ServiceAccount,从KUBE_ADMISSION_CONTROL="... ..."中删除
KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
[root@node3 k8s_pkgs]# systemctl restart kube-apiserver
- /etc/kubernetes/config
[root@node3 k8s_pkgs]# vim /etc/kubernetes/config
KUBE_MASTER="--master=http://192.168.3.3:8080"
- /etc/kubernetes/kubelet
[root@node3 k8s_pkgs]# vim /etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=0.0.0.0"
KUBELET_API_SERVER="--api-servers=http:/192.168.3.3:8080"
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=192.168.3.1:5000/pod-infrastructure" # 私有仓库地址
[root@node3 k8s_pkgs]# systemctl restart kubelet
四个yaml文件
- mysql-rc.yaml
[root@node3 tomcat_mysql]# cat mysql-rc.yaml
apiVersion: v1
kind: ReplicationController # 类型是一个RC
metadata:
name: mysql
spec:
replicas: 1 # 1个RC
selector:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: 192.168.3.1:5000/mysql # 私有仓库中的mysql镜像
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
- mysql-svc.yaml
[root@node3 tomcat_mysql]# cat mysql-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
- myweb-rc.yaml
[root@node3 tomcat_mysql]# cat myweb-rc.yaml
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 5
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: 192.168.3.1:5000/tomcat-app
ports:
- containerPort: 8080
env:
- name: MYSQL_SERVICE_HOST
value: 'mysql'
- name: MYSQL_SERVICE_PORT
value: '3306'
- myweb-svc.yaml
[root@node3 tomcat_mysql]# cat myweb-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb
8、应用测试
[root@node3 ~]# cd mykube/tomcat_mysql/
[root@node3 tomcat_mysql]# kubectl create -f mysql-rc.yaml
[root@node3 tomcat_mysql]# kubectl get rc
NAME DESIRED CURRENT READY AGE
mysql 1 1 1 54s
[root@node3 tomcat_mysql]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-f5s4w 1/1 Running 0 4m
[root@node3 tomcat_mysql]# docker ps # 查看到启动的容器
[root@node3 tomcat_mysql]# kubectl create -f mysql-svc.yaml
[root@node3 tomcat_mysql]# kubectl get service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 1h
mysql 10.254.186.86 <none> 3306/TCP 50s
[root@node3 tomcat_mysql]# kubectl create -f myweb-rc.yaml
replicationcontroller "myweb" created
[root@node3 tomcat_mysql]# kubectl create -f myweb-svc.yaml
service "myweb" created
[root@node3 tomcat_mysql]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-fxvz8 1/1 Running 0 9m
myweb-9w7qh 1/1 Running 0 3m
myweb-g31pw 1/1 Running 0 3m
myweb-gsrqk 1/1 Running 0 3m
myweb-lt9kd 1/1 Running 0 3m
myweb-wpz72 1/1 Running 0 3m
# 删除一个容器后,k8s会发现容器数目已经少于rc声明了,它会自动创建新容器
[root@node3 tomcat_mysql]# docker rm -f c03b1d754203
[root@node3 tomcat_mysql]# kubectl get pods
删除服务、rc
[root@node3 tomcat_mysql]# kubectl delete service mysql
[root@node3 tomcat_mysql]# kubectl delete service myweb
[root@node3 tomcat_mysql]# kubectl delete rc myweb
[root@node3 tomcat_mysql]# kubectl delete rc mysql
[root@node3 tomcat_mysql]# kubectl describe pod mysql-7m9rw
Name: mysql-7m9rw
Namespace: default
Node: 127.0.0.1/127.0.0.1
Start Time: Tue, 09 Apr 2019 11:45:18 +0800
Labels: app=mysql
Status: Running
IP: 172.17.0.2
Controllers: ReplicationController/mysql
Containers:
mysql:
Container ID: docker://7e23ce7d3b40ac77ba5e1d1e35eef42b66f3a4518a76037389dea6e7aaaf015b
Image: 192.168.3.3:5000/mysql
Image ID: docker-pullable://192.168.3.3:5000/mysql@sha256:ba77d87bc75b6f478c21951b14ede2d2c489b7fc871024d03c8514e4b11e54be
Port: 3306/TCP
State: Running
Started: Tue, 09 Apr 2019 11:45:20 +0800
Ready: True
Restart Count: 0
Volume Mounts: <none>
Environment Variables:
MYSQL_ROOT_PASSWORD: 123456
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
No volumes.
QoS Class: BestEffort
Tolerations: <none>
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
2m 2m 1 {default-scheduler } Normal Scheduled Successfully assigned mysql-7m9rw to 127.0.0.1
2m 2m 2 {kubelet 127.0.0.1} Warning MissingClusterDNS kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. Falling back to DNSDefault policy.
2m 2m 1 {kubelet 127.0.0.1} spec.containers{mysql} Normal Pulling pulling image "192.168.3.3:5000/mysql"
2m 2m 1 {kubelet 127.0.0.1} spec.containers{mysql} Normal Pulled Successfully pulled image "192.168.3.3:5000/mysql"
2m 2m 1 {kubelet 127.0.0.1} spec.containers{mysql} Normal Created Created container with docker id 7e23ce7d3b40; Security:[seccomp=unconfined]
2m 2m 1 {kubelet 127.0.0.1} spec.containers{mysql} Normal Started Started container with docker id 7e23ce7d3b40
[root@node3 tomcat_mysql]# kubectl create -f mysql-svc.yaml
[root@node3 tomcat_mysql]# kubectl get service
[root@node3 tomcat_mysql]# kubectl describe service mysql
Name: mysql
Namespace: default
Labels: <none>
Selector: app=mysql
Type: ClusterIP
IP: 10.254.123.67
Port: <unset> 3306/TCP
Endpoints: 172.17.0.2:3306
Session Affinity: None
No events.
[root@node3 tomcat_mysql]#
扩容RC:
[root@node3 tomcat_mysql]# kubectl scale replicationcontroller --replicas=4 mysql
[root@node3 tomcat_mysql]# kubectl get rc
[root@node3 tomcat_mysql]# kubectl get pods
[root@node3 tomcat_mysql]# docker ps
[root@node3 tomcat_mysql]# kubectl scale replicationcontroller --replicas=2 mysql
[root@node3 tomcat_mysql]# kubectl get rc
[root@node3 tomcat_mysql]# kubectl get pods
[root@node3 tomcat_mysql]# docker ps
[root@node3 php_redis]# kubectl delete service mysql
[root@node3 php_redis]# kubectl delete rc mysql
redis-master-controller.yaml:redis主
redis-slave-controller.yaml:redis从
frontend-controller.yaml:php前端
创建redis主
[root@node3 php_redis]# kubectl create -f redis-master-controller.yaml
[root@node3 php_redis]# kubectl create -f redis-master-service.yaml
[root@node3 php_redis]# kubectl get service
[root@node3 php_redis]# kubectl describe service redis-master
[root@node3 php_redis]# kubectl describe pod redis-master-qdxwm
创建redis从
[root@node3 php_redis]# kubectl create -f redis-slave-controller.yaml
[root@node3 php_redis]# kubectl get rc
[root@node3 php_redis]# kubectl get pods
[root@node3 php_redis]# kubectl create -f redis-slave-service.yaml
[root@node3 php_redis]# kubectl get service
创建php前端
[root@node3 php_redis]# kubectl create -f frontend-controller.yaml
[root@node3 php_redis]# kubectl get rc
[root@node3 php_redis]# kubectl get pods
[root@node3 php_redis]# kubectl create -f frontend-service.yaml
[root@node3 php_redis]# kubectl get service
测试:访问宿主机的30001端口
http://192.168.3.33:30001/