1611805260
Want to create an eCommerce store and make money online? Check out my Step-By-Step WooCommerce Tutorial!
Download the Follow Along Images:
https://drive.google.com/uc?export=download&id=1SJHiNQ68JondzM41fBA-sQTYU6xbRs2A
TIMESTAMPS:
0:00 - Intro: What is WooCommerce?
0:24 - Overview of tutorial
4:10 - Step 1: Get a Domain Name and Web Hosting
8:55 - Step 2: Install WordPress
11:18 - Propagation
Website Setup
13:26 - Step 3: Secure Your Website
15:28 - Step 4: Change Your Site Title & Tagline
17:50 - Step 5: Activate a New Theme
19:17 - Step 6: Important a Template Site
22:38 - Install WooCommerce
Creating First Product
23:23 - Step 7: Create a Simple Product
35:06 - Create Categories & tags
40:44 - Adding a Review to a Product
Creating Other Products
42:05 - Step 8: Create a Variable Product
49:53 - Step 9: Create a Digital Product
54:56 - Step 10: Create a Downloadable Product
59:13 - Step 11: Create an Affiliate Product
1:03:15 - Step 12: Create a Grouped Product
1:13:27 - Step 13: Set up Upsells & Cross Sells
1:16:03 - Step 14: Create a Filter By Price Sidebar
Customize Your Site
1:20:09 - Step 15: Customize Your Shop
1:23:58 - Adding a policy page
1:25:29 - Creating site Logo
1:31:40 - Customizing Homepage
Payments & Backend
1:43:31 - Step 16: Setup Payment Methods
1:57:21 - Step 17: Setup Coupon Codes
2:07:39 - Step 18: Setup Shipping
2:12:01 - Step 19: Manage Orders
2:14:14 - Step 20: Add Products to Homepage
2:20:11 - Like & Subscribe for more!
#woocommerce #web-development
1655630160
Install via pip:
$ pip install pytumblr
Install from source:
$ git clone https://github.com/tumblr/pytumblr.git
$ cd pytumblr
$ python setup.py install
A pytumblr.TumblrRestClient
is the object you'll make all of your calls to the Tumblr API through. Creating one is this easy:
client = pytumblr.TumblrRestClient(
'<consumer_key>',
'<consumer_secret>',
'<oauth_token>',
'<oauth_secret>',
)
client.info() # Grabs the current user information
Two easy ways to get your credentials to are:
interactive_console.py
tool (if you already have a consumer key & secret)client.info() # get information about the authenticating user
client.dashboard() # get the dashboard for the authenticating user
client.likes() # get the likes for the authenticating user
client.following() # get the blogs followed by the authenticating user
client.follow('codingjester.tumblr.com') # follow a blog
client.unfollow('codingjester.tumblr.com') # unfollow a blog
client.like(id, reblogkey) # like a post
client.unlike(id, reblogkey) # unlike a post
client.blog_info(blogName) # get information about a blog
client.posts(blogName, **params) # get posts for a blog
client.avatar(blogName) # get the avatar for a blog
client.blog_likes(blogName) # get the likes on a blog
client.followers(blogName) # get the followers of a blog
client.blog_following(blogName) # get the publicly exposed blogs that [blogName] follows
client.queue(blogName) # get the queue for a given blog
client.submission(blogName) # get the submissions for a given blog
Creating posts
PyTumblr lets you create all of the various types that Tumblr supports. When using these types there are a few defaults that are able to be used with any post type.
The default supported types are described below.
We'll show examples throughout of these default examples while showcasing all the specific post types.
Creating a photo post
Creating a photo post supports a bunch of different options plus the described default options * caption - a string, the user supplied caption * link - a string, the "click-through" url for the photo * source - a string, the url for the photo you want to use (use this or the data parameter) * data - a list or string, a list of filepaths or a single file path for multipart file upload
#Creates a photo post using a source URL
client.create_photo(blogName, state="published", tags=["testing", "ok"],
source="https://68.media.tumblr.com/b965fbb2e501610a29d80ffb6fb3e1ad/tumblr_n55vdeTse11rn1906o1_500.jpg")
#Creates a photo post using a local filepath
client.create_photo(blogName, state="queue", tags=["testing", "ok"],
tweet="Woah this is an incredible sweet post [URL]",
data="/Users/johnb/path/to/my/image.jpg")
#Creates a photoset post using several local filepaths
client.create_photo(blogName, state="draft", tags=["jb is cool"], format="markdown",
data=["/Users/johnb/path/to/my/image.jpg", "/Users/johnb/Pictures/kittens.jpg"],
caption="## Mega sweet kittens")
Creating a text post
Creating a text post supports the same options as default and just a two other parameters * title - a string, the optional title for the post. Supports markdown or html * body - a string, the body of the of the post. Supports markdown or html
#Creating a text post
client.create_text(blogName, state="published", slug="testing-text-posts", title="Testing", body="testing1 2 3 4")
Creating a quote post
Creating a quote post supports the same options as default and two other parameter * quote - a string, the full text of the qote. Supports markdown or html * source - a string, the cited source. HTML supported
#Creating a quote post
client.create_quote(blogName, state="queue", quote="I am the Walrus", source="Ringo")
Creating a link post
#Create a link post
client.create_link(blogName, title="I like to search things, you should too.", url="https://duckduckgo.com",
description="Search is pretty cool when a duck does it.")
Creating a chat post
Creating a chat post supports the same options as default and two other parameters * title - a string, the title of the chat post * conversation - a string, the text of the conversation/chat, with diablog labels (no html)
#Create a chat post
chat = """John: Testing can be fun!
Renee: Testing is tedious and so are you.
John: Aw.
"""
client.create_chat(blogName, title="Renee just doesn't understand.", conversation=chat, tags=["renee", "testing"])
Creating an audio post
Creating an audio post allows for all default options and a has 3 other parameters. The only thing to keep in mind while dealing with audio posts is to make sure that you use the external_url parameter or data. You cannot use both at the same time. * caption - a string, the caption for your post * external_url - a string, the url of the site that hosts the audio file * data - a string, the filepath of the audio file you want to upload to Tumblr
#Creating an audio file
client.create_audio(blogName, caption="Rock out.", data="/Users/johnb/Music/my/new/sweet/album.mp3")
#lets use soundcloud!
client.create_audio(blogName, caption="Mega rock out.", external_url="https://soundcloud.com/skrillex/sets/recess")
Creating a video post
Creating a video post allows for all default options and has three other options. Like the other post types, it has some restrictions. You cannot use the embed and data parameters at the same time. * caption - a string, the caption for your post * embed - a string, the HTML embed code for the video * data - a string, the path of the file you want to upload
#Creating an upload from YouTube
client.create_video(blogName, caption="Jon Snow. Mega ridiculous sword.",
embed="http://www.youtube.com/watch?v=40pUYLacrj4")
#Creating a video post from local file
client.create_video(blogName, caption="testing", data="/Users/johnb/testing/ok/blah.mov")
Editing a post
Updating a post requires you knowing what type a post you're updating. You'll be able to supply to the post any of the options given above for updates.
client.edit_post(blogName, id=post_id, type="text", title="Updated")
client.edit_post(blogName, id=post_id, type="photo", data="/Users/johnb/mega/awesome.jpg")
Reblogging a Post
Reblogging a post just requires knowing the post id and the reblog key, which is supplied in the JSON of any post object.
client.reblog(blogName, id=125356, reblog_key="reblog_key")
Deleting a post
Deleting just requires that you own the post and have the post id
client.delete_post(blogName, 123456) # Deletes your post :(
A note on tags: When passing tags, as params, please pass them as a list (not a comma-separated string):
client.create_text(blogName, tags=['hello', 'world'], ...)
Getting notes for a post
In order to get the notes for a post, you need to have the post id and the blog that it is on.
data = client.notes(blogName, id='123456')
The results include a timestamp you can use to make future calls.
data = client.notes(blogName, id='123456', before_timestamp=data["_links"]["next"]["query_params"]["before_timestamp"])
# get posts with a given tag
client.tagged(tag, **params)
This client comes with a nice interactive console to run you through the OAuth process, grab your tokens (and store them for future use).
You'll need pyyaml
installed to run it, but then it's just:
$ python interactive-console.py
and away you go! Tokens are stored in ~/.tumblr
and are also shared by other Tumblr API clients like the Ruby client.
The tests (and coverage reports) are run with nose, like this:
python setup.py test
Author: tumblr
Source Code: https://github.com/tumblr/pytumblr
License: Apache-2.0 license
1646796184
Bài viết này dựa trên kinh nghiệm của tôi khi học và vượt qua kỳ thi Chuyên gia bảo mật Kubernetes được chứng nhận. Tôi đã vượt qua kỳ thi trong lần thử đầu tiên vào tháng 9 năm 2021.
Tôi đã vượt qua kỳ thi Nhà phát triển ứng dụng Kubernetes được chứng nhận vào tháng 2 năm 2020, tiếp theo là Quản trị viên Kubernetes được chứng nhận vào tháng 3 năm 2020.
Kỳ thi CKS hoặc Chuyên gia bảo mật Kubernetes được chứng nhận đã được phát hành vào khoảng tháng 11 năm 2020, nhưng tôi không có cơ hội tham gia kỳ thi đó trước tháng 9 năm 2021.
Như một chút thông tin cơ bản, tôi đã làm việc với Kubernetes trong 3 năm qua gần như hàng ngày và kinh nghiệm đó là một lợi thế bổ sung giúp tôi vượt qua CKS.
Trong bài viết này, tôi sẽ chia sẻ một số tài nguyên sẽ giúp bạn học tập và vượt qua kỳ thi, cùng với một bảng đánh giá hữu ích mà bạn có thể sử dụng khi chuẩn bị. Tôi cũng sẽ chia sẻ một số lời khuyên sẽ giúp ích cho bạn trong suốt quá trình.
Kubernetes là hệ thống Điều phối vùng chứa phong phú và phát triển nhất hiện có và nó tiếp tục trở nên tốt hơn.
Nó có một cộng đồng khổng lồ để hỗ trợ và nó luôn xây dựng các tính năng mới và giải quyết các vấn đề. Kubernetes chắc chắn đang phát triển với tốc độ chóng mặt, và nó trở thành một thách thức để theo kịp tốc độ phát triển của nó. Điều này làm cho nó trở thành lựa chọn tốt nhất cho giải pháp điều phối vùng chứa.
Sau đây là một số tài nguyên tuyệt vời có sẵn để vượt qua kỳ thi CKS:
Các khóa học cho KodeKloud và Killer.sh cung cấp các trình mô phỏng kỳ thi thử rất hữu ích trong việc chuẩn bị cho kỳ thi và cung cấp một ý tưởng khá tốt về kỳ thi trông như thế nào. Tôi thực sự khuyên bạn nên đăng ký vào một hoặc cả hai khóa học.
Mua bài kiểm tra từ Linux Foundation mang đến cho bạn 2 lần thử miễn phí trong trình mô phỏng kỳ thi từ killer.sh. Bằng cách đó, nếu bạn đã thành thạo với nội dung của chương trình học, bạn có thể bỏ qua các khóa học và trực tiếp đến với trình mô phỏng kỳ thi được cung cấp kèm theo kỳ thi.
Kỳ thi có giá $ 375 nhưng có các ưu đãi và giao dịch có sẵn, và nếu bạn tìm kiếm chúng, bạn có thể có được mức giá tốt hơn. Thời gian của kỳ thi là 2 giờ và có giá trị trong 2 năm, không giống như CKA và CKAD có giá trị trong 3 năm.
CKS là một kỳ thi dựa trên thành tích, nơi bạn được cung cấp một trình mô phỏng kỳ thi mà bạn phải tìm ra các vấn đề. Bạn chỉ được phép mở một tab ngoài tab kỳ thi.
Vì kỳ thi này yêu cầu bạn viết rất nhiều lệnh, tôi đã sớm nhận ra rằng tôi sẽ phải dựa vào bí danh để giảm số lần nhấn phím nhằm tiết kiệm thời gian.
Tôi đã sử dụng trình soạn thảo vi trong suốt kỳ thi, vì vậy ở đây tôi sẽ chia sẻ một số mẹo hữu ích cho trình soạn thảo này.
vi ~/.vimrc
---
:set number
:set et
:set sw=2 ts=2 sts=2
---
^: Start of word in line
0: Start of line
$: End of line
w: End of word
GG: End of file
vi ~/.bashrc
---
alias k='kubectl'
alias kg='k get'
alias kd='k describe'
alias kl='k logs'
alias ke='k explain'
alias kr='k replace'
alias kc='k create'
alias kgp='k get po'
alias kgn='k get no'
alias kge='k get ev'
alias kex='k exec -it'
alias kgc='k config get-contexts'
alias ksn='k config set-context --current --namespace'
alias kuc='k config use-context'
alias krun='k run'
export do='--dry-run=client -oyaml'
export force='--grace-period=0 --force'
source <(kubectl completion bash)
source <(kubectl completion bash | sed 's/kubectl/k/g' )
complete -F __start_kubectl k
alias krp='k run test --image=busybox --restart=Never'
alias kuc='k config use-context'
---
Lệnh kubectl get
này cung cấp các tên ngắn gọn hấp dẫn để truy cập tài nguyên và tương tự như pvc
đối với persistentstorageclaim
. Những điều này có thể giúp tiết kiệm rất nhiều thao tác gõ phím và thời gian quý báu trong kỳ thi.
pods
replicasets
deployments
services
namespace
networkpolicy
persistentstorage
persistentstorageclaim
serviceaccounts
Lệnh kubectl run
cung cấp một cờ --restart
cho phép bạn tạo các loại đối tượng Kubernetes khác nhau từ Triển khai đến CronJob.
Đoạn mã dưới đây cho thấy các tùy chọn khác nhau có sẵn cho --restart
cờ.
k run:
--restart=Always #Creates a deployment
--restart=Never #Creates a Pod
--restart=OnFailure #Creates a Job
--restart=OnFailure --schedule="*/1 * * * *" #Creates a CronJob
Đôi khi, việc tạo một thông số kỹ thuật từ một nhóm hiện có và thực hiện các thay đổi đối với nó dễ dàng hơn là tạo một nhóm mới từ đầu. Lệnh kubectl get pod
cung cấp cho chúng ta các cờ cần thiết để xuất ra thông số nhóm ở định dạng chúng ta muốn.
kgp <pod-name> -o wide
# Generating YAML Pod spec
kgp <pod-name> -o yaml
kgp <pod-name> -o yaml > <pod-name>.yaml
# Get a pod's YAML spec without cluster specific information
kgp my-pod -o yaml --export > <pod-name>.yaml
Lệnh kubectl run
cung cấp rất nhiều tùy chọn, chẳng hạn như chỉ định các yêu cầu và giới hạn mà một nhóm phải sử dụng hoặc các lệnh mà một vùng chứa sẽ chạy sau khi được tạo.
# Output YAML for a nginx pod running an echo command
krun nginx --image=nginx --restart=Never --dry-run -o yaml -- /bin/sh -c 'echo Hello World!'
# Output YAML for a busybox pod running a sleep command
krun busybox --image=busybox:1.28 --restart=Never --dry-run -o yaml -- /bin/sh -c 'while true; do echo sleep; sleep 10; done'
# Run a pod with set requests and limits
krun nginx --image=nginx --restart=Never --requests='cpu=100m,memory=512Mi' --limits='cpu=300m,memory=1Gi'
# Delete pod without delay
k delete po busybox --grace-period=0 --force
Nhật ký là nguồn thông tin cơ bản khi nói đến gỡ lỗi một ứng dụng. Lệnh kubectl logs
cung cấp chức năng kiểm tra nhật ký của một nhóm nhất định. Bạn có thể sử dụng các lệnh dưới đây để kiểm tra nhật ký của một nhóm nhất định.
kubectl logs deploy/<podname>
kubectl logs deployment/<podname>
#Follow logs
kubectl logs deploy/<podname> --tail 1 --follow
Ngoài việc chỉ xem nhật ký, chúng tôi cũng có thể xuất nhật ký thành tệp để gỡ lỗi thêm khi chia sẻ cùng một tệp với bất kỳ ai.
kubectl logs <podname> --namespace <ns> > /path/to/file.format
Lệnh kubectl create
cho phép chúng tôi tạo Bản đồ cấu hình và Bí mật từ dòng lệnh. Chúng tôi cũng có thể sử dụng tệp YAML để tạo cùng một tài nguyên và bằng cách sử dụng kubectl apply -f <filename>
, chúng tôi có thể áp dụng các lệnh.
kc cm my-cm --from-literal=APP_ENV=dev
kc cm my-cm --from-file=test.txt
kc cm my-cm --from-env-file=config.env
kc secret generic my-secret --from-literal=APP_SECRET=sdcdcsdcsdcsdc
kc secret generic my-secret --from-file=secret.txt
kc secret generic my-secret --from-env-file=secret.env
Gỡ lỗi là một kỹ năng rất quan trọng khi bạn đang đối mặt với các vấn đề và lỗi trong công việc hàng ngày của chúng tôi và khi giải quyết các vấn đề trong kỳ thi CKS.
Ngoài khả năng xuất nhật ký từ vùng chứa, các kubectl exec
lệnh cho phép bạn đăng nhập vào vùng chứa đang chạy và gỡ lỗi các vấn đề. Khi ở bên trong vùng chứa, bạn cũng có thể sử dụng các tiện ích như nc
và nslookup
để chẩn đoán các sự cố liên quan đến mạng.
# Run busybox container
k run busybox --image=busybox:1.28 --rm --restart=Never -it sh
# Connect to a specific container in a Pod
k exec -it busybox -c busybox2 -- /bin/sh
# adding limits and requests in command
kubectl run nginx --image=nginx --restart=Never --requests='cpu=100m,memory=256Mi' --limits='cpu=200m,memory=512Mi'
# Create a Pod with a service
kubectl run nginx --image=nginx --restart=Never --port=80 --expose
# Check port
nc -z -v -w 2 <service-name> <port-name>
# NSLookup
nslookup <service-name>
nslookup 10-32-0-10.default.pod
Lệnh kubectl rollout
cung cấp khả năng kiểm tra trạng thái của các bản cập nhật và nếu được yêu cầu, quay trở lại phiên bản trước đó.
k set image deploy/nginx nginx=nginx:1.17.0 --record
k rollout status deploy/nginx
k rollout history deploy/nginx
# Rollback to previous version
k rollout undo deploy/nginx
# Rollback to revision number
k rollout undo deploy/nginx --to-revision=2
k rollout pause deploy/nginx
k rollout resume deploy/nginx
k rollout restart deploy/nginx
kubectl run nginx-deploy --image=nginx:1.16 --replias=1 --record
Lệnh kubectl scale
cung cấp chức năng mở rộng hoặc thu nhỏ các nhóm trong một triển khai nhất định.
Sử dụng kubectl autoscale
lệnh, chúng tôi có thể xác định số lượng nhóm tối thiểu sẽ chạy cho một triển khai nhất định và số lượng nhóm tối đa mà việc triển khai có thể mở rộng cùng với các tiêu chí mở rộng như tỷ lệ phần trăm CPU.
k scale deploy/nginx --replicas=6
k autoscale deploy/nginx --min=3 --max=9 --cpu-percent=80
Trong một cụm Kubernetes, tất cả các nhóm có thể giao tiếp với tất cả các nhóm theo mặc định, đây có thể là một vấn đề bảo mật trong một số triển khai.
Để giải quyết vấn đề này, Kubernetes đã giới thiệu Chính sách mạng để cho phép hoặc từ chối lưu lượng truy cập đến và đi từ các nhóm dựa trên các nhãn nhóm là một phần của thông số nhóm.
Ví dụ dưới đây từ chối cả lưu lượng vào và ra cho các nhóm đang chạy trong tất cả các không gian tên.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
- Ingress
Ví dụ dưới đây từ chối cả lưu lượng vào và ra cho các nhóm đang chạy trong tất cả các không gian tên. Nhưng nó cho phép truy cập vào các dịch vụ phân giải DNS chạy trên cổng 53.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
- Ingress
egress:
- to:
ports:
- port: 53
protocol: TCP
- port: 53
protocol: UDP
Ví dụ dưới đây từ chối quyền truy cập vào Máy chủ siêu dữ liệu đang chạy trên địa chỉ IP 169.256.169.256
trong Phiên bản AWS EC2.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name:cloud-metadata-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.256.169.256/32
Ví dụ dưới đây cho phép Truy cập vào máy chủ siêu dữ liệu đang chạy trên địa chỉ IP 169.256.169.256
trong Phiên bản AWS EC2.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cloud-metadata-accessor
namespace: default
spec:
podSelector:
matchLabels:
role: metadata-accessor
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 169.256.169.256/32
Kubesec là một công cụ Phân tích tĩnh để phân tích các tệp YAML để tìm ra các vấn đề với tệp.
kubesec scan pod.yaml
# Using online kubesec API
curl -sSX POST --data-binary @pod.yaml https://v2.kubesec.io/scan
# Running the API locally
kubesec http 8080 &
kubesec scan pod.yaml -o pod_report.json -o json
Trivvy là một công cụ Quét lỗ hổng bảo mật để quét các hình ảnh vùng chứa để tìm các vấn đề bảo mật.
trivy image nginx:1.18.0
trivy image --severity CRITICAL nginx:1.18.0
trivy image --severity CRITICAL, HIGH nginx:1.18.0
trivy image --ignore-unfixed nginx:1.18.0
# Scanning image tarball
docker save nginx:1.18.0 > nginx.tar
trivy image --input archive.tar
# Scan and output results to file
trivy image --output python_alpine.txt python:3.10.0a4-alpine
trivy image --severity HIGH --output /root/python.txt python:3.10.0a4-alpine
# Scan image tarball
trivy image --input alpine.tar --format json --output /root/alpine.json
Tính năng này systemctl
cho thấy các khả năng khởi động, dừng, bật, tắt và liệt kê các dịch vụ đang chạy trên Máy ảo Linux.
Liệt kê các dịch vụ:
systemctl list-units --type service
Dừng phục vụ:
systemctl stop apache2
Tắt dịch vụ:
systemctl disable apache2
Xóa dịch vụ:
apt remove apache2
Kubernetes đã giới thiệu tính năng RuntimeClass trong phiên bản v1.12
để chọn cấu hình thời gian chạy vùng chứa. Cấu hình thời gian chạy của vùng chứa được sử dụng để chạy các vùng chứa bên dưới của một nhóm.
Hầu hết các cụm Kubernetes sử dụng dockershim
làm lớp Thời gian chạy cho các vùng chứa đang chạy, nhưng bạn có thể sử dụng Thời gian chạy vùng chứa khác nhau.
Phiên dockershim
bản Kubernetes đã không còn được dùng nữa v1.20
và sẽ bị xóa trong v1.24
.
Cách tạo một Lớp thời gian chạy:
apiversion: node.k8s.io/v1beta1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc
Cách sử dụng một lớp thời gian chạy cho bất kỳ nhóm nào đã cho:
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx
name: nginx
spec:
runtimeClassName: gvisor
containers:
- name: nginx
image: nginx
Trong các chính phủ,
Các lệnh kiểm soát truy cập dựa trên vai trò (RBAC) cung cấp một phương pháp điều chỉnh quyền truy cập vào tài nguyên Kubernetes dựa trên vai trò của từng người dùng hoặc tài khoản dịch vụ. ( Nguồn )
Đây là cách tạo một vai trò:
kubectl create role developer --resource=pods --verb=create,list,get,update,delete --namespace=development
Cách tạo ràng buộc vai trò:
kubectl create rolebinding developer-role-binding --role=developer --user=faizan --namespace=development
Cách xác thực:
kubectl auth can-i update pods --namespace=development --as=faizan
Cách tạo vai trò cụm:
kubectl create clusterrole pvviewer-role --resource=persistentvolumes --verb=list
Và cách tạo liên kết Clusterrole Binding với tài khoản dịch vụ:
kubectl create clusterrolebinding pvviewer-role-binding --clusterrole=pvviewer-role --serviceaccount=default:pvviewer
Bạn sử dụng kubectl drain
lệnh để xóa tất cả khối lượng công việc đang chạy (nhóm) khỏi một Node nhất định.
Bạn sử dụng kubectl cordon
lệnh để buộc một nút để đánh dấu nó là có thể lập lịch.
Bạn sử dụng kubectl uncordon
lệnh để đặt nút là có thể lập lịch, nghĩa là Trình quản lý bộ điều khiển có thể lập lịch các nhóm mới cho nút đã cho.
Cách thoát một nút của tất cả các nhóm:
kubectl drain node-1
Làm thế nào để rút một nút và bỏ qua daemonsets:
kubectl drain node01 --ignore-daemonsets
Làm thế nào để buộc thoát nước:
kubectl drain node02 --ignore-daemonsets --force
Cách đánh dấu một nút là không thể lập lịch để không có nhóm mới nào có thể được lập lịch trên nút này:
kubectl cordon node-1
Đánh dấu một nút có thể lập lịch
kubectl uncordon node-1
Lệnh Kubernetes kubectl get
cung cấp cho người dùng cờ đầu ra -o
hoặc --output
giúp chúng tôi định dạng đầu ra ở dạng JSON, yaml, wide hoặc tùy chỉnh-cột.
Cách xuất nội dung của tất cả các nhóm ở dạng Đối tượng JSON:
kubectl get pods -o json
JSONPath xuất ra một khóa cụ thể từ Đối tượng JSON:
kubectl get pods -o=jsonpath='{@}'
kubectl get pods -o=jsonpath='{.items[0]}'
Được sử dụng khi chúng ta có nhiều đối tượng , .items[*]
ví dụ như nhiều vùng chứa với cấu hình nhóm:
# For list of items use .items[*]
k get pods -o 'jsonpath={.items[*].metadata.labels.version}'
# For single item
k get po busybox -o jsonpath='{.metadata}'
k get po busybox -o jsonpath="{['.metadata.name', '.metadata.namespace']}{'\n'}"
Lệnh trả về IP nội bộ của một Node sử dụng JSONPath:
kubectl get nodes -o=jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'
Lệnh kiểm tra sự bình đẳng trên một khóa cụ thể:
kubectl get pod api-stag-765797cf-lrd8q -o=jsonpath='{.spec.volumes[?(@.name=="api-data")].persistentVolumeClaim.claimName}'
kubectl get pod -o=jsonpath='{.items[*].spec.tolerations[?(@.effect=="NoSchedule")].key}'
Các Cột Tùy chỉnh rất hữu ích để xuất ra các trường cụ thể:
kubectl get pods -o='custom-columns=PODS:.metadata.name,Images:.spec.containers[*].image'
Kỳ thi CKS bao gồm các chủ đề liên quan đến bảo mật trong hệ sinh thái Kubernetes. Bảo mật Kubernetes là một chủ đề rộng lớn cần đề cập trong một bài báo, vì vậy bài viết này bao gồm một số chủ đề được đề cập trong kỳ thi.
Trong khi thiết kế hình ảnh vùng chứa để chạy mã của bạn, hãy đặc biệt chú ý đến các biện pháp bảo mật và tăng cường để ngăn chặn các vụ hack và tấn công leo thang đặc quyền. Hãy ghi nhớ những điểm dưới đây khi xây dựng hình ảnh vùng chứa:
alpine:3.13
.USER <username>
để chặn quyền truy cập root.securityContext
sử dụng readOnlyRootFilesystem: true
RUN rm -rf /bin/*
Hướng dẫn RUN
và COPY
tạo ADD
các lớp vùng chứa. Các hướng dẫn khác tạo hình ảnh trung gian tạm thời và không làm tăng kích thước của bản dựng. Các hướng dẫn tạo lớp sẽ bổ sung vào kích thước của hình ảnh kết quả.
Một Dockerfile điển hình trông giống như một tệp được đưa ra bên dưới. Nó thêm một lớp duy nhất bằng cách sử dụng RUN
hướng dẫn.
FROM ubuntu
RUN apt-get update && apt-get install -y golang-go
CMD ["sh"]
Multi-Stage xây dựng đòn bẩy nhiều FROM
câu lệnh trong Dockerfile. Hướng FROM
dẫn đánh dấu một giai đoạn mới trong quá trình xây dựng. Nó kết hợp nhiều FROM
câu lệnh cho phép tận dụng từ bản dựng trước để sao chép có chọn lọc các tệp nhị phân sang giai đoạn xây dựng mới loại bỏ các mã nhị phân không cần thiết. Hình ảnh Docker kết quả có kích thước nhỏ hơn đáng kể với bề mặt tấn công giảm đáng kể.
FROM ubuntu:20.04 AS build
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y golang-go
COPY app.go .
RUN CGO_ENABLED=0 go build app.go
FROM alpine:3.13
RUN chmod a-w /etc
RUN addgroup -S appgroup && adduser -S appuser -G appgroup -h /home/appuser
RUN rm -rf /bin/*
COPY --from=build /app /home/appuser/
USER appuser
CMD ["/home/appuser/app"]
Các tệp Kiểm soát Truy cập chứa thông tin nhạy cảm về người dùng / nhóm trong Hệ điều hành Linux.
#Stores information about the UID/GID, user shell, and home directory for a user
/etc/passwd
#Stores the user password in a hashed format
/etc/shadow
#Stores information about the group a user belongs
/etc/group
#Stored information about the Sudoers present in the system
/etc/sudoers
Vô hiệu hóa tài khoản người dùng giúp đảm bảo quyền truy cập vào Node bằng cách tắt đăng nhập vào một tài khoản người dùng nhất định.
usermod -s /bin/nologin <username>
Việc vô hiệu hóa root
tài khoản người dùng có ý nghĩa đặc biệt, vì tài khoản gốc có tất cả các khả năng.
usermod -s /bin/nologin root
Đây là cách thêm người dùng với thư mục chính và trình bao:
adduser --home /opt/faizanbashir --shell /bin/bash --uid 2328 --ingroup admin faizanbashir
useradd -d /opt/faizanbashir -s /bin/bash -G admin -u 2328 faizanbashir
Cách xóa tài khoản người dùng:
userdel <username>
Cách xóa một nhóm:
groupdel <groupname>
Cách thêm người dùng vào nhóm:
adduser <username> <groupname>
Cách xóa người dùng khỏi nhóm:
#deluser faizanbashir admin
deluser <username> <groupname>
Cách đặt mật khẩu cho người dùng:
passwd <username>
Cách nâng cao người dùng lên thành sudoer:
vim /etc/sudoers
>>>
faizanbashir ALL=(ALL:ALL) ALL
Cách bật sudo không cần mật khẩu:
vim /etc/sudoers
>>>
faizanbashir ALL=(ALL) NOPASSWD:ALL
visudo
usermod -aG sudo faizanbashir
usermod faizanbashir -G admin
Cấu hình được đưa ra trong /etc/ssh/sshd_config
có thể được tận dụng để bảo mật quyền truy cập SSH vào các nút Linux. Đặt PermitRootLogin
để no
tắt đăng nhập gốc trên một nút.
Để thực thi việc sử dụng khóa để đăng nhập và vô hiệu hóa đăng nhập bằng mật khẩu vào các nút, bạn có thể đặt PasswordAuthentication
thành no
.
vim /etc/ssh/sshd_config
>>
PermitRootLogin no
PasswordAuthentication no
<<
# Restart SSHD Service
systemctl restart sshd
Cách đặt không có đăng nhập cho người dùng root:
usermod -s /bin/nologin root
SSH Sao chép khóa người dùng / SSH không mật khẩu:
ssh-copy-id -i ~/.ssh/id_rsa.pub faizanbashir@node01
ssh faizanbashir@node01
Đây là cách bạn có thể liệt kê tất cả các dịch vụ đang chạy trên máy Ubuntu:
systemctl list-units --type service
systemctl list-units --type service --state running
Cách dừng, tắt và xóa một dịch vụ:
systemctl stop apache2
systemctl disable apache2
apt remove apache2
Trong Linux, mô-đun Kernel là những đoạn mã có thể được tải và dỡ xuống kernel theo yêu cầu. Chúng mở rộng chức năng của hạt nhân mà không cần khởi động lại hệ thống. Một mô-đun có thể được cấu hình dưới dạng tích hợp sẵn hoặc có thể tải được.
Cách liệt kê tất cả các Mô-đun nhân:
lsmod
Cách tải thủ công mô-đun vào Kernel:
modprobe pcspkr
Cách đưa vào danh sách đen một mô-đun: (Tham khảo: CIS Benchmarks -> 3.4 Giao thức mạng không phổ biến)
cat /etc/modprobe.d/blacklist.conf
>>>
blacklist sctp
blacklist dccp
# Shutdown for changes to take effect
shutdown -r now
# Verify
lsmod | grep dccp
Cách kiểm tra các cổng đang mở:
netstat -an | grep -w LISTEN
netstat -natp | grep 9090
nc -zv <hostname|IP> 22
nc -zv <hostname|IP> 10-22
ufw deny 8080
Cách kiểm tra việc sử dụng cổng:
/etc/services | grep -w 53
Đây là tài liệu tham khảo cho danh sách các cổng đang mở .
systemctl status ssh
cat /etc/services | grep ssh
netstat -an | grep 22 | grep -w LISTEN
Tường lửa không phức tạp (UFW) là một công cụ để quản lý các quy tắc tường lửa trong Arch Linux, Debian hoặc Ubuntu. UFW cho phép bạn cho phép và chặn lưu lượng truy cập trên một cổng nhất định và từ một nguồn nhất định.
Đây là cách cài đặt Tường lửa UFW:
apt-get update
apt-get install ufw
systemctl enable ufw
systemctl start ufw
ufw status
ufw status numbered
Cách cho phép tất cả các kết nối đi và đến:
ufw default allow outgoing
ufw default allow incoming
Cách cho phép các quy tắc:
ufw allow 22
ufw allow 1000:2000/tcp
ufw allow from 172.16.238.5 to any port 22 proto tcp
ufw allow from 172.16.238.5 to any port 80 proto tcp
ufw allow from 172.16.100.0/28 to any port 80 proto tcp
Cách từ chối các quy tắc:
ufw deny 8080
Cách bật và kích hoạt Tường lửa:
ufw enable
Cách xóa các quy tắc:
ufw delete deny 8080
ufw delete <rule-line>
Cách đặt lại quy tắc:
ufw reset
Linux Syscalls được sử dụng để thực hiện các yêu cầu từ không gian người dùng vào nhân Linux. Ví dụ: trong khi tạo tệp, không gian người dùng yêu cầu Nhân Linux tạo tệp.
Kernel Space có những thứ sau:
Đây là cách bạn có thể theo dõi các cuộc gọi tổng hợp bằng cách sử dụng strace:
which strace
strace touch /tmp/error.log
Cách lấy PID của một dịch vụ:
pidof sshd
strace -p <pid>
Cách liệt kê tất cả các cuộc gọi tổng hợp được thực hiện trong một hoạt động:
strace -c touch /tmp/error.log
Cách hợp nhất các cuộc gọi hệ thống danh sách: (Đếm và tóm tắt)
strace -cw ls /
Cách theo dõi PID và hợp nhất:
strace -p 3502 -f -cw
AquaSec Tracee được tạo ra bởi Aqua Security, sử dụng eBPF để theo dõi các sự kiện trong vùng chứa. Tracee sử dụng eBPF (Bộ lọc gói Berkeley mở rộng) trong thời gian chạy trực tiếp trong không gian hạt nhân mà không can thiệp vào nguồn hạt nhân hoặc tải bất kỳ mô-đun hạt nhân nào.
/tmp/tracee
--privileged
khả năng:/tmp/tracee
-> Không gian làm việc mặc định/lib/modules
-> Tiêu đề hạt nhân/usr/src
-> Tiêu đề hạt nhânLàm thế nào để Tracee thú vị trong vùng chứa Docker:
docker run --name tracee --rm --privileged --pid=host \
-v /lib/modules/:/lib/modules/:ro -v /usr/src/:/usr/src/ro \
-v /tmp/tracee:/tmp/tracee aquasec/tracee:0.4.0 --trace comm=ls
# List syscalls made by all the new process on the host
docker run --name tracee --rm --privileged --pid=host \
-v /lib/modules/:/lib/modules/:ro -v /usr/src/:/usr/src/ro \
-v /tmp/tracee:/tmp/tracee aquasec/tracee:0.4.0 --trace pid=new
# List syscalls made from any new container
docker run --name tracee --rm --privileged --pid=host \
-v /lib/modules/:/lib/modules/:ro -v /usr/src/:/usr/src/ro \
-v /tmp/tracee:/tmp/tracee aquasec/tracee:0.4.0 --trace container=new
SECCOMP - Chế độ Điện toán Bảo mật - là một tính năng cấp Kernel của Linux mà bạn có thể sử dụng cho các ứng dụng hộp cát để chỉ sử dụng các cuộc gọi hệ thống mà chúng cần.
Cách kiểm tra hỗ trợ cho seccomp:
grep -i seccomp /boot/config-$(uname -r)
Cách kiểm tra để thay đổi thời gian hệ thống:
docker run -it --rm docker/whalesay /bin/sh
# date -s '19 APR 2013 22:00:00'
ps -ef
Cách kiểm tra trạng thái seccomp cho bất kỳ PID nào:
grep -i seccomp /proc/1/status
Chế độ Seccomp:
Cấu hình sau được sử dụng để đưa vào danh sách trắng các cuộc gọi tổng hợp. Hồ sơ danh sách trắng được bảo mật nhưng các cuộc gọi tổng hợp phải được bật có chọn lọc vì nó chặn tất cả các cuộc gọi tổng hợp theo mặc định.
{
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": [
"SCMP_ARCH_X86_64",
"SCMP_ARCH_X86",
"SCMP_ARCH_X32"
],
"syscalls": [
{
"names": [
"<syscall-1>",
"<syscall-2>",
"<syscall-3>"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
Cấu hình sau được sử dụng để danh sách đen các cuộc gọi tổng hợp. Hồ sơ danh sách đen có bề mặt tấn công lớn hơn danh sách trắng.
{
"defaultAction": "SCMP_ACT_ALLOW",
"architectures": [
"SCMP_ARCH_X86_64",
"SCMP_ARCH_X86",
"SCMP_ARCH_X32"
],
"syscalls": [
{
"names": [
"<syscall-1>",
"<syscall-2>",
"<syscall-3>"
],
"action": "SCMP_ACT_ERRNO"
}
]
}
Cấu hình seccomp Docker chặn 60 trong số hơn 300 cuộc gọi tổng hợp trên kiến trúc x86.
Cách sử dụng hồ sơ seccomp với Docker:
docker run -it --rm --security-opt seccomp=/root/custom.json docker/whalesay /bin/sh
Cách cho phép tất cả các cuộc gọi tổng hợp với vùng chứa:
docker run -it --rm --security-opt seccomp=unconfined docker/whalesay /bin/sh
# Verify
grep -i seccomp /proc/1/status
# Output should be:
Seccomp: 0
Cách sử dụng vùng chứa Docker để nhận thông tin liên quan đến thời gian chạy của vùng chứa:
docker run r.j3ss.co/amicontained amicontained
Chế độ điện toán an toàn (SECCOMP) là một tính năng của hạt nhân Linux. Bạn có thể sử dụng nó để hạn chế các tác vụ có sẵn trong vùng chứa. Tài liệu Seccomp
Cách chạy không kiểm soát trong Kubernetes:
kubectl run amicontained --image r.j3ss.co/amicontained amicontained -- amicontained
Kể từ phiên bản v1.20
Kubernetes không triển khai seccomp theo mặc định.
Cấu hình docker Seccomp 'RuntimeDefault' trong Kubernetes:
apiVersion: v1
kind: Pod
metadata:
labels:
run: amicontained
name: amicontained
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- args:
- amicontained
image: r.j3ss.co/amicontained
name: amicontained
securityContext:
allowPrivilegeEscalation: false
Vị trí seccomp mặc định trong kubelet
/var/lib/kubelet/seccomp
Cách tạo hồ sơ seccomp trong nút:
mkdir -p /var/lib/kubelet/seccomp/profiles
# Add a profile for audit
vim /var/lib/kubelet/seccomp/profiles/audit.json
>>>
{
defaultAction: "SCMP_ACT_LOG"
}
# Add a profile for violations (Blocks all syscalls by default, will let nothing run)
vim /var/lib/kubelet/seccomp/profiles/violation.json
>>>
{
defaultAction: "SCMP_ACT_ERRNO"
}
Hồ sơ seccomp cục bộ - tệp này phải tồn tại cục bộ trên một nút để có thể hoạt động:
...
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/audit.json
...
Cấu hình trên sẽ cho phép các cuộc gọi tổng hợp được lưu vào một tệp.
grep syscall /var/log/syslog
Cách ánh xạ số syscall với tên syscall:
grep -w 35 /usr/include/asm/unistd_64.h
# OR
grep -w 35 /usr/include/asm-generic/unistd.h
AppArmor là một mô-đun bảo mật Linux được sử dụng để giới hạn một chương trình trong một nhóm tài nguyên giới hạn.
Cách cài đặt AppArmor utils:
apt-get install apparmor-utils
Cách kiểm tra xem AppArmor có đang chạy và được kích hoạt hay không:
systemctl status apparmor
cat /sys/module/apparmor/parameters/enabled
Y
Các cấu hình AppArmor được lưu trữ tại:
cat /etc/apparmor.d/root.add_data.sh
Cách liệt kê hồ sơ AppArmor:
cat /sys/kernel/security/apparmor/profiles
Cách từ chối tất cả các cấu hình ghi tệp:
profile apparmor-deny-write flags=(attach_disconnected) {
file,
# Deny all file writes.
deny /** w,
}
Cách từ chối ghi vào /proc
tệp:
profile apparmor-deny-proc-write flags=(attach_disconnected) {
file,
# Deny all file writes.
deny /proc/* w,
}
Cách từ chối remount root FS:
profile apparmor-deny-remount-root flags=(attach_disconnected) {
# Deny all file writes.
deny mount options=(ro, remount) -> /,
}
Cách kiểm tra trạng thái hồ sơ:
aa-status
Chế độ tải hồ sơ
Enforce
, giám sát và thực thi các quy tắcComplain
, sẽ không thực thi các quy tắc nhưng ghi lại chúng dưới dạng các sự kiệnUnconfined
, sẽ không thực thi hoặc ghi lại các sự kiệnCách kiểm tra xem hồ sơ có hợp lệ không:
apparmor_parser /etc/apparmor.d/root.add_data.sh
Cách tắt cấu hình:
apparmor_parser -R /etc/apparmor.d/root.add_data.sh
ln -s /etc/apparmor.d/root.add_data.sh /etc/apparmor.d/disable/
Cách tạo hồ sơ và trả lời một loạt câu hỏi sau:
aa-genprof /root/add_data.sh
Cách tạo cấu hình cho một lệnh:
aa-genprof curl
Cách tắt cấu hình khỏi nhật ký:
aa-logprof
Để sử dụng AppArmor với Kubernetes, bạn phải đáp ứng các điều kiện tiên quyết sau:
1.4
Cách sử dụng mẫu trong Kubernetes:
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-sleeper
annotations:
container.apparmor.security.beta.kubernetes.io/<container-name>: localhost/<profile-name>
spec:
containers:
- name: ubuntu-sleeper
image: ubuntu
command: ["sh", "-c", "echo 'Sleeping for an hour!' && sleep 1h"]
Lưu ý : Vùng chứa phải chạy trong nút chứa cấu hình AppArmor.
Tính năng khả năng của Linux chia nhỏ các đặc quyền có sẵn cho các quy trình chạy khi root
người dùng thành các nhóm đặc quyền nhỏ hơn. Bằng cách này, một tiến trình đang chạy với root
đặc quyền có thể bị giới hạn để chỉ nhận được những quyền tối thiểu mà nó cần để thực hiện hoạt động của nó.
Docker hỗ trợ các khả năng của Linux như một phần của lệnh chạy Docker: with --cap-add
và --cap-drop
. Theo mặc định, một vùng chứa được khởi động với một số khả năng được cho phép theo mặc định và có thể bị loại bỏ. Các quyền khác có thể được thêm theo cách thủ công.
Cả hai --cap-add
và --cap-drop
hỗ trợ giá trị TẤT CẢ, để cho phép hoặc loại bỏ tất cả các khả năng. Theo mặc định, vùng chứa Docker chạy với 14 khả năng.
CAP_CHOWN
CAP_SYS_TIME
CAP_SYS_BOOT
CAP_NET_ADMIN
Tham khảo tài liệu này để biết danh sách đầy đủ các Khả năng của Linux .
Cách kiểm tra những khả năng mà lệnh cần:
getcap /usr/bin/ping
Cách nhận các khả năng của quy trình:
getpcaps <pid>
Cách thêm khả năng bảo mật:
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-sleeper
spec:
containers:
- name: ubuntu-sleeper
image: ubuntu
command: ["sleep", "1000"]
securityContext:
capabilities:
add: ["SYS_TIME"]
drop: ["CHOWN"]
CKS được đánh giá là một kỳ thi khá khó. Nhưng dựa trên kinh nghiệm của tôi, tôi nghĩ rằng, với thực hành đủ tốt và nếu bạn hiểu các khái niệm mà kỳ thi bao gồm, nó sẽ có thể quản lý được trong vòng hai giờ.
Bạn chắc chắn cần hiểu các khái niệm cơ bản của Kubernetes. Và vì điều kiện tiên quyết đối với CKS là phải vượt qua kỳ thi CKA, bạn nên hiểu rõ về Kubernetes và cách nó hoạt động trước khi thử CKS.
Ngoài ra, để vượt qua CKS, bạn cần hiểu các mối đe dọa và tác động bảo mật được giới thiệu bởi điều phối vùng chứa.
Sự ra đời của kỳ thi CKS là một dấu hiệu cho thấy không nên coi nhẹ an ninh của các thùng chứa. Các cơ chế bảo mật phải luôn có sẵn để ngăn chặn các cuộc tấn công vào các cụm Kubernetes.
Vụ hack tiền điện tử Tesla nhờ vào bảng điều khiển Kubernetes không được bảo vệ, làm sáng tỏ những rủi ro liên quan đến Kubernetes hoặc bất kỳ công cụ điều phối vùng chứa nào khác. Hackerone có một trang tiền thưởng Kubernetes liệt kê các kho mã nguồn được sử dụng trong một cụm Kubernetes tiêu chuẩn.
Thực hành là chìa khóa để bẻ khóa kỳ thi, cá nhân tôi thấy rằng các trình mô phỏng kỳ thi của KodeKloud và Killer.sh vô cùng hữu ích đối với tôi.
Tôi không có nhiều thời gian để chuẩn bị cho kỳ thi CKS như tôi đã có cho kỳ thi CKA, nhưng tôi đang làm việc trên Kubernetes trong công việc hàng ngày của mình nên tôi thực sự cảm thấy thoải mái với nó.
Thực hành là chìa khóa thành công. Chúc bạn may mắn với kỳ thi!
Nguồn: https://www.freecodecamp.org/news/how-to-pass-the-certified-kubernetes-security-specialist-exam/
1657107416
The era of mobile app development has completely changed the scenario for businesses in regions like Abu Dhabi. Restaurants and food delivery businesses are experiencing huge benefits via smart business applications. The invention and development of the food ordering app have helped all-scale businesses reach new customers and boost sales and profit.
As a result, many business owners are searching for the best restaurant mobile app development company in Abu Dhabi. If you are also searching for the same, this article is helpful for you. It will let you know the step-by-step process to hire the right team of restaurant mobile app developers.
Searching for the top mobile app development company in Abu Dhabi? Don't know the best way to search for professionals? Don't panic! Here is the step-by-step process to hire the best professionals.
#Step 1 – Know the Company's Culture
Knowing the organization's culture is very crucial before finalizing a food ordering app development company in Abu Dhabi. An organization's personality is shaped by its common beliefs, goals, practices, or company culture. So, digging into the company culture reveals the core beliefs of the organization, its objectives, and its development team.
Now, you might be wondering, how will you identify the company's culture? Well, you can take reference from the following sources –
#Step 2 - Refer to Clients' Reviews
Another best way to choose the On-demand app development firm for your restaurant business is to refer to the clients' reviews. Reviews are frequently available on the organization's website with a tag of "Reviews" or "Testimonials." It's important to read the reviews as they will help you determine how happy customers are with the company's app development process.
You can also assess a company's abilities through reviews and customer testimonials. They can let you know if the mobile app developers create a valuable app or not.
#Step 3 – Analyze the App Development Process
Regardless of the company's size or scope, adhering to the restaurant delivery app development process will ensure the success of your business application. Knowing the processes an app developer follows in designing and producing a top-notch app will help you know the working process. Organizations follow different app development approaches, so getting well-versed in the process is essential before finalizing any mobile app development company.
#Step 4 – Consider Previous Experience
Besides considering other factors, considering the previous experience of the developers is a must. You can obtain a broad sense of the developer's capacity to assist you in creating a unique mobile application for a restaurant business.
You can also find out if the developers' have contributed to the creation of other successful applications or not. It will help you know the working capacity of a particular developer or organization. Prior experience is essential to evaluating their work. For instance, whether they haven't previously produced an app similar to yours or not.
#Step 5 – Check for Their Technical Support
As you expect a working and successful restaurant mobile app for your business, checking on this factor is a must. A well-established organization is nothing without a good technical support team. So, ensure whatever restaurant mobile app development company you choose they must be well-equipped with a team of dedicated developers, designers, and testers.
Strong tech support from your mobile app developers will help you identify new bugs and fix them bugs on time. All this will ensure the application's success.
#Step 6 – Analyze Design Standards
Besides focusing on an organization's development, testing, and technical support, you should check the design standards. An appealing design is crucial in attracting new users and keeping the existing ones stick to your services. So, spend some time analyzing the design standards of an organization. Now, you might be wondering, how will you do it? Simple! By looking at the organization's portfolio.
Whether hiring an iPhone app development company or any other, these steps apply to all. So, don't miss these steps.
#Step 7 – Know Their Location
Finally, the last yet very crucial factor that will not only help you finalize the right person for your restaurant mobile app development but will also decide the mobile app development cost. So, you have to choose the location of the developers wisely, as it is a crucial factor in defining the cost.
Summing Up!!!
Restaurant mobile applications have taken the food industry to heights none have ever considered. As a result, the demand for restaurant mobile app development companies has risen greatly, which is why businesses find it difficult to finalize the right person. But, we hope that after referring to this article, it will now be easier to hire dedicated developers under the desired budget. So, begin the hiring process now and get a well-craft food ordering app in hand.
1669003576
In this Python article, let's learn about Mutable and Immutable in Python.
Mutable is a fancy way of saying that the internal state of the object is changed/mutated. So, the simplest definition is: An object whose internal state can be changed is mutable. On the other hand, immutable doesn’t allow any change in the object once it has been created.
Both of these states are integral to Python data structure. If you want to become more knowledgeable in the entire Python Data Structure, take this free course which covers multiple data structures in Python including tuple data structure which is immutable. You will also receive a certificate on completion which is sure to add value to your portfolio.
Mutable is when something is changeable or has the ability to change. In Python, ‘mutable’ is the ability of objects to change their values. These are often the objects that store a collection of data.
Immutable is the when no change is possible over time. In Python, if the value of an object cannot be changed over time, then it is known as immutable. Once created, the value of these objects is permanent.
Objects of built-in type that are mutable are:
Objects of built-in type that are immutable are:
Object mutability is one of the characteristics that makes Python a dynamically typed language. Though Mutable and Immutable in Python is a very basic concept, it can at times be a little confusing due to the intransitive nature of immutability.
In Python, everything is treated as an object. Every object has these three attributes:
While ID and Type cannot be changed once it’s created, values can be changed for Mutable objects.
Check out this free python certificate course to get started with Python.
I believe, rather than diving deep into the theory aspects of mutable and immutable in Python, a simple code would be the best way to depict what it means in Python. Hence, let us discuss the below code step-by-step:
#Creating a list which contains name of Indian cities
cities = [‘Delhi’, ‘Mumbai’, ‘Kolkata’]
# Printing the elements from the list cities, separated by a comma & space
for city in cities:
print(city, end=’, ’)
Output [1]: Delhi, Mumbai, Kolkata
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(cities)))
Output [2]: 0x1691d7de8c8
#Adding a new city to the list cities
cities.append(‘Chennai’)
#Printing the elements from the list cities, separated by a comma & space
for city in cities:
print(city, end=’, ’)
Output [3]: Delhi, Mumbai, Kolkata, Chennai
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(cities)))
Output [4]: 0x1691d7de8c8
The above example shows us that we were able to change the internal state of the object ‘cities’ by adding one more city ‘Chennai’ to it, yet, the memory address of the object did not change. This confirms that we did not create a new object, rather, the same object was changed or mutated. Hence, we can say that the object which is a type of list with reference variable name ‘cities’ is a MUTABLE OBJECT.
Let us now discuss the term IMMUTABLE. Considering that we understood what mutable stands for, it is obvious that the definition of immutable will have ‘NOT’ included in it. Here is the simplest definition of immutable– An object whose internal state can NOT be changed is IMMUTABLE.
Again, if you try and concentrate on different error messages, you have encountered, thrown by the respective IDE; you use you would be able to identify the immutable objects in Python. For instance, consider the below code & associated error message with it, while trying to change the value of a Tuple at index 0.
#Creating a Tuple with variable name ‘foo’
foo = (1, 2)
#Changing the index[0] value from 1 to 3
foo[0] = 3
TypeError: 'tuple' object does not support item assignment
Once again, a simple code would be the best way to depict what immutable stands for. Hence, let us discuss the below code step-by-step:
#Creating a Tuple which contains English name of weekdays
weekdays = ‘Sunday’, ‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’
# Printing the elements of tuple weekdays
print(weekdays)
Output [1]: (‘Sunday’, ‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’)
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(weekdays)))
Output [2]: 0x1691cc35090
#tuples are immutable, so you cannot add new elements, hence, using merge of tuples with the # + operator to add a new imaginary day in the tuple ‘weekdays’
weekdays += ‘Pythonday’,
#Printing the elements of tuple weekdays
print(weekdays)
Output [3]: (‘Sunday’, ‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’, ‘Pythonday’)
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(weekdays)))
Output [4]: 0x1691cc8ad68
This above example shows that we were able to use the same variable name that is referencing an object which is a type of tuple with seven elements in it. However, the ID or the memory location of the old & new tuple is not the same. We were not able to change the internal state of the object ‘weekdays’. The Python program manager created a new object in the memory address and the variable name ‘weekdays’ started referencing the new object with eight elements in it. Hence, we can say that the object which is a type of tuple with reference variable name ‘weekdays’ is an IMMUTABLE OBJECT.
Also Read: Understanding the Exploratory Data Analysis (EDA) in Python
Where can you use mutable and immutable objects:
Mutable objects can be used where you want to allow for any updates. For example, you have a list of employee names in your organizations, and that needs to be updated every time a new member is hired. You can create a mutable list, and it can be updated easily.
Immutability offers a lot of useful applications to different sensitive tasks we do in a network centred environment where we allow for parallel processing. By creating immutable objects, you seal the values and ensure that no threads can invoke overwrite/update to your data. This is also useful in situations where you would like to write a piece of code that cannot be modified. For example, a debug code that attempts to find the value of an immutable object.
Watch outs: Non transitive nature of Immutability:
OK! Now we do understand what mutable & immutable objects in Python are. Let’s go ahead and discuss the combination of these two and explore the possibilities. Let’s discuss, as to how will it behave if you have an immutable object which contains the mutable object(s)? Or vice versa? Let us again use a code to understand this behaviour–
#creating a tuple (immutable object) which contains 2 lists(mutable) as it’s elements
#The elements (lists) contains the name, age & gender
person = (['Ayaan', 5, 'Male'], ['Aaradhya', 8, 'Female'])
#printing the tuple
print(person)
Output [1]: (['Ayaan', 5, 'Male'], ['Aaradhya', 8, 'Female'])
#printing the location of the object created in the memory address in hexadecimal format
print(hex(id(person)))
Output [2]: 0x1691ef47f88
#Changing the age for the 1st element. Selecting 1st element of tuple by using indexing [0] then 2nd element of the list by using indexing [1] and assigning a new value for age as 4
person[0][1] = 4
#printing the updated tuple
print(person)
Output [3]: (['Ayaan', 4, 'Male'], ['Aaradhya', 8, 'Female'])
#printing the location of the object created in the memory address in hexadecimal format
print(hex(id(person)))
Output [4]: 0x1691ef47f88
In the above code, you can see that the object ‘person’ is immutable since it is a type of tuple. However, it has two lists as it’s elements, and we can change the state of lists (lists being mutable). So, here we did not change the object reference inside the Tuple, but the referenced object was mutated.
Also Read: Real-Time Object Detection Using TensorFlow
Same way, let’s explore how it will behave if you have a mutable object which contains an immutable object? Let us again use a code to understand the behaviour–
#creating a list (mutable object) which contains tuples(immutable) as it’s elements
list1 = [(1, 2, 3), (4, 5, 6)]
#printing the list
print(list1)
Output [1]: [(1, 2, 3), (4, 5, 6)]
#printing the location of the object created in the memory address in hexadecimal format
print(hex(id(list1)))
Output [2]: 0x1691d5b13c8
#changing object reference at index 0
list1[0] = (7, 8, 9)
#printing the list
Output [3]: [(7, 8, 9), (4, 5, 6)]
#printing the location of the object created in the memory address in hexadecimal format
print(hex(id(list1)))
Output [4]: 0x1691d5b13c8
As an individual, it completely depends upon you and your requirements as to what kind of data structure you would like to create with a combination of mutable & immutable objects. I hope that this information will help you while deciding the type of object you would like to select going forward.
Before I end our discussion on IMMUTABILITY, allow me to use the word ‘CAVITE’ when we discuss the String and Integers. There is an exception, and you may see some surprising results while checking the truthiness for immutability. For instance:
#creating an object of integer type with value 10 and reference variable name ‘x’
x = 10
#printing the value of ‘x’
print(x)
Output [1]: 10
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(x)))
Output [2]: 0x538fb560
#creating an object of integer type with value 10 and reference variable name ‘y’
y = 10
#printing the value of ‘y’
print(y)
Output [3]: 10
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(y)))
Output [4]: 0x538fb560
As per our discussion and understanding, so far, the memory address for x & y should have been different, since, 10 is an instance of Integer class which is immutable. However, as shown in the above code, it has the same memory address. This is not something that we expected. It seems that what we have understood and discussed, has an exception as well.
Quick check – Python Data Structures
Tuples are immutable and hence cannot have any changes in them once they are created in Python. This is because they support the same sequence operations as strings. We all know that strings are immutable. The index operator will select an element from a tuple just like in a string. Hence, they are immutable.
Like all, there are exceptions in the immutability in python too. Not all immutable objects are really mutable. This will lead to a lot of doubts in your mind. Let us just take an example to understand this.
Consider a tuple ‘tup’.
Now, if we consider tuple tup = (‘GreatLearning’,[4,3,1,2]) ;
We see that the tuple has elements of different data types. The first element here is a string which as we all know is immutable in nature. The second element is a list which we all know is mutable. Now, we all know that the tuple itself is an immutable data type. It cannot change its contents. But, the list inside it can change its contents. So, the value of the Immutable objects cannot be changed but its constituent objects can. change its value.
Mutable Object | Immutable Object |
State of the object can be modified after it is created. | State of the object can’t be modified once it is created. |
They are not thread safe. | They are thread safe |
Mutable classes are not final. | It is important to make the class final before creating an immutable object. |
list, dictionary, set, user-defined classes.
int, float, decimal, bool, string, tuple, range.
Lists in Python are mutable data types as the elements of the list can be modified, individual elements can be replaced, and the order of elements can be changed even after the list has been created.
(Examples related to lists have been discussed earlier in this blog.)
Tuple and list data structures are very similar, but one big difference between the data types is that lists are mutable, whereas tuples are immutable. The reason for the tuple’s immutability is that once the elements are added to the tuple and the tuple has been created; it remains unchanged.
A programmer would always prefer building a code that can be reused instead of making the whole data object again. Still, even though tuples are immutable, like lists, they can contain any Python object, including mutable objects.
A set is an iterable unordered collection of data type which can be used to perform mathematical operations (like union, intersection, difference etc.). Every element in a set is unique and immutable, i.e. no duplicate values should be there, and the values can’t be changed. However, we can add or remove items from the set as the set itself is mutable.
Strings are not mutable in Python. Strings are a immutable data types which means that its value cannot be updated.
Join Great Learning Academy’s free online courses and upgrade your skills today.
Original article source at: https://www.mygreatlearning.com
1561523460
This Matplotlib cheat sheet introduces you to the basics that you need to plot your data with Python and includes code samples.
Data visualization and storytelling with your data are essential skills that every data scientist needs to communicate insights gained from analyses effectively to any audience out there.
For most beginners, the first package that they use to get in touch with data visualization and storytelling is, naturally, Matplotlib: it is a Python 2D plotting library that enables users to make publication-quality figures. But, what might be even more convincing is the fact that other packages, such as Pandas, intend to build more plotting integration with Matplotlib as time goes on.
However, what might slow down beginners is the fact that this package is pretty extensive. There is so much that you can do with it and it might be hard to still keep a structure when you're learning how to work with Matplotlib.
DataCamp has created a Matplotlib cheat sheet for those who might already know how to use the package to their advantage to make beautiful plots in Python, but that still want to keep a one-page reference handy. Of course, for those who don't know how to work with Matplotlib, this might be the extra push be convinced and to finally get started with data visualization in Python.
You'll see that this cheat sheet presents you with the six basic steps that you can go through to make beautiful plots.
Check out the infographic by clicking on the button below:
With this handy reference, you'll familiarize yourself in no time with the basics of Matplotlib: you'll learn how you can prepare your data, create a new plot, use some basic plotting routines to your advantage, add customizations to your plots, and save, show and close the plots that you make.
What might have looked difficult before will definitely be more clear once you start using this cheat sheet! Use it in combination with the Matplotlib Gallery, the documentation.
Matplotlib
Matplotlib is a Python 2D plotting library which produces publication-quality figures in a variety of hardcopy formats and interactive environments across platforms.
>>> import numpy as np
>>> x = np.linspace(0, 10, 100)
>>> y = np.cos(x)
>>> z = np.sin(x)
>>> data = 2 * np.random.random((10, 10))
>>> data2 = 3 * np.random.random((10, 10))
>>> Y, X = np.mgrid[-3:3:100j, -3:3:100j]
>>> U = 1 X** 2 + Y
>>> V = 1 + X Y**2
>>> from matplotlib.cbook import get_sample_data
>>> img = np.load(get_sample_data('axes_grid/bivariate_normal.npy'))
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
>>> fig2 = plt.figure(figsize=plt.figaspect(2.0))
>>> fig.add_axes()
>>> ax1 = fig.add_subplot(221) #row-col-num
>>> ax3 = fig.add_subplot(212)
>>> fig3, axes = plt.subplots(nrows=2,ncols=2)
>>> fig4, axes2 = plt.subplots(ncols=3)
>>> plt.savefig('foo.png') #Save figures
>>> plt.savefig('foo.png', transparent=True) #Save transparent figures
>>> plt.show()
>>> fig, ax = plt.subplots()
>>> lines = ax.plot(x,y) #Draw points with lines or markers connecting them
>>> ax.scatter(x,y) #Draw unconnected points, scaled or colored
>>> axes[0,0].bar([1,2,3],[3,4,5]) #Plot vertical rectangles (constant width)
>>> axes[1,0].barh([0.5,1,2.5],[0,1,2]) #Plot horiontal rectangles (constant height)
>>> axes[1,1].axhline(0.45) #Draw a horizontal line across axes
>>> axes[0,1].axvline(0.65) #Draw a vertical line across axes
>>> ax.fill(x,y,color='blue') #Draw filled polygons
>>> ax.fill_between(x,y,color='yellow') #Fill between y values and 0
>>> fig, ax = plt.subplots()
>>> im = ax.imshow(img, #Colormapped or RGB arrays
cmap= 'gist_earth',
interpolation= 'nearest',
vmin=-2,
vmax=2)
>>> axes2[0].pcolor(data2) #Pseudocolor plot of 2D array
>>> axes2[0].pcolormesh(data) #Pseudocolor plot of 2D array
>>> CS = plt.contour(Y,X,U) #Plot contours
>>> axes2[2].contourf(data1) #Plot filled contours
>>> axes2[2]= ax.clabel(CS) #Label a contour plot
>>> axes[0,1].arrow(0,0,0.5,0.5) #Add an arrow to the axes
>>> axes[1,1].quiver(y,z) #Plot a 2D field of arrows
>>> axes[0,1].streamplot(X,Y,U,V) #Plot a 2D field of arrows
>>> ax1.hist(y) #Plot a histogram
>>> ax3.boxplot(y) #Make a box and whisker plot
>>> ax3.violinplot(z) #Make a violin plot
y-axis
x-axis
The basic steps to creating plots with matplotlib are:
1 Prepare Data
2 Create Plot
3 Plot
4 Customized Plot
5 Save Plot
6 Show Plot
>>> import matplotlib.pyplot as plt
>>> x = [1,2,3,4] #Step 1
>>> y = [10,20,25,30]
>>> fig = plt.figure() #Step 2
>>> ax = fig.add_subplot(111) #Step 3
>>> ax.plot(x, y, color= 'lightblue', linewidth=3) #Step 3, 4
>>> ax.scatter([2,4,6],
[5,15,25],
color= 'darkgreen',
marker= '^' )
>>> ax.set_xlim(1, 6.5)
>>> plt.savefig('foo.png' ) #Step 5
>>> plt.show() #Step 6
>>> plt.cla() #Clear an axis
>>> plt.clf(). #Clear the entire figure
>>> plt.close(). #Close a window
>>> plt.plot(x, x, x, x**2, x, x** 3)
>>> ax.plot(x, y, alpha = 0.4)
>>> ax.plot(x, y, c= 'k')
>>> fig.colorbar(im, orientation= 'horizontal')
>>> im = ax.imshow(img,
cmap= 'seismic' )
>>> fig, ax = plt.subplots()
>>> ax.scatter(x,y,marker= ".")
>>> ax.plot(x,y,marker= "o")
>>> plt.plot(x,y,linewidth=4.0)
>>> plt.plot(x,y,ls= 'solid')
>>> plt.plot(x,y,ls= '--')
>>> plt.plot(x,y,'--' ,x**2,y**2,'-.' )
>>> plt.setp(lines,color= 'r',linewidth=4.0)
>>> ax.text(1,
-2.1,
'Example Graph',
style= 'italic' )
>>> ax.annotate("Sine",
xy=(8, 0),
xycoords= 'data',
xytext=(10.5, 0),
textcoords= 'data',
arrowprops=dict(arrowstyle= "->",
connectionstyle="arc3"),)
>>> plt.title(r '$sigma_i=15$', fontsize=20)
Limits & Autoscaling
>>> ax.margins(x=0.0,y=0.1) #Add padding to a plot
>>> ax.axis('equal') #Set the aspect ratio of the plot to 1
>>> ax.set(xlim=[0,10.5],ylim=[-1.5,1.5]) #Set limits for x-and y-axis
>>> ax.set_xlim(0,10.5) #Set limits for x-axis
Legends
>>> ax.set(title= 'An Example Axes', #Set a title and x-and y-axis labels
ylabel= 'Y-Axis',
xlabel= 'X-Axis')
>>> ax.legend(loc= 'best') #No overlapping plot elements
Ticks
>>> ax.xaxis.set(ticks=range(1,5), #Manually set x-ticks
ticklabels=[3,100, 12,"foo" ])
>>> ax.tick_params(axis= 'y', #Make y-ticks longer and go in and out
direction= 'inout',
length=10)
Subplot Spacing
>>> fig3.subplots_adjust(wspace=0.5, #Adjust the spacing between subplots
hspace=0.3,
left=0.125,
right=0.9,
top=0.9,
bottom=0.1)
>>> fig.tight_layout() #Fit subplot(s) in to the figure area
Axis Spines
>>> ax1.spines[ 'top'].set_visible(False) #Make the top axis line for a plot invisible
>>> ax1.spines['bottom' ].set_position(( 'outward',10)) #Move the bottom axis line outward
Have this Cheat Sheet at your fingertips
Original article source at https://www.datacamp.com
#matplotlib #cheatsheet #python