Ansible部署
为区分各角色,部署结构如下:
环境配置
| 主机名 | 角色 | IP地址 | 操作系统 | 硬件配置 |
|---|---|---|---|---|
| master.example.com | master | 10.10.31.161 | 7.4 mini | 4C2G+30G |
| node1.example.com | node | 10.10.31.162 | 7.4 mini | 4C2G+30G |
| node2.example.com | node | 10.10.31.163 | 7.4 mini | 4C2G+30G |
| infra-node1.example.com | node | 10.10.31.164 | 7.4 mini | 4C2G+30G |
| infra-node2.example.com | node | 10.10.31.165 | 7.4 mini | 4C2G+30G |
准备工作,所有主机执行
| 配置主机名 |
|---|
| hostnamectl set-hostname master.example.com hostnamectl set-hostname node1.example.com hostnamectl set-hostname node2.example.com hostnamectl set-hostname infra-node1.example.com hostnamectl set-hostname infra-node2.example.com |
| 若无DNS Server,则配置Hosts |
| 10.10.31.161 master.example.com 10.10.31.162 node1.example.com 10.10.31.163 node2.example.com 10.10.31.164 infra-node1.example.com 10.10.31.165 infra-node2.example.com |
| 确认网络正常 |
| nmcli con show nmcli con up ens160 nmcli con mod ens160 connection.autoconnect yes systemctl restart NetworkManager systemctl status NetworkManager systemctl is-enabled NetworkManager |
| 安装基础软件包 |
| yum install wget git net-tools bind-utils iptables-services bridge-utils bash-completion kexec-tools sos psacct -y |
| 升级系统 |
| yum update -y |
| 安装Docker |
| yum install docker -y |
| docker version |
| 配置docker后端存储 |
| cat \<\ |
| docker-storage-setup |
| 添加中科大源 |
| vim /etc/docker/daemon.json |
| { “registry-mirrors”: [“https://docker.mirrors.ustc.edu.cn/"] } |
| systemctl enable docker && systemctl start docker |
配置Ansible,Master执行
由于网络原因,提前修改repo源和导入docker images
| 配置EPEL |
|---|
| yum -y install \ https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm |
| 不启用EPEL,后续手动指定 |
| sed -i -e “s/\^enabled=1/enabled=0/“ /etc/yum.repos.d/epel.repo |
| 安装Ansible |
| yum -y –enablerepo=epel install ansible pyOpenSSL |
| 拉取最新openshift-ansible版本 |
| cd ~ git clone -b release-3.6 https://github.com/openshift/openshift-ansible.git cd openshift-ansible |
| 修改ansible playbook中的repo源 |
| vim openshift-ansible/roles/openshift_repos/templates/CentOS-OpenShift-Origin36.repo.j2 |
| baseurl=http://mirrors.ustc.edu.cn/centos/7.4.1708/paas/x86_64/openshift-origin36/ |
| ./media/image1.png |
| 提前pull好docker images |
| ./media/image2.png |
| 配置各主机互信 |
| ssh-keygen -f /root/.ssh/id_rsa -N ‘’ |
| for host in master.example.com \ etcd.example.com \ node2.example.com \ node1.example.com \ infra-node1.example.com \ infra-node2.example.com; do ssh-copy-id -i ~/.ssh/id_rsa.pub \$host; done |
执行部署
- 准备Ansible Host
| mv -f /etc/ansible/hosts /etc/ansible/hosts.old |
|---|
| vi /etc/ansible/hosts |
| # Create an OSEv3 group that contains the masters and nodes groups [OSEv3:children] masters nodes etcd # Set variables common for all OSEv3 hosts [OSEv3:vars] # SSH user, this user should allow ssh based auth without requiring a password ansible_ssh_user=root # If ansible_ssh_user is not root, ansible_become must be set to true #ansible_become=true openshift_deployment_type=origin # uncomment the following to enable htpasswd authentication; defaults to DenyAllPasswordIdentityProvider openshift_master_identity_providers=[{‘name’: ‘htpasswd_auth’, ‘login’: ‘true’, ‘challenge’: ‘true’, ‘kind’: ‘HTPasswdPasswordIdentityProvider’, ‘filename’: ‘/etc/origin/master/htpasswd’}] #Disable disk and memory checks openshift_disable_check=disk_availability,memory_availability # host group for masters [masters] master.example.com # host group for etcd [etcd] etcd.example.com # host group for nodes, includes region info [nodes] master.example.com node1.example.com openshift_node_labels=”{‘region’: ‘primary’, ‘zone’: ‘east’}” node2.example.com openshift_node_labels=”{‘region’: ‘primary’, ‘zone’: ‘west’}” infra-node1.example.com openshift_node_labels=”{‘region’: ‘infra’, ‘zone’: ‘default’}” infra-node2.example.com openshift_node_labels=”{‘region’: ‘infra’, ‘zone’: ‘default’}” |
| 运行 |
| ansible-playbook ~/openshift-ansible/playbooks/byo/config.yml |
| ./media/image3.png |
验证安装
Master上验证
确认集群状态
| oc status |
|---|
| ./media/image4.png |
| oc get nodes |
| ./media/image5.png |
| oc get all |
| ./media/image6.png |
| 验证etcd |
| yum install etcd -y |
| etcdctl -C \ https://etcd.example.com:2379 \ –ca-file=/etc/origin/master/master.etcd-ca.crt \ –cert-file=/etc/origin/master/master.etcd-client.crt \ –key-file=/etc/origin/master/master.etcd-client.key cluster-health |
| etcdctl -C \ https://etcd.example.com:2379 \ –ca-file=/etc/origin/master/master.etcd-ca.crt \ –cert-file=/etc/origin/master/master.etcd-client.crt \ –key-file=/etc/origin/master/master.etcd-client.key member list |
登陆
| 创建用户 |
|---|
| htpasswd -b /etc/origin/master/htpasswd dev dev |
| 给dev用户admin权限 |
| oc login -u system:admin |
| oc adm policy add-cluster-role-to-user cluster-admin dev |
| 浏览器登录 |
| https://master.example.com:8443 |
本地DNS Server
在建立openshift集群时,是直接修改各节点的/etc/hosts文件,要访问Router映射出的域名,是加上静态的域名解析。当节点数量很多或者后续执行节点扩容时,都需要修改大量/etc/hosts/文件,繁琐又不智能。
这里选择在本地搭建一个DNS服务器,并选择将DNS Server部署在Master节点上。
在部署过程中已经安装好dnsmasp服务,不用安装,只需要添加配置文件即可
添加dnsmasp配置
| vim /etc/dnsmasq.d/local.conf |
|---|
| address=/master.example.com/10.10.31.161 address=/www.ivops-rabbitmq.com/10.10.31.164 address=/registry-console-default.router.default.svc.cluster.local/10.10.31.164 address=/agtweb.mas.ivops/10.10.31.164 address=/agtweb2.mas.ivops/10.10.31.164 |
| ./media/image7.png |
| systemctl restart dnsmasq.service |
| systemctl status dnsmasq.service |
配置iptables
| sed -i ‘/.*–dport 22 -j ACCEPT.*/a\-A INPUT -p tcp -m state –state NEW -m tcp –dport 53 -j ACCEPT’ /etc/sysconfig/iptables |
|---|
| sed -i ‘/.*–dport 22 -j ACCEPT.*/a\-A INPUT -p udp -m state –state NEW -m udp –dport 53 -j ACCEPT’ /etc/sysconfig/iptables |
| systemctl restart iptables |
| systemctl status iptables |
本地验证
| ./media/image8.png |
|---|
| ping master.example.com -c 2 |
| ping agtweb.mas.ivops -c 2 |
| ./media/image9.png |
持久化存储-NFS
使用NFS为后端存储
- 创建NFS共享目录
| mount /dev/sdc1 /mnt/nfs/ |
|---|
| yum install nfs-utils rpcbind -y |
| chown nfsnobody:nfsnobody /mnt/nfs/ -R |
| echo “/mnt/nfs *(rw,sync,all_squash)” >> /etc/exports |
| systemctl start rpcbind && systemctl enable rpcbind |
| systemctl status rpcbind |
| exportfs -r |
| systemctl start nfs-server && systemctl enable nfs-server |
| systemctl status nfs-server |
| showmount -e 127.0.0.1 |
- 测试挂载
| mkdir /mnt/nfsmount |
|---|
| touch /mnt/nfs/test |
| mount 10.10.31.161:/mnt/nfs /mnt/nfsmount |
| ls /mnt/nfsmount/ |
| rm -rf /mnt/nfsmount/test |
| df -h |
| umount /mnt/nfsmount/ |
创建Persistent Volume
- 创建pv 的yaml文件
| vi nfs-pv.yaml |
|---|
| apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain nfs: path: /mnt/nfs server: 10.10.31.161 readOnly: false |
- 创建pv卷
| oc create -f nfs-pv.yaml -n my-project |
|---|
- 查看pv卷状态
| oc get pv |
|---|
创建Persistent Volume Claim
- 创建pvc的yaml文件
| vim nfs-pvc.yaml |
|---|
| apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc spec: accessModes: - ReadWriteMany volumeName: nfs-pv resources: requests: storage: 1Gi |
- 创建pvc
| oc create -f nfs-pvc.yaml -n my-project |
|---|
- 查看pvc状态
| oc get pvc |
|---|
配置SELinux权限
- 开启NFS卷写入权限
| setsebool -P virt_use_nfs on |
|---|
创建应用
- 创建pod的yaml文件
| vi nfs-nginx.yaml |
|---|
| apiVersion: v1 kind: Pod metadata: name: nginx-nfs-pod labels: name: nginx-nfs-pod spec: containers: - name: nginx-nfs-pod image: fedora/nginx ports: - name: web containerPort: 80 volumeMounts: - name: nfsvol mountPath: /usr/share/nginx/html securityContext: supplementalGroups: [100003] privileged: false volumes: - name: nfsvol persistentVolumeClaim: claimName: nfs-pvc |
- 创建pod
| oc create -f nfs-nginx.yaml -n my-project |
|---|
- 查看pod状态
| oc get pod –n my-project |
|---|
| oc describe pod nginx-nfs-pod |
- 在Web Console上可以看到已经挂载
| ./media/image10.png |
|---|
| ./media/image11.png |
- 查看底层docker状态
| ./media/image12.png |
|---|
| docker inspect 289c36f63273 |
| ./media/image13.png |
持久化存储-GlusterFS
使用GlusterFS为后端存储-Static
- 部署GlusterFS集群
- 环境准备
| 主机名 | IP地址 | 操作系统 | 硬件配置 |
|---|---|---|---|
| gluster1 | 10.10.31.166 | 7.4 mini | 4C2G+50G |
| gluster2 | 10.10.31.167 | 7.4 mini | 4C2G+50G |
| gluster3 | 10.10.31.168 | 7.4 mini | 4C2G+50G |
- 准备工作
配置hostname
| vi /etc/hosts |
|---|
| hostnamectl set-name glsuter1 |
| hostnamectl set-name glsuter2 |
| hostnamectl set-name glsuter3 |
关闭SELinux
开始安装,所有机器相同操作
- 安装软件仓库
| yum install centos-release-gluster |
|---|
- 格式化数据盘
| mkfs.xfs -i size=512 /dev/sdb |
|---|
| mkdir -p /bricks/brick1 |
| vi /etc/fstab |
| /dev/sdb /bricks/brick1 xfs defaults 1 2 |
| mount -a && mount |
- 安装GlusterFS
| yum –enablerepo=centos-gluster*-test install glusterfs-server |
|---|
| systemctl start glusterd && systemctl enable glusterd |
- 配置trusted pool
| gluster1执行 |
|---|
| gluster peer probe gluster2 |
| gluster peer probe gluster3 |
| gluster peer status |
| ./media/image14.png |
- 配置存储卷
| mkdir /bricks/brick1/gv0 |
|---|
| 可以在任意一个节点执行: |
| gluster volume create gv0 replica 2 gluster1:/bricks/brick1/gv0 gluster2:/bricks/brick1/gv0 |
| gluster volume start gv0 |
| gluster volume info |
- 测试挂载
| mount -t glusterfs gluster1:/gv0 /mnt |
|---|
| GlusterFS 五种卷: Distributed:分布式卷,文件通过 hash 算法随机分布到由 bricks 组成的卷上。 Replicated: 复制式卷,类似 RAID 1,replica 数必须等于 volume 中 brick 所包含的存储服务器数,可用性高。 Striped: 条带式卷,类似 RAID 0,stripe 数必须等于 volume 中 brick 所包含的存储服务器数,文件被分成数据块,以 Round Robin 的方式存储在 bricks 中,并发粒度是数据块,大文件性能好。 Distributed Striped: 分布式的条带卷,volume中 brick 所包含的存储服务器数必须是 stripe 的倍数(>=2倍),兼顾分布式和条带式的功能。 Distributed Replicated: 分布式的复制卷,volume 中 brick 所包含的存储服务器数必须是 replica 的倍数(>=2倍),兼顾分布式和复制式的功能。 |
GlusterFS持久化存储
- 在OpenShift集群所有主机上安装
| yum install glusterfs-fuse |
|---|
- OpenShift所有主机配置Hosts
| vi /etc/hosts |
|---|
| 10.10.31.166 gluster1 10.10.31.167 gluster2 10.10.31.168 gluster3 |
创建Gluster Endpoints
- 先创建Service
| vi gluster-service.yaml |
|---|
| apiVersion: v1 kind: Service metadata: name: gluster-cluster spec: ports: - port: 1 |
| oc create -f gluster-service.yaml -n s2i-project |
| oc get svc |
- 创建Endpoint
| vi gluster-endpoints.yaml |
|---|
| apiVersion: v1 kind: Endpoints metadata: name: gluster-cluster subsets: - addresses: - ip: 10.10.31.166 ports: - port: 1 protocol: TCP - addresses: - ip: 10.10.31.167 ports: - port: 1 protocol: TCP - addresses: - ip: 10.10.31.168 ports: - port: 1 protocol: TCP |
| oc create -f gluster-endpoints.yaml -n s2i-project |
| oc get endpoint |
创建Persistent Volume
| vi gluster-pv.yaml |
|---|
| apiVersion: v1 kind: PersistentVolume metadata: name: gluster-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteMany glusterfs: endpoints: gluster-cluster path: /gv0 readOnly: false persistentVolumeReclaimPolicy: Retain |
| oc create -f gluster-pv.yaml -n s2i-project |
| oc get pv |
创建Persistent Volume Claim
| vi gluster-claim.yaml |
|---|
| apiVersion: v1 kind: PersistentVolumeClaim metadata: name: gluster-claim spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi |
| oc create -f gluster-claim.yaml -n s2i-project |
| oc get pvc |
配置SELinux权限
| setsebool -P virt_sandbox_use_fusefs on |
|---|
创建应用
- 由于使用的nginx镜像需要特殊权限运行,配置SCC
| oc adm policy add-scc-to-user privileged myuser |
|---|
- 创建Pod
| vim gluster-pod1.yaml |
|---|
| apiVersion: v1 kind: Pod metadata: name: gluster-pod1 labels: name: gluster-pod1 spec: containers: - name: gluster-pod1 image: nginx ports: - name: web containerPort: 80 securityContext: privileged: true volumeMounts: - name: gluster-vol1 mountPath: /usr/share/nginx/html readOnly: false volumes: - name: gluster-vol1 persistentVolumeClaim: claimName: gluster-claim |
| oc create -f gluster-pod1.yaml -n s2i-project |
| oc get pod |
| ./media/image15.png |
| ./media/image16.png |
使用GlusterFS为后端存储-Dynamic
- 新部署GlusterFS,使用Heketi管理
- 环境准备
| 主机名 | IP地址 | 操作系统 | 硬件配置 |
|---|---|---|---|
| gluster1 | 10.10.31.166 | 7.4 mini | 4C2G+50G |
| gluster2 | 10.10.31.167 | 7.4 mini | 4C2G+50G |
| gluster3 | 10.10.31.168 | 7.4 mini | 4C2G+50G |
- 准备工作
配置hostname
| vi /etc/hosts |
|---|
| 10.10.31.166 gluster1 10.10.31.167 gluster2 10.10.31.168 gluster3 |
| hostnamectl set-hostname glsuter1 |
| hostnamectl set-hostname glsuter2 |
| hostnamectl set-hostname glsuter3 |
关闭SELinux
开始安装,所有机器相同操作
- 安装软件仓库
| yum install centos-release-gluster -y |
|---|
- 安装GlusterFS
| yum install glusterfs-server -y |
|---|
| systemctl start glusterd && systemctl enable glusterd |
| systemctl status glusterd |
安装Heketi
Heketi用于管理GlusterFS的REST API
在GlusterFS其中一台虚拟机上安装,这里选择gluster3
| yum install heketi heketi-client -y |
|---|
- Heketi使用SSH来配置GlusterFS的所有节点。创建SSH密钥对,将公钥拷贝到所有3个节点上
| ssh-keygen -f /etc/heketi/heketi_key -t rsa -N ‘’ |
|---|
| ssh-copy-id -i /etc/heketi/heketi_key.pub root\@gluster1 ssh-copy-id -i /etc/heketi/heketi_key.pub root\@gluster2 ssh-copy-id -i /etc/heketi/heketi_key.pub root\@gluster3 |
| chown heketi:heketi /etc/heketi/heketi_key* |
- 配置heketi使用SSH
| vim /etc/heketi/heketi.json |
|---|
| “executor”: “ssh”, “_sshexec_comment”: “SSH username and private key file information”, “sshexec”: { “keyfile”: “/etc/heketi/heketi_key”, “user”: “root”, “port”: “22”, “fstab”: “/etc/fstab” }, |
| ./media/image17.png |
- 启动服务
| systemctl restart heketi |
|---|
| systemctl enable heketi |
| systemctl status heketi |
- 测试服务状态
| curl http://gluster3:8080/hello |
|---|
| ./media/image18.png |
配置Topology
- 配置环境变量
| export HEKETI_CLI_SERVER=http://gluster3:8080 |
|---|
- 准备json文件
| vim topology.json |
|---|
| { “clusters”: [ { “nodes”: [ { “node”: { “hostnames”: { “manage”: [ “gluster1” ], “storage”: [ “10.10.31.166” ] }, “zone”: 1 }, “devices”: [ “/dev/sdb” ] }, { “node”: { “hostnames”: { “manage”: [ “gluster2” ], “storage”: [ “10.10.31.167” ] }, “zone”: 1 }, “devices”: [ “/dev/sdb” ] }, { “node”: { “hostnames”: { “manage”: [ “gluster3” ], “storage”: [ “10.10.31.168” ] }, “zone”: 1 }, “devices”: [ “/dev/sdb” ] } ] } ] } |
| 该文件格式,是告诉heketi要创建一个3节点的集群,其中每个节点包含的配置有FQDN,IP地址以及至少一个将用作GlusterFS块的备用块设备。 |
- 运行
| heketi-cli topology load –json=topology.json |
|---|
- 验证
| gluster peer status |
|---|
- 创建一个数据卷
| heketi-cli volume create –size=20 |
|---|
| ./media/image19.png |
| gluster volume info |
| ./media/image20.png |
将Gluster与OpenShift集成
集成OpenShift,需要一个动态的Kubernetes Storage Provisioner和一个StorageClass。
Provisioner在OpenShift中开箱即用。 实际上关键的是如何将存储挂载到容器上。
StorageClass是OpenShift中的用户可以用来实现的PersistentVolumeClaims的实体,它反过来能够触发一个Provisioner实现实际的配置,并将结果表示为Kubernetes
PersistentVolume(PV)。
先创建一个测试项目,在OpenShift Master上执行
| oc new-project gluster-storage |
|---|
创建StorageClass
| vi glusterfs-storageclass1.yaml |
|---|
| kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: gluster-dyn annotations: storageclass.kubernetes.io/is-default-class: “true” provisioner: kubernetes.io/glusterfs parameters: resturl: “http://gluster3:8080" restauthenabled: “false” |
| oc create -f glusterfs-storageclass1.yaml |
| oc get sc |
| ./media/image21.png |
| 我们的provisioner是kubernetes.io/glusterfs,将它指向我们的heketi实例。 我们将类命名为“gluster-dyn”, 同时使其成为所有没有显示指定StorageClass的PersistentVolumeClaim的默认StorageClass。 |
创建Persistent Volume Claim
| #新建这个PVC只为测试 |
|---|
| vi glusterfs-pvc-storageclass.yaml |
| apiVersion: v1 kind: PersistentVolumeClaim metadata: name: gluster-dyn-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: gluster-dyn |
| oc create -f glusterfs-pvc-storageclass.yaml |
| oc get pvc |
| ./media/image22.png |
验证GlusterFS Volume
回到GlusterFS集群中,查看volume状态
| gluster volume info |
|---|
| 可以看到当前glusterfs里存在两个Volume, 第一个Volume是上面用heketi-cli volume create创建的测试Volume, 第二个Volume是StorageClass通过PVC创建的Volume |
| ./media/image23.png |
| ./media/image24.png |
Web Console
| ./media/image25.png |
|---|
| ./media/image26.png |
创建应用
- 创建pod的yaml文件
| vi nginx-pod-gluster.yaml |
|---|
| apiVersion: v1 kind: Pod metadata: name: gluster-pod1-gluster labels: name: gluster-pod1-gluster spec: containers: - name: gluster-pod1-gluster image: nginx ports: - name: web containerPort: 80 securityContext: privileged: true volumeMounts: - name: gluster-vol1-gluster mountPath: /usr/share/nginx/html volumes: - name: gluster-vol1-gluster persistentVolumeClaim: claimName: gluster-dyn-pvc |
| oc create -f nginx-pod-gluster.yaml |
| oc get pod –o wide |
| ./media/image27.png |
| ./media/image28.png |
- 测试应用
| ./media/image29.png |
|---|
深入了解Pod
Pod的定义
Pod是Kubernetes下的概念,pod的容器的载体,所有容器都是在pod中被管理,一个或多个容器放在pod里作为一个单元方便管理。
| 下面是一个完整的yaml格式定义的文件,注意格式,子集包含关系,不要有tab,要用空格。 | ||||
|---|---|---|---|---|
| apiVersion: v1 //版本 kind: pod //类型,pod metadata: //元数据 name: String //元数据,pod的名字 namespace: String //元数据,pod的命名空间 labels: //元数据,标签列表 - name: String //元数据,标签的名字 annotations: //元数据,自定义注解列表 - name: String //元数据,自定义注解名字 spec: //pod中容器的详细定义 containers: //pod中的容器列表,可以有多个容器 - name: String image: String //容器中的镜像 imagesPullPolicy: [Always\ | Never\ | IfNotPresent]//获取镜像的策略 command: [String] //容器的启动命令列表(不配置的话使用镜像内部的命令) args: [String] //启动参数列表 workingDir: String //容器的工作目录 volumeMounts: //挂载到到容器内部的存储卷设置 - name: String mountPath: String readOnly: boolean ports: //容器需要暴露的端口号列表 - name: String containerPort: int //容器要暴露的端口 hostPort: int //容器所在主机监听的端口(容器暴露端口映射到宿主机的端口) protocol: String env: //容器运行前要设置的环境列表 - name: String value: String resources: //资源限制 limits: cpu: Srting memory: String requeste: cpu: String memory: String livenessProbe: //pod内容器健康检查的设置 exec: command: [String] httpGet: //通过httpget检查健康 path: String port: number host: String scheme: Srtring httpHeaders: - name: Stirng value: String tcpSocket: //通过tcpSocket检查健康 port: number initialDelaySeconds: 0//首次检查时间 timeoutSeconds: 0 //检查超时时间 periodSeconds: 0 //检查间隔时间 successThreshold: 0 failureThreshold: 0 securityContext: //安全配置 privileged: falae restartPolicy: [Always\ | Never\ | OnFailure]//重启策略 nodeSelector: object //节点选择 imagePullSecrets: - name: String hostNetwork: false //是否使用主机网络模式,默认否 volumes: //在该pod上定义共享存储卷 - name: String meptyDir: {} hostPath: path: string secret: //类型为secret的存储卷 secretName: String item: - key: String path: String configMap: //类型为configMap的存储卷 name: String items: - key: String path: String |
Pod的配置管理
应用部署的最佳实践,就是将应用所需的配置信息与程序进行分离。
OpenShift提供一种集群配置管理方案:ConfigMap,就是将一些环境变量或者配置文件定义为configmap,放在OpenShift中,可以让其他pod调用。
ConfigMap有以下典型用法
生成为容器内的环境变量
设置容器启动命令的启动参数
以volume的形式挂载为容器内部的文件或目录
使用示例:
| 定义一个ConfigMap配置文件 |
|---|
| vi cm-appvars.yaml |
| apiVersion: v1 kind: ConfigMap metadata: name: cm-appvars data: apploglevel: info appdatadir: /var/date |
| oc create -f cm-appvars.yaml |
| 使用ConfigMap |
| apiVersion: v1 kind: Pod metadata: name: cm-test-pod spec: containers: - name: cm-test image: busybux env: - name: APPLOGLEVEL vlaueFrom: configMapKeyRef: name: cm-appvars //要和之前创建的ConfigMap的name对应 key: apploglevel - name: APPDATADIR vlaueFrom: configMapKeyRef: name: cm-appvars //要和之前创建的ConfigMap的name对应 key: appdatadir |
Pod生命周期和重启策略
- Pod一共有四种状态
| 状态值 | 描述 |
|---|---|
| Pending | APIserver已经创建该server,但pod内有一个或多个容器的镜像还未创建,可能在下载中。 |
| Running | APIserver已经创建该server,但pod内有一个或多个容器的镜像还未创建,可能在下载中。 |
| Failed | Pod内所有容器都已退出,其中至少有一个容器退出失败 |
| Unknown | 由于某种原因无法获取Pod的状态比如网络不通。 |
- Pod的重启策略应用于Pod内的所有容器,由Pod所在Node节点上的Kubelet进行判断和重启操作。重启策略有以下三种:
| 重启策略 | 描述 |
|---|---|
| Always | 容器失效时,即重启 |
| OnFailure | 容器终止运行,且退出码不为0 时重启 |
| Never | 永不重启 |
Pod调度机制
在OpenShift系统中,pod在大部分场景下都只是容器的载体而已,通常需要通过Deployment,DaemonSet,Job等对象来完成Pod的调度与自动控制功能。
RC,Deployment: 全自动调度
- RC的主要功能之一就是自动部署一个容器应用的多份副本,以及持续监控,保持集群内有一定数量的副本数量(配置文件指定了副本数量)
DaemonSet: 特定场景调度
- DaemonSet,用于管理在集群中每个Node上只运行一份Pod的副本实例,比如在每节点上都运行有且只有一个fluentd
Pod扩容和缩容
通过scale来完成扩容或缩容
动态扩容缩容(HPA)
深入了解Service
由于Pod的IP会变化,提供某些功能的POD如果IP发生变化,会导致其他Pod无法发现这些功能,因此
引入了Service的功能。
Service的定义
| { “kind”: “Service”, “apiVersion”: “v1”, “metadata”: { “name”: “my-service” }, “spec”: { “selector”: { “app”: “MyApp” }, “ports”: [ “protocol”: “TCP”, “port”: 80, “targetPort”: 9376 } ] } } |
|---|
| 该Service 对应的Pod集合:带有label app=Myapp,对外暴露端口9376 |
| Service 能将任意的流入Port 重定向到targetPort,默认情况下,targetPort和Port为相同值,不同的Pod 可以对应不同的端口号(例如,在你应用的下一个版本中会使用不同的端口号,但是并不应用之前版本的使用) |
| Service 支持UDP和TCP,默认是TCP |
Service虚拟IP和服务代理
K8s集群内每个节点都会运行kube-proxy,负责实现服务的虚拟机IP(不是externalName)
Kube-proxy监控k8s
master节点来发现Service、Endpointd的增加和删除,对于Service,在本地打开一个随机端口作为代理端口,任何访问改代理端口的连接都会被指向Service对象的Pod集合,最终指向哪个Pod取决于Service的SessionAffinity,最后,他会配置iptables,捕获流向Service 的Cluster
IP 和Port的连接,并重定向到这个代理端口。
网络连通性
网络实现
- 查看各节点分配到的子网,每个节点默认都会被分配到一个子网,在计算节点上运行的Pod的ip将来源于此网段
| oc get hostsubnets |
|---|
| ./media/image30.png |
- 通过配置文件可以修改默认子网段
| vim /etc/origin/master/master-config.yaml |
|---|
| ./media/image31.png |
注意点
OpenShift Web Console 不支持 https 安全验证,在Deploy Image是使用Image
Name部署是提示证书验证失败- 第一种方式:用命令行加参数
| oc new-app –insecure-registry dtr.ivops.cn:5443/ivops/nginx-alpine:v1.1.x –name=nginx-alpine-test |
|---|
- 第二种方式:使用Image Stream方式
| vi ivops-mariadb.json |
|---|
| { “kind”: “ImageStream”, “apiVersion”: “v1”, “metadata”: { “name”: “ivops-mariadb”, “creationTimestamp”: null }, “spec”: { “dockerImageRepository”: “dtr.ivops.cn:5443/ivops/mariadb”, “tags”: [ { “name”: “v1.1.x”, “annotations”: null, “from”: { “kind”: “DockerImage”, “name”: “dtr.ivops.cn:5443/ivops/mariadb:v1.1.x” }, “generation”: 1, “importPolicy”: { “insecure”: true } } ] } } |
| oc create -f ivops-mariadb.json -n s2i-project |
| ./media/image32.png |
| 创建template,为以后快捷创建 |
| oc export dc,svc,route -o json –as-template=ivops-mariadb > ivops-mariadb.template |
| 把 “image”: “dtr.ivops.cn:5443/ivops/mariadb”, 改为 “image”: “” 这样做的目的是,根据 template 创建应用后,自动发布,不用再手工点击 Deploy。 |
| oc create -f ivops-mariadb.template -n openshift |
- Deployer Image镜像需要以Root启动,导致启动失败
| oadm policy add-scc-to-user anyuid -z default |
|---|
| 参考链接:https://blog.openshift.com/getting-any-docker-image-running-in-your-own-openshift-cluster/ |
若没有DNS Server解析Route的地址,需配置本地Host
- 手动添加解析将“Route URL”指向Router服务所在的IP地址
| ./media/image33.png |
|---|
| ./media/image34.png |
创建PVC的容量小于等于PV的容量
Registry-console控制台用户登陆,配置权限给用户dev
| oc adm policy add-cluster-role-to-user cluster-admin dev |
|---|
| ./media/image35.png |
- 修改资源预留配额
| ./media/image36.jpeg |
|---|
~ ../../../../Library/Containers/com.tencent.xinWeChat/Data/Library/Application%20Support/com.tencent.xinWeChat/2.0b4.0.9/28af29c3fcfa1b71d38c69c1e52a17f1/Message/MessageTemp/9e20f478899dc29eb19741386f9343c8/Image/931514879804_.pic_hd.jp