How to Use Svelte Store To Store All Variables

In this video, I'm using Svelte store to store all the variables of the Shopping cart into a single file which can be shared by multiple components.


What is GEEK

Buddha Community

How to Use Svelte Store To Store All Variables
Chloe  Butler

Chloe Butler


Pdf2gerb: Perl Script Converts PDF Files to Gerber format


Perl script converts PDF files to Gerber format

Pdf2Gerb generates Gerber 274X photoplotting and Excellon drill files from PDFs of a PCB. Up to three PDFs are used: the top copper layer, the bottom copper layer (for 2-sided PCBs), and an optional silk screen layer. The PDFs can be created directly from any PDF drawing software, or a PDF print driver can be used to capture the Print output if the drawing software does not directly support output to PDF.

The general workflow is as follows:

  1. Design the PCB using your favorite CAD or drawing software.
  2. Print the top and bottom copper and top silk screen layers to a PDF file.
  3. Run Pdf2Gerb on the PDFs to create Gerber and Excellon files.
  4. Use a Gerber viewer to double-check the output against the original PCB design.
  5. Make adjustments as needed.
  6. Submit the files to a PCB manufacturer.

Please note that Pdf2Gerb does NOT perform DRC (Design Rule Checks), as these will vary according to individual PCB manufacturer conventions and capabilities. Also note that Pdf2Gerb is not perfect, so the output files must always be checked before submitting them. As of version 1.6, Pdf2Gerb supports most PCB elements, such as round and square pads, round holes, traces, SMD pads, ground planes, no-fill areas, and panelization. However, because it interprets the graphical output of a Print function, there are limitations in what it can recognize (or there may be bugs).

See docs/Pdf2Gerb.pdf for install/setup, config, usage, and other info.

#Pdf2Gerb config settings:
#Put this file in same folder/directory as itself (global settings),
#or copy to another folder/directory with PDFs if you want PCB-specific settings.
#There is only one user of this file, so we don't need a custom package or namespace.
#NOTE: all constants defined in here will be added to main namespace.
#package pdf2gerb_cfg;

use strict; #trap undef vars (easier debug)
use warnings; #other useful info (easier debug)

#configurable settings:
#change values here instead of in main file

use constant WANT_COLORS => ($^O !~ m/Win/); #ANSI colors no worky on Windows? this must be set < first DebugPrint() call

#just a little warning; set realistic expectations:
#DebugPrint("${\(CYAN)} ${\(VERSION)}, $^O O/S\n${\(YELLOW)}${\(BOLD)}${\(ITALIC)}This is EXPERIMENTAL software.  \nGerber files MAY CONTAIN ERRORS.  Please CHECK them before fabrication!${\(RESET)}", 0); #if WANT_DEBUG

use constant METRIC => FALSE; #set to TRUE for metric units (only affect final numbers in output files, not internal arithmetic)
use constant APERTURE_LIMIT => 0; #34; #max #apertures to use; generate warnings if too many apertures are used (0 to not check)
use constant DRILL_FMT => '2.4'; #'2.3'; #'2.4' is the default for PCB fab; change to '2.3' for CNC

use constant WANT_DEBUG => 0; #10; #level of debug wanted; higher == more, lower == less, 0 == none
use constant GERBER_DEBUG => 0; #level of debug to include in Gerber file; DON'T USE FOR FABRICATION
use constant WANT_STREAMS => FALSE; #TRUE; #save decompressed streams to files (for debug)
use constant WANT_ALLINPUT => FALSE; #TRUE; #save entire input stream (for debug ONLY)

#DebugPrint(sprintf("${\(CYAN)}DEBUG: stdout %d, gerber %d, want streams? %d, all input? %d, O/S: $^O, Perl: $]${\(RESET)}\n", WANT_DEBUG, GERBER_DEBUG, WANT_STREAMS, WANT_ALLINPUT), 1);
#DebugPrint(sprintf("max int = %d, min int = %d\n", MAXINT, MININT), 1); 

#define standard trace and pad sizes to reduce scaling or PDF rendering errors:
#This avoids weird aperture settings and replaces them with more standardized values.
#(I'm not sure how photoplotters handle strange sizes).
#Fewer choices here gives more accurate mapping in the final Gerber files.
#units are in inches
use constant TOOL_SIZES => #add more as desired
#round or square pads (> 0) and drills (< 0):
    .010, -.001,  #tiny pads for SMD; dummy drill size (too small for practical use, but needed so StandardTool will use this entry)
    .031, -.014,  #used for vias
    .041, -.020,  #smallest non-filled plated hole
    .051, -.025,
    .056, -.029,  #useful for IC pins
    .070, -.033,
    .075, -.040,  #heavier leads
#    .090, -.043,  #NOTE: 600 dpi is not high enough resolution to reliably distinguish between .043" and .046", so choose 1 of the 2 here
    .100, -.046,
    .115, -.052,
    .130, -.061,
    .140, -.067,
    .150, -.079,
    .175, -.088,
    .190, -.093,
    .200, -.100,
    .220, -.110,
    .160, -.125,  #useful for mounting holes
#some additional pad sizes without holes (repeat a previous hole size if you just want the pad size):
    .090, -.040,  #want a .090 pad option, but use dummy hole size
    .065, -.040, #.065 x .065 rect pad
    .035, -.040, #.035 x .065 rect pad
    .001,  #too thin for real traces; use only for board outlines
    .006,  #minimum real trace width; mainly used for text
    .008,  #mainly used for mid-sized text, not traces
    .010,  #minimum recommended trace width for low-current signals
    .015,  #moderate low-voltage current
    .020,  #heavier trace for power, ground (even if a lighter one is adequate)
    .030,  #heavy-current traces; be careful with these ones!
#Areas larger than the values below will be filled with parallel lines:
#This cuts down on the number of aperture sizes used.
#Set to 0 to always use an aperture or drill, regardless of size.
use constant { MAX_APERTURE => max((TOOL_SIZES)) + .004, MAX_DRILL => -min((TOOL_SIZES)) + .004 }; #max aperture and drill sizes (plus a little tolerance)
#DebugPrint(sprintf("using %d standard tool sizes: %s, max aper %.3f, max drill %.3f\n", scalar((TOOL_SIZES)), join(", ", (TOOL_SIZES)), MAX_APERTURE, MAX_DRILL), 1);

#NOTE: Compare the PDF to the original CAD file to check the accuracy of the PDF rendering and parsing!
#for example, the CAD software I used generated the following circles for holes:
#CAD hole size:   parsed PDF diameter:      error:
#  .014                .016                +.002
#  .020                .02267              +.00267
#  .025                .026                +.001
#  .029                .03167              +.00267
#  .033                .036                +.003
#  .040                .04267              +.00267
#This was usually ~ .002" - .003" too big compared to the hole as displayed in the CAD software.
#To compensate for PDF rendering errors (either during CAD Print function or PDF parsing logic), adjust the values below as needed.
#units are pixels; for example, a value of 2.4 at 600 dpi = .0004 inch, 2 at 600 dpi = .0033"
use constant
    HOLE_ADJUST => -0.004 * 600, #-2.6, #holes seemed to be slightly oversized (by .002" - .004"), so shrink them a little
    RNDPAD_ADJUST => -0.003 * 600, #-2, #-2.4, #round pads seemed to be slightly oversized, so shrink them a little
    SQRPAD_ADJUST => +0.001 * 600, #+.5, #square pads are sometimes too small by .00067, so bump them up a little
    RECTPAD_ADJUST => 0, #(pixels) rectangular pads seem to be okay? (not tested much)
    TRACE_ADJUST => 0, #(pixels) traces seemed to be okay?
    REDUCE_TOLERANCE => .001, #(inches) allow this much variation when reducing circles and rects

#Also, my CAD's Print function or the PDF print driver I used was a little off for circles, so define some additional adjustment values here:
#Values are added to X/Y coordinates; units are pixels; for example, a value of 1 at 600 dpi would be ~= .002 inch
use constant
    CIRCLE_ADJUST_MINY => -0.001 * 600, #-1, #circles were a little too high, so nudge them a little lower
    CIRCLE_ADJUST_MAXX => +0.001 * 600, #+1, #circles were a little too far to the left, so nudge them a little to the right
    SUBST_CIRCLE_CLIPRECT => FALSE, #generate circle and substitute for clip rects (to compensate for the way some CAD software draws circles)
    WANT_CLIPRECT => TRUE, #FALSE, #AI doesn't need clip rect at all? should be on normally?
    RECT_COMPLETION => FALSE, #TRUE, #fill in 4th side of rect when 3 sides found

#allow .012 clearance around pads for solder mask:
#This value effectively adjusts pad sizes in the TOOL_SIZES list above (only for solder mask layers).
use constant SOLDER_MARGIN => +.012; #units are inches

#line join/cap styles:
use constant
    CAP_NONE => 0, #butt (none); line is exact length
    CAP_ROUND => 1, #round cap/join; line overhangs by a semi-circle at either end
    CAP_SQUARE => 2, #square cap/join; line overhangs by a half square on either end
    CAP_OVERRIDE => FALSE, #cap style overrides drawing logic
#number of elements in each shape type:
use constant
    RECT_SHAPELEN => 6, #x0, y0, x1, y1, count, "rect" (start, end corners)
    LINE_SHAPELEN => 6, #x0, y0, x1, y1, count, "line" (line seg)
    CURVE_SHAPELEN => 10, #xstart, ystart, x0, y0, x1, y1, xend, yend, count, "curve" (bezier 2 points)
    CIRCLE_SHAPELEN => 5, #x, y, 5, count, "circle" (center + radius)
#const my %SHAPELEN =
#Readonly my %SHAPELEN =>
    rect => RECT_SHAPELEN,
    line => LINE_SHAPELEN,
    curve => CURVE_SHAPELEN,
    circle => CIRCLE_SHAPELEN,

#This will repeat the entire body the number of times indicated along the X or Y axes (files grow accordingly).
#Display elements that overhang PCB boundary can be squashed or left as-is (typically text or other silk screen markings).
#Set "overhangs" TRUE to allow overhangs, FALSE to truncate them.
#xpad and ypad allow margins to be added around outer edge of panelized PCB.
use constant PANELIZE => {'x' => 1, 'y' => 1, 'xpad' => 0, 'ypad' => 0, 'overhangs' => TRUE}; #number of times to repeat in X and Y directions

# Set this to 1 if you need TurboCAD support.
#$turboCAD = FALSE; #is this still needed as an option?

#CIRCAD pad generation uses an appropriate aperture, then moves it (stroke) "a little" - we use this to find pads and distinguish them from PCB holes. 
use constant PAD_STROKE => 0.3; #0.0005 * 600; #units are pixels
#convert very short traces to pads or holes:
use constant TRACE_MINLEN => .001; #units are inches
#use constant ALWAYS_XY => TRUE; #FALSE; #force XY even if X or Y doesn't change; NOTE: needs to be TRUE for all pads to show in FlatCAM and ViewPlot
use constant REMOVE_POLARITY => FALSE; #TRUE; #set to remove subtractive (negative) polarity; NOTE: must be FALSE for ground planes

#PDF uses "points", each point = 1/72 inch
#combined with a PDF scale factor of .12, this gives 600 dpi resolution (1/72 * .12 = 600 dpi)
use constant INCHES_PER_POINT => 1/72; #0.0138888889; #multiply point-size by this to get inches

# The precision used when computing a bezier curve. Higher numbers are more precise but slower (and generate larger files).
#$bezierPrecision = 100;
use constant BEZIER_PRECISION => 36; #100; #use const; reduced for faster rendering (mainly used for silk screen and thermal pads)

# Ground planes and silk screen or larger copper rectangles or circles are filled line-by-line using this resolution.
use constant FILL_WIDTH => .01; #fill at most 0.01 inch at a time

# The max number of characters to read into memory
use constant MAX_BYTES => 10 * M; #bumped up to 10 MB, use const

use constant DUP_DRILL1 => TRUE; #FALSE; #kludge: ViewPlot doesn't load drill files that are too small so duplicate first tool

my $runtime = time(); #Time::HiRes::gettimeofday(); #measure my execution time

print STDERR "Loaded config settings from '${\(__FILE__)}'.\n";
1; #last value must be truthful to indicate successful load


#use Package::Constants;
#use Exporter qw(import); #

#my $caller = "pdf2gerb::";

#sub cfg
#    my $proto = shift;
#    my $class = ref($proto) || $proto;
#    my $settings =
#    {
#        $WANT_DEBUG => 990, #10; #level of debug wanted; higher == more, lower == less, 0 == none
#    };
#    bless($settings, $class);
#    return $settings;

#use constant HELLO => "hi there2"; #"main::HELLO" => "hi there";
#use constant GOODBYE => 14; #"main::GOODBYE" => 12;

#print STDERR "read cfg file\n";

#our @EXPORT_OK = Package::Constants->list(__PACKAGE__); #; NOTE: "_OK" skips short/common names

#print STDERR scalar(@EXPORT_OK) . " consts exported:\n";
#foreach(@EXPORT_OK) { print STDERR "$_\n"; }
#my $val = main::thing("xyz");
#print STDERR "caller gave me $val\n";
#foreach my $arg (@ARGV) { print STDERR "arg $arg\n"; }

Download Details:

Author: swannman
Source Code:

License: GPL-3.0 license


Why Use WordPress? What Can You Do With WordPress?

Can you use WordPress for anything other than blogging? To your surprise, yes. WordPress is more than just a blogging tool, and it has helped thousands of websites and web applications to thrive. The use of WordPress powers around 40% of online projects, and today in our blog, we would visit some amazing uses of WordPress other than blogging.
What Is The Use Of WordPress?

WordPress is the most popular website platform in the world. It is the first choice of businesses that want to set a feature-rich and dynamic Content Management System. So, if you ask what WordPress is used for, the answer is – everything. It is a super-flexible, feature-rich and secure platform that offers everything to build unique websites and applications. Let’s start knowing them:

1. Multiple Websites Under A Single Installation
WordPress Multisite allows you to develop multiple sites from a single WordPress installation. You can download WordPress and start building websites you want to launch under a single server. Literally speaking, you can handle hundreds of sites from one single dashboard, which now needs applause.
It is a highly efficient platform that allows you to easily run several websites under the same login credentials. One of the best things about WordPress is the themes it has to offer. You can simply download them and plugin for various sites and save space on sites without losing their speed.

2. WordPress Social Network
WordPress can be used for high-end projects such as Social Media Network. If you don’t have the money and patience to hire a coder and invest months in building a feature-rich social media site, go for WordPress. It is one of the most amazing uses of WordPress. Its stunning CMS is unbeatable. And you can build sites as good as Facebook or Reddit etc. It can just make the process a lot easier.
To set up a social media network, you would have to download a WordPress Plugin called BuddyPress. It would allow you to connect a community page with ease and would provide all the necessary features of a community or social media. It has direct messaging, activity stream, user groups, extended profiles, and so much more. You just have to download and configure it.
If BuddyPress doesn’t meet all your needs, don’t give up on your dreams. You can try out WP Symposium or PeepSo. There are also several themes you can use to build a social network.

3. Create A Forum For Your Brand’s Community
Communities are very important for your business. They help you stay in constant connection with your users and consumers. And allow you to turn them into a loyal customer base. Meanwhile, there are many good technologies that can be used for building a community page – the good old WordPress is still the best.
It is the best community development technology. If you want to build your online community, you need to consider all the amazing features you get with WordPress. Plugins such as BB Press is an open-source, template-driven PHP/ MySQL forum software. It is very simple and doesn’t hamper the experience of the website.
Other tools such as wpFoRo and Asgaros Forum are equally good for creating a community blog. They are lightweight tools that are easy to manage and integrate with your WordPress site easily. However, there is only one tiny problem; you need to have some technical knowledge to build a WordPress Community blog page.

4. Shortcodes
Since we gave you a problem in the previous section, we would also give you a perfect solution for it. You might not know to code, but you have shortcodes. Shortcodes help you execute functions without having to code. It is an easy way to build an amazing website, add new features, customize plugins easily. They are short lines of code, and rather than memorizing multiple lines; you can have zero technical knowledge and start building a feature-rich website or application.
There are also plugins like Shortcoder, Shortcodes Ultimate, and the Basics available on WordPress that can be used, and you would not even have to remember the shortcodes.

5. Build Online Stores
If you still think about why to use WordPress, use it to build an online store. You can start selling your goods online and start selling. It is an affordable technology that helps you build a feature-rich eCommerce store with WordPress.
WooCommerce is an extension of WordPress and is one of the most used eCommerce solutions. WooCommerce holds a 28% share of the global market and is one of the best ways to set up an online store. It allows you to build user-friendly and professional online stores and has thousands of free and paid extensions. Moreover as an open-source platform, and you don’t have to pay for the license.
Apart from WooCommerce, there are Easy Digital Downloads, iThemes Exchange, Shopify eCommerce plugin, and so much more available.

6. Security Features
WordPress takes security very seriously. It offers tons of external solutions that help you in safeguarding your WordPress site. While there is no way to ensure 100% security, it provides regular updates with security patches and provides several plugins to help with backups, two-factor authorization, and more.
By choosing hosting providers like WP Engine, you can improve the security of the website. It helps in threat detection, manage patching and updates, and internal security audits for the customers, and so much more.

Read More

#use of wordpress #use wordpress for business website #use wordpress for website #what is use of wordpress #why use wordpress #why use wordpress to build a website

Nat  Grady

Nat Grady


Wordcloud2: R interface to Wordcloud for Data Visualization


R interface to wordcloud for data visualization. Timdream's wordcloud2.js is used in this package.

Original description



knitr and shiny is support in wordcloud2 package.


wordcloud2(demoFreq, size = 1,shape = 'star')


wordcloud2(demoFreq, size = 2, minRotation = -pi/2, maxRotation = -pi/2)


wordcloud2(demoFreq, size = 2, minRotation = -pi/6, maxRotation = -pi/6,
  rotateRatio = 1)


Chinese version

## Sys.setlocale("LC_CTYPE","eng")
wordcloud2(demoFreqC, size = 2, fontFamily = "微软雅黑",
           color = "random-light", backgroundColor = "grey")


Example of successfully deploying interactivate clickable wordcloud with special shape on R-shiny

Thanks JacobXPX's contribution to this feature:

Thanks AdamSpannbauer for pointing out the issues.

Additional features are added or modified:

hover information display are fixed, refering AdeelK93's previous work, thanks!

multiple wordclouds which seperatedly click are supported.

clickedWordInputId is changed to be automatically generated by: paste0(outputId, "_clicked_word")).

See sample below for more details:

    #using default clicked word input id
    wordcloud2Output("my_wc", width = "50%", height = "400px"),
    #using custom clicked word input id
    wordcloud2Output("my_wc2", width = "50%", height = "400px"),
    figPath = system.file("examples/a.png",package = "wordcloud2")
    output$my_wc  = renderWordcloud2(wordcloud2(data = demoFreq, figPath = figPath, size = 0.4,color = "blue"))
    output$my_wc2 = renderWordcloud2(wordcloud2(demoFreq))
    #using default clicked word input id
    output$print  = renderPrint(input$my_wc_clicked_word)
    #using custom clicked word input id
    output$print2 = renderPrint(input$my_wc2_clicked_word)

run the above code and click refresh, it will work.



Download Details:

Author: Lchiffon
Source Code: 

#r #datavisualization 

Trung  Nguyen

Trung Nguyen


Vượt Qua Kỳ Thi Chuyên Gia Bảo Mật Kubernetes Được Chứng Nhận

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à gì?

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.

Tài nguyên cho kỳ thi

Sau đây là một số tài nguyên tuyệt vời có sẵn để vượt qua kỳ thi CKS:

  1. Chuyên gia bảo mật Kubernetes được chứng nhận bởi
  2. Chuyên gia bảo mật Kubernetes được chứng nhận (CKS) bởi KodeKloud
  3. Walid Shaari đã tập hợp một số tài liệu không thể thiếu cho kỳ thi CKS
  4. Tài liệu tham khảo của Abdennour cho các mục tiêu kỳ thi CKS
  5. Bộ sưu tập tài nguyên của Ibrahim Jelliti để chuẩn bị cho kỳ thi Chuyên gia bảo mật Kubernetes được chứng nhận (CKSS)

Các khóa học cho KodeKloud và 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ừ 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.

Bí danh

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 mặc định cho ~ / .vimrc:

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

kubectl mặc định cho ~ / .bashrc:

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'

Các phím tắt

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.

  • po cho pods
  • rs cho replicasets
  • triển khai cho deployments
  • svc cho services
  • ns cho namespace
  • netpol cho networkpolicy
  • pv cho persistentstorage
  • pvc cho persistentstorageclaim
  • sa cho serviceaccounts

Kubernetes Cheat Sheet

lệnh chạy kubectl

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

Cách tạo thông số yaml từ một nhóm hiện có

Đô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 pod kubectl

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

Cách in nhật ký và xuất chúng

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

Cách tạo bản đồ cấu hình và bí mật

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

Các lệnh hữu ích để gỡ lỗi

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ư ncnslookup để 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

Cập nhật lần lượt và triển khai

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 scale và autoscale

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

Chính sách mạng

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.

kind: NetworkPolicy
  name: example
  namespace: default
  podSelector: {}
  - 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.

kind: NetworkPolicy
  name: deny
  namespace: default
  podSelector: {}
  - Egress
  - Ingress
  - to:
      - 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 Phiên bản AWS EC2.

kind: Ingress
  namespace: default
  podSelector: {}
  - Egress
  - to:
      - ipBlock: 

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 Phiên bản AWS EC2.

kind: Ingress
  name: cloud-metadata-accessor
  namespace: default
      role: metadata-accessor
  - Egress
  - to:
    - ipBlock:

Phân tích tĩnh bằng Kubesec

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

# Running the API locally
kubesec http 8080 &

kubesec scan pod.yaml -o pod_report.json -o json

Quét lỗ hổng bảo mật bằng Trivvy

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

Cách xóa các dịch vụ không mong muốn

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

Các lớp thời gian chạy

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.20và sẽ bị xóa trong v1.24.

Cách tạo một Lớp thời gian chạy:

kind: RuntimeClass
  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
    run: nginx
  name: nginx
  runtimeClassName: gvisor
  - 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ảo trì cụm

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

Mẹo thi CKS

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.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[?("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=',Images:.spec.containers[*].image'

Chủ đề kỳ thi CKS

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.

Cách bảo mật và làm cứng hình ảnh vùng chứa

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:

  1. Sử dụng các phiên bản gói cụ thể như alpine:3.13.
  2. Không chạy dưới quyền root - sử dụng USER <username>để chặn quyền truy cập root.
  3. Đặt hệ thống tệp ở chế độ chỉ đọc khi securityContext sử dụng readOnlyRootFilesystem: true
  4. Xóa quyền truy cập shell bằng cách sử dụng RUN rm -rf /bin/*

Cách giảm thiểu dấu chân của hệ điều hành

Các lớp chứa

Hướng dẫn RUNCOPY 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"]

Bản dựng nhiều giai đoạn

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ách giới hạn quyền truy cập vào nút

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
#Stores the user password in a hashed format
#Stores information about the group a user belongs
#Stored information about the Sudoers present in the system

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

usermod -aG sudo faizanbashir
usermod faizanbashir -G admin

Làm cứng SSH

Cách tắt SSH

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/ faizanbashir@node01
ssh faizanbashir@node01

Cách xóa các gói và dịch vụ lỗi thời

Đâ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

Cách hạn chế mô-đun hạt nhân

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:


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 xác định và tắt các cổng đang mở

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ở .

Cách hạn chế quyền truy cập mạng

Cách xác định một dịch vụ đang chạy trên cổng:

systemctl status ssh
cat /etc/services | grep ssh
netstat -an | grep 22 | grep -w LISTEN

Tường lửa UFW

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 to any port 22 proto tcp
ufw allow from to any port 80 proto tcp
ufw allow from 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

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:

  • Mã hạt nhân
  • Phần mở rộng Kernel
  • Trình điều khiển thiết bị

Cách theo dõi Syscalls bằng Strace

Đâ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

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.

  • Nhị phân được lưu trữ tại/tmp/tracee
  • Cần quyền truy cập vào phần sau, ở chế độ chỉ đọc nếu chạy bằng vùng chứa có --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ân

Là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

Cách hạn chế Syscalls với Seccomp

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:

  • Chế độ 0: Đã tắt
  • Chế độ 1: Nghiêm ngặt
  • Chế độ 2: Đã lọc

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": [
  "syscalls": [
      "names": [
      "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": [
  "syscalls": [
      "names": [
      "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 amicontained

Seccomp trong Kubernetes

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 amicontained -- amicontained

Kể từ phiên bản v1.20Kubernetes không triển khai seccomp theo mặc định.

Cấu hình docker Seccomp 'RuntimeDefault' trong Kubernetes:

apiVersion: v1
kind: Pod
    run: amicontained
  name: amicontained
      type: RuntimeDefault
  - args:
    - amicontained
    name: amicontained
      allowPrivilegeEscalation: false

Vị trí seccomp mặc định trong kubelet


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:

    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

Các cấu hình AppArmor được lưu trữ tại:

cat /etc/apparmor.d/

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) {
  # 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) {
  # 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ơ:


Chế độ tải hồ sơ

  • Enforce, giám sát và thực thi các quy tắc
  • Complain, 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ện
  • Unconfined, sẽ không thực thi hoặc ghi lại các sự kiện

Cách kiểm tra xem hồ sơ có hợp lệ không:

apparmor_parser /etc/apparmor.d/

Cách tắt cấu hình:

apparmor_parser -R /etc/apparmor.d/
ln -s /etc/apparmor.d/ /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/

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ý:


Cách sử dụng AppArmor trong Kubernetes

Để sử dụng AppArmor với Kubernetes, bạn phải đáp ứng các điều kiện tiên quyết sau:

  • Phiên bản Kubernetes phải lớn hơn1.4
  • Mô-đun AppArmor Kernel nên được bật
  • Cấu hình AppArmor phải được tải trong hạt nhân
  • Thời gian chạy vùng chứa phải được hỗ trợ

Cách sử dụng mẫu trong Kubernetes:

apiVersion: v1
kind: Pod
  name: ubuntu-sleeper
  annotations:<container-name>: localhost/<profile-name>
  - 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.

Khả năng của Linux

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--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--cap-drophỗ 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.

  • Kernel <2,2
    • Quy trình đặc quyền
    • Quy trình đặc quyền
  • Kernel> = 2.2
    • Quy trình đặc quyền
      • CAP_CHOWN
      • CAP_SYS_TIME
      • CAP_SYS_BOOT

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
  name: ubuntu-sleeper
  - name: ubuntu-sleeper
    image: ubuntu
    command: ["sleep", "1000"]
        add: ["SYS_TIME"]
        drop: ["CHOWN"]

Làm thế nào để chuẫn bị cho một kì thi

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, Thực hành và Thực hành!

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à 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!



Josefa  Corwin

Josefa Corwin


Mailboxer: A Rails Gem to Send Messages inside A Web Application


This project is based on the need for a private message system for ging / social_stream. Instead of creating our core message system heavily dependent on our development, we are trying to implement a generic and potent messaging gem.

After looking for a good gem to use we noticed the lack of messaging gems and functionality in them. Mailboxer tries to fill this void delivering a powerful and flexible message system. It supports the use of conversations with two or more participants, sending notifications to recipients (intended to be used as system notifications “Your picture has new comments”, “John Doe has updated his document”, etc.), and emailing the messageable model (if configured to do so). It has a complete implementation of a Mailbox object for each messageable with inbox, sentbox and trash.

The gem is constantly growing and improving its functionality. As it is used with our parallel development ging / social_stream we are finding and fixing bugs continously. If you want some functionality not supported yet or marked as TODO, you can create an issue to ask for it. It will be great feedback for us, and we will know what you may find useful in the gem.

Mailboxer was born from the great, but outdated, code from lpsergi / acts_as_messageable.

We are now working to make exhaustive documentation and some wiki pages in order to make it even easier to use the gem to its full potential. Please, give us some time if you find something missing or ask for it. You can also find us on the Gitter room for this repo. Join us there to talk.


Add to your Gemfile:

gem 'mailboxer'

Then run:

$ bundle install

Run install script:

$ rails g mailboxer:install

And don't forget to migrate your database:

$ rake db:migrate

You can also generate email views:

$ rails g mailboxer:views


If upgrading from 0.11.0 to 0.12.0, run the following generators:

$ rails generate mailboxer:namespacing_compatibility
$ rails generate mailboxer:install -s

Then, migrate your database:

$ rake db:migrate

Requirements & Settings


We are now adding support for sending emails when a Notification or a Message is sent to one or more recipients. You should modify the mailboxer initializer (/config/initializer/mailboxer.rb) to edit these settings:

Mailboxer.setup do |config|
  #Enables or disables email sending for Notifications and Messages
  config.uses_emails = true
  #Configures the default `from` address for the email sent for Messages and Notifications of Mailboxer
  config.default_from = ""

You can change the way in which emails are delivered by specifying a custom implementation of notification and message mailers:

Mailboxer.setup do |config|
  config.notification_mailer = CustomNotificationMailer
  config.message_mailer = CustomMessageMailer

If you have subclassed the Mailboxer::Notification class, you can specify the mailers using a member method:

class NewDocumentNotification < Mailboxer::Notification
  def mailer_class

class NewCommentNotification < Mailboxer::Notification
  def mailer_class

Otherwise, the mailer class will be determined by appending 'Mailer' to the mailable class name.

User identities

Users must have an identity defined by a name and an email. We must ensure that Messageable models have some specific methods. These methods are:

#Returning any kind of identification you want for the model
def name
  return "You should add method :name in your Messageable model"
#Returning the email address of the model if an email should be sent for this object (Message or Notification).
#If no mail has to be sent, return nil.
def mailboxer_email(object)
  #Check if an email should be sent for that object
  #if true
  return "define_email@on_your.model"
  #if false
  #return nil

These names are explicit enough to avoid colliding with other methods, but as long as you need to change them you can do it by using mailboxer initializer (/config/initializer/mailboxer.rb). Just add or uncomment the following lines:

Mailboxer.setup do |config|
  # ...
  #Configures the methods needed by mailboxer
  config.email_method = :mailboxer_email
  config.name_method = :name
  config.notify_method = :notify
  # ...

You may change whatever you want or need. For example:

config.email_method = :notification_email
config.name_method = :display_name
config.notify_method = :notify_mailboxer

Will use the method notification_email(object) instead of mailboxer_email(object), display_name for name and notify_mailboxer for notify.

Using default or custom method names, if your model doesn't implement them, Mailboxer will use dummy methods so as to notify you of missing methods rather than crashing.

Preparing your models

In your model:

class User < ActiveRecord::Base

You are not limited to the User model. You can use Mailboxer in any other model and use it in several different models. If you have ducks and cylons in your application and you want to exchange messages as if they were the same, just add acts_as_messageable to each one and you will be able to send duck-duck, duck-cylon, cylon-duck and cylon-cylon messages. Of course, you can extend it for as many classes as you need.


class Duck < ActiveRecord::Base
class Cylon < ActiveRecord::Base

Mailboxer API

Warning for version 0.8.0

Version 0.8.0 sees Messageable#read and Messageable#unread renamed to mark_as_(un)read, and Receipt#read and Receipt#unread to is_(un)read. This may break existing applications, but read is a reserved name for Active Record, and the best pratice in this case is simply avoid using it.

How can I send a message?

#alfa wants to send a message to beta
alfa.send_message(beta, "Body", "subject")

How can I read the messages of a conversation?

As a messageable, what you receive are receipts, which are associated with the message itself. You should retrieve your receipts for the conversation and get the message associated with them.

This is done this way because receipts save the information about the relation between messageable and the messages: is it read?, is it trashed?, etc.

#alfa gets the last conversation (chronologically, the first in the inbox)
conversation = alfa.mailbox.inbox.first

#alfa gets it receipts chronologically ordered.
receipts = conversation.receipts_for alfa

#using the receipts (i.e. in the view)
receipts.each do |receipt|
  message = receipt.message
  read = receipt.is_unread? #or message.is_unread?(alfa)

How can I reply to a message?

#alfa wants to reply to all in a conversation
#using a receipt
alfa.reply_to_all(receipt, "Reply body")

#using a conversation
alfa.reply_to_conversation(conversation, "Reply body")
#alfa wants to reply to the sender of a message (and ONLY the sender)
#using a receipt
alfa.reply_to_sender(receipt, "Reply body")

How can I delete a message from trash?

#delete conversations forever for one receipt (still in database)

#you can mark conversation as deleted for one participant
conversation.mark_as_deleted participant

#Mark the object as deleted for messageable
#Object can be:
  #* A Receipt
  #* A Conversation
  #* A Notification
  #* A Message
  #* An array with any of them
alfa.mark_as_deleted conversation

# get available message for specific user

How can I retrieve my conversations?

#alfa wants to retrieve all his conversations

#A wants to retrieve his inbox

#A wants to retrieve his sent conversations

#alfa wants to retrieve his trashed conversations

How can I paginate conversations?

You can use Kaminari to paginate the conversations as normal. Please, make sure you use the last version as mailboxer uses select('DISTINCT conversations.*') which was not respected before Kaminari 0.12.4 according to its changelog. Working correctly on Kaminari 0.13.0.

#Paginating all conversations using :page parameter and 9 per page
conversations =[:page]).per(9)

#Paginating received conversations using :page parameter and 9 per page
conversations =[:page]).per(9)

#Paginating sent conversations using :page parameter and 9 per page
conversations =[:page]).per(9)

#Paginating trashed conversations using :page parameter and 9 per page
conversations =[:page]).per(9)

You can take a look at the full documentation for Mailboxer in

Do you want to test Mailboxer?

Thanks to Roman Kushnir (@RKushnir) you can test Mailboxer with this sample app.

I need a GUI!

If you need a GUI you should take a look at these links:


Author: mailboxer
Source code:
License: MIT license

#ruby  #ruby-on-rails